[PATCH 3/4] BGP: Add support for specifying interface names to allow peerings using link-local addresses

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


Signed-off-by: Matthias Schiffer <mschiffer at universe-factory.net>
---
 proto/bgp/bgp.c     |   10 ++++++++--
 proto/bgp/bgp.h     |    1 +
 proto/bgp/config.Y  |    4 +++-
 proto/bgp/packets.c |    3 +++
 4 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 28396a5..67594c7 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -585,6 +585,11 @@ bgp_connect(struct bgp_proto *p)	/* Enter Connect state and start establishing c
   s->tos = IP_PREC_INTERNET_CONTROL;
   s->password = p->cf->password;
   s->tx_hook = bgp_connected;
+
+  /* Can only be NULL for multihop instances */
+  if (p->neigh && *p->cf->interface)
+    s->iface = p->neigh->iface;
+
   BGP_TRACE(D_EVENTS, "Connecting to %I from local address %I", s->daddr, s->saddr);
   bgp_setup_conn(p, conn);
   bgp_setup_sk(conn, s);
@@ -793,7 +798,7 @@ bgp_start_locked(struct object_lock *lock)
       return;
     }
 
-  p->neigh = neigh_find(&p->p, &cf->remote_ip, NEF_STICKY);
+  p->neigh = neigh_find_ifname(&p->p, &cf->remote_ip, (*cf->interface) ? cf->interface : NULL, NEF_STICKY);
   if (!p->neigh || (p->neigh->scope == SCOPE_HOST))
     {
       log(L_ERR "%s: Invalid remote address %I", p->p.name, cf->remote_ip);
@@ -807,7 +812,7 @@ bgp_start_locked(struct object_lock *lock)
   if (p->neigh->iface)
     bgp_start_neighbor(p);
   else
-    BGP_TRACE(D_EVENTS, "Waiting for %I to become my neighbor", cf->remote_ip);
+    BGP_TRACE(D_EVENTS, "Waiting for %I to become my neighbor%s%s", cf->remote_ip, (*cf->interface) ? " on " : "", cf->interface);
 }
 
 static int
@@ -852,6 +857,7 @@ bgp_start(struct proto *P)
   lock->iface = NULL;
   lock->hook = bgp_start_locked;
   lock->data = p;
+
   olock_acquire(lock);
 
   return PS_START;
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 0c50583..76f0400 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -50,6 +50,7 @@ struct bgp_config {
   unsigned error_delay_time_min;	/* Time to wait after an error is detected */
   unsigned error_delay_time_max;
   unsigned disable_after_error;		/* Disable the protocol when error is detected */
+  char interface[16];			/* Interface to use */
   char *password;			/* Password used for MD5 authentication */
   struct rtable_config *igp_table;	/* Table used for recursive next hop lookups */
 };
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 3ef9b29..6ec3623 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -25,7 +25,8 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
 	CLUSTER, ID, AS4, ADVERTISE, IPV4, CAPABILITIES, LIMIT, PASSIVE,
 	PREFER, OLDER, MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH,
 	INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP,
-	TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC)
+	TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC,
+	INTERFACE)
 
 CF_GRAMMAR
 
@@ -100,6 +101,7 @@ bgp_proto:
  | bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
  | bgp_proto IGP TABLE rtable ';' { BGP_CFG->igp_table = $4; }
  | bgp_proto TTL SECURITY bool ';' { BGP_CFG->ttl_security = $4; }
+ | bgp_proto INTERFACE TEXT ';' { strncpy(BGP_CFG->interface, $3, sizeof(BGP_CFG->interface)-1); }
  ;
 
 CF_ADDTO(dynamic_attr, BGP_ORIGIN
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index c3a8673..7d78d9f 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -434,6 +434,9 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
 	  *tmp++ = BGP_AF_IPV6;
 	  *tmp++ = 1;
 
+	  if (ipa_has_link_scope(ip))
+	    ip = IPA_NONE;
+
 	  if (ipa_nonzero(ip_ll))
 	    {
 	      *tmp++ = 32;
-- 
1.7.8.1




More information about the Bird-users mailing list