diff options
-rw-r--r-- | sys/net/route.c | 43 | ||||
-rw-r--r-- | sys/net/route.h | 3 | ||||
-rw-r--r-- | sys/net/rtsock.c | 6 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 4 | ||||
-rw-r--r-- | sys/netmpls/mpls_input.c | 4 |
5 files changed, 40 insertions, 20 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index ac6b9cfb4cd..50cd1112ae3 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.307 2016/06/08 13:26:06 mpi Exp $ */ +/* $OpenBSD: route.c,v 1.308 2016/06/14 09:44:41 mpi Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -139,6 +139,8 @@ #include <net/if_enc.h> #endif +#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + /* Give some jitter to hash, to avoid synchronization between routers. */ static uint32_t rt_hashjitter; @@ -151,6 +153,7 @@ struct pool rtentry_pool; /* pool for rtentry structures */ struct pool rttimer_pool; /* pool for rttimer structures */ void rt_timer_init(void); +int rt_setaddr(struct rtentry *, struct sockaddr *); int rtflushclone1(struct rtentry *, void *, u_int); void rtflushclone(unsigned int, struct rtentry *); int rt_if_remove_rtdelete(struct rtentry *, void *, u_int); @@ -434,7 +437,6 @@ rtref(struct rtentry *rt) void rtfree(struct rtentry *rt) { - struct ifaddr *ifa; int refcnt; if (rt == NULL) @@ -452,16 +454,14 @@ rtfree(struct rtentry *rt) KERNEL_LOCK(); rt_timer_remove_all(rt); - ifa = rt->rt_ifa; - if (ifa) - ifafree(ifa); + ifafree(rt->rt_ifa); rtlabel_unref(rt->rt_labelid); #ifdef MPLS if (rt->rt_flags & RTF_MPLS) free(rt->rt_llinfo, M_TEMP, sizeof(struct rt_mpls)); #endif - if (rt->rt_gateway) - free(rt->rt_gateway, M_RTABLE, 0); + free(rt->rt_addr, M_RTABLE, ROUNDUP(rt->rt_addr->sa_len)); + free(rt->rt_gateway, M_RTABLE, ROUNDUP(rt->rt_gateway->sa_len)); free(rt_key(rt), M_RTABLE, rt_key(rt)->sa_len); KERNEL_UNLOCK(); @@ -486,7 +486,7 @@ rt_sendmsg(struct rtentry *rt, int cmd, u_int rtableid) ifp = if_get(rt->rt_ifidx); if (ifp != NULL) { info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); - info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; + info.rti_info[RTAX_IFA] = rt->rt_addr; } rt_missmsg(cmd, &info, rt->rt_flags, rt->rt_priority, rt->rt_ifidx, 0, @@ -767,8 +767,6 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway, return (ifa); } -#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) - int rt_getifa(struct rt_addrinfo *info, u_int rtid) { @@ -958,7 +956,7 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio, * will get the new address and interface later. */ info->rti_ifa = NULL; - info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; + info->rti_info[RTAX_IFA] = rt->rt_addr; } info->rti_flags = rt->rt_flags | (RTF_CLONED|RTF_HOST); @@ -1090,10 +1088,12 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio, * the routing table because the radix MPATH code use * it to (re)order routes. */ - if ((error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]))) { + if ((error = rt_setaddr(rt, ifa->ifa_addr)) || + (error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]))) { ifafree(ifa); rtfree(rt->rt_parent); rtfree(rt->rt_gwroute); + free(rt->rt_addr, M_RTABLE, 0); free(rt->rt_gateway, M_RTABLE, 0); free(ndst, M_RTABLE, dlen); pool_put(&rtentry_pool, rt); @@ -1124,6 +1124,7 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio, ifafree(ifa); rtfree(rt->rt_parent); rtfree(rt->rt_gwroute); + free(rt->rt_addr, M_RTABLE, 0); free(rt->rt_gateway, M_RTABLE, 0); free(ndst, M_RTABLE, dlen); pool_put(&rtentry_pool, rt); @@ -1150,6 +1151,24 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio, } int +rt_setaddr(struct rtentry *rt, struct sockaddr *addr) +{ + int alen = ROUNDUP(addr->sa_len); + struct sockaddr *sa; + + KASSERT(rt->rt_addr == NULL); + + sa = malloc(alen, M_RTABLE, M_NOWAIT); + if (sa == NULL) + return (ENOBUFS); + + memmove(sa, addr, alen); + rt->rt_addr = sa; + + return (0); +} + +int rt_setgate(struct rtentry *rt, struct sockaddr *gate) { int glen = ROUNDUP(gate->sa_len); diff --git a/sys/net/route.h b/sys/net/route.h index 940d473577f..3286f4118bb 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.136 2016/06/03 02:56:59 dlg Exp $ */ +/* $OpenBSD: route.h,v 1.137 2016/06/14 09:44:41 mpi Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -99,6 +99,7 @@ struct rtentry { struct sockaddr *rt_dest; /* destination */ SRPL_ENTRY(rtentry) rt_next; /* Next multipath entry to our dst. */ #endif + struct sockaddr *rt_addr; /* the answer: address to use */ struct sockaddr *rt_gateway; /* value */ struct ifaddr *rt_ifa; /* the answer: interface addr to use */ caddr_t rt_llinfo; /* pointer to link level info cache or diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index f3018d85cf6..4523c771ce9 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.190 2016/06/03 02:56:59 dlg Exp $ */ +/* $OpenBSD: rtsock.c,v 1.191 2016/06/14 09:44:41 mpi Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -695,7 +695,7 @@ report: ifp = if_get(rt->rt_ifidx); if (ifp != NULL && rtm->rtm_addrs & (RTA_IFP|RTA_IFA)) { info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); - info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; + info.rti_info[RTAX_IFA] = rt->rt_addr; if (ifp->if_flags & IFF_POINTOPOINT) info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; @@ -1279,7 +1279,7 @@ sysctl_dumpentry(struct rtentry *rt, void *v, unsigned int id) ifp = if_get(rt->rt_ifidx); if (ifp != NULL) { info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl); - info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; + info.rti_info[RTAX_IFA] = rt->rt_addr; if (ifp->if_flags & IFF_POINTOPOINT) info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; } diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 54abf79ae6b..284571bb467 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.c,v 1.214 2016/06/10 20:33:29 vgross Exp $ */ +/* $OpenBSD: if_ether.c,v 1.215 2016/06/14 09:44:41 mpi Exp $ */ /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ /* @@ -389,7 +389,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, rt->rt_expire = time_uptime; if (la->la_asked++ < arp_maxtries) arprequest(ifp, - &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr, + &satosin(rt->rt_addr)->sin_addr.s_addr, &satosin(dst)->sin_addr.s_addr, ac->ac_enaddr); else { diff --git a/sys/netmpls/mpls_input.c b/sys/netmpls/mpls_input.c index 4d53675686a..349e465c34b 100644 --- a/sys/netmpls/mpls_input.c +++ b/sys/netmpls/mpls_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpls_input.c,v 1.54 2015/12/04 11:13:21 claudio Exp $ */ +/* $OpenBSD: mpls_input.c,v 1.55 2016/06/14 09:44:41 mpi Exp $ */ /* * Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org> @@ -374,7 +374,7 @@ mpls_do_error(struct mbuf *m, int type, int code, int destmtu) m_freem(m); return (NULL); } - if (rt->rt_ifa->ifa_addr->sa_family == AF_INET) + if (rt->rt_addr->sa_family == AF_INET) ia = ifatoia(rt->rt_ifa); else { /* XXX this needs fixing, if the MPLS is on an IP |