Attaching a PCB to a socket is currently done via PRU_ATTACH but in most
cases this does not need the network / socket lock since no packets can be
received or sent over this socket (needs a bind or connect first)
It also cleans up a few other ugly things like how the proto is passed.
This diff works for me but I did not test each and every protocol (TCP,
UDP, ICMP, AF_UNIX work).
Also not sure if I should renumber the PRU_* defines... in a way this can
be solved in a second step.
--
:wq Claudio
Index: kern/uipc_proto.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_proto.c,v
retrieving revision 1.12
diff -u -p -r1.12 uipc_proto.c
--- kern/uipc_proto.c 22 Feb 2017 19:34:42 -0000 1.12
+++ kern/uipc_proto.c 26 Feb 2017 08:06:34 -0000
@@ -55,6 +55,7 @@ struct protosw unixsw[] = {
.pr_protocol = PF_LOCAL,
.pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
.pr_usrreq = uipc_usrreq,
+ .pr_attach = uipc_attach,
},
{
.pr_type = SOCK_SEQPACKET,
@@ -62,6 +63,7 @@ struct protosw unixsw[] = {
.pr_protocol = PF_LOCAL,
.pr_flags = PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
.pr_usrreq = uipc_usrreq,
+ .pr_attach = uipc_attach,
},
{
.pr_type = SOCK_DGRAM,
@@ -69,6 +71,7 @@ struct protosw unixsw[] = {
.pr_protocol = PF_LOCAL,
.pr_flags = PR_ATOMIC|PR_ADDR|PR_RIGHTS,
.pr_usrreq = uipc_usrreq,
+ .pr_attach = uipc_attach,
}
};
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.177
diff -u -p -r1.177 uipc_socket.c
--- kern/uipc_socket.c 14 Feb 2017 09:46:21 -0000 1.177
+++ kern/uipc_socket.c 26 Feb 2017 08:07:15 -0000
@@ -135,9 +135,9 @@ socreate(int dom, struct socket **aso, i
so->so_egid = p->p_ucred->cr_gid;
so->so_cpid = p->p_p->ps_pid;
so->so_proto = prp;
+
s = solock(so);
- error = (*prp->pr_usrreq)(so, PRU_ATTACH, NULL,
- (struct mbuf *)(long)proto, NULL, p);
+ error = (*prp->pr_attach)(so, proto);
if (error) {
so->so_state |= SS_NOFDREF;
sofree(so);
Index: kern/uipc_socket2.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.72
diff -u -p -r1.72 uipc_socket2.c
--- kern/uipc_socket2.c 14 Feb 2017 09:46:21 -0000 1.72
+++ kern/uipc_socket2.c 25 Feb 2017 18:51:02 -0000
@@ -187,8 +187,7 @@ sonewconn(struct socket *head, int conns
so->so_rcv.sb_timeo = head->so_rcv.sb_timeo;
soqinsque(head, so, soqueue);
- if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, NULL, NULL, NULL,
- curproc)) {
+ if ((*so->so_proto->pr_attach)(so, 0)) {
(void) soqremque(so, soqueue);
pool_put(&socket_pool, so);
return (NULL);
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.116
diff -u -p -r1.116 uipc_usrreq.c
--- kern/uipc_usrreq.c 14 Feb 2017 09:46:21 -0000 1.116
+++ kern/uipc_usrreq.c 26 Feb 2017 08:03:29 -0000
@@ -117,7 +117,7 @@ uipc_usrreq(struct socket *so, int req,
error = EOPNOTSUPP;
goto release;
}
- if (unp == NULL && req != PRU_ATTACH) {
+ if (unp == NULL) {
error = EINVAL;
goto release;
}
@@ -126,14 +126,6 @@ uipc_usrreq(struct socket *so, int req,
switch (req) {
- case PRU_ATTACH:
- if (unp) {
- error = EISCONN;
- break;
- }
- error = unp_attach(so);
- break;
-
case PRU_DETACH:
unp_detach(unp);
break;
@@ -351,11 +343,13 @@ u_long unpdg_recvspace = 4*1024;
int unp_rights; /* file descriptors in flight */
int
-unp_attach(struct socket *so)
+uipc_attach(struct socket *so, int proto)
{
struct unpcb *unp;
int error;
+ if (so->so_pcb)
+ return EISCONN;
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
switch (so->so_type) {
Index: net/pfkey.c
===================================================================
RCS file: /cvs/src/sys/net/pfkey.c,v
retrieving revision 1.37
diff -u -p -r1.37 pfkey.c
--- net/pfkey.c 22 Feb 2017 19:34:42 -0000 1.37
+++ net/pfkey.c 26 Feb 2017 08:29:12 -0000
@@ -188,31 +188,34 @@ ret:
return (error);
}
-static int
-pfkey_attach(struct socket *socket, struct mbuf *proto, struct proc *p)
+int
+pfkey_attach(struct socket *so, int proto)
{
int rval;
- if (!(socket->so_pcb = malloc(sizeof(struct rawcb),
+ 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);
- rval = raw_usrreq(socket, PRU_ATTACH, NULL, proto, NULL, p);
+ rval = raw_attach(so, proto);
if (rval)
goto ret;
- ((struct rawcb *)socket->so_pcb)->rcb_faddr = &pfkey_addr;
- soisconnected(socket);
+ ((struct rawcb *)so->so_pcb)->rcb_faddr = &pfkey_addr;
+ soisconnected(so);
- socket->so_options |= SO_USELOOPBACK;
+ so->so_options |= SO_USELOOPBACK;
if ((rval =
- pfkey_versions[socket->so_proto->pr_protocol]->create(socket)) != 0)
+ pfkey_versions[so->so_proto->pr_protocol]->create(so)) != 0)
goto ret;
return (0);
ret:
- free(socket->so_pcb, M_PCB, sizeof(struct rawcb));
+ free(so->so_pcb, M_PCB, sizeof(struct rawcb));
return (rval);
}
@@ -242,9 +245,6 @@ pfkey_usrreq(struct socket *socket, int
return (EPROTONOSUPPORT);
switch (req) {
- case PRU_ATTACH:
- return (pfkey_attach(socket, nam, p));
-
case PRU_DETACH:
return (pfkey_detach(socket, p));
@@ -271,7 +271,8 @@ static struct protosw pfkey_protosw_temp
.pr_protocol = -1,
.pr_flags = PR_ATOMIC | PR_ADDR,
.pr_output = (void *) pfkey_output,
- .pr_usrreq = pfkey_usrreq
+ .pr_usrreq = pfkey_usrreq,
+ .pr_attach = pfkey_attach,
};
int
Index: net/raw_usrreq.c
===================================================================
RCS file: /cvs/src/sys/net/raw_usrreq.c,v
retrieving revision 1.28
diff -u -p -r1.28 raw_usrreq.c
--- net/raw_usrreq.c 23 Jan 2017 16:31:24 -0000 1.28
+++ net/raw_usrreq.c 25 Jan 2017 23:01:28 -0000
@@ -76,20 +76,6 @@ raw_usrreq(struct socket *so, int req, s
return (EINVAL);
}
switch (req) {
-
- /*
- * Allocate a raw control block and fill in the
- * necessary info to allow packets to be routed to
- * the appropriate raw interface routine.
- */
- case PRU_ATTACH:
- if ((so->so_state & SS_PRIV) == 0) {
- error = EACCES;
- break;
- }
- error = raw_attach(so, (int)(long)nam);
- break;
-
/*
* Destroy state just before socket deallocation.
* Flush data or not depending on the options.
Index: net/rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.223
diff -u -p -r1.223 rtsock.c
--- net/rtsock.c 22 Feb 2017 19:34:42 -0000 1.223
+++ net/rtsock.c 26 Feb 2017 08:09:30 -0000
@@ -157,46 +157,6 @@ route_usrreq(struct socket *so, int req,
rp = sotorawcb(so);
switch (req) {
- case PRU_ATTACH:
- /*
- * use the rawcb but allocate a routecb, this
- * code does not care about the additional fields
- * and works directly on the raw socket.
- */
- rop = malloc(sizeof(struct routecb), M_PCB, M_WAITOK|M_ZERO);
- rp = &rop->rcb;
- so->so_pcb = rp;
- /* Init the timeout structure */
- timeout_set(&((struct routecb *)rp)->timeout, rt_senddesync,
rp);
- /*
- * Don't call raw_usrreq() in the attach case, because
- * we want to allow non-privileged processes to listen
- * on and send "safe" commands to the routing socket.
- */
- if (curproc == 0)
- error = EACCES;
- else
- error = raw_attach(so, (int)(long)nam);
- if (error) {
- free(rop, M_PCB, sizeof(struct routecb));
- return (error);
- }
- rop->rtableid = curproc->p_p->ps_rtableid;
- af = rp->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++;
-#endif
- rp->rcb_faddr = &route_src;
- route_cb.any_count++;
- soisconnected(so);
- so->so_options |= SO_USELOOPBACK;
- break;
-
case PRU_RCVD:
rop = (struct routecb *)rp;
@@ -233,6 +193,59 @@ route_usrreq(struct socket *so, int req,
}
int
+route_attach(struct socket *so, int proto)
+{
+ struct rawcb *rp;
+ struct routecb *rop;
+ int af;
+ int error = 0;
+
+ NET_ASSERT_LOCKED();
+
+ rp = sotorawcb(so);
+
+ /*
+ * use the rawcb but allocate a routecb, this
+ * code does not care about the additional fields
+ * and works directly on the raw socket.
+ */
+ rop = malloc(sizeof(struct routecb), M_PCB, M_WAITOK|M_ZERO);
+ rp = &rop->rcb;
+ so->so_pcb = rp;
+ /* Init the timeout structure */
+ timeout_set(&((struct routecb *)rp)->timeout, rt_senddesync, rp);
+ /*
+ * Don't call raw_usrreq() in the attach case, because
+ * we want to allow non-privileged processes to listen
+ * on and send "safe" commands to the routing socket.
+ */
+ if (curproc == 0)
+ error = EACCES;
+ else
+ error = raw_attach(so, proto);
+ if (error) {
+ free(rop, M_PCB, sizeof(struct routecb));
+ return (error);
+ }
+ rop->rtableid = curproc->p_p->ps_rtableid;
+ af = rp->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++;
+#endif
+ rp->rcb_faddr = &route_src;
+ route_cb.any_count++;
+ soisconnected(so);
+ so->so_options |= SO_USELOOPBACK;
+
+ return (error);
+}
+
+int
route_ctloutput(int op, struct socket *so, int level, int optname,
struct mbuf *m)
{
@@ -1661,6 +1674,7 @@ struct protosw routesw[] = {
.pr_output = route_output,
.pr_ctloutput = route_ctloutput,
.pr_usrreq = route_usrreq,
+ .pr_attach = route_attach,
.pr_init = raw_init,
.pr_sysctl = sysctl_rtable
}
Index: netinet/in_proto.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_proto.c,v
retrieving revision 1.73
diff -u -p -r1.73 in_proto.c
--- netinet/in_proto.c 22 Feb 2017 19:34:42 -0000 1.73
+++ netinet/in_proto.c 26 Feb 2017 08:28:06 -0000
@@ -191,6 +191,7 @@ struct protosw inetsw[] = {
.pr_ctlinput = udp_ctlinput,
.pr_ctloutput = ip_ctloutput,
.pr_usrreq = udp_usrreq,
+ .pr_attach = udp_attach,
.pr_init = udp_init,
.pr_sysctl = udp_sysctl
},
@@ -203,6 +204,7 @@ struct protosw inetsw[] = {
.pr_ctlinput = tcp_ctlinput,
.pr_ctloutput = tcp_ctloutput,
.pr_usrreq = tcp_usrreq,
+ .pr_attach = tcp_attach,
.pr_init = tcp_init,
.pr_slowtimo = tcp_slowtimo,
.pr_sysctl = tcp_sysctl
@@ -215,7 +217,8 @@ struct protosw inetsw[] = {
.pr_input = rip_input,
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
- .pr_usrreq = rip_usrreq
+ .pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach
},
{
.pr_type = SOCK_RAW,
@@ -226,6 +229,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_init = icmp_init,
.pr_sysctl = icmp_sysctl
},
@@ -239,6 +243,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = ipip_sysctl
},
{
@@ -250,6 +255,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = etherip_sysctl
},
#ifdef INET6
@@ -260,7 +266,8 @@ struct protosw inetsw[] = {
.pr_flags = PR_ATOMIC|PR_ADDR,
.pr_input = in_gif_input,
.pr_output = rip_output,
- .pr_usrreq = rip_usrreq /* XXX */
+ .pr_usrreq = rip_usrreq, /* XXX */
+ .pr_attach = rip_attach
},
#endif
#ifdef MPLS
@@ -271,7 +278,8 @@ struct protosw inetsw[] = {
.pr_flags = PR_ATOMIC|PR_ADDR,
.pr_input = etherip_input,
.pr_output = rip_output,
- .pr_usrreq = rip_usrreq
+ .pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach
},
#endif
#else /* NGIF */
@@ -284,6 +292,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = ipip_sysctl
},
#ifdef INET6
@@ -295,7 +304,8 @@ struct protosw inetsw[] = {
.pr_input = ip4_input,
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
- .pr_usrreq = rip_usrreq /* XXX */
+ .pr_usrreq = rip_usrreq, /* XXX */
+ .pr_attach = rip_attach
},
#endif
#endif /*NGIF*/
@@ -308,6 +318,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_init = igmp_init,
.pr_fasttimo = igmp_fasttimo,
.pr_slowtimo = igmp_slowtimo,
@@ -324,6 +335,7 @@ struct protosw inetsw[] = {
.pr_ctlinput = ah4_ctlinput,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = ah_sysctl
},
{
@@ -336,6 +348,7 @@ struct protosw inetsw[] = {
.pr_ctlinput = esp4_ctlinput,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = esp_sysctl
},
{
@@ -347,6 +360,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = ipcomp_sysctl
},
#endif /* IPSEC */
@@ -360,6 +374,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = gre_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = gre_sysctl
},
{
@@ -371,6 +386,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = ipmobile_sysctl
},
#endif /* NGRE > 0 */
@@ -384,6 +400,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = carp_sysctl
},
#endif /* NCARP > 0 */
@@ -397,6 +414,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = pfsync_sysctl
},
#endif /* NPFSYNC > 0 */
@@ -408,6 +426,7 @@ struct protosw inetsw[] = {
.pr_flags = PR_ATOMIC|PR_ADDR,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = divert_usrreq,
+ .pr_attach = divert_attach,
.pr_init = divert_init,
.pr_sysctl = divert_sysctl
},
@@ -422,6 +441,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_sysctl = ip_etherip_sysctl
},
#endif /* NETHERIP */
@@ -434,6 +454,7 @@ struct protosw inetsw[] = {
.pr_output = rip_output,
.pr_ctloutput = rip_ctloutput,
.pr_usrreq = rip_usrreq,
+ .pr_attach = rip_attach,
.pr_init = rip_init
}
};
Index: netinet/ip_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.44
diff -u -p -r1.44 ip_divert.c
--- netinet/ip_divert.c 9 Feb 2017 15:32:56 -0000 1.44
+++ netinet/ip_divert.c 26 Feb 2017 08:10:15 -0000
@@ -249,31 +249,12 @@ divert_usrreq(struct socket *so, int req
return (in_control(so, (u_long)m, (caddr_t)addr,
(struct ifnet *)control));
}
- if (inp == NULL && req != PRU_ATTACH) {
+ if (inp == NULL) {
error = EINVAL;
goto release;
}
switch (req) {
- case PRU_ATTACH:
- if (inp != NULL) {
- error = EINVAL;
- break;
- }
- if ((so->so_state & SS_PRIV) == 0) {
- error = EACCES;
- break;
- }
- error = in_pcballoc(so, &divbtable);
- if (error)
- break;
-
- error = soreserve(so, divert_sendspace, divert_recvspace);
- if (error)
- break;
- sotoinpcb(so)->inp_flags |= INP_HDRINCL;
- break;
-
case PRU_DETACH:
in_pcbdetach(inp);
break;
@@ -330,6 +311,28 @@ release:
m_freem(control);
m_freem(m);
return (error);
+}
+
+int
+divert_attach(struct socket *so, int proto)
+{
+ int error;
+
+ if (so->so_pcb != NULL)
+ return EINVAL;
+ if ((so->so_state & SS_PRIV) == 0)
+ return EACCES;
+
+ error = in_pcballoc(so, &divbtable);
+ if (error)
+ return error;
+
+ error = soreserve(so, divert_sendspace, divert_recvspace);
+ if (error)
+ return error;
+
+ sotoinpcb(so)->inp_flags |= INP_HDRINCL;
+ return (0);
}
int
Index: netinet/ip_divert.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.h,v
retrieving revision 1.8
diff -u -p -r1.8 ip_divert.h
--- netinet/ip_divert.h 9 Feb 2017 15:32:56 -0000 1.8
+++ netinet/ip_divert.h 25 Feb 2017 18:51:02 -0000
@@ -78,6 +78,7 @@ int divert_packet(struct mbuf *, int, u
int divert_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int divert_usrreq(struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+int divert_attach(struct socket *, int);
#endif /* _KERNEL */
#endif /* _IP_DIVERT_H_ */
Index: netinet/ip_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_var.h,v
retrieving revision 1.68
diff -u -p -r1.68 ip_var.h
--- netinet/ip_var.h 1 Feb 2017 20:59:47 -0000 1.68
+++ netinet/ip_var.h 25 Feb 2017 18:51:02 -0000
@@ -256,6 +256,7 @@ int rip_input(struct mbuf **, int *, in
int rip_output(struct mbuf *, ...);
int rip_usrreq(struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+int rip_attach(struct socket *, int);
#endif /* _KERNEL */
#endif /* _NETINET_IP_VAR_H_ */
Index: netinet/raw_ip.c
===================================================================
RCS file: /cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.95
diff -u -p -r1.95 raw_ip.c
--- netinet/raw_ip.c 1 Feb 2017 20:59:47 -0000 1.95
+++ netinet/raw_ip.c 25 Feb 2017 18:51:02 -0000
@@ -410,32 +410,13 @@ rip_usrreq(struct socket *so, int req, s
return (in_control(so, (u_long)m, (caddr_t)nam,
(struct ifnet *)control));
- if (inp == NULL && req != PRU_ATTACH) {
+ if (inp == NULL) {
error = EINVAL;
goto release;
}
switch (req) {
- case PRU_ATTACH:
- if (inp)
- panic("rip_attach");
- if ((so->so_state & SS_PRIV) == 0) {
- error = EACCES;
- break;
- }
- if ((long)nam < 0 || (long)nam >= IPPROTO_MAX) {
- error = EPROTONOSUPPORT;
- break;
- }
- if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
- (error = in_pcballoc(so, &rawcbtable))) {
- break;
- }
- inp = sotoinpcb(so);
- inp->inp_ip.ip_p = (long)nam;
- break;
-
case PRU_DISCONNECT:
if ((so->so_state & SS_ISCONNECTED) == 0) {
error = ENOTCONN;
@@ -566,4 +547,26 @@ rip_usrreq(struct socket *so, int req, s
release:
m_freem(m);
return (error);
+}
+
+int
+rip_attach(struct socket *so, int proto)
+{
+ struct inpcb *inp;
+ int error;
+
+ if (so->so_pcb)
+ panic("rip_attach");
+ if ((so->so_state & SS_PRIV) == 0)
+ return EACCES;
+ if (proto < 0 || proto >= IPPROTO_MAX)
+ return EPROTONOSUPPORT;
+
+ if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
+ (error = in_pcballoc(so, &rawcbtable))) {
+ return error;
+ }
+ inp = sotoinpcb(so);
+ inp->inp_ip.ip_p = proto;
+ return 0;
}
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.144
diff -u -p -r1.144 tcp_usrreq.c
--- netinet/tcp_usrreq.c 9 Feb 2017 15:19:32 -0000 1.144
+++ netinet/tcp_usrreq.c 25 Feb 2017 18:51:02 -0000
@@ -157,7 +157,7 @@ tcp_usrreq(struct socket *so, int req, s
* a (struct inpcb) pointed at by the socket, and this
* structure will point at a subsidiary (struct tcpcb).
*/
- if (inp == NULL && req != PRU_ATTACH) {
+ if (inp == NULL) {
error = so->so_error;
if (error == 0)
error = EINVAL;
@@ -184,23 +184,6 @@ tcp_usrreq(struct socket *so, int req, s
switch (req) {
/*
- * TCP attaches to socket via PRU_ATTACH, reserving space,
- * and an internet control block.
- */
- case PRU_ATTACH:
- if (inp) {
- error = EISCONN;
- break;
- }
- error = tcp_attach(so);
- if (error)
- break;
- if ((so->so_options & SO_LINGER) && so->so_linger == 0)
- so->so_linger = TCP_LINGERTIME;
- tp = sototcpcb(so);
- break;
-
- /*
* PRU_DETACH detaches the TCP protocol from the socket.
* If the protocol state is non-embryonic, then can't
* do this directly: have to initiate a PRU_DISCONNECT,
@@ -608,12 +591,14 @@ tcp_ctloutput(int op, struct socket *so,
* bufer space, and entering LISTEN state if to accept connections.
*/
int
-tcp_attach(struct socket *so)
+tcp_attach(struct socket *so, int proto)
{
struct tcpcb *tp;
struct inpcb *inp;
int error;
+ if (so->so_pcb)
+ return EISCONN;
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0 ||
sbcheckreserve(so->so_snd.sb_wat, tcp_sendspace) ||
sbcheckreserve(so->so_rcv.sb_wat, tcp_recvspace)) {
@@ -645,6 +630,11 @@ tcp_attach(struct socket *so)
#else
tp->pf = PF_INET;
#endif
+ if ((so->so_options & SO_LINGER) && so->so_linger == 0)
+ so->so_linger = TCP_LINGERTIME;
+
+ if (tp && (so->so_options & SO_DEBUG))
+ tcp_trace(TA_USER, 0, tp, (caddr_t)0, 0 /* XXX */, 0);
return (0);
}
Index: netinet/tcp_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.122
diff -u -p -r1.122 tcp_var.h
--- netinet/tcp_var.h 9 Feb 2017 15:19:32 -0000 1.122
+++ netinet/tcp_var.h 25 Feb 2017 18:51:02 -0000
@@ -716,7 +716,6 @@ extern int tcp_syn_use_limit; /* numbe
extern struct syn_cache_set tcp_syn_cache[];
extern int tcp_syn_cache_active; /* active syn cache, may be 0 or 1 */
-int tcp_attach(struct socket *);
void tcp_canceltimers(struct tcpcb *);
struct tcpcb *
tcp_close(struct tcpcb *);
@@ -765,6 +764,7 @@ struct tcpcb *
int tcp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int tcp_usrreq(struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+int tcp_attach(struct socket *, int);
void tcp_xmit_timer(struct tcpcb *, int);
void tcpdropoldhalfopen(struct tcpcb *, u_int16_t);
#ifdef TCP_SACK
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.231
diff -u -p -r1.231 udp_usrreq.c
--- netinet/udp_usrreq.c 5 Feb 2017 16:23:38 -0000 1.231
+++ netinet/udp_usrreq.c 25 Feb 2017 18:51:02 -0000
@@ -1115,7 +1115,7 @@ udp_usrreq(struct socket *so, int req, s
}
inp = sotoinpcb(so);
- if (inp == NULL && req != PRU_ATTACH) {
+ if (inp == NULL) {
error = EINVAL;
goto release;
}
@@ -1126,22 +1126,6 @@ udp_usrreq(struct socket *so, int req, s
*/
switch (req) {
- case PRU_ATTACH:
- if (inp != NULL) {
- error = EINVAL;
- break;
- }
- if ((error = soreserve(so, udp_sendspace, udp_recvspace)) ||
- (error = in_pcballoc(so, &udbtable)))
- break;
-#ifdef INET6
- if (sotoinpcb(so)->inp_flags & INP_IPV6)
- sotoinpcb(so)->inp_ipv6.ip6_hlim = ip6_defhlim;
- else
-#endif /* INET6 */
- sotoinpcb(so)->inp_ip.ip_ttl = ip_defttl;
- break;
-
case PRU_DETACH:
in_pcbdetach(inp);
break;
@@ -1305,6 +1289,26 @@ release:
m_freem(control);
m_freem(m);
return (error);
+}
+
+int
+udp_attach(struct socket *so, int proto)
+{
+ int error;
+
+ if (so->so_pcb != NULL)
+ return EINVAL;
+
+ if ((error = soreserve(so, udp_sendspace, udp_recvspace)) ||
+ (error = in_pcballoc(so, &udbtable)))
+ return error;
+#ifdef INET6
+ if (sotoinpcb(so)->inp_flags & INP_IPV6)
+ sotoinpcb(so)->inp_ipv6.ip6_hlim = ip6_defhlim;
+ else
+#endif /* INET6 */
+ sotoinpcb(so)->inp_ip.ip_ttl = ip_defttl;
+ return 0;
}
/*
Index: netinet/udp_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/udp_var.h,v
retrieving revision 1.31
diff -u -p -r1.31 udp_var.h
--- netinet/udp_var.h 29 Jan 2017 19:58:47 -0000 1.31
+++ netinet/udp_var.h 25 Feb 2017 18:51:02 -0000
@@ -149,5 +149,6 @@ int udp6_output(struct inpcb *, struct
int udp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int udp_usrreq(struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+int udp_attach(struct socket *, int);
#endif /* _KERNEL */
#endif /* _NETINET_UDP_VAR_H_ */
Index: netinet6/in6_proto.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_proto.c,v
retrieving revision 1.89
diff -u -p -r1.89 in6_proto.c
--- netinet6/in6_proto.c 22 Feb 2017 19:34:42 -0000 1.89
+++ netinet6/in6_proto.c 26 Feb 2017 08:26:48 -0000
@@ -139,6 +139,7 @@ struct protosw inet6sw[] = {
.pr_ctlinput = udp6_ctlinput,
.pr_ctloutput = ip6_ctloutput,
.pr_usrreq = udp_usrreq,
+ .pr_attach = udp_attach,
.pr_sysctl = udp_sysctl
},
{
@@ -150,6 +151,7 @@ struct protosw inet6sw[] = {
.pr_ctlinput = tcp6_ctlinput,
.pr_ctloutput = tcp_ctloutput,
.pr_usrreq = tcp_usrreq,
+ .pr_attach = tcp_attach,
.pr_sysctl = tcp_sysctl
},
{
@@ -162,6 +164,7 @@ struct protosw inet6sw[] = {
.pr_ctlinput = rip6_ctlinput,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_sysctl = rip6_sysctl
},
{
@@ -174,6 +177,7 @@ struct protosw inet6sw[] = {
.pr_ctlinput = rip6_ctlinput,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_init = icmp6_init,
.pr_fasttimo = icmp6_fasttimo,
.pr_sysctl = icmp6_sysctl
@@ -209,6 +213,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_sysctl = ah_sysctl
},
{
@@ -220,6 +225,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_sysctl = esp_sysctl
},
{
@@ -231,6 +237,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_sysctl = ipcomp_sysctl
},
#endif /* IPSEC */
@@ -244,6 +251,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_sysctl = etherip_sysctl
},
{
@@ -254,7 +262,8 @@ struct protosw inet6sw[] = {
.pr_input = in6_gif_input,
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
- .pr_usrreq = rip6_usrreq /* XXX */
+ .pr_usrreq = rip6_usrreq, /* XXX */
+ .pr_attach = rip6_attach
},
{
.pr_type = SOCK_RAW,
@@ -264,7 +273,8 @@ struct protosw inet6sw[] = {
.pr_input = in6_gif_input,
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
- .pr_usrreq = rip6_usrreq /* XXX */
+ .pr_usrreq = rip6_usrreq, /* XXX */
+ .pr_attach = rip6_attach
},
#else /* NGIF */
{
@@ -276,6 +286,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq, /* XXX */
+ .pr_attach = rip6_attach,
.pr_sysctl = ipip_sysctl
},
{
@@ -286,7 +297,8 @@ struct protosw inet6sw[] = {
.pr_input = ip4_input,
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
- .pr_usrreq = rip6_usrreq /* XXX */
+ .pr_usrreq = rip6_usrreq, /* XXX */
+ .pr_attach = rip6_attach
},
#endif /* GIF */
#if NCARP > 0
@@ -299,6 +311,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_sysctl = carp_sysctl
},
#endif /* NCARP */
@@ -310,6 +323,7 @@ struct protosw inet6sw[] = {
.pr_flags = PR_ATOMIC|PR_ADDR,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = divert6_usrreq,
+ .pr_attach = divert6_attach,
.pr_init = divert6_init,
.pr_sysctl = divert6_sysctl
},
@@ -324,6 +338,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_sysctl = ip_etherip_sysctl
},
#endif /* NETHERIP */
@@ -336,6 +351,7 @@ struct protosw inet6sw[] = {
.pr_output = rip6_output,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreq = rip6_usrreq,
+ .pr_attach = rip6_attach,
.pr_init = rip6_init
}
};
Index: netinet6/ip6_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
retrieving revision 1.45
diff -u -p -r1.45 ip6_divert.c
--- netinet6/ip6_divert.c 9 Feb 2017 15:32:56 -0000 1.45
+++ netinet6/ip6_divert.c 26 Feb 2017 08:10:47 -0000
@@ -250,31 +250,12 @@ divert6_usrreq(struct socket *so, int re
return (in6_control(so, (u_long)m, (caddr_t)addr,
(struct ifnet *)control));
}
- if (inp == NULL && req != PRU_ATTACH) {
+ if (inp == NULL) {
error = EINVAL;
goto release;
}
switch (req) {
- case PRU_ATTACH:
- if (inp != NULL) {
- error = EINVAL;
- break;
- }
- if ((so->so_state & SS_PRIV) == 0) {
- error = EACCES;
- break;
- }
- error = in_pcballoc(so, &divb6table);
- if (error)
- break;
-
- error = soreserve(so, divert6_sendspace, divert6_recvspace);
- if (error)
- break;
- sotoinpcb(so)->inp_flags |= INP_HDRINCL;
- break;
-
case PRU_DETACH:
in_pcbdetach(inp);
break;
@@ -331,6 +312,28 @@ release:
m_freem(control);
m_freem(m);
return (error);
+}
+
+int
+divert6_attach(struct socket *so, int proto)
+{
+ int error;
+
+ if (so->so_pcb != NULL)
+ return EINVAL;
+
+ if ((so->so_state & SS_PRIV) == 0)
+ return EACCES;
+
+ error = in_pcballoc(so, &divb6table);
+ if (error)
+ return (error);
+
+ error = soreserve(so, divert6_sendspace, divert6_recvspace);
+ if (error)
+ return (error);
+ sotoinpcb(so)->inp_flags |= INP_HDRINCL;
+ return (0);
}
int
Index: netinet6/ip6_divert.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.h,v
retrieving revision 1.6
diff -u -p -r1.6 ip6_divert.h
--- netinet6/ip6_divert.h 9 Feb 2017 15:32:56 -0000 1.6
+++ netinet6/ip6_divert.h 25 Feb 2017 18:51:02 -0000
@@ -78,6 +78,7 @@ int divert6_packet(struct mbuf *, int,
int divert6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int divert6_usrreq(struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+int divert6_attach(struct socket *, int);
#endif /* _KERNEL */
#endif /* _IP6_DIVERT_H_ */
Index: netinet6/ip6_var.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_var.h,v
retrieving revision 1.68
diff -u -p -r1.68 ip6_var.h
--- netinet6/ip6_var.h 8 Feb 2017 12:37:43 -0000 1.68
+++ netinet6/ip6_var.h 25 Feb 2017 18:51:02 -0000
@@ -348,6 +348,7 @@ int rip6_ctloutput(int, struct socket *,
int rip6_output(struct mbuf *, ...);
int rip6_usrreq(struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+int rip6_attach(struct socket *, int);
int rip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int dest6_input(struct mbuf **, int *, int);
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.106
diff -u -p -r1.106 raw_ip6.c
--- netinet6/raw_ip6.c 9 Feb 2017 15:23:35 -0000 1.106
+++ netinet6/raw_ip6.c 26 Feb 2017 08:11:08 -0000
@@ -578,35 +578,6 @@ rip6_usrreq(struct socket *so, int req,
(struct ifnet *)control));
switch (req) {
- case PRU_ATTACH:
- if (in6p)
- panic("rip6_attach");
- if (!priv) {
- error = EACCES;
- break;
- }
- if ((long)nam < 0 || (long)nam >= IPPROTO_MAX) {
- error = EPROTONOSUPPORT;
- break;
- }
- if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)) ||
- (error = in_pcballoc(so, &rawin6pcbtable))) {
- break;
- }
- in6p = sotoinpcb(so);
- in6p->inp_ipv6.ip6_nxt = (long)nam;
- in6p->inp_cksum6 = -1;
-
- in6p->inp_icmp6filt = malloc(sizeof(struct icmp6_filter),
- M_PCB, M_NOWAIT);
- if (in6p->inp_icmp6filt == NULL) {
- in_pcbdetach(in6p);
- error = ENOMEM;
- break;
- }
- ICMP6_FILTER_SETPASSALL(in6p->inp_icmp6filt);
- break;
-
case PRU_DISCONNECT:
if ((so->so_state & SS_ISCONNECTED) == 0) {
error = ENOTCONN;
@@ -766,6 +737,37 @@ rip6_usrreq(struct socket *so, int req,
}
m_freem(m);
return (error);
+}
+
+int
+rip6_attach(struct socket *so, int proto)
+{
+ struct inpcb *in6p;
+ int error;
+
+ if (so->so_pcb)
+ panic("rip6_attach");
+ if ((so->so_state & SS_PRIV) == 0)
+ return (EACCES);
+ if (proto < 0 || proto >= IPPROTO_MAX)
+ return EPROTONOSUPPORT;
+
+ if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)) ||
+ (error = in_pcballoc(so, &rawin6pcbtable)))
+ return error;
+
+ in6p = sotoinpcb(so);
+ in6p->inp_ipv6.ip6_nxt = proto;
+ in6p->inp_cksum6 = -1;
+
+ in6p->inp_icmp6filt = malloc(sizeof(struct icmp6_filter),
+ M_PCB, M_NOWAIT);
+ if (in6p->inp_icmp6filt == NULL) {
+ in_pcbdetach(in6p);
+ return ENOMEM;
+ }
+ ICMP6_FILTER_SETPASSALL(in6p->inp_icmp6filt);
+ return 0;
}
int
Index: netmpls/mpls_proto.c
===================================================================
RCS file: /cvs/src/sys/netmpls/mpls_proto.c,v
retrieving revision 1.14
diff -u -p -r1.14 mpls_proto.c
--- netmpls/mpls_proto.c 3 Dec 2015 21:57:59 -0000 1.14
+++ netmpls/mpls_proto.c 26 Jan 2017 01:59:51 -0000
@@ -48,18 +48,18 @@
struct protosw mplssw[] = {
{ 0, &mplsdomain, 0, 0,
0, 0, 0, 0,
- 0,
+ 0, NULL,
mpls_init, 0, 0, 0, mpls_sysctl
},
{ SOCK_DGRAM, &mplsdomain, 0, PR_ATOMIC|PR_ADDR,
0, 0, 0, 0,
- mpls_raw_usrreq,
+ mpls_raw_usrreq, NULL,
0, 0, 0, 0, mpls_sysctl,
},
/* raw wildcard */
{ SOCK_RAW, &mplsdomain, 0, PR_ATOMIC|PR_ADDR,
0, 0, 0, 0,
- mpls_raw_usrreq,
+ mpls_raw_usrreq, NULL,
0, 0, 0, 0, mpls_sysctl,
},
};
Index: netmpls/mpls_raw.c
===================================================================
RCS file: /cvs/src/sys/netmpls/mpls_raw.c,v
retrieving revision 1.14
diff -u -p -r1.14 mpls_raw.c
--- netmpls/mpls_raw.c 15 Nov 2016 13:44:03 -0000 1.14
+++ netmpls/mpls_raw.c 26 Jan 2017 02:00:09 -0000
@@ -74,15 +74,6 @@ mpls_raw_usrreq(struct socket *so, int r
return (EOPNOTSUPP);
switch (req) {
- case PRU_ATTACH:
- if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
- error = soreserve(so, mpls_raw_sendspace,
- mpls_raw_recvspace);
- if (error)
- break;
- }
- break;
-
case PRU_DETACH:
case PRU_BIND:
case PRU_LISTEN:
Index: sys/protosw.h
===================================================================
RCS file: /cvs/src/sys/sys/protosw.h,v
retrieving revision 1.22
diff -u -p -r1.22 protosw.h
--- sys/protosw.h 1 Feb 2017 20:59:47 -0000 1.22
+++ sys/protosw.h 26 Feb 2017 09:49:58 -0000
@@ -82,6 +82,8 @@ struct protosw {
int (*pr_usrreq)(struct socket *, int, struct mbuf *,
struct mbuf *, struct mbuf *, struct proc *);
+ int (*pr_attach)(struct socket *, int);
+
/* utility hooks */
void (*pr_init)(void); /* initialization hook */
void (*pr_fasttimo)(void); /* fast timeout (200ms) */
@@ -120,7 +122,6 @@ struct protosw {
* A non-zero return from usrreq gives an
* UNIX error number which should be passed to higher level software.
*/
-#define PRU_ATTACH 0 /* attach protocol to up */
#define PRU_DETACH 1 /* detach protocol from up */
#define PRU_BIND 2 /* bind socket to address */
#define PRU_LISTEN 3 /* listen for connection */
@@ -148,7 +149,7 @@ struct protosw {
#ifdef PRUREQUESTS
char *prurequests[] = {
- "ATTACH", "DETACH", "BIND", "LISTEN",
+ "", "DETACH", "BIND", "LISTEN",
"CONNECT", "ACCEPT", "DISCONNECT", "SHUTDOWN",
"RCVD", "SEND", "ABORT", "CONTROL",
"SENSE", "RCVOOB", "SENDOOB", "SOCKADDR",
Index: sys/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
retrieving revision 1.68
diff -u -p -r1.68 socketvar.h
--- sys/socketvar.h 14 Feb 2017 09:46:21 -0000 1.68
+++ sys/socketvar.h 26 Feb 2017 08:05:05 -0000
@@ -258,8 +258,6 @@ int soo_poll(struct file *fp, int events
int soo_kqfilter(struct file *fp, struct knote *kn);
int soo_close(struct file *fp, struct proc *p);
int soo_stat(struct file *, struct stat *, struct proc *);
-int uipc_usrreq(struct socket *, int , struct mbuf *,
- struct mbuf *, struct mbuf *, struct proc *);
void sbappend(struct sockbuf *sb, struct mbuf *m);
void sbappendstream(struct sockbuf *sb, struct mbuf *m);
int sbappendaddr(struct sockbuf *sb, struct sockaddr *asa,
Index: sys/unpcb.h
===================================================================
RCS file: /cvs/src/sys/sys/unpcb.h,v
retrieving revision 1.14
diff -u -p -r1.14 unpcb.h
--- sys/unpcb.h 27 Jan 2017 20:31:42 -0000 1.14
+++ sys/unpcb.h 26 Feb 2017 08:05:45 -0000
@@ -91,7 +91,10 @@ struct fdpass {
int flags;
};
-int unp_attach(struct socket *);
+int uipc_usrreq(struct socket *, int , struct mbuf *,
+ struct mbuf *, struct mbuf *, struct proc *);
+int uipc_attach(struct socket *, int);
+
int unp_bind(struct unpcb *, struct mbuf *, struct proc *);
int unp_connect(struct socket *, struct mbuf *, struct proc *);
int unp_connect2(struct socket *, struct socket *);