From 93a508df6028dc838117d620f0daee6c6d15ccbf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 8 Dec 2011 09:00:13 +0100 Subject: BGP: Add support for specifying interface names to allow peerings using link-local addresses --- proto/bgp/bgp.c | 6 ++++-- proto/bgp/bgp.h | 1 + proto/bgp/config.Y | 3 ++- proto/bgp/packets.c | 3 +++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 675342d..e537fce 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -579,6 +579,7 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c s->saddr = p->source_addr; s->daddr = p->cf->remote_ip; s->dport = BGP_PORT; + s->iface = p->neigh->iface; s->ttl = p->cf->ttl_security ? 255 : hops; s->rbsize = BGP_RX_BUFFER_SIZE; s->tbsize = BGP_TX_BUFFER_SIZE; @@ -793,7 +794,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 +808,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 +853,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 437ba33..e8fcdbb 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -49,6 +49,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 03c233d..f943ea5 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -25,7 +25,7 @@ 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) + TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, INTERFACE) CF_GRAMMAR @@ -99,6 +99,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; -- cgit v1.2.3