Currently it is impossible to use gre(4) for directly connected hosts
because the route trick used fails in so many bad ways it is not even fun.
I came to the conclusion that we don't need such bad magic tricks
especially since the same can be achieved by using routing priorities.
Btw. gif(4) never did this strange game and IIRC does not even cache the
route for the tunnel.

So if you're a gre(4) user better test this diff
-- 
:wq Claudio

Index: if_gre.c
===================================================================
RCS file: /cvs/src/sys/net/if_gre.c,v
retrieving revision 1.52
diff -u -p -r1.52 if_gre.c
--- if_gre.c    23 Sep 2010 11:34:50 -0000      1.52
+++ if_gre.c    24 Sep 2010 02:01:30 -0000
@@ -675,29 +675,13 @@ void
 gre_compute_route(struct gre_softc *sc)
 {
        struct route *ro;
-       u_int32_t a, b, c;
 
        ro = &sc->route;
 
        bzero(ro, sizeof(struct route));
-       ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = sc->g_dst;
        ro->ro_dst.sa_family = AF_INET;
        ro->ro_dst.sa_len = sizeof(ro->ro_dst);
-
-       /*
-        * toggle last bit, so our interface is not found, but a less
-        * specific route. I'd rather like to specify a shorter mask,
-        * but this is not possible. Should work though. XXX
-        * there is a simpler way ...
-        */
-       if ((sc->sc_if.if_flags & IFF_LINK1) == 0) {
-               a = ntohl(sc->g_dst.s_addr);
-               b = a & 0x01;
-               c = a & 0xfffffffe;
-               b = b ^ 0x01;
-               a = b | c;
-               ((struct sockaddr_in *) &ro->ro_dst)->sin_addr.s_addr = 
htonl(a);
-       }
+       ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = sc->g_dst;
 
        ro->ro_rt = rtalloc1(&ro->ro_dst, RT_REPORT | RT_NOCLONING,
            sc->g_rtableid);
@@ -714,13 +698,6 @@ gre_compute_route(struct gre_softc *sc)
                ro->ro_rt = NULL;
                return;
        }
-
-       /*
-        * now change it back - else ip_output will just drop
-        * the route and search one to this interface ...
-        */
-       if ((sc->sc_if.if_flags & IFF_LINK1) == 0)
-               ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = sc->g_dst;
 }
 
 /*

Reply via email to