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)
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 */
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);
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);
}
offsetlen--;
/* get node */
- dest = bgp_node_get(bgp->rib[afi][safi], addr);
+ dest = bgp_node_lookup(bgp->rib[afi][safi], addr);
}
if (!dest)
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)
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) {
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;
/* Encode bgp4V2NlriIndex*/
- *offset = 1;
+ *offset = nrli_index;
offset++;
*length = offset - name;
}
memset(&paddr.ip, 0, sizeof(paddr.ip));
+ nrli_index = 1;
} while ((dest = bgp_route_next(dest)));