summaryrefslogtreecommitdiff
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r--bgpd/bgp_zebra.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 5d3176537b..fa290743c7 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -683,7 +683,7 @@ static int if_get_ipv6_global(struct interface *ifp, struct in6_addr *addr)
return 0;
}
-static int if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
+static bool if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
{
struct listnode *cnode;
struct connected *connected;
@@ -695,10 +695,10 @@ static int if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
if (cp->family == AF_INET6)
if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6)) {
memcpy(addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr)
@@ -724,6 +724,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
{
int ret = 0;
struct interface *ifp = NULL;
+ bool v6_ll_avail = true;
memset(nexthop, 0, sizeof(struct bgp_nexthop));
@@ -749,6 +750,9 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
? peer->conf_if
: peer->ifname,
peer->bgp->vrf_id);
+ else if (peer->update_if)
+ ifp = if_lookup_by_name(peer->update_if,
+ peer->bgp->vrf_id);
} else if (peer->update_if)
ifp = if_lookup_by_name(peer->update_if,
peer->bgp->vrf_id);
@@ -793,12 +797,20 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
* route-map to
* specify the global IPv6 nexthop.
*/
- if_get_ipv6_local(ifp, &nexthop->v6_global);
+ v6_ll_avail =
+ if_get_ipv6_local(ifp, &nexthop->v6_global);
memcpy(&nexthop->v6_local, &nexthop->v6_global,
IPV6_MAX_BYTELEN);
} else
- if_get_ipv6_local(ifp, &nexthop->v6_local);
+ v6_ll_avail =
+ if_get_ipv6_local(ifp, &nexthop->v6_local);
+ /*
+ * If we are a v4 connection and we are not doing unnumbered
+ * not having a v6 LL address is ok
+ */
+ if (!v6_ll_avail && !peer->conf_if)
+ v6_ll_avail = true;
if (if_lookup_by_ipv4(&remote->sin.sin_addr, peer->bgp->vrf_id))
peer->shared_network = 1;
else
@@ -824,7 +836,8 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
remote->sin6.sin6_scope_id,
peer->bgp->vrf_id);
if (direct)
- if_get_ipv6_local(ifp, &nexthop->v6_local);
+ v6_ll_avail = if_get_ipv6_local(
+ ifp, &nexthop->v6_local);
} else
/* Link-local address. */
{
@@ -871,7 +884,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
/* If we have identified the local interface, there is no error for now.
*/
- return true;
+ return v6_ll_avail;
}
static struct in6_addr *
@@ -2563,6 +2576,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
stream_putl(s, pbr->unique);
else
stream_putl(s, pbra->unique);
+ stream_putc(s, 0); /* ip protocol being used */
if (pbr && pbr->flags & MATCH_IP_SRC_SET)
memcpy(&pfx, &(pbr->src), sizeof(struct prefix));
else {
@@ -3302,6 +3316,13 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
&& nh->type != NEXTHOP_TYPE_IPV6)
|| nh->vrf_id == VRF_UNKNOWN)
return;
+
+ /* in vrf-lite, no default route has to be announced
+ * the table id of vrf is directly used to divert traffic
+ */
+ if (!vrf_is_backend_netns() && bgp->vrf_id != nh->vrf_id)
+ return;
+
memset(&p, 0, sizeof(struct prefix));
if (afi != AFI_IP && afi != AFI_IP6)
return;