summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-12-15 14:01:57 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-12-16 15:43:58 +0100
commitcb311b441a6bbc02e88cd4a92e19044e2e95aac2 (patch)
tree773e6a72accef3540bd06fdba8ea0c9f7ae118e2 /proto
parent3a2a3c7325b34923c4ecc465700708dd13e6ad73 (diff)
BGP: Better handling of non-matching AFI in nexthops
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/attrs.c2
-rw-r--r--proto/bgp/packets.c10
2 files changed, 10 insertions, 2 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 868caca5..cbb22038 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1386,8 +1386,6 @@ bgp_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
if (src == NULL)
return 0;
- // XXXX: Check next hop AF
-
/* IBGP route reflection, RFC 4456 */
if (p->is_internal && src->is_internal && (p->local_as == src->local_as))
{
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index c2261870..e7089eba 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -855,6 +855,7 @@ static inline int
bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
{
struct bgp_proto *p = s->proto;
+ struct bgp_channel *c = s->channel;
ip_addr *nh = (void *) a->u.ptr->data;
if (s->channel->cf->next_hop_self)
@@ -867,6 +868,10 @@ bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
if (a->type & EAF_FRESH)
return 1;
+ /* Check for non-matching AF */
+ if ((ipa_is_ip4(*nh) != bgp_channel_is_ipv4(c)) && !c->ext_next_hop)
+ return 0;
+
/* Keep it when exported to internal peers */
if (p->is_interior && ipa_nonzero(*nh))
return 1;
@@ -880,6 +885,7 @@ static inline int
bgp_use_gateway(struct bgp_export_state *s)
{
struct bgp_proto *p = s->proto;
+ struct bgp_channel *c = s->channel;
rta *ra = s->route->attrs;
if (s->channel->cf->next_hop_self)
@@ -889,6 +895,10 @@ bgp_use_gateway(struct bgp_export_state *s)
if ((ra->dest != RTD_UNICAST) || ra->nh.next || ipa_zero(ra->nh.gw) || ipa_is_link_local(ra->nh.gw))
return 0;
+ /* Check for non-matching AF */
+ if ((ipa_is_ip4(ra->nh.gw) != bgp_channel_is_ipv4(c)) && !c->ext_next_hop)
+ return 0;
+
/* Use it when exported to internal peers */
if (p->is_interior)
return 1;