Author: rrs
Date: Thu Apr 28 15:53:10 2016
New Revision: 298747
URL: https://svnweb.freebsd.org/changeset/base/298747

Log:
  Complete the UDP tunneling of ICMP msgs to those protocols
  interested in having tunneled UDP and finding out about the
  ICMP (tested by Michael Tuexen with SCTP.. soon to be using
  this feature).
  
  Differential Revision:        http://reviews.freebsd.org/D5875

Modified:
  head/sys/net/if_vxlan.c
  head/sys/netinet/sctputil.c
  head/sys/netinet/udp_usrreq.c
  head/sys/netinet/udp_var.h
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/net/if_vxlan.c
==============================================================================
--- head/sys/net/if_vxlan.c     Thu Apr 28 15:20:08 2016        (r298746)
+++ head/sys/net/if_vxlan.c     Thu Apr 28 15:53:10 2016        (r298747)
@@ -930,7 +930,7 @@ vxlan_socket_init(struct vxlan_socket *v
        }
 
        error = udp_set_kernel_tunneling(vso->vxlso_sock,
-           vxlan_rcv_udp_packet, vso);
+           vxlan_rcv_udp_packet, NULL, vso);
        if (error) {
                if_printf(ifp, "cannot set tunneling function: %d\n", error);
                return (error);

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c Thu Apr 28 15:20:08 2016        (r298746)
+++ head/sys/netinet/sctputil.c Thu Apr 28 15:53:10 2016        (r298747)
@@ -6945,7 +6945,7 @@ sctp_over_udp_start(void)
        }
        /* Call the special UDP hook. */
        if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket),
-           sctp_recv_udp_tunneled_packet, NULL))) {
+           sctp_recv_udp_tunneled_packet, NULL, NULL))) {
                sctp_over_udp_stop();
                return (ret);
        }
@@ -6969,7 +6969,7 @@ sctp_over_udp_start(void)
        }
        /* Call the special UDP hook. */
        if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket),
-           sctp_recv_udp_tunneled_packet, NULL))) {
+           sctp_recv_udp_tunneled_packet, NULL, NULL))) {
                sctp_over_udp_stop();
                return (ret);
        }

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c       Thu Apr 28 15:20:08 2016        
(r298746)
+++ head/sys/netinet/udp_usrreq.c       Thu Apr 28 15:53:10 2016        
(r298747)
@@ -792,6 +792,21 @@ udp_common_ctlinput(int cmd, struct sock
                                udp_notify(inp, inetctlerrmap[cmd]);
                        }
                        INP_RUNLOCK(inp);
+               } else {
+                       inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
+                                          ip->ip_src, uh->uh_sport,
+                                          INPLOOKUP_WILDCARD | 
INPLOOKUP_RLOCKPCB, NULL);
+                       if (inp != NULL) {
+                               struct udpcb *up;
+
+                               up = intoudpcb(inp);
+                               if (up->u_icmp_func != NULL) {
+                                       INP_RUNLOCK(inp);
+                                       (*up->u_icmp_func)(cmd, sa, vip, 
up->u_tun_ctx);
+                               } else {
+                                       INP_RUNLOCK(inp);
+                               }
+                       }
                }
        } else
                in_pcbnotifyall(pcbinfo, faddr, inetctlerrmap[cmd],
@@ -1748,7 +1763,7 @@ udp_attach(struct socket *so, int proto,
 #endif /* INET */
 
 int
-udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, void *ctx)
+udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f, udp_tun_icmp_t 
i, void *ctx)
 {
        struct inpcb *inp;
        struct udpcb *up;
@@ -1759,11 +1774,13 @@ udp_set_kernel_tunneling(struct socket *
        KASSERT(inp != NULL, ("udp_set_kernel_tunneling: inp == NULL"));
        INP_WLOCK(inp);
        up = intoudpcb(inp);
-       if (up->u_tun_func != NULL) {
+       if ((up->u_tun_func != NULL) ||
+           (up->u_icmp_func != NULL)) {
                INP_WUNLOCK(inp);
                return (EBUSY);
        }
        up->u_tun_func = f;
+       up->u_icmp_func = i;
        up->u_tun_ctx = ctx;
        INP_WUNLOCK(inp);
        return (0);

Modified: head/sys/netinet/udp_var.h
==============================================================================
--- head/sys/netinet/udp_var.h  Thu Apr 28 15:20:08 2016        (r298746)
+++ head/sys/netinet/udp_var.h  Thu Apr 28 15:53:10 2016        (r298747)
@@ -55,14 +55,16 @@ struct udpiphdr {
 struct inpcb;
 struct mbuf;
 
-typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *,
+typedef void(*udp_tun_func_t)(struct mbuf *, int, struct inpcb *,
                              const struct sockaddr *, void *);
-
+typedef void(*udp_tun_icmp_t)(int, struct sockaddr *, void *, void *);
+                             
 /*
  * UDP control block; one per udp.
  */
 struct udpcb {
        udp_tun_func_t  u_tun_func;     /* UDP kernel tunneling callback. */
+       udp_tun_icmp_t  u_icmp_func;    /* UDP kernel tunneling icmp callback */
        u_int           u_flags;        /* Generic UDP flags. */
        uint16_t        u_rxcslen;      /* Coverage for incoming datagrams. */
        uint16_t        u_txcslen;      /* Coverage for outgoing datagrams. */
@@ -179,7 +181,7 @@ struct inpcb        *udp_notify(struct inpcb *i
 int            udp_shutdown(struct socket *so);
 
 int            udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f,
-                                        void *ctx);
+                   udp_tun_icmp_t i, void *ctx);
 
 #endif /* _KERNEL */
 

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c     Thu Apr 28 15:20:08 2016        
(r298746)
+++ head/sys/netinet6/udp6_usrreq.c     Thu Apr 28 15:53:10 2016        
(r298747)
@@ -553,6 +553,29 @@ udp6_common_ctlinput(int cmd, struct soc
                bzero(&uh, sizeof(uh));
                m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
 
+               if (!PRC_IS_REDIRECT(cmd)) {
+                       /* Check to see if its tunneled */
+                       struct inpcb *inp;
+                       inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src,
+                           uh.uh_sport, &ip6->ip6_dst, uh.uh_dport,
+                           INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
+                           m->m_pkthdr.rcvif, m);
+                       if (inp != NULL) {
+                               struct udpcb *up;
+                               
+                               up = intoudpcb(inp);
+                               if (up->u_icmp_func) {
+                                       /* Yes it is. */
+                                       INP_RUNLOCK(inp);       
+                                       (*up->u_icmp_func)(cmd, (struct 
sockaddr *)ip6cp->ip6c_src,
+                                             d, up->u_tun_ctx);
+                                       return;
+                               } else {
+                                       /* Can't find it. */
+                                       INP_RUNLOCK(inp);
+                               }
+                       }
+               }
                (void)in6_pcbnotify(pcbinfo, sa, uh.uh_dport,
                    (struct sockaddr *)ip6cp->ip6c_src, uh.uh_sport, cmd,
                    cmdarg, notify);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to