]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Do not discard an UPDATE if the global nexthop is set to ::
authorDonatas Abraitis <donatas.abraitis@gmail.com>
Mon, 20 Apr 2020 15:46:23 +0000 (18:46 +0300)
committerDonatas Abraitis <donatas.abraitis@gmail.com>
Mon, 20 Apr 2020 15:59:15 +0000 (18:59 +0300)
When we receive an UPDATE with MP_NEXTHOP len as 32 bytes, we shouldn't
check if the global (1st) nexthop is unspecified.

Peering between bird and FRRouting we receive from Bird something like:
```
rcvd UPDATE w/ attr: , origin i, mp_nexthop ::(fe80::a00:27ff:fe09:f8a3)
```
The link-local (2nd) nexthop is valid and validated later in the code.

Before it was marked:
```
IPv6 unicast -- DENIED due to: martian or self next-hop;
```

After it's a valid prefix:
```
spine1-debian-9# show bgp
BGP table version is 0, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 65002
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
   2a02:4780::/64   fe80::a00:27ff:fe09:f8a3
                                                           0 65001 i

Displayed  1 routes and 1 total paths
```

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
bgpd/bgp_route.c

index 4b9550d79a7b01ff96905028a48594846ff6ddcb..09eb6fcf82ce1b2fb3a3c542da5d80c129888585 100644 (file)
@@ -3257,6 +3257,10 @@ static bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
        /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
         * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
         * it is not an IPv6 link-local address.
+        *
+        * If we receive an UPDATE with nexthop length set to 32 bytes
+        * we shouldn't discard an UPDATE if it's set to (::).
+        * The link-local (2st) is validated along the code path later.
         */
        if (attr->mp_nexthop_len) {
                switch (attr->mp_nexthop_len) {
@@ -3270,7 +3274,6 @@ static bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
                        break;
 
                case BGP_ATTR_NHLEN_IPV6_GLOBAL:
-               case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
                case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
                        ret = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global)
                               || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
@@ -3279,6 +3282,13 @@ static bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
                               || bgp_nexthop_self(bgp, afi, type, stype,
                                                   attr, rn));
                        break;
+               case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
+                       ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
+                              || IN6_IS_ADDR_MULTICAST(
+                                      &attr->mp_nexthop_global)
+                              || bgp_nexthop_self(bgp, afi, type, stype, attr,
+                                                  rn));
+                       break;
 
                default:
                        ret = true;