@@ -446,6 +446,8 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
446
446
size_t afi_len ;
447
447
long prefix_type = 0 ;
448
448
long peer_addr_type = 0 ;
449
+ long nrli_index = 1 ;
450
+ long cur_index = 0 ;
449
451
450
452
/* Bgp4V2AddressFamilyIdentifierTC limited to IPv6 */
451
453
if (name [namelen - 1 ] > IANA_AFI_IPV6 )
@@ -455,12 +457,17 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
455
457
assert (IS_VALID_AFI (afi ));
456
458
457
459
#define BGP_NLRI_ENTRY_OFFSET namelen
460
+ #define BGP4V2_NLRI_V4_V4_OFFSET IN_ADDR_SIZE + IN_ADDR_SIZE + 5
461
+ #define BGP4V2_NLRI_V4_V6_OFFSET IN_ADDR_SIZE + IN6_ADDR_SIZE + 5
462
+ #define BGP4V2_NLRI_V6_V6_OFFSET IN6_ADDR_SIZE + IN6_ADDR_SIZE + 5
458
463
459
464
460
465
sockunion_init (& su );
461
466
462
467
if (exact ) {
463
- if (* length - namelen != BGP_NLRI_ENTRY_OFFSET )
468
+ if (* length - namelen != BGP4V2_NLRI_V4_V4_OFFSET &&
469
+ * length - namelen != BGP4V2_NLRI_V4_V6_OFFSET &&
470
+ * length - namelen != BGP4V2_NLRI_V6_V6_OFFSET )
464
471
return NULL ;
465
472
466
473
/* Set OID offset for prefix type */
@@ -504,21 +511,29 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
504
511
su .sin .sin_family = family ;
505
512
506
513
/* get bgp4V2PeerRemoteAddr*/
507
- if (family == AF_INET )
514
+ if (family == AF_INET ) {
508
515
oid2in_addr (offset , IN_ADDR_SIZE , & su .sin .sin_addr );
509
- else
516
+ offset += IN_ADDR_SIZE ;
517
+ } else {
510
518
oid2in6_addr (offset , & su .sin6 .sin6_addr );
519
+ offset += IN6_ADDR_SIZE ;
520
+ }
511
521
512
- /* bgp4V2NlriIndex currently ignored */
522
+ /* bgp4V2NlriIndex */
523
+ nrli_index = * offset ;
524
+ offset ++ ;
513
525
514
526
/* Lookup node */
515
527
dest = bgp_node_lookup (bgp -> rib [afi ][safi ], addr );
516
528
if (dest ) {
517
529
for (path = bgp_dest_get_bgp_path_info (dest ); path ;
518
530
path = path -> next )
519
531
if (sockunion_same (& path -> peer -> connection -> su ,
520
- & su ))
521
- return path ;
532
+ & su )) {
533
+ cur_index ++ ;
534
+ if (cur_index == nrli_index )
535
+ return path ;
536
+ }
522
537
523
538
bgp_dest_unlock_node (dest );
524
539
}
@@ -573,7 +588,7 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
573
588
offsetlen -- ;
574
589
575
590
/* get node */
576
- dest = bgp_node_get (bgp -> rib [afi ][safi ], addr );
591
+ dest = bgp_node_lookup (bgp -> rib [afi ][safi ], addr );
577
592
}
578
593
579
594
if (!dest )
@@ -593,22 +608,31 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
593
608
family = AF_INET6 ;
594
609
offset ++ ;
595
610
596
- if (family == AF_INET )
611
+ if (family == AF_INET ) {
597
612
oid2in_addr (offset , IN_ADDR_SIZE , & paddr .ip ._v4_addr );
598
- else
613
+ offset += IN_ADDR_SIZE ;
614
+ } else {
599
615
oid2in6_addr (offset , & paddr .ip ._v6_addr );
616
+ offset += IN6_ADDR_SIZE ;
617
+ }
618
+ /* get bgp4V2NlriIndex */
619
+ nrli_index = * offset ;
620
+ offset ++ ;
621
+
600
622
} else {
601
623
/* default case start with ipv4*/
602
624
if (afi == AFI_IP )
603
625
family = AF_INET ;
604
626
else
605
627
family = AF_INET6 ;
606
628
memset (& paddr .ip , 0 , sizeof (paddr .ip ));
629
+ nrli_index = 1 ;
607
630
}
608
631
609
632
do {
610
633
min = NULL ;
611
634
min_family = 0 ;
635
+ cur_index = 0 ;
612
636
613
637
for (path = bgp_dest_get_bgp_path_info (dest ); path ;
614
638
path = path -> next ) {
@@ -618,19 +642,44 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
618
642
if (path_family < family )
619
643
continue ;
620
644
621
- if (family == AF_INET
622
- && IPV4_ADDR_CMP (& paddr .ip ._v4_addr ,
623
- & path -> peer -> connection -> su .sin . sin_addr )
624
- >= 0 )
645
+ if (family == AF_INET &&
646
+ IPV4_ADDR_CMP (& paddr .ip ._v4_addr ,
647
+ & path -> peer -> connection -> su .sin
648
+ . sin_addr ) > 0 )
625
649
continue ;
626
- else if (family == AF_INET6
627
- && IPV6_ADDR_CMP (
628
- & paddr .ip ._v6_addr ,
629
- & path -> peer -> connection -> su .sin6 .sin6_addr )
630
- >= 0 )
650
+ else if (family == AF_INET6 &&
651
+ IPV6_ADDR_CMP (& paddr .ip ._v6_addr ,
652
+ & path -> peer -> connection -> su .sin6
653
+ .sin6_addr ) > 0 )
631
654
continue ;
632
655
633
- /* first valid path its the min*/
656
+ if (family == AF_INET &&
657
+ IPV4_ADDR_CMP (& paddr .ip ._v4_addr ,
658
+ & path -> peer -> connection -> su .sin
659
+ .sin_addr ) == 0 ) {
660
+ if (cur_index == nrli_index ) {
661
+ min = path ;
662
+ min_family = family ;
663
+ nrli_index ++ ;
664
+ break ;
665
+ }
666
+ cur_index ++ ;
667
+ continue ;
668
+ } else if (family == AF_INET6 &&
669
+ IPV6_ADDR_CMP (& paddr .ip ._v6_addr ,
670
+ & path -> peer -> connection -> su
671
+ .sin6 .sin6_addr ) == 0 ) {
672
+ if (cur_index == nrli_index ) {
673
+ min = path ;
674
+ min_family = family ;
675
+ nrli_index ++ ;
676
+ break ;
677
+ }
678
+ cur_index ++ ;
679
+ continue ;
680
+ }
681
+
682
+ /* first valid path its the min peer addr*/
634
683
if (!min ) {
635
684
min = path ;
636
685
min_family = path_family ;
@@ -706,7 +755,7 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
706
755
707
756
/* Encode bgp4V2NlriIndex*/
708
757
709
- * offset = 1 ;
758
+ * offset = nrli_index ;
710
759
offset ++ ;
711
760
712
761
* length = offset - name ;
@@ -720,6 +769,7 @@ bgp4v2PathAttrLookup(struct variable *v, oid name[], size_t *length,
720
769
}
721
770
722
771
memset (& paddr .ip , 0 , sizeof (paddr .ip ));
772
+ nrli_index = 1 ;
723
773
724
774
} while ((dest = bgp_route_next (dest )));
725
775
0 commit comments