-/* $OpenBSD: udp_usrreq.c,v 1.199 2015/05/23 12:38:53 markus Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.200 2015/06/05 21:41:43 krw Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
+#include <sys/domain.h>
#include <net/if.h>
#include <net/if_var.h>
struct udpstat udpstat;
int udp_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *);
-void udp_detach(struct inpcb *);
void udp_notify(struct inpcb *, int);
#ifndef UDB_INITIAL_HASH_SIZE
udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
struct mbuf *control, struct proc *p)
{
- struct inpcb *inp = sotoinpcb(so);
+ struct inpcb *inp;
int error = 0;
int s;
if (req == PRU_CONTROL) {
#ifdef INET6
- if (inp->inp_flags & INP_IPV6)
+ if (sotopf(so) == PF_INET6)
return (in6_control(so, (u_long)m, (caddr_t)addr,
(struct ifnet *)control));
else
return (in_control(so, (u_long)m, (caddr_t)addr,
(struct ifnet *)control));
}
+
+ s = splsoftnet();
+ inp = sotoinpcb(so);
if (inp == NULL && req != PRU_ATTACH) {
error = EINVAL;
goto release;
}
+
/*
* Note: need to block udp_input while changing
* the udp pcb queue and/or pcb addresses.
error = EINVAL;
break;
}
- s = splsoftnet();
if ((error = soreserve(so, udp_sendspace, udp_recvspace)) ||
- (error = in_pcballoc(so, &udbtable))) {
- splx(s);
+ (error = in_pcballoc(so, &udbtable)))
break;
- }
- splx(s);
#ifdef INET6
if (sotoinpcb(so)->inp_flags & INP_IPV6)
sotoinpcb(so)->inp_ipv6.ip6_hlim = ip6_defhlim;
break;
case PRU_DETACH:
- udp_detach(inp);
+ in_pcbdetach(inp);
break;
case PRU_BIND:
- s = splsoftnet();
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
error = in6_pcbbind(inp, addr, p);
else
#endif
error = in_pcbbind(inp, addr, p);
- splx(s);
break;
case PRU_LISTEN:
error = EISCONN;
break;
}
- s = splsoftnet();
error = in6_pcbconnect(inp, addr);
- splx(s);
} else
#endif /* INET6 */
{
error = EISCONN;
break;
}
- s = splsoftnet();
error = in_pcbconnect(inp, addr);
- splx(s);
}
if (error == 0)
}
}
- s = splsoftnet();
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
inp->inp_laddr6 = in6addr_any;
inp->inp_laddr.s_addr = INADDR_ANY;
in_pcbdisconnect(inp);
- splx(s);
so->so_state &= ~SS_ISCONNECTED; /* XXX */
break;
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
- return (udp6_output(inp, m, addr, control));
+ error = udp6_output(inp, m, addr, control);
else
- return (udp_output(inp, m, addr, control));
-#else
- return (udp_output(inp, m, addr, control));
#endif
+ error = udp_output(inp, m, addr, control);
+ splx(s);
+ return (error);
case PRU_ABORT:
soisdisconnected(so);
- udp_detach(inp);
+ in_pcbdetach(inp);
break;
case PRU_SOCKADDR:
* Perhaps Path MTU might be returned for a connected
* UDP socket in this case.
*/
+ splx(s);
return (0);
case PRU_SENDOOB:
case PRU_RCVD:
case PRU_RCVOOB:
+ splx(s);
return (EOPNOTSUPP); /* do not free mbuf's */
default:
}
release:
+ splx(s);
if (control) {
m_freem(control);
}
return (error);
}
-void
-udp_detach(struct inpcb *inp)
-{
- int s = splsoftnet();
-
- in_pcbdetach(inp);
- splx(s);
-}
-
/*
* Sysctl for udp variables.
*/