Fixes problems with creating/removing/renaming ifaces on BSD.
This commit is contained in:
parent
5c78e0e386
commit
732a0a257d
4 changed files with 54 additions and 28 deletions
20
nest/iface.c
20
nest/iface.c
|
@ -252,6 +252,24 @@ if_change_flags(struct iface *i, unsigned flags)
|
|||
if_notify_change((i->flags & IF_UP) ? IF_CHANGE_UP : IF_CHANGE_DOWN, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* if_delete - remove interface
|
||||
* @old: interface
|
||||
*
|
||||
* This function is called by the low-level platform dependent code
|
||||
* whenever it notices an interface disappears. It is just a shorthand
|
||||
* for if_update().
|
||||
*/
|
||||
|
||||
void
|
||||
if_delete(struct iface *old)
|
||||
{
|
||||
struct iface f = {};
|
||||
strncpy(f.name, old->name, sizeof(f.name)-1);
|
||||
f.flags = IF_SHUTDOWN;
|
||||
if_update(&f);
|
||||
}
|
||||
|
||||
/**
|
||||
* if_update - update interface status
|
||||
* @new: new interface status
|
||||
|
@ -400,7 +418,7 @@ if_find_by_index(unsigned idx)
|
|||
struct iface *i;
|
||||
|
||||
WALK_LIST(i, iface_list)
|
||||
if (i->index == idx)
|
||||
if (i->index == idx && !(i->flags & IF_SHUTDOWN))
|
||||
return i;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ void ifa_dump(struct ifa *);
|
|||
void if_show(void);
|
||||
void if_show_summary(void);
|
||||
struct iface *if_update(struct iface *);
|
||||
void if_delete(struct iface *old);
|
||||
struct ifa *ifa_update(struct ifa *);
|
||||
void ifa_delete(struct ifa *);
|
||||
void if_start_update(void);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -438,25 +439,36 @@ krt_read_ifinfo(struct ks_msg *msg)
|
|||
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 */
|
||||
|
||||
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;
|
||||
|
|
|
@ -386,7 +386,7 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
|||
struct ifinfomsg *i;
|
||||
struct rtattr *a[IFLA_WIRELESS+1];
|
||||
int new = h->nlmsg_type == RTM_NEWLINK;
|
||||
struct iface f;
|
||||
struct iface f = {};
|
||||
struct iface *ifi;
|
||||
char *name;
|
||||
u32 mtu;
|
||||
|
@ -408,26 +408,21 @@ nl_parse_link(struct nlmsghdr *h, int scan)
|
|||
if (!new)
|
||||
{
|
||||
DBG("KIF: IF%d(%s) goes down\n", i->ifi_index, name);
|
||||
if (ifi && !scan)
|
||||
{
|
||||
memcpy(&f, ifi, sizeof(struct iface));
|
||||
f.flags |= IF_SHUTDOWN;
|
||||
if_update(&f);
|
||||
}
|
||||
if (!ifi)
|
||||
return;
|
||||
|
||||
if_delete(ifi);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("KIF: IF%d(%s) goes up (mtu=%d,flg=%x)\n", i->ifi_index, name, mtu, i->ifi_flags);
|
||||
if (ifi)
|
||||
memcpy(&f, ifi, sizeof(f));
|
||||
else
|
||||
{
|
||||
bzero(&f, sizeof(f));
|
||||
if (ifi && strncmp(ifi->name, name, sizeof(ifi->name)-1))
|
||||
if_delete(ifi);
|
||||
|
||||
strncpy(f.name, name, sizeof(f.name)-1);
|
||||
f.index = i->ifi_index;
|
||||
}
|
||||
strncpy(f.name, RTA_DATA(a[IFLA_IFNAME]), sizeof(f.name)-1);
|
||||
f.mtu = mtu;
|
||||
f.flags = 0;
|
||||
|
||||
fl = i->ifi_flags;
|
||||
if (fl & IFF_UP)
|
||||
f.flags |= IF_ADMIN_UP;
|
||||
|
|
Loading…
Reference in a new issue