On Mon, Jul 09, 2018 at 01:19:52PM +0200, Claudio Jeker wrote:
> raw_usrreq() is just unneeded abstraction. It is easier to just handle
> all the PRU cases in route_usrreq() instead. Simplifies a few things
> and will hopefully make further MP work easier.
>
> This is a mix of raw_usrreq() and uipc_usrreq() (I think that raw_usrreq
> is leaking mbufs in some cases). route regress, bgpd and route(8) are
> happy with this.
> --
> :wq Claudio
OK bluhm@
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.276
> diff -u -p -r1.276 rtsock.c
> --- net/rtsock.c 5 Jul 2018 21:48:32 -0000 1.276
> +++ net/rtsock.c 9 Jul 2018 10:52:18 -0000
> @@ -136,11 +136,7 @@ int sysctl_ifnames(struct walkarg *);
> int sysctl_rtable_rtstat(void *, size_t *, void *);
>
> struct rtpcb {
> - struct rawcb rop_rcb;
> -#define rop_socket rop_rcb.rcb_socket
> -#define rop_faddr rop_rcb.rcb_faddr
> -#define rop_laddr rop_rcb.rcb_laddr
> -#define rop_proto rop_rcb.rcb_proto
> + struct socket *rop_socket;
>
> SRPL_ENTRY(rtpcb) rop_list;
> struct refcnt rop_refcnt;
> @@ -148,6 +144,7 @@ struct rtpcb {
> unsigned int rop_msgfilter;
> unsigned int rop_flags;
> u_int rop_rtableid;
> + unsigned short rop_proto;
> u_char rop_priority;
> };
> #define sotortpcb(so) ((struct rtpcb *)(so)->so_pcb)
> @@ -203,15 +200,54 @@ route_usrreq(struct socket *so, int req,
> struct rtpcb *rop;
> int error = 0;
>
> + if (req == PRU_CONTROL)
> + return (EOPNOTSUPP);
> +
> soassertlocked(so);
>
> + if (control && control->m_len) {
> + error = EOPNOTSUPP;
> + goto release;
> + }
> +
> rop = sotortpcb(so);
> if (rop == NULL) {
> - m_freem(m);
> - return (EINVAL);
> + error = EINVAL;
> + goto release;
> }
>
> switch (req) {
> + /* no connect, bind, accept. Socket is connected from the start */
> + case PRU_CONNECT:
> + case PRU_BIND:
> + case PRU_CONNECT2:
> + case PRU_LISTEN:
> + case PRU_ACCEPT:
> + error = EOPNOTSUPP;
> + break;
> +
> + case PRU_DISCONNECT:
> + case PRU_ABORT:
> + soisdisconnected(so);
> + break;
> + case PRU_SHUTDOWN:
> + socantsendmore(so);
> + break;
> + case PRU_SENSE:
> + /* stat: don't bother with a blocksize. */
> + return (0);
> +
> + /* minimal support, just implement a fake peer address */
> + case PRU_SOCKADDR:
> + error = EINVAL;
> + break;
> + case PRU_PEERADDR:
> + bcopy(&route_src, mtod(nam, caddr_t), route_src.sa_len);
> + nam->m_len = route_src.sa_len;
> + break;
> +
> + case PRU_RCVOOB:
> + return (EOPNOTSUPP);
> case PRU_RCVD:
> /*
> * If we are in a FLUSH state, check if the buffer is
> @@ -221,12 +257,26 @@ route_usrreq(struct socket *so, int req,
> ((sbspace(rop->rop_socket, &rop->rop_socket->so_rcv) ==
> rop->rop_socket->so_rcv.sb_hiwat)))
> rop->rop_flags &= ~ROUTECB_FLAG_FLUSH;
> - break;
> + return (0);
>
> + case PRU_SENDOOB:
> + error = EOPNOTSUPP;
> + break;
> + case PRU_SEND:
> + if (nam) {
> + error = EISCONN;
> + break;
> + }
> + error = (*so->so_proto->pr_output)(m, so, NULL, NULL);
> + m = NULL;
> + break;
> default:
> - error = raw_usrreq(so, req, m, nam, control, p);
> + panic("route_usrreq");
> }
>
> + release:
> + m_freem(control);
> + m_freem(m);
> return (error);
> }
>
> @@ -257,16 +307,13 @@ route_attach(struct socket *so, int prot
> }
>
> rop->rop_socket = so;
> - rop->rop_proto.sp_family = so->so_proto->pr_domain->dom_family;
> - rop->rop_proto.sp_protocol = proto;
> + rop->rop_proto = proto;
>
> rop->rop_rtableid = curproc->p_p->ps_rtableid;
>
> soisconnected(so);
> so->so_options |= SO_USELOOPBACK;
>
> - rop->rop_faddr = &route_src;
> -
> rw_enter(&rtptable.rtp_lk, RW_WRITE);
> SRPL_INSERT_HEAD_LOCKED(&rtptable.rtp_rc, &rtptable.rtp_list, rop,
> rop_list);
> rtptable.rtp_count++;
> @@ -438,9 +485,8 @@ route_input(struct mbuf *m0, struct sock
> * messages that match the address family. Address family
> * agnostic messages are always sent.
> */
> - if (sa_family != AF_UNSPEC &&
> - rop->rop_proto.sp_protocol != AF_UNSPEC &&
> - rop->rop_proto.sp_protocol != sa_family)
> + if (sa_family != AF_UNSPEC && rop->rop_proto != AF_UNSPEC &&
> + rop->rop_proto != sa_family)
> continue;
>
>