diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2012-01-23 01:26:40 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2012-01-23 01:26:40 +0100 |
commit | 732a0a257d180a95a02587203555b8552b6128ac (patch) | |
tree | 298d92b6fd7c7c59f4c58f60692ecdf592cd9ba3 /sysdep/bsd/krt-sock.c | |
parent | 5c78e0e386d4c770b646cab4a8adc3c87987f50f (diff) |
Fixes problems with creating/removing/renaming ifaces on BSD.
Diffstat (limited to 'sysdep/bsd/krt-sock.c')
-rw-r--r-- | sysdep/bsd/krt-sock.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index 4a91e85a..f831327b 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -416,8 +416,9 @@ krt_read_ifinfo(struct ks_msg *msg) void *body = (void *)(ifm + 1); struct sockaddr_dl *dl = NULL; unsigned int i; - struct iface *iface = NULL, f; + struct iface *iface = NULL, f = {}; int fl = ifm->ifm_flags; + int nlen = 0; for (i = 1; i<=RTA_IFP; i <<= 1) { @@ -432,31 +433,42 @@ krt_read_ifinfo(struct ks_msg *msg) } } - if(dl && (dl->sdl_family != AF_LINK)) + if (dl && (dl->sdl_family != AF_LINK)) { log("Ignoring strange IFINFO"); return; } - iface = if_find_by_index(ifm->ifm_index); + if (dl) + nlen = MIN(sizeof(f.name)-1, dl->sdl_nlen); + + /* Note that asynchronous IFINFO messages do not contain iface + name, so we have to found an existing iface by iface index */ - if(!iface) + iface = if_find_by_index(ifm->ifm_index); + if (!iface) { /* New interface */ - if(!dl) return; /* No interface name, ignoring */ + if (!dl) + return; /* No interface name, ignoring */ - bzero(&f, sizeof(f)); - f.index = ifm->ifm_index; - memcpy(f.name, dl->sdl_data, MIN(sizeof(f.name)-1, dl->sdl_nlen)); - DBG("New interface '%s' found", f.name); + memcpy(f.name, dl->sdl_data, nlen); + DBG("New interface '%s' found\n", f.name); + } + else if (dl && memcmp(iface->name, dl->sdl_data, nlen)) + { + /* Interface renamed */ + if_delete(iface); + memcpy(f.name, dl->sdl_data, nlen); } else { - memcpy(&f, iface, sizeof(struct iface)); + /* Old interface */ + memcpy(f.name, iface->name, sizeof(f.name)); } + f.index = ifm->ifm_index; f.mtu = ifm->ifm_data.ifi_mtu; - f.flags = 0; if (fl & IFF_UP) f.flags |= IF_ADMIN_UP; |