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

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);



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)

_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to