2
0
mirror of git://github.com/lxc/lxc synced 2025-09-01 06:19:38 +00:00

conf: refactor network deletion

I'm ashamed at how aweful my previous code was.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner
2017-08-24 16:10:30 +02:00
parent 581c75e7f4
commit f5c0d3f2cc

View File

@@ -3187,92 +3187,96 @@ int lxc_setup_networks_in_parent_namespaces(struct lxc_handler *handler)
bool lxc_delete_network(struct lxc_handler *handler) bool lxc_delete_network(struct lxc_handler *handler)
{ {
int ret; int ret;
struct lxc_list *network = &handler->conf->network;
struct lxc_list *iterator; struct lxc_list *iterator;
struct lxc_netdev *netdev; struct lxc_list *network = &handler->conf->network;
bool deleted_all = true; bool deleted_all = true;
lxc_list_for_each(iterator, network) { lxc_list_for_each(iterator, network) {
netdev = iterator->elem; char *hostveth = NULL;
struct lxc_netdev *netdev = iterator->elem;
if (netdev->ifindex != 0 && netdev->type == LXC_NET_PHYS) { /* We can only delete devices whose ifindex we have. If we don't
if (lxc_netdev_rename_by_index(netdev->ifindex, netdev->link)) * have the index it means that we didn't create it.
*/
if (!netdev->ifindex)
continue;
if (netdev->type == LXC_NET_PHYS) {
ret = lxc_netdev_rename_by_index(netdev->ifindex, netdev->link);
if (ret < 0)
WARN("Failed to rename interface with index %d " WARN("Failed to rename interface with index %d "
"to its initial name \"%s\".", "to its initial name \"%s\"",
netdev->ifindex, netdev->link); netdev->ifindex, netdev->link);
else
TRACE("Renamed interface with index %d to its "
"initial name \"%s\"",
netdev->ifindex, netdev->link);
continue; continue;
} }
if (netdev_deconf[netdev->type](handler, netdev)) { ret = netdev_deconf[netdev->type](handler, netdev);
WARN("Failed to destroy netdev"); if (ret < 0)
} WARN("Failed to deconfigure network device");
/* Recent kernel remove the virtual interfaces when the network /* Recent kernel remove the virtual interfaces when the network
* namespace is destroyed but in case we did not move the * namespace is destroyed but in case we did not move the
* interface to the network namespace, we have to destroy it * interface to the network namespace, we have to destroy it
*/ */
if (netdev->ifindex != 0) { ret = lxc_netdev_delete_by_index(netdev->ifindex);
ret = lxc_netdev_delete_by_index(netdev->ifindex); if (-ret == ENODEV) {
if (-ret == ENODEV) { INFO("Interface \"%s\" with index %d already deleted "
INFO("Interface \"%s\" with index %d already " "or existing in different network namespace",
"deleted or existing in different network " netdev->name ? netdev->name : "(null)", netdev->ifindex);
"namespace.", } else if (ret < 0) {
netdev->name ? netdev->name : "(null)", deleted_all = false;
netdev->ifindex); WARN("Failed to remove interface \"%s\" with index %d: "
} else if (ret < 0) { "%s", netdev->name ? netdev->name : "(null)",
deleted_all = false; netdev->ifindex, strerror(-ret));
WARN("Failed to remove interface \"%s\" with " continue;
"index %d: %s.",
netdev->name ? netdev->name : "(null)",
netdev->ifindex, strerror(-ret));
} else {
INFO("Removed interface \"%s\" with index %d.",
netdev->name ? netdev->name : "(null)",
netdev->ifindex);
}
} }
INFO("Removed interface \"%s\" with index %d",
netdev->name ? netdev->name : "(null)", netdev->ifindex);
if (netdev->type != LXC_NET_VETH)
continue;
if (am_unpriv())
continue;
/* Explicitly delete host veth device to prevent lingering /* Explicitly delete host veth device to prevent lingering
* devices. We had issues in LXD around this. * devices. We had issues in LXD around this.
*/ */
if (netdev->ifindex != 0 && netdev->type == LXC_NET_VETH && !am_unpriv()) { if (netdev->priv.veth_attr.pair)
char *hostveth; hostveth = netdev->priv.veth_attr.pair;
if (netdev->priv.veth_attr.pair) { else
hostveth = netdev->priv.veth_attr.pair; hostveth = netdev->priv.veth_attr.veth1;
if (*hostveth == '\0')
continue;
ret = lxc_netdev_delete_by_name(hostveth); ret = lxc_netdev_delete_by_name(hostveth);
if (ret < 0) if (ret < 0) {
WARN("Failed to remove interface \"%s\" from host: %s.", hostveth, strerror(-ret)); deleted_all = false;
else WARN("Failed to remove interface \"%s\" from \"%s\": %s",
INFO("Removed interface \"%s\" from host.", hostveth); hostveth, netdev->link, strerror(-ret));
continue;
if (is_ovs_bridge(netdev->link)) {
ret = lxc_ovs_delete_port(netdev->link, hostveth);
if (ret < 0)
WARN("Failed to remove port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
else
INFO("Removed port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
}
} else if (strlen(netdev->priv.veth_attr.veth1) > 0) {
hostveth = netdev->priv.veth_attr.veth1;
ret = lxc_netdev_delete_by_name(hostveth);
if (ret < 0) {
WARN("Failed to remove \"%s\" from host: %s.", hostveth, strerror(-ret));
} else {
INFO("Removed interface \"%s\" from host.", hostveth);
if (is_ovs_bridge(netdev->link)) {
ret = lxc_ovs_delete_port(netdev->link, hostveth);
if (ret < 0) {
WARN("Failed to remove port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
} else {
INFO("Removed port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
memset((void *)&netdev->priv.veth_attr.veth1, 0, sizeof(netdev->priv.veth_attr.veth1));
}
}
}
}
} }
INFO("Removed interface \"%s\" from \"%s\"", hostveth, netdev->link);
if (!is_ovs_bridge(netdev->link)) {
netdev->priv.veth_attr.veth1[0] = '\0';
continue;
}
/* Delete the openvswitch port. */
ret = lxc_ovs_delete_port(netdev->link, hostveth);
if (ret < 0)
WARN("Failed to remove port \"%s\" from openvswitch "
"bridge \"%s\"", hostveth, netdev->link);
else
INFO("Removed port \"%s\" from openvswitch bridge \"%s\"",
hostveth, netdev->link);
netdev->priv.veth_attr.veth1[0] = '\0';
} }
return deleted_all; return deleted_all;