On 28 May 2014 10:18, Kenneth Westerback <[email protected]> wrote:
> On 28 May 2014 10:15, Martin Pieuchot <[email protected]> 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);