summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2001-10-17 18:07:05 +0000
committerru <ru@FreeBSD.org>2001-10-17 18:07:05 +0000
commitecb4d3d05f89eabc8020bb6563d903164e3002a1 (patch)
tree6e9f67b95d216263dd912c61fa5f86b94ce2d728 /sys
parentddef7c98c51d09f80ae57f4f83e00ee5b6e3ee72 (diff)
downloadFreeBSD-src-ecb4d3d05f89eabc8020bb6563d903164e3002a1.zip
FreeBSD-src-ecb4d3d05f89eabc8020bb6563d903164e3002a1.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c8
-rw-r--r--sys/net/if_disc.c4
-rw-r--r--sys/net/if_faith.c6
-rw-r--r--sys/net/if_loop.c6
-rw-r--r--sys/net/if_stf.c6
-rw-r--r--sys/net/if_var.h3
-rw-r--r--sys/net/route.c256
-rw-r--r--sys/net/route.h5
-rw-r--r--sys/net/rtsock.c35
-rw-r--r--sys/netinet/if_atm.c6
-rw-r--r--sys/netinet/if_atm.h2
-rw-r--r--sys/netinet/if_ether.c6
-rw-r--r--sys/netinet/in_pcb.c10
-rw-r--r--sys/netinet6/in6_pcb.c8
-rw-r--r--sys/netinet6/nd6.c4
-rw-r--r--sys/netinet6/nd6.h2
16 files changed, 206 insertions, 161 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index b97302d..1e3dfac 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 @@ done:
* 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 c04c6c2..fbabf30 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 1dac1b6..585cf1d 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 f5b5130..b36e907 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 ebbbe70..b3f80da 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 cc1983d..2738c36 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 d19ed8a..ac130aa 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 *));
@@ -456,6 +474,70 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
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;
register struct radix_node *rn;
@@ -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 ae3753b..1a38ceb 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 efd7d57..84f38d6 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 04b49bf..83fe027 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 b448253..8603825 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 dc662a8..1b654f4 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 2725e80..8c0109f 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 417ad0c..a82ab84 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 6fa087a..2dd1758 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 a2b3423..f3c17be 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));
OpenPOWER on IntegriCloud