]> 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>
Thu, 23 Apr 2020 19:18:25 +0000 (22:18 +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 5f4486b8004252115eed66fa33771999d78f33ca..d4bd82965edfaae52fb9883abb7763d7c7519767 100644 (file)
@@ -3003,6 +3003,10 @@ static int 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) {
@@ -3016,7 +3020,6 @@ static int 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)
@@ -3025,6 +3028,13 @@ static int 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 = 1;