summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/udp6_usrreq.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2009-01-06 12:13:40 +0000
committerrrs <rrs@FreeBSD.org>2009-01-06 12:13:40 +0000
commit8bff422255e003d595b727bcf2832648dfad012a (patch)
treecad2ca9862c1a23be9a4b0173dc9c2fc8924165a /sys/netinet6/udp6_usrreq.c
parentdf83de35ebaea44832c83fe1de66ab651752d270 (diff)
downloadFreeBSD-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.c46
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);
OpenPOWER on IntegriCloud