cleanups prior to adding locking (and in some cases to eliminate locking):
o move route_cb to be private to rtsock.c o replace global static route_proto by locals o eliminate global #define shorthands for info references o remove some register decls o ansi-fy function decls o move items to be close in scope to their usage o add rt_dispatch function for dispatching the actual message o cleanup tangled logic for doing all-but-me msg send Support by: FreeBSD Foundation
This commit is contained in:
parent
c3b52d6499
commit
becc44d76c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=120701
@ -53,7 +53,6 @@
|
||||
|
||||
#define SA(p) ((struct sockaddr *)(p))
|
||||
|
||||
struct route_cb route_cb;
|
||||
static struct rtstat rtstat;
|
||||
struct radix_node_head *rt_tables[AF_MAX+1];
|
||||
|
||||
|
@ -254,13 +254,6 @@ struct rt_addrinfo {
|
||||
struct ifnet *rti_ifp;
|
||||
};
|
||||
|
||||
struct route_cb {
|
||||
int ip_count;
|
||||
int ip6_count;
|
||||
int ipx_count;
|
||||
int any_count;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define RT_LOCK_INIT(rt) \
|
||||
@ -277,7 +270,6 @@ struct route_cb {
|
||||
(rt)->rt_refcnt--; \
|
||||
} while (0)
|
||||
|
||||
extern struct route_cb route_cb;
|
||||
extern struct radix_node_head *rt_tables[AF_MAX+1];
|
||||
|
||||
struct ifmultiaddr;
|
||||
|
337
sys/net/rtsock.c
337
sys/net/rtsock.c
@ -34,7 +34,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -55,10 +54,17 @@
|
||||
|
||||
MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
|
||||
|
||||
/* NB: these are not modified */
|
||||
static struct sockaddr route_dst = { 2, PF_ROUTE, };
|
||||
static struct sockaddr route_src = { 2, PF_ROUTE, };
|
||||
static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, };
|
||||
static struct sockproto route_proto = { PF_ROUTE, };
|
||||
|
||||
static struct {
|
||||
int ip_count; /* attacked w/ AF_INET */
|
||||
int ip6_count; /* attached w/ AF_INET6 */
|
||||
int ipx_count; /* attached w/ AF_IPX */
|
||||
int any_count; /* total attached */
|
||||
} route_cb;
|
||||
|
||||
struct walkarg {
|
||||
int w_tmemsize;
|
||||
@ -67,23 +73,14 @@ struct walkarg {
|
||||
struct sysctl_req *w_req;
|
||||
};
|
||||
|
||||
static struct mbuf *
|
||||
rt_msg1(int, struct rt_addrinfo *);
|
||||
static struct mbuf *rt_msg1(int, struct rt_addrinfo *);
|
||||
static int rt_msg2(int, struct rt_addrinfo *, caddr_t, struct walkarg *);
|
||||
static int rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
|
||||
static int sysctl_dumpentry(struct radix_node *rn, void *vw);
|
||||
static int sysctl_iflist(int af, struct walkarg *w);
|
||||
static int route_output(struct mbuf *, struct socket *);
|
||||
static void rt_setmetrics(u_long, struct rt_metrics *, struct rt_metrics *);
|
||||
|
||||
/* Sleazy use of local variables throughout file, warning!!!! */
|
||||
#define dst info.rti_info[RTAX_DST]
|
||||
#define gate info.rti_info[RTAX_GATEWAY]
|
||||
#define netmask info.rti_info[RTAX_NETMASK]
|
||||
#define genmask info.rti_info[RTAX_GENMASK]
|
||||
#define ifpaddr info.rti_info[RTAX_IFP]
|
||||
#define ifaaddr info.rti_info[RTAX_IFA]
|
||||
#define brdaddr info.rti_info[RTAX_BRD]
|
||||
static int route_output(struct mbuf *, struct socket *);
|
||||
static void rt_setmetrics(u_long, struct rt_metrics *, struct rt_metrics *);
|
||||
static void rt_dispatch(struct mbuf *, struct sockaddr *);
|
||||
|
||||
/*
|
||||
* It really doesn't make any sense at all for this code to share much
|
||||
@ -271,9 +268,9 @@ route_output(m, so)
|
||||
register struct mbuf *m;
|
||||
struct socket *so;
|
||||
{
|
||||
#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
|
||||
register struct rt_msghdr *rtm = 0;
|
||||
register struct rtentry *rt = 0;
|
||||
struct rtentry *saved_nrt = 0;
|
||||
struct radix_node_head *rnh;
|
||||
struct rt_addrinfo info;
|
||||
int len, error = 0;
|
||||
@ -289,36 +286,40 @@ route_output(m, so)
|
||||
len = m->m_pkthdr.len;
|
||||
if (len < sizeof(*rtm) ||
|
||||
len != mtod(m, struct rt_msghdr *)->rtm_msglen) {
|
||||
dst = 0;
|
||||
info.rti_info[RTAX_DST] = 0;
|
||||
senderr(EINVAL);
|
||||
}
|
||||
R_Malloc(rtm, struct rt_msghdr *, len);
|
||||
if (rtm == 0) {
|
||||
dst = 0;
|
||||
info.rti_info[RTAX_DST] = 0;
|
||||
senderr(ENOBUFS);
|
||||
}
|
||||
m_copydata(m, 0, len, (caddr_t)rtm);
|
||||
if (rtm->rtm_version != RTM_VERSION) {
|
||||
dst = 0;
|
||||
info.rti_info[RTAX_DST] = 0;
|
||||
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;
|
||||
info.rti_info[RTAX_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)))
|
||||
if (info.rti_info[RTAX_DST] == 0 ||
|
||||
info.rti_info[RTAX_DST]->sa_family >= AF_MAX ||
|
||||
(info.rti_info[RTAX_GATEWAY] != 0 &&
|
||||
info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX))
|
||||
senderr(EINVAL);
|
||||
if (genmask) {
|
||||
if (info.rti_info[RTAX_GENMASK]) {
|
||||
struct radix_node *t;
|
||||
t = rn_addmask((caddr_t)genmask, 0, 1);
|
||||
if (t && Bcmp((caddr_t *)genmask + 1, (caddr_t *)t->rn_key + 1,
|
||||
t = rn_addmask((caddr_t) info.rti_info[RTAX_GENMASK], 0, 1);
|
||||
if (t && Bcmp((caddr_t *) info.rti_info[RTAX_GENMASK] + 1,
|
||||
(caddr_t *)t->rn_key + 1,
|
||||
*(u_char *)t->rn_key - 1) == 0)
|
||||
genmask = (struct sockaddr *)(t->rn_key);
|
||||
info.rti_info[RTAX_GENMASK] =
|
||||
(struct sockaddr *)(t->rn_key);
|
||||
else
|
||||
senderr(ENOBUFS);
|
||||
}
|
||||
@ -331,10 +332,12 @@ route_output(m, so)
|
||||
senderr(error);
|
||||
|
||||
switch (rtm->rtm_type) {
|
||||
struct rtentry *saved_nrt;
|
||||
|
||||
case RTM_ADD:
|
||||
if (gate == 0)
|
||||
if (info.rti_info[RTAX_GATEWAY] == 0)
|
||||
senderr(EINVAL);
|
||||
saved_nrt = 0;
|
||||
error = rtrequest1(RTM_ADD, &info, &saved_nrt);
|
||||
if (error == 0 && saved_nrt) {
|
||||
rt_setmetrics(rtm->rtm_inits,
|
||||
@ -343,11 +346,12 @@ route_output(m, so)
|
||||
saved_nrt->rt_rmx.rmx_locks |=
|
||||
(rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);
|
||||
saved_nrt->rt_refcnt--;
|
||||
saved_nrt->rt_genmask = genmask;
|
||||
saved_nrt->rt_genmask = info.rti_info[RTAX_GENMASK];
|
||||
}
|
||||
break;
|
||||
|
||||
case RTM_DELETE:
|
||||
saved_nrt = 0;
|
||||
error = rtrequest1(RTM_DELETE, &info, &saved_nrt);
|
||||
if (error == 0) {
|
||||
rt = saved_nrt;
|
||||
@ -358,36 +362,38 @@ route_output(m, so)
|
||||
case RTM_GET:
|
||||
case RTM_CHANGE:
|
||||
case RTM_LOCK:
|
||||
if ((rnh = rt_tables[dst->sa_family]) == 0) {
|
||||
rnh = rt_tables[info.rti_info[RTAX_DST]->sa_family];
|
||||
if (rnh == 0)
|
||||
senderr(EAFNOSUPPORT);
|
||||
}
|
||||
RADIX_NODE_HEAD_LOCK(rnh);
|
||||
rt = (struct rtentry *) rnh->rnh_lookup(dst, netmask, rnh);
|
||||
rt = (struct rtentry *) rnh->rnh_lookup(info.rti_info[RTAX_DST],
|
||||
info.rti_info[RTAX_NETMASK], rnh);
|
||||
RADIX_NODE_HEAD_UNLOCK(rnh);
|
||||
if (rt != NULL)
|
||||
rt->rt_refcnt++;
|
||||
else
|
||||
if (rt == NULL) /* XXX looks bogus */
|
||||
senderr(ESRCH);
|
||||
rt->rt_refcnt++;
|
||||
|
||||
switch(rtm->rtm_type) {
|
||||
|
||||
case RTM_GET:
|
||||
report:
|
||||
dst = rt_key(rt);
|
||||
gate = rt->rt_gateway;
|
||||
netmask = rt_mask(rt);
|
||||
genmask = rt->rt_genmask;
|
||||
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_GENMASK] = rt->rt_genmask;
|
||||
if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
|
||||
ifp = rt->rt_ifp;
|
||||
if (ifp) {
|
||||
ifpaddr = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
|
||||
ifaaddr = rt->rt_ifa->ifa_addr;
|
||||
info.rti_info[RTAX_IFP] = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
|
||||
info.rti_info[RTAX_IFA] =
|
||||
rt->rt_ifa->ifa_addr;
|
||||
if (ifp->if_flags & IFF_POINTOPOINT)
|
||||
brdaddr = rt->rt_ifa->ifa_dstaddr;
|
||||
info.rti_info[RTAX_BRD] =
|
||||
rt->rt_ifa->ifa_dstaddr;
|
||||
rtm->rtm_index = ifp->if_index;
|
||||
} else {
|
||||
ifpaddr = 0;
|
||||
ifaaddr = 0;
|
||||
info.rti_info[RTAX_IFP] = 0;
|
||||
info.rti_info[RTAX_IFA] = 0;
|
||||
}
|
||||
}
|
||||
len = rt_msg2(rtm->rtm_type, &info, (caddr_t)0,
|
||||
@ -395,8 +401,9 @@ route_output(m, so)
|
||||
if (len > rtm->rtm_msglen) {
|
||||
struct rt_msghdr *new_rtm;
|
||||
R_Malloc(new_rtm, struct rt_msghdr *, len);
|
||||
if (new_rtm == 0)
|
||||
if (new_rtm == 0) {
|
||||
senderr(ENOBUFS);
|
||||
}
|
||||
Bcopy(rtm, new_rtm, rtm->rtm_msglen);
|
||||
Free(rtm); rtm = new_rtm;
|
||||
}
|
||||
@ -408,41 +415,47 @@ route_output(m, so)
|
||||
break;
|
||||
|
||||
case RTM_CHANGE:
|
||||
/* new gateway could require new ifaddr, ifp;
|
||||
flags may also be different; ifp may be specified
|
||||
by ll sockaddr when protocol address is ambiguous */
|
||||
/* compare two sockaddr structures */
|
||||
#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
|
||||
if ((rt->rt_flags & RTF_GATEWAY && gate != NULL) ||
|
||||
ifpaddr != NULL ||
|
||||
(ifaaddr != NULL &&
|
||||
!sa_equal(ifaaddr, rt->rt_ifa->ifa_addr))) {
|
||||
if ((error = rt_getifa(&info)) != 0)
|
||||
/*
|
||||
* 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 (((rt->rt_flags & RTF_GATEWAY) &&
|
||||
info.rti_info[RTAX_GATEWAY] != NULL) ||
|
||||
info.rti_info[RTAX_IFP] != NULL ||
|
||||
(info.rti_info[RTAX_IFA] != NULL &&
|
||||
!sa_equal(info.rti_info[RTAX_IFA],
|
||||
rt->rt_ifa->ifa_addr))) {
|
||||
if ((error = rt_getifa(&info)) != 0) {
|
||||
senderr(error);
|
||||
}
|
||||
}
|
||||
if (gate != NULL &&
|
||||
(error = rt_setgate(rt, rt_key(rt), gate)) != 0)
|
||||
if (info.rti_info[RTAX_GATEWAY] != NULL &&
|
||||
(error = rt_setgate(rt, rt_key(rt),
|
||||
info.rti_info[RTAX_GATEWAY])) != 0) {
|
||||
senderr(error);
|
||||
}
|
||||
if ((ifa = info.rti_ifa) != NULL) {
|
||||
register struct ifaddr *oifa = rt->rt_ifa;
|
||||
struct ifaddr *oifa = rt->rt_ifa;
|
||||
if (oifa != ifa) {
|
||||
if (oifa) {
|
||||
if (oifa->ifa_rtrequest)
|
||||
oifa->ifa_rtrequest(RTM_DELETE, rt,
|
||||
&info);
|
||||
IFAFREE(oifa);
|
||||
}
|
||||
IFAREF(ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = info.rti_ifp;
|
||||
if (oifa) {
|
||||
if (oifa->ifa_rtrequest)
|
||||
oifa->ifa_rtrequest(
|
||||
RTM_DELETE, rt,
|
||||
&info);
|
||||
IFAFREE(oifa);
|
||||
}
|
||||
IFAREF(ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
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, &info);
|
||||
if (genmask)
|
||||
rt->rt_genmask = genmask;
|
||||
if (info.rti_info[RTAX_GENMASK])
|
||||
rt->rt_genmask = info.rti_info[RTAX_GENMASK];
|
||||
/* FALLTHROUGH */
|
||||
case RTM_LOCK:
|
||||
rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
|
||||
@ -463,8 +476,8 @@ route_output(m, so)
|
||||
else
|
||||
rtm->rtm_flags |= RTF_DONE;
|
||||
}
|
||||
if (rt)
|
||||
rtfree(rt);
|
||||
if (rt) /* XXX can this be true? */
|
||||
RTFREE(rt);
|
||||
{
|
||||
register struct rawcb *rp = 0;
|
||||
/*
|
||||
@ -489,22 +502,26 @@ route_output(m, so)
|
||||
m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
|
||||
Free(rtm);
|
||||
}
|
||||
if (rp)
|
||||
rp->rcb_proto.sp_family = 0; /* Avoid us */
|
||||
if (dst)
|
||||
route_proto.sp_protocol = dst->sa_family;
|
||||
if (m)
|
||||
raw_input(m, &route_proto, &route_src, &route_dst);
|
||||
if (rp)
|
||||
rp->rcb_proto.sp_family = PF_ROUTE;
|
||||
if (m) {
|
||||
if (rp) {
|
||||
/*
|
||||
* XXX insure we don't get a copy by
|
||||
* invalidating our protocol
|
||||
*/
|
||||
unsigned short family = rp->rcb_proto.sp_family;
|
||||
rp->rcb_proto.sp_family = 0;
|
||||
rt_dispatch(m, info.rti_info[RTAX_DST]);
|
||||
rp->rcb_proto.sp_family = family;
|
||||
} else
|
||||
rt_dispatch(m, info.rti_info[RTAX_DST]);
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
#undef sa_equal
|
||||
}
|
||||
|
||||
static void
|
||||
rt_setmetrics(which, in, out)
|
||||
u_long which;
|
||||
register struct rt_metrics *in, *out;
|
||||
rt_setmetrics(u_long which, struct rt_metrics *in, struct rt_metrics *out)
|
||||
{
|
||||
#define metric(f, e) if (which & (f)) out->e = in->e;
|
||||
metric(RTV_RPIPE, rmx_recvpipe);
|
||||
@ -520,8 +537,6 @@ rt_setmetrics(which, in, out)
|
||||
|
||||
#define ROUNDUP(a) \
|
||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
|
||||
|
||||
|
||||
/*
|
||||
* Extract the addresses of the passed sockaddrs.
|
||||
@ -529,24 +544,21 @@ rt_setmetrics(which, in, out)
|
||||
* This data is derived straight from userland.
|
||||
*/
|
||||
static int
|
||||
rt_xaddrs(cp, cplim, rtinfo)
|
||||
register caddr_t cp, cplim;
|
||||
register struct rt_addrinfo *rtinfo;
|
||||
rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
|
||||
{
|
||||
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
|
||||
register struct sockaddr *sa;
|
||||
register int i;
|
||||
|
||||
for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
|
||||
for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
|
||||
if ((rtinfo->rti_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
sa = (struct sockaddr *)cp;
|
||||
/*
|
||||
* It won't fit.
|
||||
*/
|
||||
if ( (cp + sa->sa_len) > cplim ) {
|
||||
if (cp + sa->sa_len > cplim)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* there are no more.. quit now
|
||||
* If there are more bits, they are in error.
|
||||
@ -558,18 +570,16 @@ rt_xaddrs(cp, cplim, rtinfo)
|
||||
rtinfo->rti_info[i] = &sa_zero;
|
||||
return (0); /* should be EINVAL but for compat */
|
||||
}
|
||||
|
||||
/* accept it */
|
||||
rtinfo->rti_info[i] = sa;
|
||||
ADVANCE(cp, sa);
|
||||
}
|
||||
return (0);
|
||||
#undef ADVANCE
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
rt_msg1(type, rtinfo)
|
||||
int type;
|
||||
register struct rt_addrinfo *rtinfo;
|
||||
rt_msg1(int type, struct rt_addrinfo *rtinfo)
|
||||
{
|
||||
register struct rt_msghdr *rtm;
|
||||
register struct mbuf *m;
|
||||
@ -635,11 +645,7 @@ rt_msg1(type, rtinfo)
|
||||
}
|
||||
|
||||
static int
|
||||
rt_msg2(type, rtinfo, cp, w)
|
||||
int type;
|
||||
register struct rt_addrinfo *rtinfo;
|
||||
caddr_t cp;
|
||||
struct walkarg *w;
|
||||
rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w)
|
||||
{
|
||||
register int i;
|
||||
int len, dlen, second_time = 0;
|
||||
@ -714,12 +720,10 @@ rt_msg2(type, rtinfo, cp, w)
|
||||
* destination.
|
||||
*/
|
||||
void
|
||||
rt_missmsg(type, rtinfo, flags, error)
|
||||
int type, flags, error;
|
||||
register struct rt_addrinfo *rtinfo;
|
||||
rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
|
||||
{
|
||||
register struct rt_msghdr *rtm;
|
||||
register struct mbuf *m;
|
||||
struct rt_msghdr *rtm;
|
||||
struct mbuf *m;
|
||||
struct sockaddr *sa = rtinfo->rti_info[RTAX_DST];
|
||||
|
||||
if (route_cb.any_count == 0)
|
||||
@ -731,8 +735,7 @@ rt_missmsg(type, rtinfo, flags, error)
|
||||
rtm->rtm_flags = RTF_DONE | flags;
|
||||
rtm->rtm_errno = error;
|
||||
rtm->rtm_addrs = rtinfo->rti_addrs;
|
||||
route_proto.sp_protocol = sa ? sa->sa_family : 0;
|
||||
raw_input(m, &route_proto, &route_src, &route_dst);
|
||||
rt_dispatch(m, sa);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -740,10 +743,9 @@ rt_missmsg(type, rtinfo, flags, error)
|
||||
* socket indicating that the status of a network interface has changed.
|
||||
*/
|
||||
void
|
||||
rt_ifmsg(ifp)
|
||||
register struct ifnet *ifp;
|
||||
rt_ifmsg(struct ifnet *ifp)
|
||||
{
|
||||
register struct if_msghdr *ifm;
|
||||
struct if_msghdr *ifm;
|
||||
struct mbuf *m;
|
||||
struct rt_addrinfo info;
|
||||
|
||||
@ -758,8 +760,7 @@ rt_ifmsg(ifp)
|
||||
ifm->ifm_flags = ifp->if_flags;
|
||||
ifm->ifm_data = ifp->if_data;
|
||||
ifm->ifm_addrs = 0;
|
||||
route_proto.sp_protocol = 0;
|
||||
raw_input(m, &route_proto, &route_src, &route_dst);
|
||||
rt_dispatch(m, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -771,10 +772,7 @@ rt_ifmsg(ifp)
|
||||
* copies of it.
|
||||
*/
|
||||
void
|
||||
rt_newaddrmsg(cmd, ifa, error, rt)
|
||||
int cmd, error;
|
||||
register struct ifaddr *ifa;
|
||||
register struct rtentry *rt;
|
||||
rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
|
||||
{
|
||||
struct rt_addrinfo info;
|
||||
struct sockaddr *sa = 0;
|
||||
@ -791,10 +789,10 @@ rt_newaddrmsg(cmd, ifa, error, rt)
|
||||
register struct ifa_msghdr *ifam;
|
||||
int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
|
||||
|
||||
ifaaddr = sa = ifa->ifa_addr;
|
||||
ifpaddr = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
|
||||
netmask = ifa->ifa_netmask;
|
||||
brdaddr = ifa->ifa_dstaddr;
|
||||
info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
|
||||
info.rti_info[RTAX_IFP] = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
|
||||
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 *);
|
||||
@ -809,9 +807,9 @@ rt_newaddrmsg(cmd, ifa, error, rt)
|
||||
|
||||
if (rt == 0)
|
||||
continue;
|
||||
netmask = rt_mask(rt);
|
||||
dst = sa = rt_key(rt);
|
||||
gate = rt->rt_gateway;
|
||||
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;
|
||||
if ((m = rt_msg1(cmd, &info)) == NULL)
|
||||
continue;
|
||||
rtm = mtod(m, struct rt_msghdr *);
|
||||
@ -820,8 +818,7 @@ rt_newaddrmsg(cmd, ifa, error, rt)
|
||||
rtm->rtm_errno = error;
|
||||
rtm->rtm_addrs = info.rti_addrs;
|
||||
}
|
||||
route_proto.sp_protocol = sa ? sa->sa_family : 0;
|
||||
raw_input(m, &route_proto, &route_src, &route_dst);
|
||||
rt_dispatch(m, sa);
|
||||
}
|
||||
}
|
||||
|
||||
@ -831,9 +828,7 @@ rt_newaddrmsg(cmd, ifa, error, rt)
|
||||
* there is no route state to worry about.
|
||||
*/
|
||||
void
|
||||
rt_newmaddrmsg(cmd, ifma)
|
||||
int cmd;
|
||||
struct ifmultiaddr *ifma;
|
||||
rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma)
|
||||
{
|
||||
struct rt_addrinfo info;
|
||||
struct mbuf *m = 0;
|
||||
@ -844,23 +839,24 @@ rt_newmaddrmsg(cmd, ifma)
|
||||
return;
|
||||
|
||||
bzero((caddr_t)&info, sizeof(info));
|
||||
ifaaddr = ifma->ifma_addr;
|
||||
info.rti_info[RTAX_IFA] = ifma->ifma_addr;
|
||||
if (ifp && TAILQ_FIRST(&ifp->if_addrhead))
|
||||
ifpaddr = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
|
||||
info.rti_info[RTAX_IFP] =
|
||||
TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
|
||||
else
|
||||
ifpaddr = NULL;
|
||||
info.rti_info[RTAX_IFP] = NULL;
|
||||
/*
|
||||
* If a link-layer address is present, present it as a ``gateway''
|
||||
* (similarly to how ARP entries, e.g., are presented).
|
||||
*/
|
||||
gate = ifma->ifma_lladdr;
|
||||
if ((m = rt_msg1(cmd, &info)) == NULL)
|
||||
info.rti_info[RTAX_GATEWAY] = ifma->ifma_lladdr;
|
||||
m = rt_msg1(cmd, &info);
|
||||
if (m == NULL)
|
||||
return;
|
||||
ifmam = mtod(m, struct ifma_msghdr *);
|
||||
ifmam->ifmam_index = ifp->if_index;
|
||||
ifmam->ifmam_addrs = info.rti_addrs;
|
||||
route_proto.sp_protocol = ifma->ifma_addr->sa_family;
|
||||
raw_input(m, &route_proto, &route_src, &route_dst);
|
||||
rt_dispatch(m, ifma->ifma_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -868,9 +864,7 @@ rt_newmaddrmsg(cmd, ifma)
|
||||
* network interface arrival and departure.
|
||||
*/
|
||||
void
|
||||
rt_ifannouncemsg(ifp, what)
|
||||
struct ifnet *ifp;
|
||||
int what;
|
||||
rt_ifannouncemsg(struct ifnet *ifp, int what)
|
||||
{
|
||||
struct if_announcemsghdr *ifan;
|
||||
struct mbuf *m;
|
||||
@ -887,39 +881,47 @@ rt_ifannouncemsg(ifp, what)
|
||||
snprintf(ifan->ifan_name, sizeof(ifan->ifan_name),
|
||||
"%s%d", ifp->if_name, ifp->if_unit);
|
||||
ifan->ifan_what = what;
|
||||
route_proto.sp_protocol = 0;
|
||||
raw_input(m, &route_proto, &route_src, &route_dst);
|
||||
rt_dispatch(m, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_dispatch(struct mbuf *m, struct sockaddr *sa)
|
||||
{
|
||||
struct sockproto route_proto;
|
||||
|
||||
route_proto.sp_family = PF_ROUTE;
|
||||
route_proto.sp_protocol = sa ? sa->sa_family : 0;
|
||||
raw_input(m, &route_proto, &route_src, &route_dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used in dumping the kernel table via sysctl().
|
||||
*/
|
||||
static int
|
||||
sysctl_dumpentry(rn, vw)
|
||||
struct radix_node *rn;
|
||||
void *vw;
|
||||
sysctl_dumpentry(struct radix_node *rn, void *vw)
|
||||
{
|
||||
register struct walkarg *w = vw;
|
||||
register struct rtentry *rt = (struct rtentry *)rn;
|
||||
struct walkarg *w = vw;
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
int error = 0, size;
|
||||
struct rt_addrinfo info;
|
||||
|
||||
if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
|
||||
return 0;
|
||||
bzero((caddr_t)&info, sizeof(info));
|
||||
dst = rt_key(rt);
|
||||
gate = rt->rt_gateway;
|
||||
netmask = rt_mask(rt);
|
||||
genmask = rt->rt_genmask;
|
||||
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_GENMASK] = rt->rt_genmask;
|
||||
if (rt->rt_ifp) {
|
||||
ifpaddr = TAILQ_FIRST(&rt->rt_ifp->if_addrhead)->ifa_addr;
|
||||
ifaaddr = rt->rt_ifa->ifa_addr;
|
||||
info.rti_info[RTAX_IFP] =
|
||||
TAILQ_FIRST(&rt->rt_ifp->if_addrhead)->ifa_addr;
|
||||
info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
|
||||
if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)
|
||||
brdaddr = rt->rt_ifa->ifa_dstaddr;
|
||||
info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr;
|
||||
}
|
||||
size = rt_msg2(RTM_GET, &info, 0, w);
|
||||
if (w->w_req && w->w_tmem) {
|
||||
register struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
|
||||
struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
|
||||
|
||||
rtm->rtm_flags = rt->rt_flags;
|
||||
rtm->rtm_use = rt->rt_use;
|
||||
@ -934,14 +936,12 @@ sysctl_dumpentry(rn, vw)
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_iflist(af, w)
|
||||
int af;
|
||||
register struct walkarg *w;
|
||||
sysctl_iflist(int af, struct walkarg *w)
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
struct rt_addrinfo info;
|
||||
int len, error = 0;
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
struct rt_addrinfo info;
|
||||
int len, error = 0;
|
||||
|
||||
bzero((caddr_t)&info, sizeof(info));
|
||||
/* IFNET_RLOCK(); */ /* could sleep XXX */
|
||||
@ -949,11 +949,11 @@ sysctl_iflist(af, w)
|
||||
if (w->w_arg && w->w_arg != ifp->if_index)
|
||||
continue;
|
||||
ifa = TAILQ_FIRST(&ifp->if_addrhead);
|
||||
ifpaddr = ifa->ifa_addr;
|
||||
info.rti_info[RTAX_IFP] = ifa->ifa_addr;
|
||||
len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w);
|
||||
ifpaddr = 0;
|
||||
info.rti_info[RTAX_IFP] = 0;
|
||||
if (w->w_req && w->w_tmem) {
|
||||
register struct if_msghdr *ifm;
|
||||
struct if_msghdr *ifm;
|
||||
|
||||
ifm = (struct if_msghdr *)w->w_tmem;
|
||||
ifm->ifm_index = ifp->if_index;
|
||||
@ -970,12 +970,12 @@ sysctl_iflist(af, w)
|
||||
if (jailed(curthread->td_ucred) &&
|
||||
prison_if(curthread->td_ucred, ifa->ifa_addr))
|
||||
continue;
|
||||
ifaaddr = ifa->ifa_addr;
|
||||
netmask = ifa->ifa_netmask;
|
||||
brdaddr = ifa->ifa_dstaddr;
|
||||
info.rti_info[RTAX_IFA] = ifa->ifa_addr;
|
||||
info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
|
||||
info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
|
||||
len = rt_msg2(RTM_NEWADDR, &info, 0, w);
|
||||
if (w->w_req && w->w_tmem) {
|
||||
register struct ifa_msghdr *ifam;
|
||||
struct ifa_msghdr *ifam;
|
||||
|
||||
ifam = (struct ifa_msghdr *)w->w_tmem;
|
||||
ifam->ifam_index = ifa->ifa_ifp->if_index;
|
||||
@ -987,7 +987,8 @@ sysctl_iflist(af, w)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
ifaaddr = netmask = brdaddr = 0;
|
||||
info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] =
|
||||
info.rti_info[RTAX_BRD] = 0;
|
||||
}
|
||||
done:
|
||||
/* IFNET_RUNLOCK(); */ /* XXX */
|
||||
@ -999,7 +1000,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int *name = (int *)arg1;
|
||||
u_int namelen = arg2;
|
||||
register struct radix_node_head *rnh;
|
||||
struct radix_node_head *rnh;
|
||||
int i, s, error = EINVAL;
|
||||
u_char af;
|
||||
struct walkarg w;
|
||||
|
Loading…
Reference in New Issue
Block a user