Skip to content

Commit

Permalink
Merge pull request #14889 from fdumontet6WIND/snmpv2
Browse files Browse the repository at this point in the history
bgpd: add multiple paths support for draft ietf bgp4v2 in nlriTable
  • Loading branch information
ton31337 authored Dec 8, 2023
2 parents 2df4683 + 869047f commit 6b79b56
Show file tree
Hide file tree
Showing 9 changed files with 419 additions and 177 deletions.
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

0 comments on commit 6b79b56

Please sign in to comment.