On 28 May 2014 10:18, Kenneth Westerback <kwesterb...@gmail.com> wrote: > On 28 May 2014 10:15, Martin Pieuchot <mpieuc...@nolizard.org> wrote: >> On 26/05/14(Mon) 15:17, Martin Pieuchot wrote: >>> On 26/05/14(Mon) 08:03, Kenneth Westerback wrote: >>> > [...] >>> > >>> > dhclient used to create such routes but that was removed as useless so >>> > I'm not sure why we want/need to add them back. I'm not a routing >>> > table guru so perhaps this is different in some way. >>> >>> We want it back to be able to tell if an address is configured locally >>> by using the routing table. But to be able to trust the routing table >>> we must ensure that every local address is associated to a route entry. >>> This diff is a step in this direction. >>> >>> > Extra RTM_NEWADDR messages may cause problems for dhclient, since it >>> > will exit on what it thinks are attempts to add addresses to an >>> > interface. Not sure if RTM_NEWADDR makes sense if all you are doing is >>> > adding a route. >>> >>> That's a really good question, and I don't have the answer. >>> >>> Originally RTM_NEWADDR was generated when a route to prefix was added >>> for a new address. It was simple: 1 address -> 1 route + message. >>> >>> Later on the logic in netinet/in.c has been modified to be able to setup >>> an address without adding a route to prefix, if this route was already >>> present for example. That's what happens if you have two addresses on >>> the same subnet configured on your machine. With this, we now have: >>> 1 address -> maybe 1 route + message. >>> >>> With this diff we always create a route, but maybe a second one if it is >>> the first address of a subnet. So we have: 1 address -> 1 or 2 route + >>> messages. >> >> Here's a more complete diff that seems to not freak out dhclient(8). It >> makes use of the RTF_LOCAL flag to restore the original behavior of the >> RTM_NEWADDR message. >> >> I appreciate if people can test it and report back. It should be pretty >> safe from the IPv4 side, but I'd like to know if it causes any >> regression in IPv6 land. >> > > In my tree and snap a-building. > > .... Ken
And dhclient does seem to like this much better. I withdraw my objection, even if I don't understand enough to ok it. :-) .... Ken > >> Index: net/route.c >> =================================================================== >> RCS file: /home/ncvs/src/sys/net/route.c,v >> retrieving revision 1.168 >> diff -u -p -r1.168 route.c >> --- net/route.c 27 May 2014 19:38:15 -0000 1.168 >> +++ net/route.c 28 May 2014 11:59:14 -0000 >> @@ -1097,6 +1097,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags >> struct sockaddr_rtlabel sa_rl; >> struct rt_addrinfo info; >> u_short rtableid = ifa->ifa_ifp->if_rdomain; >> + u_int8_t prio = RTP_CONNECTED; >> int error; >> >> memset(&info, 0, sizeof(info)); >> @@ -1110,7 +1111,10 @@ rt_ifa_add(struct ifaddr *ifa, int flags >> if ((flags & RTF_HOST) == 0) >> info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; >> >> - error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &nrt, rtableid); >> + if (flags & RTF_LOCAL) >> + prio = RTP_LOCAL; >> + >> + error = rtrequest1(RTM_ADD, &info, prio, &nrt, rtableid); >> if (error == 0 && (rt = nrt) != NULL) { >> rt->rt_refcnt--; >> if (rt->rt_ifa != ifa) { >> @@ -1125,7 +1129,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags >> if (ifa->ifa_rtrequest) >> ifa->ifa_rtrequest(RTM_ADD, rt); >> } >> - rt_newaddrmsg(RTM_ADD, ifa, error, nrt); >> + if (flags & RTF_LOCAL) >> + rt_newaddrmsg(RTM_ADD, ifa, error, nrt); >> } >> return (error); >> } >> @@ -1139,6 +1144,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags >> struct rt_addrinfo info; >> struct sockaddr_rtlabel sa_rl; >> u_short rtableid = ifa->ifa_ifp->if_rdomain; >> + u_int8_t prio = RTP_CONNECTED; >> int error; >> >> if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) { >> @@ -1173,9 +1179,13 @@ rt_ifa_del(struct ifaddr *ifa, int flags >> if ((flags & RTF_HOST) == 0) >> info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; >> >> - error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &nrt, rtableid); >> + if (flags & RTF_LOCAL) >> + prio = RTP_LOCAL; >> + >> + error = rtrequest1(RTM_DELETE, &info, prio, &nrt, rtableid); >> if (error == 0 && (rt = nrt) != NULL) { >> - rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); >> + if (flags & RTF_LOCAL) >> + rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); >> if (rt->rt_refcnt <= 0) { >> rt->rt_refcnt++; >> rtfree(rt); >> @@ -1199,7 +1209,8 @@ rt_ifa_addloop(struct ifaddr *ifa) >> rt = rtalloc1(ifa->ifa_addr, 0, ifa->ifa_ifp->if_rdomain); >> if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 || >> (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) >> - rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO, >> ifa->ifa_addr); >> + rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO | RTF_LOCAL, >> + ifa->ifa_addr); >> if (rt) >> rt->rt_refcnt--; >> } >> @@ -1223,7 +1234,8 @@ rt_ifa_delloop(struct ifaddr *ifa) >> rt = rtalloc1(ifa->ifa_addr, 0, ifa->ifa_ifp->if_rdomain); >> if (rt != NULL && (rt->rt_flags & RTF_HOST) != 0 && >> (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) >> - rt_ifa_del(ifa, RTF_HOST | RTF_LLINFO, ifa->ifa_addr); >> + rt_ifa_del(ifa, RTF_HOST | RTF_LLINFO | RTF_LOCAL, >> + ifa->ifa_addr); >> if (rt) >> rt->rt_refcnt--; >> } >> Index: netinet/if_ether.c >> =================================================================== >> RCS file: /home/ncvs/src/sys/netinet/if_ether.c,v >> retrieving revision 1.127 >> diff -u -p -r1.127 if_ether.c >> --- netinet/if_ether.c 7 May 2014 08:14:59 -0000 1.127 >> +++ netinet/if_ether.c 28 May 2014 11:59:14 -0000 >> @@ -174,7 +174,8 @@ arp_rtrequest(int req, struct rtentry *r >> if ((rt->rt_flags & RTF_HOST) == 0 && rt_mask(rt) && >> satosin(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) >> rt->rt_flags |= RTF_CLONING; >> - if (rt->rt_flags & RTF_CLONING) { >> + if (rt->rt_flags & RTF_CLONING || >> + ((rt->rt_flags & RTF_LLINFO) && !la)) { >> /* >> * Case 1: This route should come from a route to >> iface. >> */ >> @@ -189,7 +190,8 @@ arp_rtrequest(int req, struct rtentry *r >> * from it do not need their expiration time set. >> */ >> rt->rt_expire = time_second; >> - break; >> + if ((rt->rt_flags & RTF_CLONING) != 0) >> + break; >> } >> /* Announce a new entry if requested. */ >> if (rt->rt_flags & RTF_ANNOUNCE) >> Index: netinet/in.c >> =================================================================== >> RCS file: /home/ncvs/src/sys/netinet/in.c,v >> retrieving revision 1.96 >> diff -u -p -r1.96 in.c >> --- netinet/in.c 25 Apr 2014 09:44:38 -0000 1.96 >> +++ netinet/in.c 28 May 2014 11:59:14 -0000 >> @@ -702,6 +702,7 @@ out: >> * carp(4). >> */ >> ifa_add(ifp, &ia->ia_ifa); >> + rt_ifa_addloop(&ia->ia_ifa); >> >> if (error && newaddr) >> in_purgeaddr(&ia->ia_ifa); >> @@ -718,6 +719,8 @@ in_purgeaddr(struct ifaddr *ifa) >> splsoftassert(IPL_SOFTNET); >> >> in_ifscrub(ifp, ia); >> + >> + rt_ifa_delloop(&ia->ia_ifa); >> >> ifa_del(ifp, &ia->ia_ifa); >> TAILQ_REMOVE(&in_ifaddr, ia, ia_list);