From ae1a35b945bee2de88fd338f3cb0fb1d40142f0e Mon Sep 17 00:00:00 2001 From: mpi Date: Tue, 13 Jan 2015 12:14:00 +0000 Subject: [PATCH] Restore sending RTM_ADD and RTM_DELETE messages to userland for every route created/deleted with rt_ifa_add(9)/rt_ifa_del(9), not only for RTF_LOCAL routes. Regression introduced in r1.172 when restoring the original behavior of RTM_NEWADDR/RTM_RTM_DELADDR reported by Florian Riehm. Joint work with Florian Riehm, with input from and ok bluhm@. --- sys/net/route.c | 12 ++++--- sys/net/route.h | 4 +-- sys/net/rtsock.c | 84 ++++++++++++++---------------------------------- 3 files changed, 35 insertions(+), 65 deletions(-) diff --git a/sys/net/route.c b/sys/net/route.c index 4e7cd6c476e..90ad7f11c92 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.198 2015/01/08 15:05:44 mpi Exp $ */ +/* $OpenBSD: route.c,v 1.199 2015/01/13 12:14:00 mpi Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -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; @@ -1138,7 +1140,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags, struct sockaddr *dst) * 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); } @@ -1192,8 +1195,9 @@ rt_ifa_del(struct ifaddr *ifa, int flags, struct sockaddr *dst) error = rtrequest1(RTM_DELETE, &info, prio, &nrt, rtableid); if (error == 0 && (rt = nrt) != NULL) { + rt_sendmsg(nrt, RTM_DELETE, rtableid); if (flags & RTF_LOCAL) - rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); + rt_sendaddrmsg(nrt, RTM_DELADDR); if (rt->rt_refcnt <= 0) { rt->rt_refcnt++; rtfree(rt); diff --git a/sys/net/route.h b/sys/net/route.h index 62a910faeea..74a0d5da23e 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.103 2015/01/08 15:05:44 mpi Exp $ */ +/* $OpenBSD: route.h,v 1.104 2015/01/13 12:14:00 mpi Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -357,9 +357,9 @@ void rt_ifannouncemsg(struct ifnet *, int); void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *); void rt_sendmsg(struct rtentry *, int, u_int); +void rt_sendaddrmsg(struct rtentry *, int); void rt_missmsg(int, struct rt_addrinfo *, int, struct ifnet *, int, u_int); -void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *); int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *, u_int); int rt_checkgate(struct ifnet *, struct rtentry *, struct sockaddr *, diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 80c53bc2ff7..2c4802e1068 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.155 2014/12/19 18:57:17 bluhm Exp $ */ +/* $OpenBSD: rtsock.c,v 1.156 2015/01/13 12:14:00 mpi Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -1137,70 +1137,36 @@ rt_ifmsg(struct ifnet *ifp) * copies of it. */ void -rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt) +rt_sendaddrmsg(struct rtentry *rt, int cmd) { - struct rt_addrinfo info; - struct sockaddr *sa = NULL; - int pass; - struct mbuf *m = NULL; + struct ifaddr *ifa = rt->rt_ifa; struct ifnet *ifp = ifa->ifa_ifp; + struct mbuf *m = NULL; + struct rt_addrinfo info; + struct ifa_msghdr *ifam; if (route_cb.any_count == 0) return; - for (pass = 1; pass < 3; pass++) { - bzero(&info, sizeof(info)); - if ((cmd == RTM_ADD && pass == 1) || - (cmd == RTM_DELETE && pass == 2)) { - struct ifa_msghdr *ifam; - int ncmd; - - if (cmd == RTM_ADD) - ncmd = RTM_NEWADDR; - else - ncmd = RTM_DELADDR; - info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr; - info.rti_info[RTAX_IFP] = - (struct sockaddr *)ifp->if_sadl; - info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; - info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; - if ((m = rt_msg1(ncmd, &info)) == NULL) - continue; - ifam = mtod(m, struct ifa_msghdr *); - ifam->ifam_index = ifp->if_index; - ifam->ifam_metric = ifa->ifa_metric; - ifam->ifam_flags = ifa->ifa_flags; - ifam->ifam_addrs = info.rti_addrs; - ifam->ifam_tableid = ifp->if_rdomain; - } - if ((cmd == RTM_ADD && pass == 2) || - (cmd == RTM_DELETE && pass == 1)) { - struct rt_msghdr *rtm; - struct sockaddr_rtlabel sa_rl; - - if (rt == 0) - continue; - info.rti_info[RTAX_NETMASK] = rt_mask(rt); - info.rti_info[RTAX_DST] = sa = rt_key(rt); - info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; - info.rti_info[RTAX_LABEL] = - rtlabel_id2sa(rt->rt_labelid, &sa_rl); - if ((m = rt_msg1(cmd, &info)) == NULL) - continue; - rtm = mtod(m, struct rt_msghdr *); - rtm->rtm_index = ifp->if_index; - rtm->rtm_flags |= rt->rt_flags; - rtm->rtm_priority = rt->rt_priority & RTP_MASK; - rtm->rtm_errno = error; - rtm->rtm_addrs = info.rti_addrs; - rtm->rtm_tableid = ifp->if_rdomain; - } - if (sa == NULL) - route_proto.sp_protocol = 0; - else - route_proto.sp_protocol = sa->sa_family; - route_input(m, &route_proto, &route_src, &route_dst); - } + memset(&info, 0, sizeof(info)); + info.rti_info[RTAX_IFA] = ifa->ifa_addr; + info.rti_info[RTAX_IFP] = (struct sockaddr *)ifp->if_sadl; + info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; + info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; + if ((m = rt_msg1(cmd, &info)) == NULL) + return; + ifam = mtod(m, struct ifa_msghdr *); + ifam->ifam_index = ifp->if_index; + ifam->ifam_metric = ifa->ifa_metric; + ifam->ifam_flags = ifa->ifa_flags; + ifam->ifam_addrs = info.rti_addrs; + ifam->ifam_tableid = ifp->if_rdomain; + + if (ifa->ifa_addr == NULL) + route_proto.sp_protocol = 0; + else + route_proto.sp_protocol = ifa->ifa_addr->sa_family; + route_input(m, &route_proto, &route_src, &route_dst); } /* -- 2.20.1