Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: add multiple paths support for draft ietf bgp4v2 in nlriTable #14889

Merged
merged 2 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 70 additions & 20 deletions bgpd/bgp_snmp_bgp4v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
size_t afi_len;
long prefix_type = 0;
long peer_addr_type = 0;
long nrli_index = 1;
long cur_index = 0;

/* Bgp4V2AddressFamilyIdentifierTC limited to IPv6 */
if (name[namelen - 1] > IANA_AFI_IPV6)
Expand All @@ -455,12 +457,17 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
assert(IS_VALID_AFI(afi));

#define BGP_NLRI_ENTRY_OFFSET namelen
#define BGP4V2_NLRI_V4_V4_OFFSET IN_ADDR_SIZE + IN_ADDR_SIZE + 5
#define BGP4V2_NLRI_V4_V6_OFFSET IN_ADDR_SIZE + IN6_ADDR_SIZE + 5
#define BGP4V2_NLRI_V6_V6_OFFSET IN6_ADDR_SIZE + IN6_ADDR_SIZE + 5


sockunion_init(&su);

if (exact) {
if (*length - namelen != BGP_NLRI_ENTRY_OFFSET)
if (*length - namelen != BGP4V2_NLRI_V4_V4_OFFSET &&
*length - namelen != BGP4V2_NLRI_V4_V6_OFFSET &&
*length - namelen != BGP4V2_NLRI_V6_V6_OFFSET)
return NULL;

/* Set OID offset for prefix type */
Expand Down Expand Up @@ -504,21 +511,29 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
su.sin.sin_family = family;

/* get bgp4V2PeerRemoteAddr*/
if (family == AF_INET)
if (family == AF_INET) {
oid2in_addr(offset, IN_ADDR_SIZE, &su.sin.sin_addr);
else
offset += IN_ADDR_SIZE;
} else {
oid2in6_addr(offset, &su.sin6.sin6_addr);
offset += IN6_ADDR_SIZE;
}

/* bgp4V2NlriIndex currently ignored */
/* bgp4V2NlriIndex */
nrli_index = *offset;
offset++;

/* Lookup node */
dest = bgp_node_lookup(bgp->rib[afi][safi], addr);
if (dest) {
for (path = bgp_dest_get_bgp_path_info(dest); path;
path = path->next)
if (sockunion_same(&path->peer->connection->su,
&su))
return path;
&su)) {
cur_index++;
if (cur_index == nrli_index)
return path;
}

bgp_dest_unlock_node(dest);
}
Expand Down Expand Up @@ -573,7 +588,7 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
offsetlen--;

/* get node */
dest = bgp_node_get(bgp->rib[afi][safi], addr);
dest = bgp_node_lookup(bgp->rib[afi][safi], addr);
}

if (!dest)
Expand All @@ -593,22 +608,31 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
family = AF_INET6;
offset++;

if (family == AF_INET)
if (family == AF_INET) {
oid2in_addr(offset, IN_ADDR_SIZE, &paddr.ip._v4_addr);
else
offset += IN_ADDR_SIZE;
} else {
oid2in6_addr(offset, &paddr.ip._v6_addr);
offset += IN6_ADDR_SIZE;
}
/* get bgp4V2NlriIndex */
nrli_index = *offset;
offset++;

} else {
/* default case start with ipv4*/
if (afi == AFI_IP)
family = AF_INET;
else
family = AF_INET6;
memset(&paddr.ip, 0, sizeof(paddr.ip));
nrli_index = 1;
}

