2
0
mirror of git://github.com/lxc/lxc synced 2025-09-01 23:30:11 +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)
{
int ret;
struct lxc_list *network = &handler->conf->network;
struct lxc_list *iterator;
struct lxc_netdev *netdev;
struct lxc_list *network = &handler->conf->network;
bool deleted_all = true;
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) {
if (lxc_netdev_rename_by_index(netdev->ifindex, netdev->link))
/* We can only delete devices whose ifindex we have. If we don't
* 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 "
"to its initial name \"%s\".",
"to its initial name \"%s\"",
netdev->ifindex, netdev->link);
else
TRACE("Renamed interface with index %d to its "
"initial name \"%s\"",
netdev->ifindex, netdev->link);
continue;
}
if (netdev_deconf[netdev->type](handler, netdev)) {
WARN("Failed to destroy netdev");
}
ret = netdev_deconf[netdev->type](handler, netdev);
if (ret < 0)
WARN("Failed to deconfigure network device");
/* Recent kernel remove the virtual interfaces when the network
* namespace is destroyed but in case we did not move the
* interface to the network namespace, we have to destroy it
*/
if (netdev->ifindex != 0) {
ret = lxc_netdev_delete_by_index(netdev->ifindex);
if (-ret == ENODEV) {
INFO("Interface \"%s\" with index %d already "
"deleted or existing in different network "
"namespace.",
netdev->name ? netdev->name : "(null)",
netdev->ifindex);
} else if (ret < 0) {
deleted_all = false;
WARN("Failed to remove interface \"%s\" with "
"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);
}
ret = lxc_netdev_delete_by_index(netdev->ifindex);
if (-ret == ENODEV) {
INFO("Interface \"%s\" with index %d already deleted "
"or existing in different network namespace",
netdev->name ? netdev->name : "(null)", netdev->ifindex);
} else if (ret < 0) {
deleted_all = false;
WARN("Failed to remove interface \"%s\" with index %d: "
"%s", netdev->name ? netdev->name : "(null)",
netdev->ifindex, strerror(-ret));
continue;
}
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
* devices. We had issues in LXD around this.
*/
if (netdev->ifindex != 0 && netdev->type == LXC_NET_VETH && !am_unpriv()) {
char *hostveth;
if (netdev->priv.veth_attr.pair) {
hostveth = netdev->priv.veth_attr.pair;
if (netdev->priv.veth_attr.pair)
hostveth = netdev->priv.veth_attr.pair;
else
hostveth = netdev->priv.veth_attr.veth1;
if (*hostveth == '\0')
continue;
ret = lxc_netdev_delete_by_name(hostveth);
if (ret < 0)
WARN("Failed to remove interface \"%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);
}
} 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));
}
}
}
}
ret = lxc_netdev_delete_by_name(hostveth);
if (ret < 0) {
deleted_all = false;
WARN("Failed to remove interface \"%s\" from \"%s\": %s",
hostveth, netdev->link, strerror(-ret));
continue;
}
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;