summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2017-07-03 19:23:48 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2017-07-03 19:23:48 +0000
commita150de3216375a1c79f136bf9ef505ce588bf99b (patch)
tree89e15a1a62010a3b28dbab03cabcd641e0f1e9fe /sys
parent834db85448f45cbc6a61d5bd56ff46ea455730e7 (diff)
Both PF_ROUTE and PF_KEY need to start to take care of their own PCB list
to simplify the locking of those lists. For now move the LIST_ENTRY from rawcb into routecb and in the pfkey case a new keycb. Do some cleanup and renaming in the pfkey code but more to come. OK bluhm@ mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pfkeyv2.c152
-rw-r--r--sys/net/raw_cb.c13
-rw-r--r--sys/net/raw_cb.h5
-rw-r--r--sys/net/raw_usrreq.c17
-rw-r--r--sys/net/rtsock.c113
5 files changed, 134 insertions, 166 deletions
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index 6e870613c92..5fbb23a2578 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.162 2017/06/26 09:32:32 mpi Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.163 2017/07/03 19:23:47 claudio Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -131,14 +131,16 @@ extern struct radix_node_head **spd_tables;
struct sockaddr pfkey_addr = { 2, PF_KEY, };
struct domain pfkeydomain;
-struct pfkeyv2_socket {
- LIST_ENTRY(pfkeyv2_socket) kcb_list;
- struct socket *socket;
+struct keycb {
+ struct rawcb rcb;
+ LIST_ENTRY(keycb) kcb_list;
int flags;
uint32_t pid;
uint32_t registration; /* Increase size if SATYPE_MAX > 31 */
uint rdomain;
};
+#define sotokeycb(so) ((struct keycb *)(so)->so_pcb)
+
struct dump_state {
struct sadb_msg *sadb_msg;
@@ -146,8 +148,7 @@ struct dump_state {
};
/* Static globals */
-static LIST_HEAD(, pfkeyv2_socket) pfkeyv2_sockets =
- LIST_HEAD_INITIALIZER(pfkeyv2_sockets);
+static LIST_HEAD(, keycb) pfkeyv2_sockets = LIST_HEAD_INITIALIZER(keycb);
static uint32_t pfkeyv2_seq = 1;
static int nregistered = 0;
static int npromisc = 0;
@@ -160,7 +161,7 @@ int pfkeyv2_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
struct mbuf *, struct proc *);
int pfkeyv2_output(struct mbuf *, struct socket *, struct sockaddr *,
struct mbuf *);
-int pfkey_sendup(struct socket *socket, struct mbuf *packet, int more);
+int pfkey_sendup(struct keycb *, struct mbuf *, int);
/*
* Wrapper around m_devget(); copy data from contiguous buffer to mbuf
@@ -212,72 +213,62 @@ pfkey_init(void)
int
pfkeyv2_attach(struct socket *so, int proto)
{
- struct pfkeyv2_socket *pfkeyv2_socket;
+ struct rawcb *rp;
+ struct keycb *pk;
int error;
if ((so->so_state & SS_PRIV) == 0)
return EACCES;
- if (!(so->so_pcb = malloc(sizeof(struct rawcb),
- M_PCB, M_DONTWAIT | M_ZERO)))
- return (ENOMEM);
-
- error = raw_attach(so, so->so_proto->pr_protocol);
- if (error)
- goto ret;
+ pk = malloc(sizeof(struct keycb), M_PCB, M_WAITOK | M_ZERO);
+ rp = &pk->rcb;
+ so->so_pcb = rp;
- ((struct rawcb *)so->so_pcb)->rcb_faddr = &pfkey_addr;
+ error = raw_attach(so, proto);
+ if (error) {
+ free(pk, M_PCB, sizeof(struct keycb));
+ return (error);
+ }
- if (!(pfkeyv2_socket = malloc(sizeof(struct pfkeyv2_socket),
- M_PFKEY, M_NOWAIT | M_ZERO)))
- return (ENOMEM);
+ so->so_options |= SO_USELOOPBACK;
+ soisconnected(so);
- LIST_INSERT_HEAD(&pfkeyv2_sockets, pfkeyv2_socket, kcb_list);
- pfkeyv2_socket->socket = so;
- pfkeyv2_socket->pid = curproc->p_p->ps_pid;
+ rp->rcb_faddr = &pfkey_addr;
+ pk->pid = curproc->p_p->ps_pid;
/*
* XXX we should get this from the socket instead but
* XXX rawcb doesn't store the rdomain like inpcb does.
*/
- pfkeyv2_socket->rdomain = rtable_l2(curproc->p_p->ps_rtableid);
+ pk->rdomain = rtable_l2(curproc->p_p->ps_rtableid);
- so->so_options |= SO_USELOOPBACK;
- soisconnected(so);
+ LIST_INSERT_HEAD(&pfkeyv2_sockets, pk, kcb_list);
return (0);
-ret:
- free(so->so_pcb, M_PCB, sizeof(struct rawcb));
- return (error);
}
/*
* Close a PF_KEYv2 socket.
*/
int
-pfkeyv2_detach(struct socket *socket, struct proc *p)
+pfkeyv2_detach(struct socket *so, struct proc *p)
{
- struct pfkeyv2_socket *pp;
- int error;
-
- LIST_FOREACH(pp, &pfkeyv2_sockets, kcb_list)
- if (pp->socket == socket)
- break;
+ struct keycb *pk;
- if (pp) {
- LIST_REMOVE(pp, kcb_list);
+ pk = sotokeycb(so);
+ if (pk == NULL)
+ return ENOTCONN;
- if (pp->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)
- nregistered--;
+ LIST_REMOVE(pk, kcb_list);
- if (pp->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
- npromisc--;
+ if (pk->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)
+ nregistered--;
- free(pp, M_PFKEY, 0);
- }
+ if (pk->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
+ npromisc--;
- error = raw_usrreq(socket, PRU_DETACH, NULL, NULL, NULL, p);
- return (error);
+ raw_detach(&pk->rcb);
+ return (0);
}
int
@@ -293,7 +284,7 @@ pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *mbuf,
}
int
-pfkeyv2_output(struct mbuf *mbuf, struct socket *socket,
+pfkeyv2_output(struct mbuf *mbuf, struct socket *so,
struct sockaddr *dstaddr, struct mbuf *control)
{
void *message;
@@ -319,7 +310,7 @@ pfkeyv2_output(struct mbuf *mbuf, struct socket *socket,
m_copydata(mbuf, 0, mbuf->m_pkthdr.len, message);
- error = pfkeyv2_send(socket, message, mbuf->m_pkthdr.len);
+ error = pfkeyv2_send(so, message, mbuf->m_pkthdr.len);
ret:
m_freem(mbuf);
@@ -327,8 +318,9 @@ ret:
}
int
-pfkey_sendup(struct socket *so, struct mbuf *packet, int more)
+pfkey_sendup(struct keycb *kp, struct mbuf *packet, int more)
{
+ struct socket *so = kp->rcb.rcb_socket;
struct mbuf *packet2;
NET_ASSERT_LOCKED();
@@ -354,13 +346,13 @@ pfkey_sendup(struct socket *so, struct mbuf *packet, int more)
* third argument.
*/
int
-pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
+pfkeyv2_sendmessage(void **headers, int mode, struct socket *so,
u_int8_t satype, int count, u_int rdomain)
{
int i, j, rval;
void *p, *buffer = NULL;
struct mbuf *packet;
- struct pfkeyv2_socket *s;
+ struct keycb *s;
struct sadb_msg *smsg;
/* Find out how much space we'll need... */
@@ -401,7 +393,7 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
* Send message to the specified socket, plus all
* promiscuous listeners.
*/
- pfkey_sendup(socket, packet, 0);
+ pfkey_sendup(sotokeycb(so), packet, 0);
/*
* Promiscuous messages contain the original message
@@ -426,9 +418,9 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
*/
LIST_FOREACH(s, &pfkeyv2_sockets, kcb_list) {
if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
- (s->socket != socket) &&
+ (s->rcb.rcb_socket != so) &&
(s->rdomain == rdomain))
- pfkey_sendup(s->socket, packet, 1);
+ pfkey_sendup(s, packet, 1);
}
m_freem(packet);
break;
@@ -442,11 +434,11 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
if ((s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) &&
(s->rdomain == rdomain)) {
if (!satype) /* Just send to everyone registered */
- pfkey_sendup(s->socket, packet, 1);
+ pfkey_sendup(s, packet, 1);
else {
/* Check for specified satype */
if ((1 << satype) & s->registration)
- pfkey_sendup(s->socket, packet, 1);
+ pfkey_sendup(s, packet, 1);
}
}
}
@@ -472,7 +464,7 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
!(s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) &&
(s->rdomain == rdomain))
- pfkey_sendup(s->socket, packet, 1);
+ pfkey_sendup(s, packet, 1);
}
m_freem(packet);
break;
@@ -481,7 +473,7 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
/* Send message to all sockets */
LIST_FOREACH(s, &pfkeyv2_sockets, kcb_list) {
if (s->rdomain == rdomain)
- pfkey_sendup(s->socket, packet, 1);
+ pfkey_sendup(s, packet, 1);
}
m_freem(packet);
break;
@@ -940,7 +932,7 @@ pfkeyv2_get_proto_alg(u_int8_t satype, u_int8_t *sproto, int *alg)
* Handle all messages from userland to kernel.
*/
int
-pfkeyv2_send(struct socket *socket, void *message, int len)
+pfkeyv2_send(struct socket *so, void *message, int len)
{
int i, j, s, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST;
int delflag = 0;
@@ -950,7 +942,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
struct radix_node_head *rnh;
struct radix_node *rn = NULL;
- struct pfkeyv2_socket *pfkeyv2_socket, *so = NULL;
+ struct keycb *pk, *bpk = NULL;
void *freeme = NULL, *bckptr = NULL;
void *headers[SADB_EXT_MAX + 1];
@@ -972,16 +964,14 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
/* Verify that we received this over a legitimate pfkeyv2 socket */
bzero(headers, sizeof(headers));
- LIST_FOREACH(pfkeyv2_socket, &pfkeyv2_sockets, kcb_list)
- if (pfkeyv2_socket->socket == socket)
- break;
+ pk = sotokeycb(so);
- if (!pfkeyv2_socket) {
+ if (!pk) {
rval = EINVAL;
goto ret;
}
- rdomain = pfkeyv2_socket->rdomain;
+ rdomain = pk->rdomain;
/* If we have any promiscuous listeners, send them a copy of the message */
if (npromisc) {
@@ -1010,10 +1000,10 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
goto ret;
/* Send to all promiscuous listeners */
- LIST_FOREACH(so, &pfkeyv2_sockets, kcb_list) {
- if ((so->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
- (so->rdomain == rdomain))
- pfkey_sendup(so->socket, packet, 1);
+ LIST_FOREACH(bpk, &pfkeyv2_sockets, kcb_list) {
+ if ((bpk->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
+ (bpk->rdomain == rdomain))
+ pfkey_sendup(bpk, packet, 1);
}
m_freem(packet);
@@ -1402,8 +1392,8 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
break;
case SADB_REGISTER:
- if (!(pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) {
- pfkeyv2_socket->flags |= PFKEYV2_SOCKETFLAGS_REGISTERED;
+ if (!(pk->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) {
+ pk->flags |= PFKEYV2_SOCKETFLAGS_REGISTERED;
nregistered++;
}
@@ -1433,7 +1423,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
}
/* Keep track what this socket has registered for */
- pfkeyv2_socket->registration |= (1 << ((struct sadb_msg *)message)->sadb_msg_satype);
+ pk->registration |= (1 << ((struct sadb_msg *)message)->sadb_msg_satype);
ssup = (struct sadb_supported *) freeme;
ssup->sadb_supported_len = i / sizeof(uint64_t);
@@ -1506,7 +1496,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
{
struct dump_state dump_state;
dump_state.sadb_msg = (struct sadb_msg *) headers[0];
- dump_state.socket = socket;
+ dump_state.socket = so;
rval = tdb_walk(rdomain, pfkeyv2_dump_walker, &dump_state);
if (!rval)
@@ -1778,12 +1768,12 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
if ((rval = pfdatatopacket(message, len, &packet)) != 0)
goto ret;
- LIST_FOREACH(so, &pfkeyv2_sockets, kcb_list)
- if ((so != pfkeyv2_socket) &&
- (so->rdomain == rdomain) &&
+ LIST_FOREACH(bpk, &pfkeyv2_sockets, kcb_list)
+ if ((bpk != pk) &&
+ (bpk->rdomain == rdomain) &&
(!smsg->sadb_msg_seq ||
- (smsg->sadb_msg_seq == pfkeyv2_socket->pid)))
- pfkey_sendup(so->socket, packet, 1);
+ (smsg->sadb_msg_seq == pk->pid)))
+ pfkey_sendup(bpk, packet, 1);
m_freem(packet);
} else {
@@ -1792,17 +1782,17 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
goto ret;
}
- i = (pfkeyv2_socket->flags &
+ i = (pk->flags &
PFKEYV2_SOCKETFLAGS_PROMISC) ? 1 : 0;
j = smsg->sadb_msg_satype ? 1 : 0;
if (i ^ j) {
if (j) {
- pfkeyv2_socket->flags |=
+ pk->flags |=
PFKEYV2_SOCKETFLAGS_PROMISC;
npromisc++;
} else {
- pfkeyv2_socket->flags &=
+ pk->flags &=
~PFKEYV2_SOCKETFLAGS_PROMISC;
npromisc--;
}
@@ -1841,7 +1831,7 @@ ret:
goto realret;
}
- rval = pfkeyv2_sendmessage(headers, mode, socket, 0, 0, rdomain);
+ rval = pfkeyv2_sendmessage(headers, mode, so, 0, 0, rdomain);
realret:
NET_UNLOCK(s);
diff --git a/sys/net/raw_cb.c b/sys/net/raw_cb.c
index 974db3afe78..e77da50b039 100644
--- a/sys/net/raw_cb.c
+++ b/sys/net/raw_cb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_cb.c,v 1.11 2017/01/24 10:08:30 krw Exp $ */
+/* $OpenBSD: raw_cb.c,v 1.12 2017/07/03 19:23:47 claudio Exp $ */
/* $NetBSD: raw_cb.c,v 1.9 1996/02/13 22:00:39 christos Exp $ */
/*
@@ -46,16 +46,10 @@
/*
* Routines to manage the raw protocol control blocks.
- *
- * TODO:
- * hash lookups by protocol family/protocol + address family
- * take care of unique address problems per AF?
- * redo address binding to allow wildcards
*/
u_long raw_sendspace = RAWSNDQ;
u_long raw_recvspace = RAWRCVQ;
-struct rawcbhead rawcb;
/*
* Allocate a control block and a nominal amount
@@ -72,14 +66,13 @@ raw_attach(struct socket *so, int proto)
* after space has been allocated for the
* rawcb.
*/
- if (rp == 0)
+ if (rp == NULL)
return (ENOBUFS);
if ((error = soreserve(so, raw_sendspace, raw_recvspace)) != 0)
return (error);
rp->rcb_socket = so;
rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
rp->rcb_proto.sp_protocol = proto;
- LIST_INSERT_HEAD(&rawcb, rp, rcb_list);
return (0);
}
@@ -94,7 +87,6 @@ raw_detach(struct rawcb *rp)
so->so_pcb = 0;
sofree(so);
- LIST_REMOVE(rp, rcb_list);
free((caddr_t)(rp), M_PCB, 0);
}
@@ -104,7 +96,6 @@ raw_detach(struct rawcb *rp)
void
raw_disconnect(struct rawcb *rp)
{
-
if (rp->rcb_socket->so_state & SS_NOFDREF)
raw_detach(rp);
}
diff --git a/sys/net/raw_cb.h b/sys/net/raw_cb.h
index f08d75c128e..00c3d30f98a 100644
--- a/sys/net/raw_cb.h
+++ b/sys/net/raw_cb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_cb.h,v 1.11 2017/01/23 16:31:24 bluhm Exp $ */
+/* $OpenBSD: raw_cb.h,v 1.12 2017/07/03 19:23:47 claudio Exp $ */
/* $NetBSD: raw_cb.h,v 1.9 1996/02/13 22:00:41 christos Exp $ */
/*
@@ -40,7 +40,6 @@
* to tie a socket to the generic raw interface.
*/
struct rawcb {
- LIST_ENTRY(rawcb) rcb_list; /* doubly linked list */
struct socket *rcb_socket; /* back pointer to socket */
struct sockaddr *rcb_faddr; /* destination address */
struct sockaddr *rcb_laddr; /* socket's address */
@@ -55,8 +54,6 @@ struct rawcb {
#ifdef _KERNEL
-extern LIST_HEAD(rawcbhead, rawcb) rawcb; /* head of list */
-
#define sotorawcb(so) ((struct rawcb *)(so)->so_pcb)
int raw_attach(struct socket *, int);
void raw_detach(struct rawcb *);
diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c
index cbf137a43af..d72f242c892 100644
--- a/sys/net/raw_usrreq.c
+++ b/sys/net/raw_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_usrreq.c,v 1.31 2017/03/13 20:18:21 claudio Exp $ */
+/* $OpenBSD: raw_usrreq.c,v 1.32 2017/07/03 19:23:47 claudio Exp $ */
/* $NetBSD: raw_usrreq.c,v 1.11 1996/02/13 22:00:43 christos Exp $ */
/*
@@ -45,15 +45,6 @@
#include <net/raw_cb.h>
#include <sys/stdarg.h>
-/*
- * Initialize raw connection block q.
- */
-void
-raw_init(void)
-{
-
- LIST_INIT(&rawcb);
-}
int
raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
@@ -71,7 +62,7 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
m_freem(m);
return (EOPNOTSUPP);
}
- if (rp == 0) {
+ if (rp == NULL) {
m_freem(m);
return (EINVAL);
}
@@ -81,10 +72,6 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
* Flush data or not depending on the options.
*/
case PRU_DETACH:
- if (rp == 0) {
- error = ENOTCONN;
- break;
- }
raw_detach(rp);
break;
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index fff48f069ab..7fdc5291892 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.239 2017/06/26 09:32:32 mpi Exp $ */
+/* $OpenBSD: rtsock.c,v 1.240 2017/07/03 19:23:47 claudio Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -98,6 +98,7 @@ struct walkarg {
caddr_t w_where, w_tmem;
};
+void route_prinit(void);
int route_output(struct mbuf *, struct socket *, struct sockaddr *,
struct mbuf *);
int route_ctloutput(int, struct socket *, int, int, struct mbuf *);
@@ -126,19 +127,21 @@ int sysctl_ifnames(struct walkarg *);
int sysctl_rtable_rtstat(void *, size_t *, void *);
struct routecb {
- struct rawcb rcb;
- struct timeout timeout;
- unsigned int msgfilter;
- unsigned int flags;
- u_int rtableid;
+ struct rawcb rcb;
+ LIST_ENTRY(routecb) rcb_list;
+ struct timeout timeout;
+ unsigned int msgfilter;
+ unsigned int flags;
+ u_int rtableid;
};
#define sotoroutecb(so) ((struct routecb *)(so)->so_pcb)
struct route_cb {
- int ip_count;
- int ip6_count;
- int mpls_count;
- int any_count;
+ LIST_HEAD(, routecb) rcb;
+ int ip_count;
+ int ip6_count;
+ int mpls_count;
+ int any_count;
};
struct route_cb route_cb;
@@ -154,45 +157,53 @@ struct route_cb route_cb;
#define ROUTE_DESYNC_RESEND_TIMEOUT (hz / 5) /* In hz */
+void
+route_prinit(void)
+{
+ LIST_INIT(&route_cb.rcb);
+}
+
+
int
route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
struct mbuf *control, struct proc *p)
{
- struct rawcb *rp;
struct routecb *rop;
int af;
int error = 0;
- rp = sotorawcb(so);
+ rop = sotoroutecb(so);
+ if (rop == NULL) {
+ m_freem(m);
+ return (EINVAL);
+ }
switch (req) {
case PRU_RCVD:
- rop = (struct routecb *)rp;
-
/*
* If we are in a FLUSH state, check if the buffer is
* empty so that we can clear the flag.
*/
if (((rop->flags & ROUTECB_FLAG_FLUSH) != 0) &&
- ((sbspace(rp->rcb_socket, &rp->rcb_socket->so_rcv) ==
- rp->rcb_socket->so_rcv.sb_hiwat)))
+ ((sbspace(rop->rcb.rcb_socket,
+ &rop->rcb.rcb_socket->so_rcv) ==
+ rop->rcb.rcb_socket->so_rcv.sb_hiwat)))
rop->flags &= ~ROUTECB_FLAG_FLUSH;
break;
case PRU_DETACH:
- if (rp) {
- timeout_del(&((struct routecb *)rp)->timeout);
- af = rp->rcb_proto.sp_protocol;
- if (af == AF_INET)
- route_cb.ip_count--;
- else if (af == AF_INET6)
- route_cb.ip6_count--;
+ timeout_del(&rop->timeout);
+ af = rop->rcb.rcb_proto.sp_protocol;
+ if (af == AF_INET)
+ route_cb.ip_count--;
+ else if (af == AF_INET6)
+ route_cb.ip6_count--;
#ifdef MPLS
- else if (af == AF_MPLS)
- route_cb.mpls_count--;
+ else if (af == AF_MPLS)
+ route_cb.mpls_count--;
#endif
- route_cb.any_count--;
- }
+ route_cb.any_count--;
+ LIST_REMOVE(rop, rcb_list);
/* FALLTHROUGH */
default:
error = raw_usrreq(so, req, m, nam, control, p);
@@ -206,8 +217,7 @@ route_attach(struct socket *so, int proto)
{
struct rawcb *rp;
struct routecb *rop;
- int af;
- int error = 0;
+ int error;
/*
* use the rawcb but allocate a routecb, this
@@ -229,21 +239,28 @@ route_attach(struct socket *so, int proto)
return (error);
}
rop->rtableid = curproc->p_p->ps_rtableid;
- af = rp->rcb_proto.sp_protocol;
- if (af == AF_INET)
+ switch (rp->rcb_proto.sp_protocol) {
+ case AF_INET:
route_cb.ip_count++;
- else if (af == AF_INET6)
+ break;
+ case AF_INET6:
route_cb.ip6_count++;
+ break;
#ifdef MPLS
- else if (af == AF_MPLS)
+ case AF_MPLS:
route_cb.mpls_count++;
+ break;
#endif
- rp->rcb_faddr = &route_src;
- route_cb.any_count++;
+ }
+
soisconnected(so);
so->so_options |= SO_USELOOPBACK;
- return (error);
+ rp->rcb_faddr = &route_src;
+ route_cb.any_count++;
+ LIST_INSERT_HEAD(&route_cb.rcb, rop, rcb_list);
+
+ return (0);
}
int
@@ -360,10 +377,11 @@ route_input(struct mbuf *m0, struct socket *so, sa_family_t sa_family)
return;
}
- LIST_FOREACH(rp, &rawcb, rcb_list) {
- if (rp->rcb_socket->so_state & SS_CANTRCVMORE)
+ LIST_FOREACH(rop, &route_cb.rcb, rcb_list) {
+ rp = &rop->rcb;
+ if (!(rp->rcb_socket->so_state & SS_ISCONNECTED))
continue;
- if (rp->rcb_proto.sp_family != PF_ROUTE)
+ if (rp->rcb_socket->so_state & SS_CANTRCVMORE)
continue;
/* Check to see if we don't want our own messages. */
if (so == rp->rcb_socket && !(so->so_options & SO_USELOOPBACK))
@@ -378,23 +396,8 @@ route_input(struct mbuf *m0, struct socket *so, sa_family_t sa_family)
sa_family != AF_UNSPEC &&
rp->rcb_proto.sp_protocol != sa_family)
continue;
- /*
- * We assume the lower level routines have
- * placed the address in a canonical format
- * suitable for a structure comparison.
- *
- * Note that if the lengths are not the same
- * the comparison will fail at the first byte.
- */
-#define equal(a1, a2) \
- (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
- if (rp->rcb_laddr && !equal(rp->rcb_laddr, sodst))
- continue;
- if (rp->rcb_faddr && !equal(rp->rcb_faddr, sosrc))
- continue;
/* filter messages that the process does not want */
- rop = (struct routecb *)rp;
rtm = mtod(m, struct rt_msghdr *);
/* but RTM_DESYNC can't be filtered */
if (rtm->rtm_type != RTM_DESYNC && rop->msgfilter != 0 &&
@@ -1787,7 +1790,7 @@ struct protosw routesw[] = {
.pr_ctloutput = route_ctloutput,
.pr_usrreq = route_usrreq,
.pr_attach = route_attach,
- .pr_init = raw_init,
+ .pr_init = route_prinit,
.pr_sysctl = sysctl_rtable
}
};