Hi,

I ran into a problem where when using /31 netmasks on point to point
links, I am unable to add a larger summary route that happens to have
the same network address as the /31 link route the box has. It's a
bit hard to explain so hopefully the art below helps.


                bsd1                                rtr2
      +---------------------+             +---------------------+
      | vio0  172.19.6.33/31|<----------->|172.19.6.32/31  if1  |
      +---------------------+             +---------------------+
172.19.6.32/27 -> 172.19.6.32

$route show
...
172.17.6.32/31     172.17.6.33        UCn        1        0     -     4 vio0
172.17.6.32        50:40:61:d6:05:e3  UHLch     79     5959     -     3 vio0
172.17.6.33        52:54:00:e7:0c:c5  UHLl       0       70     -     1 vio0

When I try to add the /27 route, it comes back with invalid argument

$ doas route add 172.17.6.32/27 172.17.6.32
add net 172.17.6.32/27: gateway 172.17.6.32: Invalid argument

I managed to track this down to a check in rtsock.c where it thinks that
the route I am adding is a modification of the existing L2 route for
172.19.7.32. The Invalid Argument is because later on in the RTM_CHANGE
code it wants a AF of the new nexthop to be the same as the route it
thinks its changing. When using /30 routes this would never happen as
you wouldn't get a host on the network address I guess. 

Diff below fixed the problem by also checking the prefix length matches
before assuming the route isn't a new route and jumping into RTM_CHANGE
code.

The code in change: also checks the AF are the same, before it will
do a modification so I'm not sure if this should also check that before
assuming the route isn't actually a new one?

As far as I could tell reading the other code, it seemed like the only
way to get RTF_CACHED flag was to be a L2 nexthop, so I don't think that
there would be a case where the prefix length of the new and old entries
don't match but the intent was to go through the change path. 




diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index a717d112e..9dbc8ca90 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -937,7 +937,10 @@ rtm_output(struct rt_msghdr *rtm, struct rtentry **prt,
                 * cached route because this can lead to races in the
                 * receive path.  Instead we update the L2 cache.
                 */
-               if ((rt != NULL) && ISSET(rt->rt_flags, RTF_CACHED)) {
+               plen = rtable_satoplen(info->rti_info[RTAX_DST]->sa_family,
+                   info->rti_info[RTAX_NETMASK]);
+               if ((rt != NULL) && (plen == rt->rt_plen) &&
+                   ISSET(rt->rt_flags, RTF_CACHED)) {
                        ifp = if_get(rt->rt_ifidx);
                        if (ifp == NULL) {
                                rtfree(rt);

Reply via email to