Hi Martin,
Thanks for your diff! Regardless of my problem it makes our code
more clear. The loop in rt_newaddrmsg() was ugly.
>
> Here's a diff that should generate a RTM_ADD message for every CLONING
> route added while keeping the existing RTM_NEWADDR/RTM_DELADDR logic.
>
> dhclient(8) is happy with this change, does it fix your use case too?
There is a small bug in your diff of route.c, because rt_ifa_del() is
never called with flag RTF_CLONING, so ospfd doesn't notice if an address
gets deleted.
I was thinking about this three options to fix the problem:
1.) Check with rt->rt_flags instead of flags for RTF_CLONING flag:
-if (flags & (RTF_LOCAL|RTF_CLONING))
+if (rt->rt_flags & (RTF_LOCAL|RTF_CLONING))
2) Add RTF_CLONING to flags argument at certain calls of rt_ifa_add() /
rt_ifa_delete()
3.) Remove the check completely and call always rt_sendmsg()
At the moment I would prefer the 3. solution. After rtrequest1() has been
called, we check for error and check if rt ist not NULL. If this conditions are
true we have added or deleted a route. Why should we not send a route message
then?
Below an updated diff for route.c with my fix.
I noticed that the RTM_ADD/RTM_DELETE routing messages doesn't contain a
priority anymore with your diff. I guess this is not a problem.
If nobody needs the priority I prefer the new behavior.
If something needs it, we had to add another argument to rt_missmsg().
Regards
Florian
Index: net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.196
diff -u -p -r1.196 route.c
--- net/route.c 29 Dec 2014 11:53:58 -0000 1.196
+++ net/route.c 7 Jan 2015 17:29:56 -0000
@@ -382,11 +382,13 @@ void
rt_sendmsg(struct rtentry *rt, int cmd, u_int rtableid)
{
struct rt_addrinfo info;
+ struct sockaddr_rtlabel sa_rl;
- bzero(&info, sizeof(info));
+ memset(&info, 0, sizeof(info));
info.rti_info[RTAX_DST] = rt_key(rt);
info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+ info.rti_info[RTAX_LABEL] = rtlabel_id2sa(rt->rt_labelid, &sa_rl);
if (rt->rt_ifp != NULL) {
info.rti_info[RTAX_IFP] =(struct sockaddr *)rt->rt_ifp->if_sadl;
info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
@@ -1098,7 +1100,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags
* userland that a new address has been added.
*/
if (flags & RTF_LOCAL)
- rt_newaddrmsg(RTM_ADD, ifa, error, nrt);
+ rt_sendaddrmsg(nrt, RTM_NEWADDR);
+ rt_sendmsg(nrt, RTM_ADD, rtableid);
}
return (error);
}
@@ -1153,7 +1156,8 @@ rt_ifa_del(struct ifaddr *ifa, int flags
error = rtrequest1(RTM_DELETE, &info, prio, &nrt, rtableid);
if (error == 0 && (rt = nrt) != NULL) {
if (flags & RTF_LOCAL)
- rt_newaddrmsg(RTM_DELETE, ifa, error, nrt);
+ rt_sendaddrmsg(nrt, RTM_DELADDR);
+ rt_sendmsg(nrt, RTM_DELETE, rtableid);
if (rt->rt_refcnt <= 0) {
rt->rt_refcnt++;
rtfree(rt);