]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements link state detection.
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 11 Nov 2010 09:03:02 +0000 (10:03 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 11 Nov 2010 09:03:02 +0000 (10:03 +0100)
Also changes some symbol names (IFF_ADMIN_DOWN -> IFF_SHUTDOWN,
IFF_LINK_UP -> IFF_ADMIN_UP).

nest/iface.c
nest/iface.h
sysdep/bsd/krt-sock.c
sysdep/linux/netlink/netlink.c
sysdep/unix/krt-iface.c

index 4d0cf04c40a03346762a185cd9f97ac67a51e976..8e4593637d44ecef8b4ab6d5dbfe6597dc848db1 100644 (file)
@@ -67,13 +67,13 @@ if_dump(struct iface *i)
   struct ifa *a;
 
   debug("IF%d: %s", i->index, i->name);
-  if (i->flags & IF_ADMIN_DOWN)
-    debug(" ADMIN-DOWN");
+  if (i->flags & IF_SHUTDOWN)
+    debug(" SHUTDOWN");
   if (i->flags & IF_UP)
     debug(" UP");
   else
     debug(" DOWN");
-  if (i->flags & IF_LINK_UP)
+  if (i->flags & IF_ADMIN_UP)
     debug(" LINK-UP");
   if (i->flags & IF_MULTIACCESS)
     debug(" MA");
@@ -117,12 +117,14 @@ if_what_changed(struct iface *i, struct iface *j)
 {
   unsigned c;
 
-  if (((i->flags ^ j->flags) & ~(IF_UP | IF_ADMIN_DOWN | IF_UPDATED | IF_LINK_UP | IF_TMP_DOWN | IF_JUST_CREATED))
+  if (((i->flags ^ j->flags) & ~(IF_UP | IF_SHUTDOWN | IF_UPDATED | IF_ADMIN_UP | IF_TMP_DOWN | IF_JUST_CREATED))
       || i->index != j->index)
     return IF_CHANGE_TOO_MUCH;
   c = 0;
   if ((i->flags ^ j->flags) & IF_UP)
     c |= (i->flags & IF_UP) ? IF_CHANGE_DOWN : IF_CHANGE_UP;
+  if ((i->flags ^ j->flags) & IF_LINK_UP)
+    c |= IF_CHANGE_LINK;
   if (i->mtu != j->mtu)
     c |= IF_CHANGE_MTU;
   return c;
@@ -169,6 +171,7 @@ if_send_notify(struct proto *p, unsigned c, struct iface *i)
            (c & IF_CHANGE_UP) ? "goes up" :
            (c & IF_CHANGE_DOWN) ? "goes down" :
            (c & IF_CHANGE_MTU) ? "changes MTU" :
+           (c & IF_CHANGE_LINK) ? "changes link" :
            (c & IF_CHANGE_CREATE) ? "created" :
            "sends unknown event");
       p->if_notify(p, c, i);
@@ -217,8 +220,8 @@ if_notify_change(unsigned c, struct iface *i)
 static unsigned
 if_recalc_flags(struct iface *i, unsigned flags)
 {
-  if ((flags & (IF_ADMIN_DOWN | IF_TMP_DOWN)) ||
-      !(flags & IF_LINK_UP) ||
+  if ((flags & (IF_SHUTDOWN | IF_TMP_DOWN)) ||
+      !(flags & IF_ADMIN_UP) ||
       !i->addr)
     flags &= ~IF_UP;
   else
@@ -325,7 +328,7 @@ if_end_update(void)
   WALK_LIST(i, iface_list)
     {
       if (!(i->flags & IF_UPDATED))
-       if_change_flags(i, (i->flags & ~IF_LINK_UP) | IF_ADMIN_DOWN);
+       if_change_flags(i, (i->flags & ~IF_ADMIN_UP) | IF_SHUTDOWN);
       else
        {
          WALK_LIST_DELSAFE(a, b, i->addrs)
@@ -535,8 +538,8 @@ auto_router_id(void)
 
   j = NULL;
   WALK_LIST(i, iface_list)
-    if ((i->flags & IF_LINK_UP) &&
-       !(i->flags & (IF_IGNORE | IF_ADMIN_DOWN)) &&
+    if ((i->flags & IF_ADMIN_UP) &&
+       !(i->flags & (IF_IGNORE | IF_SHUTDOWN)) &&
        i->addr &&
        !(i->addr->flags & IA_UNNUMBERED) &&
        (!j || ipa_to_u32(i->addr->ip) < ipa_to_u32(j->addr->ip)))
@@ -694,6 +697,9 @@ if_show(void)
 
   WALK_LIST(i, iface_list)
     {
+      if (i->flags & IF_SHUTDOWN)
+       continue;
+
       cli_msg(-1001, "%s %s (index=%d)", i->name, (i->flags & IF_UP) ? "up" : "DOWN", i->index);
       if (!(i->flags & IF_MULTIACCESS))
        type = "PtP";
@@ -703,7 +709,7 @@ if_show(void)
              type,
              (i->flags & IF_BROADCAST) ? " Broadcast" : "",
              (i->flags & IF_MULTICAST) ? " Multicast" : "",
-             (i->flags & IF_ADMIN_DOWN) ? "Down" : "Up",
+             (i->flags & IF_ADMIN_UP) ? "Up" : "Down",
              (i->flags & IF_LINK_UP) ? "Up" : "Down",
              (i->flags & IF_LOOPBACK) ? " Loopback" : "",
              (i->flags & IF_IGNORE) ? " Ignored" : "",
index c116db8b71548629cd8f6d500217ca37964ce5de..471625f23edbdcde36a646bde112e03bc4424a71 100644 (file)
@@ -39,14 +39,15 @@ struct iface {
   list neighbors;                      /* All neighbors on this interface */
 };
 
-#define IF_UP 1                                /* IF_LINK_UP and IP address known */
+#define IF_UP 1                                /* IF_ADMIN_UP and IP address known */
 #define IF_MULTIACCESS 2
 #define IF_BROADCAST 4
 #define IF_MULTICAST 8
-#define IF_ADMIN_DOWN 0x10
+#define IF_SHUTDOWN 0x10               /* Interface disappeared */
 #define IF_LOOPBACK 0x20
 #define IF_IGNORE 0x40                 /* Not to be used by routing protocols (loopbacks etc.) */
-#define IF_LINK_UP 0x80
+#define IF_ADMIN_UP 0x80               /* Administrative up (e.q. IFF_UP in Linux) */
+#define IF_LINK_UP 0x100               /* Link available (e.q. IFF_LOWER_UP in Linux) */
 
 #define IA_PRIMARY 0x10000             /* This address is primary */
 #define IA_SECONDARY 0x20000           /* This address has been reported as secondary by the kernel */
@@ -63,6 +64,7 @@ struct iface {
 #define IF_CHANGE_DOWN 2
 #define IF_CHANGE_MTU 4
 #define IF_CHANGE_CREATE 8             /* Seen this interface for the first time */
+#define IF_CHANGE_LINK 0x10
 #define IF_CHANGE_TOO_MUCH 0x40000000  /* Used internally */
 
 void if_init(void);
index 9ae658d686f24a0049ddd99102eba3082d4ee4ec..53b30ca453a3f1d6ae3cf3e84e4ac15aa048cfb6 100644 (file)
@@ -456,7 +456,9 @@ krt_read_ifinfo(struct ks_msg *msg)
   f.flags = 0;
 
   if (fl & IFF_UP)
-    f.flags |= IF_LINK_UP;
+    f.flags |= IF_ADMIN_UP;
+  if (ifm->ifm_data.ifi_link_state != LINK_STATE_DOWN)
+    f.flags |= IF_LINK_UP;          /* up or unknown */
   if (fl & IFF_LOOPBACK)            /* Loopback */
     f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
   else if (fl & IFF_POINTOPOINT)    /* PtP */
index 2dd0359bf0a40e3e727f593947aa5607a1d74bc8..79f7210a9e0203a5a19dc8d9eb6d927d15140f65 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <stdio.h>
 #include <fcntl.h>
-#include <net/if.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
 #include <errno.h>
@@ -27,6 +26,7 @@
 #include "conf/conf.h"
 
 #include <asm/types.h>
+#include <linux/if.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 
 #define MSG_TRUNC 0x20
 #endif
 
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP 0x10000
+#endif
+
 /*
  *     Synchronous Netlink interface
  */
@@ -281,6 +285,8 @@ nl_parse_link(struct nlmsghdr *h, int scan)
   u32 mtu;
   unsigned int fl;
 
+  debug("nl_parse_link %d\n", new); 
+
   if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFLA_RTA(i), a, sizeof(a)))
     return;
   if (!a[IFLA_IFNAME] || RTA_PAYLOAD(a[IFLA_IFNAME]) < 2 ||
@@ -293,6 +299,8 @@ nl_parse_link(struct nlmsghdr *h, int scan)
   name = RTA_DATA(a[IFLA_IFNAME]);
   memcpy(&mtu, RTA_DATA(a[IFLA_MTU]), sizeof(u32));
 
+  debug("nl_parse_link name %s index %d flags %x\n", name, i->ifi_index, i->ifi_flags);
+
   ifi = if_find_by_index(i->ifi_index);
   if (!new)
     {
@@ -300,7 +308,7 @@ nl_parse_link(struct nlmsghdr *h, int scan)
       if (ifi && !scan)
        {
          memcpy(&f, ifi, sizeof(struct iface));
-         f.flags |= IF_ADMIN_DOWN;
+         f.flags |= IF_SHUTDOWN;
          if_update(&f);
        }
     }
@@ -319,6 +327,8 @@ nl_parse_link(struct nlmsghdr *h, int scan)
       f.flags = 0;
       fl = i->ifi_flags;
       if (fl & IFF_UP)
+       f.flags |= IF_ADMIN_UP;
+      if (fl & IFF_LOWER_UP)
        f.flags |= IF_LINK_UP;
       if (fl & IFF_LOOPBACK)           /* Loopback */
        f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
index 5fda0d1d8eb99c4ea6ddfc8c32b4a47d1e8f552b..c305d27a439114681a299e43c0a515fe6c844c76 100644 (file)
@@ -78,12 +78,12 @@ scan_ifs(struct ifreq *r, int cnt)
        faulty:
          log(L_ERR "%s(%s): %m", err, i.name);
        bad:
-         i.flags = (i.flags & ~IF_LINK_UP) | IF_ADMIN_DOWN;
+         i.flags = (i.flags & ~IF_ADMIN_UP) | IF_SHUTDOWN;
          continue;
        }
       fl = r->ifr_flags;
       if (fl & IFF_UP)
-       i.flags |= IF_LINK_UP;
+       i.flags |= IF_ADMIN_UP;
 
       if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0)
        { err = "SIOCGIFNETMASK"; goto faulty; }