[PATCH 2/4] Make NEF_STICKY work with fixed interfaces and allow specifying interface names

Matthias Schiffer mschiffer at universe-factory.net
Thu Dec 29 22:56:45 CET 2011


Signed-off-by: Matthias Schiffer <mschiffer at universe-factory.net>
---
 nest/iface.h    |    2 ++
 nest/neighbor.c |   34 +++++++++++++++++++++++++++-------
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/nest/iface.h b/nest/iface.h
index 7307844..8636c0a 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -106,6 +106,7 @@ typedef struct neighbor {
   node if_n;				/* Node in per-interface neighbor list */
   ip_addr addr;				/* Address of the neighbor */
   struct iface *iface;			/* Interface it's connected to */
+  char bound_iface[16];			/* Name of the interface it's bound to */
   struct proto *proto;			/* Protocol this belongs to */
   void *data;				/* Protocol-specific data */
   unsigned aux;				/* Protocol-specific data */
@@ -118,6 +119,7 @@ typedef struct neighbor {
 
 neighbor *neigh_find(struct proto *, ip_addr *, unsigned flags);
 neighbor *neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags);
+neighbor *neigh_find_ifname(struct proto *, ip_addr *, char *, unsigned flags);
 
 static inline int neigh_connected_to(struct proto *p, ip_addr *a, struct iface *i)
 {
diff --git a/nest/neighbor.c b/nest/neighbor.c
index 67bd32b..458d9fb 100644
--- a/nest/neighbor.c
+++ b/nest/neighbor.c
@@ -49,6 +49,9 @@
 static slab *neigh_slab;
 static list sticky_neigh_list, neigh_hash_table[NEIGH_HASH_SIZE];
 
+static neighbor *
+neigh_find_internal(struct proto *p, ip_addr *a, struct iface *ifa, char *bound_iface, unsigned flags);
+
 static inline unsigned int
 neigh_hash(struct proto *p, ip_addr *a)
 {
@@ -103,18 +106,32 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */
  * If the node is not connected directly or *@a is not a valid unicast
  * IP address, neigh_find() returns %NULL.
  */
+
+
 neighbor *
 neigh_find(struct proto *p, ip_addr *a, unsigned flags)
 {
-  return neigh_find2(p, a, NULL, flags);
+  return neigh_find_internal(p, a, NULL, NULL, flags);
 }
 
 
 neighbor *
 neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
 {
+  return neigh_find_internal(p, a, ifa, ifa ? ifa->name : NULL, flags);
+}
+
+neighbor *
+neigh_find_ifname(struct proto *p, ip_addr *a, char *ifname, unsigned flags)
+{
+  return neigh_find_internal(p, a, ifname ? if_find_by_name(ifname) : NULL, ifname, flags);
+}
+
+static neighbor *
+neigh_find_internal(struct proto *p, ip_addr *a, struct iface *ifa, char *ifname, unsigned flags)
+{
   neighbor *n;
-  int class, scope = -1;       ;
+  int class, scope = -1;
   unsigned int h = neigh_hash(p, a);
   struct iface *i;
 
@@ -126,7 +143,7 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
   if (class < 0)			/* Invalid address */
     return NULL;
   if (((class & IADDR_SCOPE_MASK) == SCOPE_HOST) ||
-      (((class & IADDR_SCOPE_MASK) == SCOPE_LINK) && (ifa == NULL)) ||
+      (((class & IADDR_SCOPE_MASK) == SCOPE_LINK) && (ifa == NULL) && (ifname == NULL)) ||
       !(class & IADDR_HOST))
     return NULL;			/* Bad scope or a somecast */
 
@@ -137,7 +154,7 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
       if ((scope < 0) && (flags & NEF_ONLINK))
 	scope = class & IADDR_SCOPE_MASK;
     }
-  else
+  else if (ifname == NULL)
     WALK_LIST(i, iface_list)
       if ((scope = if_connected(a, i)) >= 0)
 	{
@@ -160,8 +177,6 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
     }
   else
     {
-      /* sticky flag does not work for link-local neighbors;
-	 fortunately, we don't use this combination */
       add_tail(&sticky_neigh_list, &n->n);
       ifa = NULL;
       scope = -1;
@@ -172,6 +187,8 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
   n->aux = 0;
   n->flags = flags;
   n->scope = scope;
+  strncpy(n->bound_iface, ifname ?: "", sizeof(n->bound_iface)-1);
+
   return n;
 }
 
@@ -193,6 +210,8 @@ neigh_dump(neighbor *n)
   debug("%s %p %08x scope %s", n->proto->name, n->data, n->aux, ip_scope_text(n->scope));
   if (n->flags & NEF_STICKY)
     debug(" STICKY");
+  if (*n->bound_iface)
+    debug(" bound to %s", n->bound_iface);
   debug("\n");
 }
 
@@ -262,7 +281,8 @@ neigh_if_up(struct iface *i)
   int scope;
 
   WALK_LIST_DELSAFE(n, next, sticky_neigh_list)
-    if ((scope = if_connected(&n->addr, i)) >= 0)
+    if ((!(*n->bound_iface) || strcmp(n->bound_iface, i->name) == 0)
+	&& (scope = if_connected(&n->addr, i)) >= 0)
       neigh_up(n, i, scope);
 }
 
-- 
1.7.8.1




More information about the Bird-users mailing list