BGP: Better dispatch of incoming connections

Since v2 we have multiple listening BGP sockets, and each BGP protocol
has associated one of them. Use listening socket that accepted the
incoming connection as a key in the dispatch process so only BGP
protocols assocaited with that listening socket can be selected.
This is necesary for proper dispatch when VRFs are used.
This commit is contained in:
Ondrej Zajicek (work) 2019-01-02 16:01:21 +01:00
parent e16b0aef31
commit 470740f97b
2 changed files with 13 additions and 6 deletions

View file

@ -188,6 +188,7 @@ bgp_open(struct bgp_proto *p)
bs->sk = sk; bs->sk = sk;
bs->uc = 1; bs->uc = 1;
p->sock = bs; p->sock = bs;
sk->data = bs;
add_tail(&bgp_sockets, &bs->n); add_tail(&bgp_sockets, &bs->n);
@ -1049,7 +1050,8 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c
s->tos = IP_PREC_INTERNET_CONTROL; s->tos = IP_PREC_INTERNET_CONTROL;
s->password = p->cf->password; s->password = p->cf->password;
s->tx_hook = bgp_connected; s->tx_hook = bgp_connected;
BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J", s->daddr, p->cf->iface, BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J",
s->daddr, ipa_is_link_local(s->daddr) ? p->cf->iface : NULL,
s->saddr, ipa_is_link_local(s->saddr) ? s->iface : NULL); s->saddr, ipa_is_link_local(s->saddr) ? s->iface : NULL);
bgp_setup_conn(p, conn); bgp_setup_conn(p, conn);
bgp_setup_sk(conn, s); bgp_setup_sk(conn, s);
@ -1083,12 +1085,15 @@ bgp_find_proto(sock *sk)
{ {
struct bgp_proto *p; struct bgp_proto *p;
/* sk->iface is valid only if src or dst address is link-local */
int link = ipa_is_link_local(sk->saddr) || ipa_is_link_local(sk->daddr);
WALK_LIST(p, proto_list) WALK_LIST(p, proto_list)
if ((p->p.proto == &proto_bgp) && if ((p->p.proto == &proto_bgp) &&
(p->sock == sk->data) &&
ipa_equal(p->cf->remote_ip, sk->daddr) && ipa_equal(p->cf->remote_ip, sk->daddr) &&
(!p->cf->iface || (p->cf->iface == sk->iface)) && (!link || (p->cf->iface == sk->iface)) &&
(ipa_zero(p->cf->local_ip) || ipa_equal(p->cf->local_ip, sk->saddr)) && (ipa_zero(p->cf->local_ip) || ipa_equal(p->cf->local_ip, sk->saddr)))
(p->cf->local_port == sk->sport))
return p; return p;
return NULL; return NULL;
@ -1765,8 +1770,9 @@ bgp_postconfig(struct proto_config *CF)
if (!cf->remote_as) if (!cf->remote_as)
cf_error("Remote AS number must be set"); cf_error("Remote AS number must be set");
if (ipa_is_link_local(cf->remote_ip) && !cf->iface) if (!cf->iface && (ipa_is_link_local(cf->local_ip) ||
cf_error("Link-local neighbor address requires specified interface"); ipa_is_link_local(cf->remote_ip)))
cf_error("Link-local addresses require defined interface");
if (!(cf->capabilities && cf->enable_as4) && (cf->remote_as > 0xFFFF)) if (!(cf->capabilities && cf->enable_as4) && (cf->remote_as > 0xFFFF))
cf_error("Neighbor AS number out of range (AS4 not available)"); cf_error("Neighbor AS number out of range (AS4 not available)");

View file

@ -1077,6 +1077,7 @@ sk_passive_connected(sock *s, int type)
sock *t = sk_new(s->pool); sock *t = sk_new(s->pool);
t->type = type; t->type = type;
t->data = s->data;
t->af = s->af; t->af = s->af;
t->fd = fd; t->fd = fd;
t->ttl = s->ttl; t->ttl = s->ttl;