]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Netlink support for secondary interface addresses.
authorMartin Mares <mj@ucw.cz>
Fri, 7 May 1999 13:46:16 +0000 (13:46 +0000)
committerMartin Mares <mj@ucw.cz>
Fri, 7 May 1999 13:46:16 +0000 (13:46 +0000)
TODO
nest/iface.c
sysdep/linux/netlink/netlink.c

diff --git a/TODO b/TODO
index ce658851148cc0bc18ce505536791a2ebe6f8c41..0746c483ded07bb22f26bcb56484950ba603628b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -26,6 +26,7 @@ Core
 - iface: when seen an invalid broadcast, fix it up or at least report
 - iface: we always need ifindex at least for PtP links (OSPF)
 - iface: interface filters should support filtering by IP address as well
+- iface: SIOCGIFINDEX exists on glibc systems, but it doesn't work on 2.0.x kernels!
 
 - socket: Use IP_RECVERR for BGP TCP sockets?
 
index 069b740c9fabb85201af954c05eabf3adc5e5f29..19ed7fbd5dc6808cf1d648b7094df46bebbc38d7 100644 (file)
@@ -361,8 +361,9 @@ if_update(struct iface *new)
            DBG("Interface %s changed too much -- forcing down/up transition\n", i->name);
            if_change_flags(i, i->flags | IF_TMP_DOWN);
            rem_node(&i->n);
-           WALK_LIST_DELSAFE(a, b, i->addrs)
-             ifa_delete(a);
+           new->addr = i->addr;
+           memcpy(&new->addrs, &i->addrs, sizeof(i->addrs));
+           memcpy(i, new, sizeof(*i));
            goto newif;
          }
        else if (c)
@@ -374,9 +375,9 @@ if_update(struct iface *new)
        return i;
       }
   i = mb_alloc(if_pool, sizeof(struct iface));
-newif:
   memcpy(i, new, sizeof(*i));
   init_list(&i->addrs);
+newif:
   i->flags |= IF_UPDATED | IF_TMP_DOWN;                /* Tmp down as we don't have addresses yet */
   add_tail(&iface_list, &i->n);
   return i;
@@ -543,6 +544,7 @@ ifa_delete(struct ifa *a)
            ifa_recalc_primary(i);
          }
        mb_free(b);
+       return;
       }
 }
 
index 5a15607a1ecfe17bdf7b9b4a7a54ab4f100a1558..10eb27a9a57f7874cd95e6dd548c2b86a5c1a3ad 100644 (file)
@@ -316,7 +316,7 @@ nl_parse_addr(struct nlmsghdr *h)
   struct ifaddrmsg *i;
   struct rtattr *a[IFA_ANYCAST+1];
   int new = h->nlmsg_type == RTM_NEWADDR;
-  struct iface f;
+  struct ifa ifa;
   struct iface *ifi;
 
   if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFA_RTA(i), a, sizeof(a)))
@@ -330,11 +330,6 @@ nl_parse_addr(struct nlmsghdr *h)
       log(L_ERR "nl_parse_addr: Malformed message received");
       return;
     }
-  if (i->ifa_flags & IFA_F_SECONDARY)
-    {
-      DBG("KIF: Received address message for secondary address which is not supported.\n"); /* FIXME */
-      return;
-    }
 
   ifi = if_find_by_index(i->ifa_index);
   if (!ifi)
@@ -342,41 +337,42 @@ nl_parse_addr(struct nlmsghdr *h)
       log(L_ERR "KIF: Received address message for unknown interface %d\n", i->ifa_index);
       return;
     }
-  memcpy(&f, ifi, sizeof(f));
 
   if (i->ifa_prefixlen > 32 || i->ifa_prefixlen == 31 ||
-      (f.flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
+      (ifi->flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
     {
-      log(L_ERR "KIF: Invalid prefix length for interface %s: %d\n", f.name, i->ifa_prefixlen);
+      log(L_ERR "KIF: Invalid prefix length for interface %s: %d\n", ifi->name, i->ifa_prefixlen);
       new = 0;
     }
 
-  f.ip = f.brd = f.opposite = IPA_NONE;
-  if (!new)
+  bzero(&ifa, sizeof(ifa));
+  ifa.iface = ifi;
+  if (i->ifa_flags & IFA_F_SECONDARY)
+    ifa.flags |= IA_SECONDARY;
+  memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(ifa.ip));
+  ifa.ip = ipa_ntoh(ifa.ip);
+  ifa.pxlen = i->ifa_prefixlen;
+  if (ifi->flags & IF_UNNUMBERED)
     {
-      DBG("KIF: IF%d IP address deleted\n");
-      f.pxlen = 0;
+      memcpy(&ifa.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(ifa.opposite));
+      ifa.opposite = ifa.brd = ipa_ntoh(ifa.opposite);
     }
-  else
+  else if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
     {
-      memcpy(&f.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(f.ip));
-      f.ip = ipa_ntoh(f.ip);
-      f.pxlen = i->ifa_prefixlen;
-      if (f.flags & IF_UNNUMBERED)
-       {
-         memcpy(&f.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(f.opposite));
-         f.opposite = f.brd = ipa_ntoh(f.opposite);
-       }
-      else if ((f.flags & IF_BROADCAST) && a[IFA_BROADCAST])
-       {
-         memcpy(&f.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(f.brd));
-         f.brd = ipa_ntoh(f.brd);
-       }
-      /* else a NBMA link */
-      f.prefix = ipa_and(f.ip, ipa_mkmask(f.pxlen));
-      DBG("KIF: IF%d IP address set to %I, net %I/%d, brd %I, opp %I\n", f.index, f.ip, f.prefix, f.pxlen, f.brd, f.opposite);
+      memcpy(&ifa.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(ifa.brd));
+      ifa.brd = ipa_ntoh(ifa.brd);
     }
-  if_update(&f);
+  /* else a NBMA link */
+  ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(ifa.pxlen));
+
+  DBG("KIF: IF%d(%s): %s IPA %I, net %I/%d, brd %I, opp %I\n",
+      ifi->index, ifi->name,
+      new ? "added" : "removed",
+      ifa.ip, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
+  if (new)
+    ifa_update(&ifa);
+  else
+    ifa_delete(&ifa);
 }
 
 void