Hi Martin - Thanks for the patch.
It installed ok on my 5.9 stable system. patch failed to process it - I think because line numbers have changed. But it was not too difficult to install it manually. Thing seem to be working ok so far. I will keep watching and let you know. This is what I see for routes starting with ff01 and ff02 in netstat -rn output now, which looks encouraging: ff01::/16 ::1 UGRS 0 2 32768 8 lo0 ff01::%em0/32 fe80::207:e9ff:fe19:e002%em0 Um 0 1 - 4 em0 ff01::%em1/32 fe80::207:e9ff:fe19:e003%em1 Um 0 1 - 4 em1 ff01::%lo0/32 ::1 Um 0 1 32768 4 lo0 ff02::/16 ::1 UGRS 0 2 32768 8 lo0 ff02::%em0/32 fe80::207:e9ff:fe19:e002%em0 Um 1 2 - 4 em0 ff02::%em1/32 fe80::207:e9ff:fe19:e003%em1 Um 0 3 - 4 em1 ff02::%lo0/32 ::1 Um 0 1 32768 4 lo0 On Tue, Jul 5, 2016 at 9:46 AM, Martin Pieuchot <[email protected]> wrote: > Hello Aaron, > > On 24/06/16(Fri) 06:25, Aaron Riekenberg wrote: > > I am running an OpenBSD 5.9 box as a firewall/router on a Comcast cable > > connection. My box has 2 interfaces: em0 on external network (cable > modem) > > and em1 on internal network. I have applied all available patches for > 5.9. > > > > For ipv6 I'm running wide-dhcpv6 package to get a non-temporary address > on > > em0 and prefix delegation (/64) on em1. > > > > I'm using slaac on em0 to get the default inet6 route from Comcast - I > have > > "rtsol" line in hostname.em0. > > > > Finally I'm running rtadvd on em1 to advertise inet6 route and prefix to > > internal clients. I'm using default rtadvd config (no config file). > > > > This all works great, but one issue I'm noticing is netstat -rn output > > seems to keep growing, particularly for ff02::1:ff routes on the internal > > interface (em1). After 2 days of uptime I have this: > > > > $ netstat -rn | grep -c 'ff02::1:ff' > > 124 > > > > These routes look like this - notice c flag so these are cloned routes: > > > > $ netstat -rn | grep 'ff02::1:ff' > > ff02::1:ff02:e530%em1 link#3 UHLc > > 0 3 - 4 em1 > > ff02::1:ff04:8e23%em1 link#3 UHLc > > 0 71 - 4 em1 > > ff02::1:ff04:ee06%em1 link#3 UHLc > > 0 2 - 4 em1 > > > > Wikipedia says these are solicited node multicast addresses: > > https://en.wikipedia.org/wiki/Solicited-node_multicast_address > > > > Looking at the kernel code - I think these are all cloned child routes > of a > > route set up by this code in sys/netinet6/in6.c (interesting comment): > > > > 807 bzero(&info, sizeof(info)); > > 808 info.rti_info[RTAX_DST] = > sin6tosa(&mltaddr); > > 809 info.rti_info[RTAX_GATEWAY] = > > sin6tosa(&ia6->ia_addr); > > 810 info.rti_info[RTAX_NETMASK] = > > sin6tosa(&mltmask); > > 811 info.rti_info[RTAX_IFA] = > > sin6tosa(&ia6->ia_addr); > > 812 /* XXX: we need RTF_CLONING to fake > > nd6_rtrequest */ > > 813 info.rti_flags = RTF_CLONING; > > 814 error = rtrequest(RTM_ADD, &info, > > RTP_CONNECTED, NULL, > > 815 ifp->if_rdomain); > > > > mltaddr is set to in6addr_linklocal_allnodes, which > > is IN6ADDR_LINKLOCAL_ALLNODES_INIT, which is ff02::1:ff > > > > > > Questions - Are these child routes really leaking? Is there a max number > > of cloned child routes or a timeout for these? I cannot find any > evidence > > of this. > > Yes they are leaking. It believe very few people trigger this problem > that's why it went unnoticed. > > This hack is here to prevent the following error: > > nd6_rtrequest: bad gateway value: em0 > > That's because the routing table hasn't been designed to handle multicast > addresses and KAME people worked around that. Setting the RTF_CLONING > flag was the worst thing to do to have a working route entry without > triggering this error. > > I plan to start flagging multicast route entries as such. Here's > what I have in my tree. The diff below should prevent your leak, I'd > be interested to know if everything still work on your setup with it. > > Note that it is for -current but it might apply without problem on a > 5.9 tree. > > Index: sys/net/route.h > =================================================================== > RCS file: /cvs/src/sys/net/route.h,v > retrieving revision 1.138 > diff -u -p -r1.138 route.h > --- sys/net/route.h 14 Jun 2016 09:48:52 -0000 1.138 > +++ sys/net/route.h 5 Jul 2016 14:28:22 -0000 > @@ -131,7 +131,7 @@ struct rtentry { > #define RTF_DONE 0x40 /* message confirmed */ > #define RTF_MASK 0x80 /* subnet mask present */ > #define RTF_CLONING 0x100 /* generate new routes on use */ > -/* 0x200 unused */ > +#define RTF_MULTICAST 0x200 /* route associated to a mcast > addr. */ > #define RTF_LLINFO 0x400 /* generated by ARP or ND */ > #define RTF_STATIC 0x800 /* manually added */ > #define RTF_BLACKHOLE 0x1000 /* just discard pkts (during > updates) */ > Index: sys/netinet/if_ether.c > =================================================================== > RCS file: /cvs/src/sys/netinet/if_ether.c,v > retrieving revision 1.216 > diff -u -p -r1.216 if_ether.c > --- sys/netinet/if_ether.c 28 Jun 2016 17:18:24 -0000 1.216 > +++ sys/netinet/if_ether.c 5 Jul 2016 14:34:10 -0000 > @@ -139,7 +139,7 @@ arp_rtrequest(struct ifnet *ifp, int req > timeout_add_sec(&arptimer_to, 1); > } > > - if (rt->rt_flags & (RTF_GATEWAY|RTF_BROADCAST)) > + if (ISSET(rt->rt_flags, RTF_GATEWAY|RTF_BROADCAST|RTF_MULTICAST)) > return; > > switch (req) { > Index: sys/netinet6/in6.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/in6.c,v > retrieving revision 1.188 > diff -u -p -r1.188 in6.c > --- sys/netinet6/in6.c 5 Jul 2016 10:17:14 -0000 1.188 > +++ sys/netinet6/in6.c 5 Jul 2016 14:19:36 -0000 > @@ -757,8 +757,7 @@ in6_update_ifa(struct ifnet *ifp, struct > info.rti_info[RTAX_GATEWAY] = > sin6tosa(&ia6->ia_addr); > info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask); > info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr); > - /* XXX: we need RTF_CLONING to fake nd6_rtrequest > */ > - info.rti_flags = RTF_CLONING; > + info.rti_flags = RTF_MULTICAST; > error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, > NULL, > ifp->if_rdomain); > if (error) > @@ -814,7 +813,7 @@ in6_update_ifa(struct ifnet *ifp, struct > info.rti_info[RTAX_GATEWAY] = > sin6tosa(&ia6->ia_addr); > info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask); > info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr); > - info.rti_flags = RTF_CLONING; > + info.rti_flags = RTF_MULTICAST; > error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, > NULL, > ifp->if_rdomain); > if (error) > Index: sys/netinet6/nd6.c > =================================================================== > RCS file: /cvs/src/sys/netinet6/nd6.c,v > retrieving revision 1.186 > diff -u -p -r1.186 nd6.c > --- sys/netinet6/nd6.c 15 Jun 2016 11:49:34 -0000 1.186 > +++ sys/netinet6/nd6.c 5 Jul 2016 14:34:55 -0000 > @@ -882,7 +882,7 @@ nd6_rtrequest(struct ifnet *ifp, int req > dr->installed = 0; > } > > - if ((rt->rt_flags & RTF_GATEWAY) != 0) > + if (ISSET(rt->rt_flags, RTF_GATEWAY|RTF_MULTICAST)) > return; > > if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) { > Index: sbin/route/show.c > =================================================================== > RCS file: /cvs/src/sbin/route/show.c,v > retrieving revision 1.103 > diff -u -p -r1.103 show.c > --- sbin/route/show.c 27 Nov 2015 16:26:52 -0000 1.103 > +++ sbin/route/show.c 5 Jul 2016 14:18:24 -0000 > @@ -78,8 +78,8 @@ static const struct bits bits[] = { > { RTF_DYNAMIC, 'D' }, > { RTF_MODIFIED, 'M' }, > { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ > - { RTF_MASK, 'm' }, /* Mask Present -- for routing messages > only */ > { RTF_CLONING, 'C' }, > + { RTF_MULTICAST,'m' }, > { RTF_LLINFO, 'L' }, > { RTF_STATIC, 'S' }, > { RTF_PROTO1, '1' }, > Index: usr.bin/netstat/show.c > =================================================================== > RCS file: /cvs/src/usr.bin/netstat/show.c,v > retrieving revision 1.49 > diff -u -p -r1.49 show.c > --- usr.bin/netstat/show.c 11 Sep 2015 20:10:26 -0000 1.49 > +++ usr.bin/netstat/show.c 5 Jul 2016 14:20:05 -0000 > @@ -78,8 +78,8 @@ static const struct bits bits[] = { > { RTF_DYNAMIC, 'D' }, > { RTF_MODIFIED, 'M' }, > { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ > - { RTF_MASK, 'm' }, /* Mask Present -- for routing messages > only */ > { RTF_CLONING, 'C' }, > + { RTF_MULTICAST,'m' }, > { RTF_LLINFO, 'L' }, > { RTF_STATIC, 'S' }, > { RTF_PROTO1, '1' }, > Index: usr.sbin/route6d/route6d.c > =================================================================== > RCS file: /cvs/src/usr.sbin/route6d/route6d.c,v > retrieving revision 1.86 > diff -u -p -r1.86 route6d.c > --- usr.sbin/route6d/route6d.c 25 Jan 2016 05:15:43 -0000 1.86 > +++ usr.sbin/route6d/route6d.c 5 Jul 2016 14:24:03 -0000 > @@ -2319,45 +2319,16 @@ do { \ > RTFLAG("D", RTF_DYNAMIC); > RTFLAG("M", RTF_MODIFIED); > RTFLAG("d", RTF_DONE); > -#ifdef RTF_MASK > - RTFLAG("m", RTF_MASK); > -#endif > + RTFLAG("m", RTF_MULTICAST); > RTFLAG("C", RTF_CLONING); > -#ifdef RTF_CLONED > RTFLAG("c", RTF_CLONED); > -#endif > -#ifdef RTF_PRCLONING > - RTFLAG("c", RTF_PRCLONING); > -#endif > -#ifdef RTF_WASCLONED > - RTFLAG("W", RTF_WASCLONED); > -#endif > RTFLAG("L", RTF_LLINFO); > RTFLAG("S", RTF_STATIC); > RTFLAG("B", RTF_BLACKHOLE); > -#ifdef RTF_PROTO3 > RTFLAG("3", RTF_PROTO3); > -#endif > RTFLAG("2", RTF_PROTO2); > RTFLAG("1", RTF_PROTO1); > -#ifdef RTF_BROADCAST > RTFLAG("b", RTF_BROADCAST); > -#endif > -#ifdef RTF_DEFAULT > - RTFLAG("d", RTF_DEFAULT); > -#endif > -#ifdef RTF_ISAROUTER > - RTFLAG("r", RTF_ISAROUTER); > -#endif > -#ifdef RTF_TUNNEL > - RTFLAG("T", RTF_TUNNEL); > -#endif > -#ifdef RTF_AUTH > - RTFLAG("A", RTF_AUTH); > -#endif > -#ifdef RTF_CRYPT > - RTFLAG("E", RTF_CRYPT); > -#endif > #undef RTFLAG > return buf; > } > Index: share/man/man4/route.4 > =================================================================== > RCS file: /cvs/src/share/man/man4/route.4,v > retrieving revision 1.40 > diff -u -p -r1.40 route.4 > --- share/man/man4/route.4 23 Mar 2016 12:57:53 -0000 1.40 > +++ share/man/man4/route.4 5 Jul 2016 14:22:27 -0000 > @@ -358,6 +358,7 @@ Flags include the values: > #define RTF_DONE 0x40 /* message confirmed */ > #define RTF_MASK 0x80 /* subnet mask present */ > #define RTF_CLONING 0x100 /* generate new routes on use */ > +#define RTF_MULTICAST 0x200 /* route associated to a mcast > addr. */ > #define RTF_LLINFO 0x400 /* generated by ARP or NDP */ > #define RTF_STATIC 0x800 /* manually added */ > #define RTF_BLACKHOLE 0x1000 /* just discard pkts (during > updates) */

