Heads up --- Thinking about UDP and tunneling
Randall Stewart
rrs at lakerest.net
Fri Dec 12 05:46:32 PST 2008
Ok:
Here is an updated patch it:
1) Fixes style9 issues (I hope.. I went back to vi and tried
tabs :-0.. sigh one of
these doys I will figure out why my .emacs settings just never cut
it :-()
2) move to _t typedef
3) Allow multicast/broadcast to also be tunneled.
4) Binding is now no longer a requirement to set tunneling mode, in
fact most
protocols had better NOT have bound.. first set options, then
bind :-)
There was one thing I was a bit leary of for <3>. In the loop for
going through all the inp's of UDP that are listening to a m-cast/b-cast
I could not release the INP_INFO_LOCK() in other cases I make sure all
locks are released when we call into the tunneling protocol. I think
this
will be ok as long as the tunnelee does not try to use the
INP_INFO_LOCK of
the UDP world... I know for SCTP this is a non-issue.. but it may be
something
we want to think about... not sure.
If there are no serious objections I will submit this into head.. and
followed behind it
I will send in the changes so SCTP can be tunneled over this new
mechanism :-)
R
-------------- next part --------------
Index: netinet/udp_usrreq.c
===================================================================
--- netinet/udp_usrreq.c (revision 185928)
+++ netinet/udp_usrreq.c (working copy)
@@ -488,10 +488,25 @@
struct mbuf *n;
n = m_copy(m, 0, M_COPYALL);
- if (n != NULL)
- udp_append(last, ip, n, iphlen +
- sizeof(struct udphdr), &udp_in);
- INP_RUNLOCK(last);
+
+ if (last->inp_ppcb == NULL) {
+ if (n != NULL)
+ udp_append(last, ip, n, iphlen +
+ sizeof(struct udphdr), &udp_in);
+ INP_RUNLOCK(last);
+ } else {
+ /* 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_tunnel_function_t tunnel_func;
+
+ INP_RUNLOCK(last);
+ tunnel_func = (udp_tunnel_function_t)last->inp_ppcb;
+ INP_RUNLOCK(last);
+ tunnel_func(m, iphlen);
+ }
}
last = inp;
/*
@@ -516,10 +531,25 @@
V_udpstat.udps_noportbcast++;
goto badheadlocked;
}
- udp_append(last, ip, m, iphlen + sizeof(struct udphdr),
- &udp_in);
- INP_RUNLOCK(last);
- INP_INFO_RUNLOCK(&V_udbinfo);
+ if (last->inp_ppcb == NULL) {
+ udp_append(last, ip, m, iphlen + sizeof(struct udphdr),
+ &udp_in);
+ INP_RUNLOCK(last);
+ INP_INFO_RUNLOCK(&V_udbinfo);
+ } else {
+ /* Engage the tunneling protocol
+ * we must make sure all locks
+ * are released when we call the
+ * tunneling protocol.
+ */
+ udp_tunnel_function_t tunnel_func;
+
+ INP_RUNLOCK(last);
+ INP_INFO_RUNLOCK(&V_udbinfo);
+ tunnel_func = (udp_tunnel_function_t)last->inp_ppcb;
+ INP_RUNLOCK(last);
+ tunnel_func(m, iphlen);
+ }
return;
}
@@ -563,6 +593,18 @@
INP_RUNLOCK(inp);
goto badunlocked;
}
+ if (inp->inp_ppcb) {
+ /* Engage the tunneling protocol
+ * we must make sure all locks
+ * are released when we call the
+ * tunneling protocol.
+ */
+ udp_tunnel_function_t tunnel_func;
+ tunnel_func = (udp_tunnel_function_t)inp->inp_ppcb;
+ INP_RUNLOCK(inp);
+ tunnel_func(m, iphlen);
+ return;
+ }
udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in);
INP_RUNLOCK(inp);
return;
@@ -1138,10 +1180,41 @@
INP_INFO_WUNLOCK(&V_udbinfo);
inp->inp_vflag |= INP_IPV4;
inp->inp_ip_ttl = V_ip_defttl;
+ /*
+ * UDP does not have a per-protocol
+ * pcb (inp->inp_ppcb). We use this
+ * pointer for kernel tunneling pointer.
+ * If we ever need to have a protocol
+ * block we will need to move this
+ * function pointer there. Null
+ * in this pointer means "do the normal
+ * thing".
+ */
+ inp->inp_ppcb = NULL;
INP_WUNLOCK(inp);
return (0);
}
+int
+udp_set_kernel_tunneling(struct socket *so, udp_tunnel_function_t f)
+{
+ struct inpcb *inp;
+ inp = (struct inpcb *)so->so_pcb;
+
+ if (so->so_type != SOCK_DGRAM) {
+ /* Not UDP socket... sorry */
+ return (ENOTSUP);
+ }
+ if (inp == NULL) {
+ /* NULL INP? */
+ return (EINVAL);
+ }
+ INP_WLOCK(inp);
+ inp->inp_ppcb = f;
+ INP_WUNLOCK(inp);
+ return (0);
+}
+
static int
udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
Index: netinet/udp_var.h
===================================================================
--- netinet/udp_var.h (revision 185928)
+++ netinet/udp_var.h (working copy)
@@ -107,6 +107,10 @@
void udp_input(struct mbuf *, int);
struct inpcb *udp_notify(struct inpcb *inp, int errno);
int udp_shutdown(struct socket *so);
+
+
+typedef void(*udp_tunnel_function_t)(struct mbuf *, int off);
+int udp_set_kernel_tunneling(struct socket *so, udp_tunnel_function_t f);
#endif
#endif
Index: netinet6/udp6_usrreq.c
===================================================================
--- netinet6/udp6_usrreq.c (revision 185928)
+++ netinet6/udp6_usrreq.c (working copy)
@@ -286,9 +286,21 @@
struct mbuf *n;
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) {
+ /* 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_tunnel_function_t tunnel_func;
+ tunnel_func = (udp_tunnel_function_t)last->inp_ppcb;
+ INP_RUNLOCK(last);
+ tunnel_func(m, off);
+ } else {
+ INP_RLOCK(last);
+ udp6_append(last, n, off, &fromsa);
+ INP_RUNLOCK(last);
+ }
}
}
last = inp;
@@ -317,6 +329,19 @@
}
INP_RLOCK(last);
INP_INFO_RUNLOCK(&V_udbinfo);
+ if (last->inp_ppcb) {
+ /* Engage the tunneling protocol
+ * we must make sure all locks
+ * are released when we call the
+ * tunneling protocol.
+ */
+ udp_tunnel_function_t tunnel_func;
+
+ tunnel_func = (udp_tunnel_function_t)inp->inp_ppcb;
+ INP_RUNLOCK(last);
+ tunnel_func(m, off);
+ return (IPPROTO_DONE);
+ }
udp6_append(last, m, off, &fromsa);
INP_RUNLOCK(last);
return (IPPROTO_DONE);
@@ -354,6 +379,18 @@
}
INP_RLOCK(inp);
INP_INFO_RUNLOCK(&V_udbinfo);
+ if (inp->inp_ppcb) {
+ /* Engage the tunneling protocol
+ * we must make sure all locks
+ * are released when we call the
+ * tunneling protocol.
+ */
+ udp_tunnel_function_t tunnel_func;
+ tunnel_func = (udp_tunnel_function_t)inp->inp_ppcb;
+ INP_RUNLOCK(inp);
+ tunnel_func(m, off);
+ return (IPPROTO_DONE);
+ }
udp6_append(inp, m, off, &fromsa);
INP_RUNLOCK(inp);
return (IPPROTO_DONE);
-------------- next part --------------
On Dec 11, 2008, at 1:11 PM, Bruce M. Simpson wrote:
> Hi,
>
> I am missing context of what Max's suggestion was, do you have a
> reference to an old email thread?
>
> Style bugs:
> * needs style(9) and whitespace cleanup.
> * C typedefs should be suffixed with _t for consistency with other
> kernel typedefs.
> * Function typedefs usually named like foo_func_t (see other
> subsystems)
>
> Have you looked at m_apply() ? It already exists for stuff like this
> i.e. functions which act on an mbuf chain, although it doesn't
> necessarily expect chain heads.
>
> cheers
> BMS
>
------------------------------
Randall Stewart
803-317-4952 (cell)
803-345-0391(direct)
More information about the freebsd-net
mailing list