From owner-freebsd-net@FreeBSD.ORG Sat Dec 13 19:30:18 2008 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6B5F01065673 for ; Sat, 13 Dec 2008 19:30:18 +0000 (UTC) (envelope-from max@love2party.net) Received: from moutng.kundenserver.de (moutng.kundenserver.de [212.227.126.186]) by mx1.freebsd.org (Postfix) with ESMTP id DBA3F8FC1C for ; Sat, 13 Dec 2008 19:30:17 +0000 (UTC) (envelope-from max@love2party.net) Received: from vampire.homelinux.org (dslb-088-066-024-089.pools.arcor-ip.net [88.66.24.89]) by mrelayeu.kundenserver.de (node=mrelayeu1) with ESMTP (Nemesis) id 0MKwpI-1LBaBs12u4-0002DC; Sat, 13 Dec 2008 20:30:16 +0100 Received: (qmail 31165 invoked from network); 13 Dec 2008 19:30:15 -0000 Received: from fbsd8.laiers.local (192.168.4.151) by laiers.local with SMTP; 13 Dec 2008 19:30:15 -0000 From: Max Laier Organization: FreeBSD To: freebsd-net@freebsd.org Date: Sat, 13 Dec 2008 20:30:15 +0100 User-Agent: KMail/1.10.1 (FreeBSD/8.0-CURRENT; KDE/4.1.1; i386; ; ) References: <494157DF.6030802@FreeBSD.org> <13C9478E-CBF6-4EDA-8E78-AD76549EB844@lakerest.net> In-Reply-To: <13C9478E-CBF6-4EDA-8E78-AD76549EB844@lakerest.net> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_H1ARJKf5YREingh" Message-Id: <200812132030.15665.max@love2party.net> X-Provags-ID: V01U2FsdGVkX18hz1UdNocy86y97PC2ejc4XPHPDMxJQkWHl6R xmXu9FN6D/WeV898i/lxfM1bX2js2SJTNZs4nEgugA5rnnqwZB kF2riNNLTjPB02Gm18Dkw== Cc: "Bruce M. Simpson" , Randall Stewart Subject: Re: Heads up --- Thinking about UDP and tunneling X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Dec 2008 19:30:18 -0000 --Boundary-00=_H1ARJKf5YREingh Content-Type: text/plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Friday 12 December 2008 14:46:30 Randall Stewart wrote: > Ok: > > Here is an updated patch it: > > 1) Fixes style9 issues > 2) move to _t typedef I won't get into this. > 3) Allow multicast/broadcast to also be tunneled. There seems to be an error with your patch. You RUNLOCK twice in some places - should be fixed in my version of the patch (see attached). > 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 :-) Yep. > 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. I added a comment inline. Maybe we should add a flag to the tunnel function prototype, so that the called party can figure out if they need to defer work that is not allowed under the lock (e.g. malloc WAITOK). On top of that, I was wondering if it might make sense to pass in the inp as an argument - so that the tunnel consumer can figure out which tunnel the packet was received on (without relying on data off the wire). In that case I'd leave the inp RLOCK'ed and leave it up the the called party to release the lock if they so desire. > If there are no serious objections I will submit this into head.. and There are some open issues, see above - but in general okay with me. > followed behind it I will send in the changes so SCTP can be tunneled over > this new mechanism :-) -- /"\ Best regards, | mlaier@freebsd.org \ / Max Laier | ICQ #67774661 X http://pf4freebsd.love2party.net/ | mlaier@EFnet / \ ASCII Ribbon Campaign | Against HTML Mail and News --Boundary-00=_H1ARJKf5YREingh Content-Type: text/plain; charset="iso-8859-15"; name="new_udp_diff.mlaier.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="new_udp_diff.mlaier.txt" Index: netinet/udp_var.h =================================================================== --- netinet/udp_var.h (revision 186046) +++ netinet/udp_var.h (working copy) @@ -110,6 +110,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: netinet/udp_usrreq.c =================================================================== --- netinet/udp_usrreq.c (revision 186046) +++ netinet/udp_usrreq.c (working copy) @@ -488,10 +488,29 @@ 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 :-( + * + * XXXML: Maybe add a flag to the + * prototype so that the tunneling + * can defer work that can't be done + * under the info lock? + */ + udp_tunnel_function_t tunnel_func; + + tunnel_func = (udp_tunnel_function_t)last->inp_ppcb; + INP_RUNLOCK(last); + tunnel_func(m, iphlen); + } } last = inp; /* @@ -516,10 +535,24 @@ 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; + + tunnel_func = (udp_tunnel_function_t)last->inp_ppcb; + INP_RUNLOCK(last); + INP_INFO_RUNLOCK(&V_udbinfo); + tunnel_func(m, iphlen); + } return; } @@ -563,6 +596,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 +1183,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: netinet6/udp6_usrreq.c =================================================================== --- netinet6/udp6_usrreq.c (revision 186046) +++ netinet6/udp6_usrreq.c (working copy) @@ -287,8 +287,20 @@ 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 { + 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); --Boundary-00=_H1ARJKf5YREingh--