Commit 732a0a25 authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

Fixes problems with creating/removing/renaming ifaces on BSD.

parent 5c78e0e3
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -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;
}
+1 −0
Original line number Diff line number Diff line
@@ -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);
+23 −11
Original line number Diff line number Diff line
@@ -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;
+11 −16
Original line number Diff line number Diff line
@@ -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;