From 8071913df2dce4a8c721eeecb338c9fb7d0f8485 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Wed, 17 Oct 2001 18:07:05 +0000 Subject: [PATCH] Pull post-4.4BSD change to sys/net/route.c from BSD/OS 4.2. Have sys/net/route.c:rtrequest1(), which takes ``rt_addrinfo *'' as the argument. Pass rt_addrinfo all the way down to rtrequest1 and ifa->ifa_rtrequest. 3rd argument of ifa->ifa_rtrequest is now ``rt_addrinfo *'' instead of ``sockaddr *'' (almost noone is using it anyways). Benefit: the following command now works. Previously we needed two route(8) invocations, "add" then "change". # route add -inet6 default ::1 -ifp gif0 Remove unsafe typecast in rtrequest(), from ``rtentry *'' to ``sockaddr *''. It was introduced by 4.3BSD-Reno and never corrected. Obtained from: BSD/OS, NetBSD MFC after: 1 month PR: kern/28360 --- sys/net/if.c | 8 +- sys/net/if_disc.c | 4 +- sys/net/if_faith.c | 6 +- sys/net/if_loop.c | 6 +- sys/net/if_stf.c | 6 +- sys/net/if_var.h | 3 +- sys/net/route.c | 256 ++++++++++++++++++++++++----------------- sys/net/route.h | 5 + sys/net/rtsock.c | 35 +++--- sys/netinet/if_atm.c | 6 +- sys/netinet/if_atm.h | 2 +- sys/netinet/if_ether.c | 6 +- sys/netinet/in_pcb.c | 10 +- sys/netinet6/in6_pcb.c | 8 +- sys/netinet6/nd6.c | 4 +- sys/netinet6/nd6.h | 2 +- 16 files changed, 206 insertions(+), 161 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index b97302d7e67..1e3dfac0bac 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -79,7 +79,7 @@ static void if_check(void *); static int if_findindex(struct ifnet *); static void if_qflush(struct ifqueue *); static void if_slowtimo(void *); -static void link_rtrequest(int, struct rtentry *, struct sockaddr *); +static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *); static int if_rtdel(struct radix_node *, void *); static struct if_clone *if_clone_lookup(const char *, int *); static int if_clone_list(struct if_clonereq *); @@ -943,10 +943,10 @@ ifaof_ifpforaddr(addr, ifp) * This should be moved to /sys/net/link.c eventually. */ static void -link_rtrequest(cmd, rt, sa) +link_rtrequest(cmd, rt, info) int cmd; register struct rtentry *rt; - struct sockaddr *sa; + struct rt_addrinfo *info; { register struct ifaddr *ifa; struct sockaddr *dst; @@ -961,7 +961,7 @@ link_rtrequest(cmd, rt, sa) rt->rt_ifa = ifa; ifa->ifa_refcnt++; if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) - ifa->ifa_rtrequest(cmd, rt, sa); + ifa->ifa_rtrequest(cmd, rt, info); } } diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c index c04c6c29d6f..fbabf3078df 100644 --- a/sys/net/if_disc.c +++ b/sys/net/if_disc.c @@ -66,7 +66,7 @@ static void discattach(void); static struct ifnet discif; static int discoutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); -static void discrtrequest(int, struct rtentry *, struct sockaddr *); +static void discrtrequest(int, struct rtentry *, struct rt_addrinfo *); static int discioctl(struct ifnet *, u_long, caddr_t); static void @@ -151,7 +151,7 @@ discoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, /* ARGSUSED */ static void -discrtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa) +discrtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info) { if (rt) rt->rt_rmx.rmx_mtu = DSMTU; diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index 1dac1b686dd..585cf1dd2bf 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -96,7 +96,7 @@ struct faith_softc { static int faithioctl __P((struct ifnet *, u_long, caddr_t)); int faithoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); -static void faithrtrequest __P((int, struct rtentry *, struct sockaddr *)); +static void faithrtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); static int faithprefix __P((struct in6_addr *)); static int faithmodevent __P((module_t, int, void *)); @@ -311,10 +311,10 @@ faithoutput(ifp, m, dst, rt) /* ARGSUSED */ static void -faithrtrequest(cmd, rt, sa) +faithrtrequest(cmd, rt, info) int cmd; struct rtentry *rt; - struct sockaddr *sa; + struct rt_addrinfo *info; { if (rt) { rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */ diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index f5b51302d65..b36e907f52d 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -89,7 +89,7 @@ #endif int loioctl __P((struct ifnet *, u_long, caddr_t)); -static void lortrequest __P((int, struct rtentry *, struct sockaddr *)); +static void lortrequest __P((int, struct rtentry *, struct rt_addrinfo *)); int looutput __P((struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt)); @@ -383,10 +383,10 @@ if_simloop(ifp, m, af, hlen) /* ARGSUSED */ static void -lortrequest(cmd, rt, sa) +lortrequest(cmd, rt, info) int cmd; struct rtentry *rt; - struct sockaddr *sa; + struct rt_addrinfo *info; { if (rt) { rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */ diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index ebbbe705199..b3f80da1020 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -159,7 +159,7 @@ static int stf_checkaddr4 __P((struct stf_softc *, struct in_addr *, struct ifnet *)); static int stf_checkaddr6 __P((struct stf_softc *, struct in6_addr *, struct ifnet *)); -static void stf_rtrequest __P((int, struct rtentry *, struct sockaddr *)); +static void stf_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); static int stf_ioctl __P((struct ifnet *, u_long, caddr_t)); int stf_clone_create __P((struct if_clone *, int *)); @@ -706,10 +706,10 @@ in_stf_input(m, off) /* ARGSUSED */ static void -stf_rtrequest(cmd, rt, sa) +stf_rtrequest(cmd, rt, info) int cmd; struct rtentry *rt; - struct sockaddr *sa; + struct rt_addrinfo *info; { if (rt) diff --git a/sys/net/if_var.h b/sys/net/if_var.h index cc1983d3386..2738c36f120 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -69,6 +69,7 @@ struct mbuf; struct thread; struct rtentry; +struct rt_addrinfo; struct socket; struct ether_header; #endif @@ -327,7 +328,7 @@ struct ifaddr { struct ifnet *ifa_ifp; /* back-pointer to interface */ TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ - __P((int, struct rtentry *, struct sockaddr *)); + __P((int, struct rtentry *, struct rt_addrinfo *)); u_short ifa_flags; /* mostly rt_flags for cloning */ u_int ifa_refcnt; /* references to this structure */ int ifa_metric; /* cost of going out this interface */ diff --git a/sys/net/route.c b/sys/net/route.c index d19ed8aa77b..ac130aa733d 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -165,6 +165,17 @@ rtalloc1(dst, report, ignflags) msgtype = RTM_RESOLVE; goto miss; } + /* Inform listeners of the new route. */ + bzero(&info, sizeof(info)); + info.rti_info[RTAX_DST] = rt_key(rt); + info.rti_info[RTAX_NETMASK] = rt_mask(rt); + info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; + if (rt->rt_ifp != NULL) { + info.rti_info[RTAX_IFP] = + TAILQ_FIRST(&rt->rt_ifp->if_addrhead)->ifa_addr; + info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; + } + rt_missmsg(RTM_ADD, &info, rt->rt_flags, 0); } else rt->rt_refcnt++; } else { @@ -288,7 +299,7 @@ rtredirect(dst, gateway, netmask, flags, src, rtp) int flags; struct rtentry **rtp; { - register struct rtentry *rt; + struct rtentry *rt; int error = 0; short *stat = 0; struct rt_addrinfo info; @@ -333,10 +344,19 @@ rtredirect(dst, gateway, netmask, flags, src, rtp) * Create new route, rather than smashing route to net. */ create: + if (rt) + rtfree(rt); flags |= RTF_GATEWAY | RTF_DYNAMIC; - error = rtrequest((int)RTM_ADD, dst, gateway, - netmask, flags, - (struct rtentry **)0); + bzero((caddr_t)&info, sizeof(info)); + info.rti_info[RTAX_DST] = dst; + info.rti_info[RTAX_GATEWAY] = gateway; + info.rti_info[RTAX_NETMASK] = netmask; + info.rti_ifa = ifa; + info.rti_flags = flags; + rt = NULL; + error = rtrequest1(RTM_ADD, &info, &rt); + if (rt != NULL) + flags = rt->rt_flags; stat = &rtstat.rts_dynamic; } else { /* @@ -436,8 +456,6 @@ ifa_ifwithroute(flags, dst, gateway) return (ifa); } -#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) - static int rt_fixdelete __P((struct radix_node *, void *)); static int rt_fixchange __P((struct radix_node *, void *)); @@ -455,6 +473,70 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) int req, flags; struct sockaddr *dst, *gateway, *netmask; struct rtentry **ret_nrt; +{ + struct rt_addrinfo info; + + bzero((caddr_t)&info, sizeof(info)); + info.rti_flags = flags; + info.rti_info[RTAX_DST] = dst; + info.rti_info[RTAX_GATEWAY] = gateway; + info.rti_info[RTAX_NETMASK] = netmask; + return rtrequest1(req, &info, ret_nrt); +} + +/* + * These (questionable) definitions of apparent local variables apply + * to the next two functions. XXXXXX!!! + */ +#define dst info->rti_info[RTAX_DST] +#define gateway info->rti_info[RTAX_GATEWAY] +#define netmask info->rti_info[RTAX_NETMASK] +#define ifaaddr info->rti_info[RTAX_IFA] +#define ifpaddr info->rti_info[RTAX_IFP] +#define flags info->rti_flags + +int +rt_getifa(info) + struct rt_addrinfo *info; +{ + struct ifaddr *ifa; + int error = 0; + + /* + * ifp may be specified by sockaddr_dl + * when protocol address is ambiguous. + */ + if (info->rti_ifp == NULL && ifpaddr != NULL && + ifpaddr->sa_family == AF_LINK && + (ifa = ifa_ifwithnet(ifpaddr)) != NULL) + info->rti_ifp = ifa->ifa_ifp; + if (info->rti_ifa == NULL && ifaaddr != NULL) + info->rti_ifa = ifa_ifwithaddr(ifaaddr); + if (info->rti_ifa == NULL) { + struct sockaddr *sa; + + sa = ifaaddr != NULL ? ifaaddr : + (gateway != NULL ? gateway : dst); + if (sa != NULL && info->rti_ifp != NULL) + info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp); + else if (dst != NULL && gateway != NULL) + info->rti_ifa = ifa_ifwithroute(flags, dst, gateway); + else if (sa != NULL) + info->rti_ifa = ifa_ifwithroute(flags, sa, sa); + } + if ((ifa = info->rti_ifa) != NULL) { + if (info->rti_ifp == NULL) + info->rti_ifp = ifa->ifa_ifp; + } else + error = ENETUNREACH; + return (error); +} + +int +rtrequest1(req, info, ret_nrt) + int req; + struct rt_addrinfo *info; + struct rtentry **ret_nrt; { int s = splnet(); int error = 0; register struct rtentry *rt; @@ -468,7 +550,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) * Find the correct routing tree to use for this Address Family */ if ((rnh = rt_tables[dst->sa_family]) == 0) - senderr(ESRCH); + senderr(EAFNOSUPPORT); /* * If we are adding a host route then we don't want to put * a netmask in the tree, nor do we want to clone it. @@ -523,7 +605,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) * give the protocol a chance to keep things in sync. */ if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) - ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); + ifa->ifa_rtrequest(RTM_DELETE, rt, info); /* * one more rtentry floating around that is not @@ -560,8 +642,9 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) if ((flags & RTF_GATEWAY) && !gateway) panic("rtrequest: GATEWAY but no gateway"); - if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0) - senderr(ENETUNREACH); + if (info->rti_ifa == NULL && (error = rt_getifa(info))) + senderr(error); + ifa = info->rti_ifa; makeroute: R_Malloc(rt, struct rtentry *, sizeof(*rt)); @@ -663,7 +746,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) * allow it to do that as well. */ if (ifa->ifa_rtrequest) - ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); + ifa->ifa_rtrequest(req, rt, info); /* * We repeat the same procedure from rt_setgate() here because @@ -687,10 +770,18 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) rt->rt_refcnt++; } break; + default: + error = EOPNOTSUPP; } bad: splx(s); return (error); +#undef dst +#undef gateway +#undef netmask +#undef ifaaddr +#undef ifpaddr +#undef flags } /* @@ -819,6 +910,8 @@ rt_fixchange(rn, vp) rt_mask(rt), rt->rt_flags, (struct rtentry **)0); } +#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + int rt_setgate(rt0, dst, gate) struct rtentry *rt0; @@ -886,9 +979,9 @@ rt_setgate(rt0, dst, gate) * If there is already a gwroute, it's now almost definitly wrong * so drop it. */ - if (rt->rt_gwroute) { - rt = rt->rt_gwroute; RTFREE(rt); - rt = rt0; rt->rt_gwroute = 0; + if (rt->rt_gwroute != NULL) { + RTFREE(rt->rt_gwroute); + rt->rt_gwroute = NULL; } /* * Cloning loop avoidance: @@ -957,11 +1050,21 @@ rtinit(ifa, cmd, flags) register struct rtentry *rt; register struct sockaddr *dst; register struct sockaddr *deldst; + struct sockaddr *netmask; struct mbuf *m = 0; struct rtentry *nrt = 0; + struct radix_node_head *rnh; + struct radix_node *rn; int error; + struct rt_addrinfo info; - dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr; + if (flags & RTF_HOST) { + dst = ifa->ifa_dstaddr; + netmask = NULL; + } else { + dst = ifa->ifa_addr; + netmask = ifa->ifa_netmask; + } /* * If it's a delete, check that if it exists, it's on the correct * interface or we might scrub a route to another ifa which would @@ -973,41 +1076,26 @@ rtinit(ifa, cmd, flags) * If it's a net, mask off the host bits * (Assuming we have a mask) */ - if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) { + if (netmask != NULL) { m = m_get(M_DONTWAIT, MT_SONAME); if (m == NULL) return(ENOBUFS); deldst = mtod(m, struct sockaddr *); - rt_maskedcopy(dst, deldst, ifa->ifa_netmask); + rt_maskedcopy(dst, deldst, netmask); dst = deldst; } /* - * Get an rtentry that is in the routing tree and - * contains the correct info. (if this fails, can't get there). - * We set "report" to FALSE so that if it doesn't exist, - * it doesn't report an error or clone a route, etc. etc. + * Look up an rtentry that is in the routing tree and + * contains the correct info. */ - rt = rtalloc1(dst, 0, 0UL); - if (rt) { - /* - * Ok so we found the rtentry. it has an extra reference - * for us at this stage. we won't need that so - * lop that off now. - */ - rt->rt_refcnt--; - if (rt->rt_ifa != ifa) { - /* - * If the interface in the rtentry doesn't match - * the interface we are using, then we don't - * want to delete it, so return an error. - * This seems to be the only point of - * this whole RTM_DELETE clause. - */ - if (m) - (void) m_free(m); - return (flags & RTF_HOST ? EHOSTUNREACH - : ENETUNREACH); - } + if ((rnh = rt_tables[dst->sa_family]) == NULL || + (rn = rnh->rnh_lookup(dst, netmask, rnh)) == NULL || + (rn->rn_flags & RNF_ROOT) || + ((struct rtentry *)rn)->rt_ifa != ifa || + !equal(SA(rn->rn_key), dst)) { + if (m) + (void) m_free(m); + return (flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); } /* XXX */ #if 0 @@ -1017,82 +1105,44 @@ rtinit(ifa, cmd, flags) * it doesn't exist, we could just return at this point * with an "ELSE" clause, but apparently not.. */ - return (flags & RTF_HOST ? EHOSTUNREACH - : ENETUNREACH); + return (flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); } #endif } /* * Do the actual request */ - error = rtrequest(cmd, dst, ifa->ifa_addr, ifa->ifa_netmask, - flags | ifa->ifa_flags, &nrt); - if (m) - (void) m_free(m); - /* - * If we are deleting, and we found an entry, then - * it's been removed from the tree.. now throw it away. - */ - if (cmd == RTM_DELETE && error == 0 && (rt = nrt)) { + bzero((caddr_t)&info, sizeof(info)); + info.rti_ifa = ifa; + info.rti_flags = flags | ifa->ifa_flags; + info.rti_info[RTAX_DST] = dst; + info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; + info.rti_info[RTAX_NETMASK] = netmask; + error = rtrequest1(cmd, &info, &nrt); + if (error == 0 && (rt = nrt) != NULL) { /* * notify any listenning routing agents of the change */ - rt_newaddrmsg(cmd, ifa, error, nrt); - if (rt->rt_refcnt <= 0) { - rt->rt_refcnt++; /* need a 1->0 transition to free */ - rtfree(rt); - } - } - - /* - * We are adding, and we have a returned routing entry. - * We need to sanity check the result. - */ - if (cmd == RTM_ADD && error == 0 && (rt = nrt)) { - /* - * We just wanted to add it.. we don't actually need a reference - */ - rt->rt_refcnt--; - /* - * If it came back with an unexpected interface, then it must - * have already existed or something. (XXX) - */ - if (rt->rt_ifa != ifa) { - if (!(rt->rt_ifa->ifa_ifp->if_flags & - (IFF_POINTOPOINT|IFF_LOOPBACK))) - printf("rtinit: wrong ifa (%p) was (%p)\n", - ifa, rt->rt_ifa); - /* - * Ask that the protocol in question - * remove anything it has associated with - * this route and ifaddr. - */ - if (rt->rt_ifa->ifa_rtrequest) - rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0)); + rt_newaddrmsg(cmd, ifa, error, rt); + if (cmd == RTM_DELETE) { /* - * Remove the reference to its ifaddr. + * If we are deleting, and we found an entry, then + * it's been removed from the tree.. now throw it away. */ - IFAFREE(rt->rt_ifa); - /* - * And substitute in references to the ifaddr - * we are adding. - */ - rt->rt_ifa = ifa; - rt->rt_ifp = ifa->ifa_ifp; - rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu; /*XXX*/ - ifa->ifa_refcnt++; + if (rt->rt_refcnt <= 0) { + rt->rt_refcnt++; /* make a 1->0 transition */ + rtfree(rt); + } + } else if (cmd == RTM_ADD) { /* - * Now ask the protocol to check if it needs - * any special processing in its new form. + * We just wanted to add it.. we don't actually + * need a reference. */ - if (ifa->ifa_rtrequest) - ifa->ifa_rtrequest(RTM_ADD, rt, SA(0)); + rt->rt_refcnt--; } - /* - * notify any listenning routing agents of the change - */ - rt_newaddrmsg(cmd, ifa, error, nrt); } + if (m) + (void) m_free(m); return (error); } diff --git a/sys/net/route.h b/sys/net/route.h index ae3753bce55..1a38ceb36cf 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -248,6 +248,9 @@ struct rt_msghdr { struct rt_addrinfo { int rti_addrs; struct sockaddr *rti_info[RTAX_MAX]; + int rti_flags; + struct ifaddr *rti_ifa; + struct ifnet *rti_ifp; }; struct route_cb { @@ -273,6 +276,7 @@ extern struct radix_node_head *rt_tables[AF_MAX+1]; struct ifmultiaddr; void route_init __P((void)); +int rt_getifa __P((struct rt_addrinfo *)); void rt_ifmsg __P((struct ifnet *)); void rt_missmsg __P((int, struct rt_addrinfo *, int, int)); void rt_newaddrmsg __P((int, struct ifaddr *, int, struct rtentry *)); @@ -290,6 +294,7 @@ void rtredirect __P((struct sockaddr *, struct sockaddr *, struct sockaddr *, int, struct sockaddr *, struct rtentry **)); int rtrequest __P((int, struct sockaddr *, struct sockaddr *, struct sockaddr *, int, struct rtentry **)); +int rtrequest1 __P((int, struct rt_addrinfo *, struct rtentry **)); #endif #endif diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index efd7d572479..84f38d64ec2 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -309,11 +309,13 @@ route_output(m, so) senderr(EPROTONOSUPPORT); } rtm->rtm_pid = curproc->p_pid; + bzero(&info, sizeof(info)); info.rti_addrs = rtm->rtm_addrs; if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { dst = 0; senderr(EINVAL); } + info.rti_flags = rtm->rtm_flags; if (dst == 0 || (dst->sa_family >= AF_MAX) || (gate != 0 && (gate->sa_family >= AF_MAX))) senderr(EINVAL); @@ -339,8 +341,7 @@ route_output(m, so) case RTM_ADD: if (gate == 0) senderr(EINVAL); - error = rtrequest(RTM_ADD, dst, gate, netmask, - rtm->rtm_flags, &saved_nrt); + error = rtrequest1(RTM_ADD, &info, &saved_nrt); if (error == 0 && saved_nrt) { rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, &saved_nrt->rt_rmx); @@ -353,8 +354,7 @@ route_output(m, so) break; case RTM_DELETE: - error = rtrequest(RTM_DELETE, dst, gate, netmask, - rtm->rtm_flags, &saved_nrt); + error = rtrequest1(RTM_DELETE, &info, &saved_nrt); if (error == 0) { if ((rt = saved_nrt)) rt->rt_refcnt++; @@ -411,9 +411,6 @@ route_output(m, so) break; case RTM_CHANGE: - if (gate && (error = rt_setgate(rt, rt_key(rt), gate))) - senderr(error); - /* * If they tried to change things but didn't specify * the required gateway, then just use the old one. @@ -427,30 +424,27 @@ route_output(m, so) /* new gateway could require new ifaddr, ifp; flags may also be different; ifp may be specified by ll sockaddr when protocol address is ambiguous */ - if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) && - (ifp = ifa->ifa_ifp) && (ifaaddr || gate)) - ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate, - ifp); - else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) || - (gate && (ifa = ifa_ifwithroute(rt->rt_flags, - rt_key(rt), gate)))) - ifp = ifa->ifa_ifp; - if (ifa) { + if ((error = rt_getifa(&info)) != 0) + senderr(error); + if (gate != NULL && + (error = rt_setgate(rt, rt_key(rt), gate)) != 0) + senderr(error); + if ((ifa = info.rti_ifa) != NULL) { register struct ifaddr *oifa = rt->rt_ifa; if (oifa != ifa) { if (oifa && oifa->ifa_rtrequest) - oifa->ifa_rtrequest(RTM_DELETE, - rt, gate); + oifa->ifa_rtrequest(RTM_DELETE, rt, + &info); IFAFREE(rt->rt_ifa); rt->rt_ifa = ifa; ifa->ifa_refcnt++; - rt->rt_ifp = ifp; + rt->rt_ifp = info.rti_ifp; } } rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, &rt->rt_rmx); if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) - rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, gate); + rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info); if (genmask) rt->rt_genmask = genmask; /* @@ -548,7 +542,6 @@ rt_xaddrs(cp, cplim, rtinfo) register struct sockaddr *sa; register int i; - bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { if ((rtinfo->rti_addrs & (1 << i)) == 0) continue; diff --git a/sys/netinet/if_atm.c b/sys/netinet/if_atm.c index 04b49bf7573..83fe0271433 100644 --- a/sys/netinet/if_atm.c +++ b/sys/netinet/if_atm.c @@ -71,14 +71,14 @@ * atm_rtrequest: handle ATM rt request (in support of generic code) * inputs: "req" = request code * "rt" = route entry - * "sa" = sockaddr + * "info" = rt_addrinfo */ void -atm_rtrequest(req, rt, sa) +atm_rtrequest(req, rt, info) int req; register struct rtentry *rt; - struct sockaddr *sa; + struct rt_addrinfo *info; { register struct sockaddr *gate = rt->rt_gateway; struct atm_pseudoioctl api; diff --git a/sys/netinet/if_atm.h b/sys/netinet/if_atm.h index b448253b78d..8603825d719 100644 --- a/sys/netinet/if_atm.h +++ b/sys/netinet/if_atm.h @@ -42,6 +42,6 @@ struct mbuf; struct rtentry; struct sockaddr; -void atm_rtrequest __P((int, struct rtentry *, struct sockaddr *)); +void atm_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); int atmresolve __P((struct rtentry *, struct mbuf *, struct sockaddr *, struct atm_pseudohdr *)); diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index dc662a8084e..1b654f4f1f7 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -116,7 +116,7 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW, &arp_proxyall, 0, ""); static void arp_init __P((void)); -static void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *)); +static void arp_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); static void arprequest __P((struct ifnet *, struct in_addr *, struct in_addr *, u_char *)); static void arpintr __P((void)); @@ -154,10 +154,10 @@ arptimer(ignored_arg) * Parallel to llc_rtrequest. */ static void -arp_rtrequest(req, rt, sa) +arp_rtrequest(req, rt, info) int req; register struct rtentry *rt; - struct sockaddr *sa; + struct rt_addrinfo *info; { register struct sockaddr *gate = rt->rt_gateway; register struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo; diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 2725e80e872..8c0109fdb0b 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -738,16 +738,14 @@ in_losing(inp) if ((rt = inp->inp_route.ro_rt)) { bzero((caddr_t)&info, sizeof(info)); - info.rti_info[RTAX_DST] = - (struct sockaddr *)&inp->inp_route.ro_dst; + info.rti_flags = rt->rt_flags; + info.rti_info[RTAX_DST] = rt_key(rt); info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; info.rti_info[RTAX_NETMASK] = rt_mask(rt); rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); if (rt->rt_flags & RTF_DYNAMIC) - (void) rtrequest(RTM_DELETE, rt_key(rt), - rt->rt_gateway, rt_mask(rt), rt->rt_flags, - (struct rtentry **)0); - inp->inp_route.ro_rt = 0; + (void) rtrequest1(RTM_DELETE, &info, NULL); + inp->inp_route.ro_rt = NULL; rtfree(rt); /* * A new route can be allocated diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 417ad0c26f4..a82ab8453ed 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -980,15 +980,13 @@ in6_losing(in6p) if ((rt = in6p->in6p_route.ro_rt) != NULL) { bzero((caddr_t)&info, sizeof(info)); - info.rti_info[RTAX_DST] = - (struct sockaddr *)&in6p->in6p_route.ro_dst; + info.rti_flags = rt->rt_flags; + info.rti_info[RTAX_DST] = rt_key(rt); info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; info.rti_info[RTAX_NETMASK] = rt_mask(rt); rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); if (rt->rt_flags & RTF_DYNAMIC) - (void)rtrequest(RTM_DELETE, rt_key(rt), - rt->rt_gateway, rt_mask(rt), rt->rt_flags, - (struct rtentry **)0); + (void)rtrequest1(RTM_DELETE, &info, NULL); in6p->in6p_route.ro_rt = NULL; rtfree(rt); /* diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 6fa087a635f..2dd1758ff0b 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1085,10 +1085,10 @@ nd6_nud_hint(rt, dst6, force) } void -nd6_rtrequest(req, rt, sa) +nd6_rtrequest(req, rt, info) int req; struct rtentry *rt; - struct sockaddr *sa; /* xxx unused */ + struct rt_addrinfo *info; /* xxx unused */ { struct sockaddr *gate = rt->rt_gateway; struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo; diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index a2b342359fa..f3c17be9790 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -353,7 +353,7 @@ struct llinfo_nd6 *nd6_free __P((struct rtentry *)); void nd6_nud_hint __P((struct rtentry *, struct in6_addr *, int)); int nd6_resolve __P((struct ifnet *, struct rtentry *, struct mbuf *, struct sockaddr *, u_char *)); -void nd6_rtrequest __P((int, struct rtentry *, struct sockaddr *)); +void nd6_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); int nd6_ioctl __P((u_long, caddr_t, struct ifnet *)); struct rtentry *nd6_cache_lladdr __P((struct ifnet *, struct in6_addr *, char *, int, int, int)); -- 2.45.2