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
This commit is contained in:
parent
9082264160
commit
8071913df2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=85074
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
270
sys/net/route.c
270
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);
|
||||
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, rt);
|
||||
if (cmd == RTM_DELETE) {
|
||||
/*
|
||||
* If we are deleting, and we found an entry, then
|
||||
* it's been removed from the tree.. now throw it away.
|
||||
*/
|
||||
if (rt->rt_refcnt <= 0) {
|
||||
rt->rt_refcnt++; /* make a 1->0 transition */
|
||||
rtfree(rt);
|
||||
}
|
||||
} else if (cmd == RTM_ADD) {
|
||||
/*
|
||||
* We just wanted to add it.. we don't actually
|
||||
* need a reference.
|
||||
*/
|
||||
rt->rt_refcnt--;
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
/*
|
||||
* 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));
|
||||
/*
|
||||
* Remove the reference to its ifaddr.
|
||||
*/
|
||||
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++;
|
||||
/*
|
||||
* Now ask the protocol to check if it needs
|
||||
* any special processing in its new form.
|
||||
*/
|
||||
if (ifa->ifa_rtrequest)
|
||||
ifa->ifa_rtrequest(RTM_ADD, rt, SA(0));
|
||||
}
|
||||
/*
|
||||
* notify any listenning routing agents of the change
|
||||
*/
|
||||
rt_newaddrmsg(cmd, ifa, error, nrt);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 *));
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user