This is a step I need to do to make progress on the PF_KEY cleanup I'm doing. Both PF_ROUTE and PF_KEY need to start to take care of their own PCB list and so move the LIST_ENTRY out of rawcb into routecb. This allows me to do the same in PF_KEY which will be sent as the next diff.
-- :wq Claudio Index: net/raw_cb.c =================================================================== RCS file: /cvs/src/sys/net/raw_cb.c,v retrieving revision 1.11 diff -u -p -r1.11 raw_cb.c --- net/raw_cb.c 24 Jan 2017 10:08:30 -0000 1.11 +++ net/raw_cb.c 30 May 2017 08:44:05 -0000 @@ -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); } Index: net/raw_cb.h =================================================================== RCS file: /cvs/src/sys/net/raw_cb.h,v retrieving revision 1.11 diff -u -p -r1.11 raw_cb.h --- net/raw_cb.h 23 Jan 2017 16:31:24 -0000 1.11 +++ net/raw_cb.h 30 May 2017 08:44:05 -0000 @@ -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 */ @@ -54,8 +53,6 @@ struct rawcb { #define RAWRCVQ 8192 #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); Index: net/raw_usrreq.c =================================================================== RCS file: /cvs/src/sys/net/raw_usrreq.c,v retrieving revision 1.31 diff -u -p -r1.31 raw_usrreq.c --- net/raw_usrreq.c 13 Mar 2017 20:18:21 -0000 1.31 +++ net/raw_usrreq.c 30 May 2017 08:44:05 -0000 @@ -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, s 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, s * Flush data or not depending on the options. */ case PRU_DETACH: - if (rp == 0) { - error = ENOTCONN; - break; - } raw_detach(rp); break; Index: net/rtsock.c =================================================================== RCS file: /cvs/src/sys/net/rtsock.c,v retrieving revision 1.237 diff -u -p -r1.237 rtsock.c --- net/rtsock.c 19 Apr 2017 15:21:54 -0000 1.237 +++ net/rtsock.c 30 May 2017 10:29:25 -0000 @@ -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,50 @@ 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) + return ENOTCONN; 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->so_rcv) == - rp->rcb_socket->so_rcv.sb_hiwat))) + ((sbspace(&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); @@ -207,7 +215,7 @@ route_attach(struct socket *so, int prot struct rawcb *rp; struct routecb *rop; int af; - int error = 0; + int error; /* * use the rawcb but allocate a routecb, this @@ -240,10 +248,11 @@ route_attach(struct socket *so, int prot #endif rp->rcb_faddr = &route_src; route_cb.any_count++; + LIST_INSERT_HEAD(&route_cb.rcb, rop, rcb_list); soisconnected(so); so->so_options |= SO_USELOOPBACK; - return (error); + return (0); } int @@ -359,7 +368,8 @@ route_input(struct mbuf *m0, struct sock return; } - LIST_FOREACH(rp, &rawcb, rcb_list) { + LIST_FOREACH(rop, &route_cb.rcb, rcb_list) { + rp = &rop->rcb; if (rp->rcb_socket->so_state & SS_CANTRCVMORE) continue; if (rp->rcb_proto.sp_family != PF_ROUTE) @@ -393,7 +403,6 @@ route_input(struct mbuf *m0, struct sock 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 && @@ -1781,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 } };