bgpd: Allow overriding MPLS VPN next-hops via route-maps

Just do not reset next-hop for MPLS VPN routes.

Example of 172.16.255.1/32 (using extended next-hop capability):

```
pe2# sh bgp ipv4 vpn
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

    Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 192.168.1.2:2
 *>i10.0.0.0/24      2001:db8:1::1            0    100      0 65000 ?
    UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
 *>i172.16.255.1/32  2001:db8::1              0    100      0 65000 ?
    UN=2001:db8::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
 *>i192.168.1.0/24   2001:db8:1::1            0    100      0 65000 ?
    UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
 *>i192.168.2.0/24   2001:db8:1::1                 100      0 65000 ?
    UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
Route Distinguisher: 192.168.2.2:2
 *> 10.0.0.0/24      192.168.2.1@4<           0     50      0 65000 ?
    UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
 *> 172.16.255.1/32  192.168.2.1@4<                 50      0 65000 ?
    UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
 *> 192.168.1.0/24   192.168.2.1@4<                 50      0 65000 ?
    UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
 *> 192.168.2.0/24   192.168.2.1@4<           0     50      0 65000 ?
    UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5

Displayed  8 routes and 8 total paths
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This commit is contained in:
Donatas Abraitis 2022-11-18 15:47:50 +02:00
parent 9a84cb612e
commit 6eeb925545
4 changed files with 40 additions and 16 deletions

View File

@ -344,6 +344,8 @@ struct attr {
#define BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED (1 << 6)
#define BATTR_RMAP_LINK_BW_SET (1 << 7)
#define BATTR_RMAP_L3VPN_ACCEPT_GRE (1 << 8)
#define BATTR_RMAP_VPNV4_NHOP_CHANGED (1 << 9)
#define BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED (1 << 10)
/* Router Reflector related structure. */
struct cluster_list {
@ -476,15 +478,18 @@ extern enum bgp_attr_parse_ret bgp_attr_nexthop_valid(struct peer *peer,
static inline int bgp_rmap_nhop_changed(uint32_t out_rmap_flags,
uint32_t in_rmap_flags)
{
return ((CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_PEER_ADDRESS)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV4_NHOP_CHANGED)
|| CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED)
|| CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED)
|| CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_LL_NHOP_CHANGED)
|| CHECK_FLAG(in_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED))
return ((CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_PEER_ADDRESS) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV4_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_VPNV4_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_LL_NHOP_CHANGED) ||
CHECK_FLAG(in_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED))
? 1
: 0);
}

View File

@ -3725,6 +3725,8 @@ route_set_vpnv4_nexthop(void *rule, const struct prefix *prefix, void *object)
path->attr->mp_nexthop_global_in = *address;
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
SET_FLAG(path->attr->rmap_change_flags, BATTR_RMAP_VPNV4_NHOP_CHANGED);
return RMAP_OKAY;
}
@ -3762,6 +3764,9 @@ route_set_vpnv6_nexthop(void *rule, const struct prefix *prefix, void *object)
sizeof(struct in6_addr));
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_VPNV6_GLOBAL;
SET_FLAG(path->attr->rmap_change_flags,
BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED);
return RMAP_OKAY;
}

View File

@ -88,6 +88,8 @@ typedef struct {
#define BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED (1 << 4)
#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED (1 << 5)
#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_LNH_CHANGED (1 << 6)
#define BPKT_ATTRVEC_FLAGS_RMAP_VPNV4_NH_CHANGED (1 << 7)
#define BPKT_ATTRVEC_FLAGS_RMAP_VPNV6_GNH_CHANGED (1 << 8)
typedef struct bpacket_attr_vec_arr {
bpacket_attr_vec entries[BGP_ATTR_VEC_MAX];

View File

@ -379,10 +379,11 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
route_map_sets_nh =
(CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED)
|| CHECK_FLAG(
vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED) ||
CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_VPNV4_NH_CHANGED) ||
CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
switch (nhlen) {
case BGP_ATTR_NHLEN_IPV4:
@ -468,10 +469,12 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
route_map_sets_nh =
(CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED)
|| CHECK_FLAG(
BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED) ||
CHECK_FLAG(
vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
BPKT_ATTRVEC_FLAGS_RMAP_VPNV6_GNH_CHANGED) ||
CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS));
/*
* The logic here is rather similar to that for IPv4, the
@ -1276,6 +1279,15 @@ bpacket_vec_arr_inherit_attr_flags(struct bpacket_attr_vec_arr *vecarr,
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED);
if (CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_VPNV4_NHOP_CHANGED))
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
BPKT_ATTRVEC_FLAGS_RMAP_VPNV4_NH_CHANGED);
if (CHECK_FLAG(attr->rmap_change_flags,
BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED))
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,
BPKT_ATTRVEC_FLAGS_RMAP_VPNV6_GNH_CHANGED);
if (CHECK_FLAG(attr->rmap_change_flags,
BATTR_RMAP_IPV6_LL_NHOP_CHANGED))
SET_FLAG(vecarr->entries[BGP_ATTR_VEC_NH].flags,