Have been running with this for several days, still working fine. On Wed, Jul 6, 2016 at 6:53 AM, Aaron Riekenberg <aaron.riekenb...@gmail.com > wrote:
> 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 <m...@openbsd.org> 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) */