]> git.puffer.fish Git - mirror/frr.git/commitdiff
nhrpd: Create route to private spoke-spoke network correctly
authorGaurav Goyal <gaurav.goyal@4rf.com>
Sun, 1 Nov 2020 23:11:19 +0000 (12:11 +1300)
committerReuben Dowle <reuben.dowle@4rf.com>
Wed, 16 Dec 2020 21:17:13 +0000 (10:17 +1300)
Currently when the first traffic to a private network causes a shortcut, an
on-link route to the private network is created on the gre interface, along
with the cache entry.

When connecting to a second IP in the same network, the kernel tries to resolve
the public IP for this private network via query to NHRP. nhrpd sees no entry
in the cache, so the packet is dropped.

The fix to this solution can be instead of creating an on-link route, create an
off-link route to private network, with the next-hop being the remote tunnel's
gre IP address.

Signed-off-by: Reuben Dowle <reuben.dowle@4rf.com>
nhrpd/nhrp_shortcut.c

index 2359cfa4ac09f84ae678f255df75790cc862a5be..6ad0c9ea03926f8a278c863f73fac3e1353e36a1 100644 (file)
@@ -62,7 +62,7 @@ static void nhrp_shortcut_cache_notify(struct notifier_block *n,
                               s->p, s->cache->ifp->name);
 
                        nhrp_route_announce(1, s->type, s->p, s->cache->ifp,
-                                           NULL, 0);
+                                           &s->cache->remote_addr, 0);
                        s->route_installed = 1;
                }
                break;
@@ -207,6 +207,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid,
        struct nhrp_extension_header *ext;
        struct nhrp_cie_header *cie;
        struct nhrp_cache *c = NULL;
+       struct nhrp_cache *c_dst_proto = NULL;
        union sockunion *proto, cie_proto, *nbma, cie_nbma, nat_nbma;
        struct prefix prefix, route_prefix;
        struct zbuf extpl;
@@ -304,6 +305,22 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid,
                        debugf(NHRP_DEBUG_COMMON,
                               "Shortcut: no cache for nbma %s", buf[2]);
                }
+
+               /* Update cache binding for dst_proto as well */
+               if (proto != &pp->dst_proto) {
+                       c_dst_proto = nhrp_cache_get(pp->ifp, &pp->dst_proto, 1);
+                       if (c_dst_proto) {
+                               debugf(NHRP_DEBUG_COMMON,
+                              "Shortcut: cache found, update binding");
+                               nhrp_cache_update_binding(c_dst_proto, NHRP_CACHE_DYNAMIC,
+                                                 holding_time,
+                                                 nhrp_peer_get(pp->ifp, nbma),
+                                                 htons(cie->mtu), nbma);
+                       } else {
+                               debugf(NHRP_DEBUG_COMMON,
+                              "Shortcut: no cache for nbma %s", buf[2]);
+                       }
+               }
        }
 
        /* Update shortcut entry for subnet to protocol gw binding */