diff options
author | rrs <rrs@FreeBSD.org> | 2009-01-06 12:13:40 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2009-01-06 12:13:40 +0000 |
commit | 8bff422255e003d595b727bcf2832648dfad012a (patch) | |
tree | cad2ca9862c1a23be9a4b0173dc9c2fc8924165a /sys/netinet6/udp6_usrreq.c | |
parent | df83de35ebaea44832c83fe1de66ab651752d270 (diff) | |
download | FreeBSD-src-8bff422255e003d595b727bcf2832648dfad012a.zip FreeBSD-src-8bff422255e003d595b727bcf2832648dfad012a.tar.gz |
Add the ability of an alternate transport protocol
to easily tunnel over udp by providing a hook
function that will be called instead of appending
to the socket buffer.
Diffstat (limited to 'sys/netinet6/udp6_usrreq.c')
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index f1634cb..ed75759 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -287,8 +287,25 @@ udp6_input(struct mbuf **mp, int *offp, int proto) if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { INP_RLOCK(last); - udp6_append(last, n, off, &fromsa); - INP_RUNLOCK(last); + if (last->inp_ppcb != NULL) { + /* + * Engage the tunneling + * protocol we will have to + * leave the info_lock up, + * since we are hunting + * through multiple UDP + * inp's hope we don't break. + * + */ + 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); + } } } last = inp; @@ -317,6 +334,19 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } INP_RLOCK(last); INP_INFO_RUNLOCK(&V_udbinfo); + if (last->inp_ppcb != NULL) { + /* + * Engage the tunneling protocol we must make sure + * all locks are released when we call 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); + } udp6_append(last, m, off, &fromsa); INP_RUNLOCK(last); return (IPPROTO_DONE); @@ -354,6 +384,18 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } INP_RLOCK(inp); INP_INFO_RUNLOCK(&V_udbinfo); + if (inp->inp_ppcb != NULL) { + /* + * Engage the tunneling protocol we must make sure all locks + * are released when we call 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); + } udp6_append(inp, m, off, &fromsa); INP_RUNLOCK(inp); return (IPPROTO_DONE); |