From: Vincent Bernat Date: Fri, 1 Jan 2016 20:11:02 +0000 (+0100) Subject: netlink: handle veth loops correctly X-Git-Tag: 0.9.0~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=100266c1e2efa0857fbc1e681a765c753a5de3cf;p=thirdparty%2Flldpd.git netlink: handle veth loops correctly Since Linux 4.1, a pair of veth are referenced as IFLINK for each other. We previously detected this loop easily and did break the loop by removing this bogus information. However, when one of the interface is updated, only the modified interface has IFLINK pointing to the other interface. Therefore, no more loop but the information is incorrect. To avoid that, don't reset indexes, just pointers. We only use indexes to build correctly those pointers. --- diff --git a/src/daemon/netlink.c b/src/daemon/netlink.c index 720af383..e0c2b888 100644 --- a/src/daemon/netlink.c +++ b/src/daemon/netlink.c @@ -498,19 +498,29 @@ end: break; } } + if (iface2 == NULL) + iface1->upper = NULL; } else { iface1->upper = NULL; } if (iface1->lower_idx != -1 && iface1->lower_idx != iface1->index) { TAILQ_FOREACH(iface2, ifs, next) { if (iface1->lower_idx == iface2->index) { + /* Workaround a bug introduced + * in Linux 4.1: a pair of veth + * will be lower interface of + * each other. Do not modify + * index as if one of them is + * updated, we will loose the + * information about the + * loop. */ if (iface2->lower_idx == iface1->index) { - /* Workaround a bug introduced in Linux 4.1 */ - iface2->lower_idx = iface2->index; - iface1->lower_idx = iface1->index; + iface1->lower = NULL; } else iface1->lower = iface2; break; } + if (iface2 == NULL) + iface1->lower = NULL; } } else { iface1->lower = NULL;