summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/udp6_usrreq.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2009-05-23 16:51:13 +0000
committerbz <bz@FreeBSD.org>2009-05-23 16:51:13 +0000
commit7b0a0ba0e1bd6190ed9dbd7f1bae0326022164d8 (patch)
treefbcc30d291acdaa8951271fc6757c5e7b17f5bb0 /sys/netinet6/udp6_usrreq.c
parent9642ff6e283a56096187f128604a36cf5e445825 (diff)
downloadFreeBSD-src-7b0a0ba0e1bd6190ed9dbd7f1bae0326022164d8.zip
FreeBSD-src-7b0a0ba0e1bd6190ed9dbd7f1bae0326022164d8.tar.gz
Implement UDP control block support.
So far the udp_tun_func_t had been (ab)using inp_ppcb for udp in kernel tunneling callbacks. Move that into the udpcb and add a field for flags there to be used by upcoming changes instead of sticking udp only flags into in_pcb flags2. Bump __FreeBSD_version for ports to detect it and because of vnet* struct size changes. Submitted by: jhb (7.x version) Reviewed by: rwatson
Diffstat (limited to 'sys/netinet6/udp6_usrreq.c')
-rw-r--r--sys/netinet6/udp6_usrreq.c55
1 files changed, 30 insertions, 25 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 19cca2c..11dcf24 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -181,6 +181,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
struct ip6_hdr *ip6;
struct udphdr *uh;
struct inpcb *inp;
+ struct udpcb *up;
int off = *offp;
int plen, ulen;
struct sockaddr_in6 fromsa;
@@ -315,7 +316,10 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
INP_RLOCK(last);
- if (last->inp_ppcb != NULL) {
+ up = intoudpcb(last);
+ if (up->u_tun_func == NULL) {
+ udp6_append(last, n, off, &fromsa);
+ } else {
/*
* Engage the tunneling
* protocol we will have to
@@ -324,15 +328,9 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
* through multiple UDP's.
*
*/
- udp_tun_func_t tunnel_func;
-
- tunnel_func = (udp_tun_func_t)last->inp_ppcb;
- tunnel_func(n, off, last);
- INP_RUNLOCK(last);
- } else {
- udp6_append(last, n, off, &fromsa);
- INP_RUNLOCK(last);
+ (*up->u_tun_func)(n, off, last);
}
+ INP_RUNLOCK(last);
}
}
last = inp;
@@ -361,18 +359,15 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
}
INP_RLOCK(last);
INP_INFO_RUNLOCK(&V_udbinfo);
- if (last->inp_ppcb != NULL) {
+ up = intoudpcb(last);
+ if (up->u_tun_func == NULL) {
+ udp6_append(last, m, off, &fromsa);
+ } else {
/*
* Engage the tunneling protocol.
*/
- udp_tun_func_t tunnel_func;
-
- tunnel_func = (udp_tun_func_t)inp->inp_ppcb;
- tunnel_func(m, off, last);
- INP_RUNLOCK(last);
- return (IPPROTO_DONE);
+ (*up->u_tun_func)(m, off, last);
}
- udp6_append(last, m, off, &fromsa);
INP_RUNLOCK(last);
return (IPPROTO_DONE);
}
@@ -409,18 +404,16 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
}
INP_RLOCK(inp);
INP_INFO_RUNLOCK(&V_udbinfo);
- if (inp->inp_ppcb != NULL) {
+ up = intoudpcb(inp);
+ if (up->u_tun_func == NULL) {
+ udp6_append(inp, m, off, &fromsa);
+ } else {
/*
* Engage the tunneling protocol.
*/
- udp_tun_func_t tunnel_func;
- tunnel_func = (udp_tun_func_t)inp->inp_ppcb;
- tunnel_func(m, off, inp);
- INP_RUNLOCK(inp);
- return (IPPROTO_DONE);
+ (*up->u_tun_func)(m, off, inp);
}
- udp6_append(inp, m, off, &fromsa);
INP_RUNLOCK(inp);
return (IPPROTO_DONE);
@@ -820,7 +813,6 @@ udp6_attach(struct socket *so, int proto, struct thread *td)
return (error);
}
inp = (struct inpcb *)so->so_pcb;
- INP_INFO_WUNLOCK(&V_udbinfo);
inp->inp_vflag |= INP_IPV6;
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
inp->inp_vflag |= INP_IPV4;
@@ -833,7 +825,16 @@ udp6_attach(struct socket *so, int proto, struct thread *td)
* which may match an IPv4-mapped IPv6 address.
*/
inp->inp_ip_ttl = V_ip_defttl;
+
+ error = udp_newudpcb(inp);
+ if (error) {
+ in_pcbdetach(inp);
+ in_pcbfree(inp);
+ INP_INFO_WUNLOCK(&V_udbinfo);
+ return (error);
+ }
INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_udbinfo);
return (0);
}
@@ -968,15 +969,19 @@ udp6_detach(struct socket *so)
{
INIT_VNET_INET(so->so_vnet);
struct inpcb *inp;
+ struct udpcb *up;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_detach: inp == NULL"));
INP_INFO_WLOCK(&V_udbinfo);
INP_WLOCK(inp);
+ up = intoudpcb(inp);
+ KASSERT(up != NULL, ("%s: up == NULL", __func__));
in_pcbdetach(inp);
in_pcbfree(inp);
INP_INFO_WUNLOCK(&V_udbinfo);
+ udp_discardcb(up);
}
static int
OpenPOWER on IntegriCloud