do {
min = NULL;
min_family = 0;
cur_index = 0;

for (path = bgp_dest_get_bgp_path_info(dest); path;
path = path->next) {
Expand All @@ -618,19 +642,44 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
if (path_family < family)
continue;

if (family == AF_INET
&& IPV4_ADDR_CMP(&paddr.ip._v4_addr,
&path->peer->connection->su.sin.sin_addr)
>= 0)
if (family == AF_INET &&
IPV4_ADDR_CMP(&paddr.ip._v4_addr,
&path->peer->connection->su.sin
.sin_addr) > 0)
continue;
else if (family == AF_INET6
&& IPV6_ADDR_CMP(
&paddr.ip._v6_addr,
&path->peer->connection->su.sin6.sin6_addr)
>= 0)
else if (family == AF_INET6 &&
IPV6_ADDR_CMP(&paddr.ip._v6_addr,
&path->peer->connection->su.sin6
.sin6_addr) > 0)
continue;

/* first valid path its the min*/
if (family == AF_INET &&
IPV4_ADDR_CMP(&paddr.ip._v4_addr,
&path->peer->connection->su.sin
.sin_addr) == 0) {
if (cur_index == nrli_index) {
min = path;
min_family = family;
nrli_index++;
break;
}
cur_index++;
continue;
} else if (family == AF_INET6 &&
IPV6_ADDR_CMP(&paddr.ip._v6_addr,
&path->peer->connection->su
.sin6.sin6_addr) == 0) {
if (cur_index == nrli_index) {
min = path;
min_family = family;
nrli_index++;
break;
}
cur_index++;
continue;
}

/* first valid path its the min peer addr*/
if (!min) {
min = path;
min_family = path_family;
Expand Down Expand Up @@ -706,7 +755,7 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,

/* Encode bgp4V2NlriIndex*/

*offset = 1;
*offset = nrli_index;
offset++;

*length = offset - name;
Expand All @@ -720,6 +769,7 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
}

memset(&paddr.ip, 0, sizeof(paddr.ip));
nrli_index = 1;

} while ((dest = bgp_route_next(dest)));

Expand Down
21 changes: 12 additions & 9 deletions tests/topotests/bgp_snmp_bgp4v2mib/r1/bgpd.conf
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
!
!debug bgp updates
!
router bgp 65001
no bgp ebgp-requires-policy
no bgp network import-check
no bgp default ipv4-unicast
neighbor 192.168.12.2 remote-as external
neighbor 192.168.12.2 timers 1 3
neighbor 192.168.12.2 timers connect 1
neighbor 2001:db8::12:2 remote-as external
neighbor 2001:db8::12:2 timers 1 3
neighbor 2001:db8::12:2 timers connect 1
neighbor 192.168.12.4 remote-as external
neighbor 192.168.12.4 timers 1 3
neighbor 192.168.12.4 timers connect 1
neighbor 2001:db8::12:4 remote-as external
neighbor 2001:db8::12:4 timers 1 3
neighbor 2001:db8::12:4 timers connect 1
!
address-family ipv4 unicast
network 10.0.0.0/31 route-map p1
network 10.0.0.2/32 route-map p2
neighbor 192.168.12.2 activate
neighbor 192.168.12.4 activate
neighbor 192.168.12.4 addpath-tx-all-paths
network 10.10.10.10/32
exit-address-family
address-family ipv6 unicast
network 2001:db8::1/128 route-map p1
network 2001:db8:1::/56 route-map p2
neighbor 2001:db8::12:2 activate
neighbor 2001:db8::12:4 activate
exit-address-family
!
route-map p1 permit 10
Expand All @@ -28,4 +32,3 @@ route-map p2 permit 10
set metric 2
set origin incomplete
exit
!
18 changes: 10 additions & 8 deletions tests/topotests/bgp_snmp_bgp4v2mib/r2/bgpd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ router bgp 65002
no bgp ebgp-requires-policy
no bgp network import-check
no bgp default ipv4-unicast
neighbor 192.168.12.1 remote-as external
neighbor 192.168.12.1 timers 1 3
neighbor 192.168.12.1 timers connect 1
neighbor 2001:db8::12:1 remote-as external
neighbor 2001:db8::12:1 timers 1 3
neighbor 2001:db8::12:1 timers connect 1
neighbor 192.168.12.4 remote-as external
neighbor 192.168.12.4 timers 1 3
neighbor 192.168.12.4 timers connect 1
neighbor 2001:db8::12:4 remote-as external
neighbor 2001:db8::12:4 timers 1 3
neighbor 2001:db8::12:4 timers connect 1
!
address-family ipv4 unicast
neighbor 192.168.12.1 activate
neighbor 192.168.12.4 activate
neighbor 192.168.12.4 addpath-tx-all-paths

exit-address-family
address-family ipv6 unicast
neighbor 2001:db8::12:1 activate
neighbor 2001:db8::12:4 activate
exit-address-family
!
agentx
Expand Down
25 changes: 25 additions & 0 deletions tests/topotests/bgp_snmp_bgp4v2mib/r3/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
!
!debug bgp updates
!
router bgp 65003
no bgp ebgp-requires-policy
no bgp network import-check
no bgp default ipv4-unicast
neighbor 192.168.12.4 remote-as external
neighbor 192.168.12.4 timers 1 3
neighbor 192.168.12.4 timers connect 1
neighbor 2001:db8::12:4 remote-as external
neighbor 2001:db8::12:4 timers 1 3
neighbor 2001:db8::12:4 timers connect 1
!
address-family ipv4 unicast
neighbor 192.168.12.4 activate
neighbor 192.168.12.4 addpath-tx-all-paths
network 10.10.10.10/32
exit-address-family
address-family ipv6 unicast
neighbor 2001:db8::12:4 activate
exit-address-family
!
agentx
!
5 changes: 5 additions & 0 deletions tests/topotests/bgp_snmp_bgp4v2mib/r3/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
!
interface r3-eth0
ip address 192.168.12.3/24
ipv6 address 2001:db8::12:3/64
!
67 changes: 67 additions & 0 deletions tests/topotests/bgp_snmp_bgp4v2mib/rr/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
!
! debug bgp updates
!
router bgp 65004
no bgp ebgp-requires-policy
no bgp network import-check
no bgp default ipv4-unicast
neighbor 192.168.12.1 remote-as external
neighbor 192.168.12.1 timers 1 3
neighbor 192.168.12.1 timers connect 1
neighbor 192.168.12.2 remote-as external
neighbor 192.168.12.2 timers 1 3
neighbor 192.168.12.2 timers connect 1
neighbor 192.168.12.3 remote-as external
neighbor 192.168.12.3 timers 1 3
neighbor 192.168.12.3 timers connect 1
neighbor 2001:db8::12:1 remote-as external
neighbor 2001:db8::12:1 timers 1 3
neighbor 2001:db8::12:1 timers connect 1
neighbor 2001:db8::12:2 remote-as external
neighbor 2001:db8::12:2 timers 1 3
neighbor 2001:db8::12:2 timers connect 1
neighbor 2001:db8::12:3 remote-as external
neighbor 2001:db8::12:3 timers 1 3
neighbor 2001:db8::12:3 timers connect 1
!
address-family ipv4 unicast
network 10.0.0.0/31 route-map p1
network 10.0.0.2/32 route-map p2
neighbor 192.168.12.1 activate
neighbor 192.168.12.2 activate
neighbor 192.168.12.2 addpath-tx-all-paths
neighbor 192.168.12.2 route-map r2-import in
neighbor 192.168.12.2 route-map r2-export out
! neighbor 192.168.12.2 soft-reconfiguration inbound
neighbor 192.168.12.3 activate
exit-address-family
address-family ipv6 unicast
network 2001:db8::1/128 route-map p1
network 2001:db8:1::/56 route-map p2
neighbor 2001:db8::12:1 activate
neighbor 2001:db8::12:2 activate
neighbor 2001:db8::12:2 addpath-tx-all-paths
neighbor 2001:db8::12:3 activate
exit-address-family


ip prefix-list r2-toto permit any

route-map r2-import permit 10
match ip address prefix-list r2-toto

route-map r2-export permit 10
match ip address prefix-list r2-toto
!
route-map p1 permit 10
set metric 1
exit
route-map p2 permit 10
set metric 2
set origin incomplete
exit



agentx
!
5 changes: 5 additions & 0 deletions tests/topotests/bgp_snmp_bgp4v2mib/rr/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
!
interface rr-eth0
ip address 192.168.12.4/24
ipv6 address 2001:db8::12:4/64
!
Loading
Loading