/* * PPP.delete method */ static dbus_bool_t ni_objectmodel_ppp_device_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *dev; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return FALSE; NI_TRACE_ENTER_ARGS("dev=%s", dev->name); if (ni_system_ppp_delete(nc, dev) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Error deleting ppp interface %s", dev->name); return FALSE; } ni_client_state_drop(dev->link.ifindex); return TRUE; }
/* * InfinibandChild.delete method */ static dbus_bool_t ni_objectmodel_ib_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_netdev_t *ifp; if (!(ifp = ni_objectmodel_unwrap_netif(object, error))) return FALSE; NI_TRACE_ENTER_ARGS("ifp=%s", ifp->name); if (ni_system_infiniband_child_delete(ifp) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to delete infiniband child interface", ifp->name); return FALSE; } ni_client_state_drop(ifp->link.ifindex); ni_dbus_object_free(object); return TRUE; }
static dbus_bool_t __ni_objectmodel_macvlan_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_netdev_t *dev; int rv; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return FALSE; NI_TRACE_ENTER_ARGS("dev=%s", dev->name); if ((rv = ni_system_macvlan_delete(dev)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Error deleting macvlan interface %s: %s", dev->name, ni_strerror(rv)); return FALSE; } ni_client_state_drop(dev->link.ifindex); return TRUE; }
/* * Delete a PPP interface */ dbus_bool_t ni_objectmodel_ppp_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_netdev_t *dev; int rv; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return FALSE; NI_TRACE_ENTER_ARGS("dev=%s", dev->name); if ((rv = ni_system_ppp_delete(dev)) < 0) { ni_dbus_set_error_from_code(error, rv, "Unable to delete PPP interface %s: %s", dev->name, ni_strerror(rv)); return FALSE; } ni_client_state_drop(dev->link.ifindex); ni_dbus_object_free(object); return TRUE; }
/* * Process DELLINK event */ int __ni_rtevent_dellink(ni_netconfig_t *nc, const struct sockaddr_nl *nladdr, struct nlmsghdr *h) { struct ifinfomsg *ifi; ni_netdev_t *dev; struct nlattr *nla; const char *ifname = NULL; if (!(ifi = ni_rtnl_ifinfomsg(h, RTM_DELLINK))) return -1; if ((nla = nlmsg_find_attr(h, sizeof(*ifi), IFLA_IFNAME)) != NULL) { ifname = (char *) nla_data(nla); } if (ifi->ifi_family == AF_BRIDGE) { ni_debug_events("%s: ignoring bridge DELLINK event", ifname); return 0; } /* Open code interface removal. */ if ((dev = ni_netdev_by_index(nc, ifi->ifi_index)) == NULL) { ni_debug_events("RTM_DELLINK message for unknown interface %s index %d", ifname, ifi->ifi_index); return -1; } else { unsigned int old_flags = dev->link.ifflags; dev->link.ifflags = __ni_netdev_translate_ifflags(ifi->ifi_flags, old_flags); dev->deleted = 1; __ni_netdev_process_events(nc, dev, old_flags); ni_client_state_drop(dev->link.ifindex); ni_netconfig_device_remove(nc, dev); } return 0; }
/* * Process NEWLINK event */ int __ni_rtevent_newlink(ni_netconfig_t *nc, const struct sockaddr_nl *nladdr, struct nlmsghdr *h) { char namebuf[IF_NAMESIZE+1] = {'\0'}; ni_netdev_t *dev, *old; struct ifinfomsg *ifi; struct nlattr *nla; char *ifname = NULL; int old_flags = 0; if (!(ifi = ni_rtnl_ifinfomsg(h, RTM_NEWLINK))) return -1; if (ifi->ifi_family == AF_BRIDGE) return 0; old = ni_netdev_by_index(nc, ifi->ifi_index); ifname = if_indextoname(ifi->ifi_index, namebuf); if (!ifname) { /* * device (index) does not exists any more; * process deletion/cleanup of the device. */ if (old) { old_flags = old->link.ifflags; old->link.ifflags = 0; old->deleted = 1; __ni_netdev_process_events(nc, old, old_flags); ni_client_state_drop(old->link.ifindex); ni_netconfig_device_remove(nc, old); } return 0; } if (old) { if (!ni_string_eq(old->name, ifname)) { ni_debug_events("%s[%u]: device renamed to %s", old->name, old->link.ifindex, ifname); ni_string_dup(&old->name, ifname); __ni_netdev_event(nc, old, NI_EVENT_DEVICE_RENAME); } dev = old; old_flags = old->link.ifflags; } else { if (!(dev = ni_netdev_new(ifname, ifi->ifi_index))) { ni_warn("%s[%u]: unable to allocate memory for device", ifname, ifi->ifi_index); return -1; } dev->created = 1; ni_netconfig_device_append(nc, dev); } if (__ni_netdev_process_newlink(dev, h, ifi, nc) < 0) { ni_error("Problem parsing RTM_NEWLINK message for %s", ifname); return -1; } if ((ifname = dev->name)) { ni_netdev_t *conflict; conflict = ni_netdev_by_name(nc, ifname); if (conflict && conflict->link.ifindex != (unsigned int)ifi->ifi_index) { /* * As the events often provide an already obsolete name [2 events, * we process 1st with next in read buffer], we are reading the * current dev->name in advance (above). * * On a rename like eth0->rename1->eth1, eth1->rename2->eth0, the * current dev->name is already eth1 at processing time of eth0 * to rename1 event. This sometimes causes that we find eth1 in * our device list [eth1 -> rename2 event in the read buffer]. * * Just update the name of the conflicting device in advance too * and when the interface does not exist any more, emit events. */ char *current = if_indextoname(conflict->link.ifindex, namebuf); if (current) { ni_string_dup(&conflict->name, current); __ni_netdev_event(nc, conflict, NI_EVENT_DEVICE_RENAME); } else { unsigned int ifflags = conflict->link.ifflags; conflict->link.ifflags = 0; conflict->deleted = 1; __ni_netdev_process_events(nc, conflict, ifflags); ni_client_state_drop(conflict->link.ifindex); ni_netconfig_device_remove(nc, conflict); } } } __ni_netdev_process_events(nc, dev, old_flags); if ((nla = nlmsg_find_attr(h, sizeof(*ifi), IFLA_WIRELESS)) != NULL) __ni_wireless_link_event(nc, dev, nla_data(nla), nla_len(nla)); return 0; }