One single route-map for both IPv4 and IPv6 BGP prefixes

I just want to share here a note-to-myself about route-maps and IPv4/IPv6 BGP prefixes matching.

R1 and R2 were BGP speakers, R1 was announcing both IPv4 and IPv6 prefixes to R2 and I wanted to set, let’s say, different weights on those prefixes: weight = 4 to the IPv4 prefix and weight = 6 to the IPv6 prefix. It’s stupid, of course, but it’s just to simplify the real task I had to face. 🙂



My goal was to have a single route-map for both IPv6 and IPv4 routes manipulation: a single route-map applied to the two neighbor statements in ipv4 and ipv6 address-family:

So, on R2 I wrote the route-map and applied it to the neighbor statement:

R2:

ip prefix-list IPv4 seq 5 permit 192.168.1.1/32
!
ipv6 prefix-list IPv6 seq 5 permit 2001:DB8:1::/64
!
route-map RouteMapIN permit 10
 match ip address prefix-list IPv4
 set weight 4
!
route-map RouteMapIN permit 20
 match ipv6 address prefix-list IPv6
 set weight 6
!
route-map RouteMapIN permit 100
!
router bgp 65535
 address-family ipv4
  neighbor 192.168.0.1 route-map RouteMapIN in
 exit-address-family
 !
 address-family ipv6
  neighbor 2001:DB8::1 route-map RouteMapIN in
 exit-address-family
!

This is what I expected:

I thought it was fine to match only the IPv4 prefix on sequence number 10, and only the IPv6 prefix on sequence number 20, but that was incorrect:

R2#clear bgp all 65535
R2#show bgp all
For address family: IPv4 Unicast
BGP table version is 6, local router ID is 192.168.2.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i192.168.1.1/32   192.168.0.1              0    100      4 i

For address family: IPv6 Unicast
BGP table version is 6, local router ID is 192.168.2.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i2001:DB8:1::/64  2001:DB8::1              0    100      4 i

Both prefixes had weight = 4!

So I tried to exchange the route-map entries’ position to confirm my doubt:

R2:

no route-map RouteMapIN
!
route-map RouteMapIN permit 10
 match ipv6 address prefix-list IPv6
 set weight 6
!
route-map RouteMapIN permit 20
 match ip address prefix-list IPv4
 set weight 4
!
route-map RouteMapIN permit 100
R2#clear bgp all 65535
R2#show bgp all
For address family: IPv4 Unicast
BGP table version is 8, local router ID is 192.168.2.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i192.168.1.1/32   192.168.0.1              0    100      6 i

For address family: IPv6 Unicast
BGP table version is 8, local router ID is 192.168.2.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i2001:DB8:1::/64  2001:DB8::1              0    100      6 i

As supposed, both prefixes had weight = 6!

Finally, I decided to use more restrictive statements, by matching the specific prefix I wanted to match and explicitly denying the other…

R2:

! Here I deny every IPv4 prefix
ip prefix-list NoIPv4 seq 5 deny 0.0.0.0/0 le 32
!
! Here I deny every IPv6 prefix
ipv6 prefix-list NoIPv6 seq 5 deny ::/0 le 128
!
no route-map RouteMapIN
!
route-map RouteMapIN permit 10
 ! Match the IPv4 prefix...
 match ip address prefix-list IPv4
 ! ... but not IPv6 prefixes.
 match ipv6 address prefix-list NoIPv6
 set weight 4
!
route-map RouteMapIN permit 20
 ! Do not match IPv4 prefixes...
 match ip address prefix-list NoIPv4
 ! ... but match only the wanted IPv6 prefix.
 match ipv6 address prefix-list IPv6
 set weight 6
!
route-map RouteMapIN permit 100

… and I got the right result:

R2#clear bgp all 65535
R2#show bgp all
For address family: IPv4 Unicast
BGP table version is 10, local router ID is 192.168.2.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i192.168.1.1/32   192.168.0.1              0    100      4 i

For address family: IPv6 Unicast
BGP table version is 10, local router ID is 192.168.2.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i2001:DB8:1::/64  2001:DB8::1              0    100      6 i

The IPv4 prefix had weight = 4, and the IPv6 one weight = 6!

What did I miss? Any suggestion is strongly appreciated!

The following two tabs change content below.
Italian, born in 1980, I started working in the IT area in the late '90s; I'm now a system and network administrator with a deep knowledge of the global Internet and its core architectures.

4 Comments

  1. Marco Rizzi says:

    Hi Pierky!

    Interesting one! seems that route-maps are working on address familes, so you have implicit match.

    Let’s rewrite your first route map with a match for each address family, looks like:

    route-map RouteMapIN permit 10
     match ip address prefix-list IPv4     <-- match for ipv4 address family
     {implicit match any ipv6 address}     <-- match for ipv6 address family
     set weight 4
    !
    route-map RouteMapIN permit 20
     {implicit match any ipv4 address}     <-- match for ipv4 address family
     match ipv6 address prefix-list IPv6   <-- match for ipv6 address family
     set weight 6
    !
    route-map RouteMapIN permit 100
    

    If you look it in this perspective, it makes sense, the missing match statement for the address family acts as a match all.

    Seems that a match in a different address family is simply ignored and not used as tie breaker to the next statement.

    nice troubleshooting task 🙂

    Marco

    • pierky says:

      Hi Marco,

      Seems that a match in a different address family is simply ignored and not used as tie breaker to the next statement.

      yes, of course, this is a good reason! When applied to BGP UPDATEs in the ipv4 address-family it acts like if the “match ipv6…” statement does not exist. Same thing when applied to ipv6 address-family prefixes with the “match ip…” statement.

      Nice hint! 🙂

      Pierky

      P.S.: congrats again for your number! 🙂

  2. Frank DiGravina says:

    If A and B are bgp peering for ip and IPv6 prefixes, is it the consensus that separate route-maps
    ought to be used? Bad things happen when a common route-map us used for both address-families, when you are calling out specific IPv4 or IPv6 addresses in that common route-map.

  3. A Friend says:

    I was bitten by this too, am using IRRtoolset to build prefix-filters. They’re applied using route-maps. I ended up doing one route-map per address family, and also spelling out the peera ddress in the IRR entry. Not as elegant but easier to automate.

Leave a Reply to A Friend Cancel reply