summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2011-12-08 09:00:13 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2011-12-09 06:08:58 +0100
commit93a508df6028dc838117d620f0daee6c6d15ccbf (patch)
tree7f3fe51a2a18539826b02897d604de5195ba4ee1
parent631487aa2d45aa2078a08f1852e4a7482abbc2b5 (diff)
downloadbird-93a508df6028dc838117d620f0daee6c6d15ccbf.tar
bird-93a508df6028dc838117d620f0daee6c6d15ccbf.zip
BGP: Add support for specifying interface names to allow peerings using link-local addressesll-peering-old2
-rw-r--r--proto/bgp/bgp.c6
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y3
-rw-r--r--proto/bgp/packets.c3
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;