diff options
Diffstat (limited to 'bgpd/bgp_zebra.c')
| -rw-r--r-- | bgpd/bgp_zebra.c | 35 |
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; |
