Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Apr 2022 08:05:15 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 742e7210d00b - main - udp: allow udp_tun_func_t() to indicate it did not eat the packet
Message-ID:  <202204120805.23C85Fn2012519@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=742e7210d00b359d81b9c778ab520003704e9b6c

commit 742e7210d00b359d81b9c778ab520003704e9b6c
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-04-11 13:58:28 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-04-12 08:04:59 +0000

    udp: allow udp_tun_func_t() to indicate it did not eat the packet
    
    Allow udp tunnel functions to indicate they have not taken ownership of
    the packet, and that normal UDP processing should continue.
    
    This is especially useful for scenarios where the kernel has taken
    ownership of a socket that was originally created by userspace. It
    allows the tunnel function to pass through certain packets for userspace
    processing.
    
    The primary user of this is if_ovpn, when it receives messages from
    unknown peers (which might be a new client).
    
    Reviewed by:    tuexen
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D34883
---
 sys/net/if_vxlan.c       | 6 ++++--
 sys/netinet/ip_gre.c     | 6 ++++--
 sys/netinet/sctputil.c   | 6 ++++--
 sys/netinet/tcp_subr.c   | 6 ++++--
 sys/netinet/udp_usrreq.c | 6 ++++--
 sys/netinet/udp_var.h    | 5 ++++-
 sys/netinet6/ip6_gre.c   | 8 +++++---
 7 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c
index 291c7b591766..99efbe255695 100644
--- a/sys/net/if_vxlan.c
+++ b/sys/net/if_vxlan.c
@@ -363,7 +363,7 @@ static int	vxlan_encap6(struct vxlan_softc *,
 		    const union vxlan_sockaddr *, struct mbuf *);
 static int	vxlan_transmit(struct ifnet *, struct mbuf *);
 static void	vxlan_qflush(struct ifnet *);
-static void	vxlan_rcv_udp_packet(struct mbuf *, int, struct inpcb *,
+static bool	vxlan_rcv_udp_packet(struct mbuf *, int, struct inpcb *,
 		    const struct sockaddr *, void *);
 static int	vxlan_input(struct vxlan_socket *, uint32_t, struct mbuf **,
 		    const struct sockaddr *);
@@ -2758,7 +2758,7 @@ vxlan_qflush(struct ifnet *ifp __unused)
 {
 }
 
-static void
+static bool
 vxlan_rcv_udp_packet(struct mbuf *m, int offset, struct inpcb *inpcb,
     const struct sockaddr *srcsa, void *xvso)
 {
@@ -2802,6 +2802,8 @@ vxlan_rcv_udp_packet(struct mbuf *m, int offset, struct inpcb *inpcb,
 out:
 	if (m != NULL)
 		m_freem(m);
+
+	return (true);
 }
 
 static int
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index a70452026642..93261a094a36 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -219,7 +219,7 @@ in_gre_srcaddr(void *arg __unused, const struct sockaddr *sa,
 	}
 }
 
-static void
+static bool
 in_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp,
     const struct sockaddr *sa, void *ctx)
 {
@@ -237,9 +237,11 @@ in_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp,
 	}
 	if (sc != NULL && (GRE2IFP(sc)->if_flags & IFF_UP) != 0){
 		gre_input(m, off + sizeof(struct udphdr), IPPROTO_UDP, sc);
-		return;
+		return (true);
 	}
 	m_freem(m);
+
+	return (true);
 }
 
 static int
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index e0ac9e23fc68..7b82a2ce6d86 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -7094,7 +7094,7 @@ sctp_log_trace(uint32_t subsys, const char *str SCTP_UNUSED, uint32_t a, uint32_
 }
 
 #endif
-static void
+static bool
 sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,
     const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED)
 {
@@ -7172,9 +7172,11 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,
 		goto out;
 		break;
 	}
-	return;
+	return (true);
 out:
 	m_freem(m);
+
+	return (true);
 }
 
 #ifdef INET
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 95c34c581e59..348a8bb7151e 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -590,7 +590,7 @@ tcp_switch_back_to_default(struct tcpcb *tp)
 	}
 }
 
-static void
+static bool
 tcp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,
     const struct sockaddr *sa, void *ctx)
 {
@@ -659,9 +659,11 @@ tcp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,
 		goto out;
 		break;
 	}
-	return;
+	return (true);
 out:
 	m_freem(m);
+
+	return (true);
 }
 
 static int
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index f216e993b4f3..f35ba81f3936 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -278,6 +278,7 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
 	struct sockaddr_in6 udp_in6;
 #endif
 	struct udpcb *up;
+	bool filtered;
 
 	INP_LOCK_ASSERT(inp);
 
@@ -288,10 +289,11 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
 	if (up->u_tun_func != NULL) {
 		in_pcbref(inp);
 		INP_RUNLOCK(inp);
-		(*up->u_tun_func)(n, off, inp, (struct sockaddr *)&udp_in[0],
+		filtered = (*up->u_tun_func)(n, off, inp, (struct sockaddr *)&udp_in[0],
 		    up->u_tun_ctx);
 		INP_RLOCK(inp);
-		return (in_pcbrele_rlocked(inp));
+		if (filtered)
+			return (in_pcbrele_rlocked(inp));
 	}
 
 	off += sizeof(struct udphdr);
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index cd9c4fd47e4f..9db5494ab82b 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -36,6 +36,7 @@
 #ifndef _NETINET_UDP_VAR_H_
 #define	_NETINET_UDP_VAR_H_
 
+#include <sys/types.h>
 #include <netinet/ip_var.h>
 #include <netinet/udp.h>
 
@@ -60,7 +61,8 @@ struct udpiphdr {
 struct inpcb;
 struct mbuf;
 
-typedef void(*udp_tun_func_t)(struct mbuf *, int, struct inpcb *,
+#ifdef _KERNEL
+typedef bool(*udp_tun_func_t)(struct mbuf *, int, struct inpcb *,
 			      const struct sockaddr *, void *);
 typedef void(*udp_tun_icmp_t)(int, struct sockaddr *, void *, void *);
 
@@ -78,6 +80,7 @@ struct udpcb {
 
 #define	intoudpcb(ip)	((struct udpcb *)(ip)->inp_ppcb)
 #define	sotoudpcb(so)	(intoudpcb(sotoinpcb(so)))
+#endif
 
 				/* IPsec: ESP in UDP tunneling: */
 #define	UF_ESPINUDP_NON_IKE	0x00000001	/* w/ non-IKE marker .. */
diff --git a/sys/netinet6/ip6_gre.c b/sys/netinet6/ip6_gre.c
index eb3f92d55adc..9057a95e109b 100644
--- a/sys/netinet6/ip6_gre.c
+++ b/sys/netinet6/ip6_gre.c
@@ -212,7 +212,7 @@ in6_gre_srcaddr(void *arg __unused, const struct sockaddr *sa,
 	}
 }
 
-static void
+static bool
 in6_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp,
     const struct sockaddr *sa, void *ctx)
 {
@@ -226,7 +226,7 @@ in6_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp,
 	dst = *(const struct sockaddr_in6 *)sa;
 	if (sa6_embedscope(&dst, 0)) {
 		m_freem(m);
-		return;
+		return (true);
 	}
 	CK_LIST_FOREACH(sc, &gs->list, chain) {
 		if (IN6_ARE_ADDR_EQUAL(&sc->gre_oip6.ip6_dst, &dst.sin6_addr))
@@ -234,9 +234,11 @@ in6_gre_udp_input(struct mbuf *m, int off, struct inpcb *inp,
 	}
 	if (sc != NULL && (GRE2IFP(sc)->if_flags & IFF_UP) != 0){
 		gre_input(m, off + sizeof(struct udphdr), IPPROTO_UDP, sc);
-		return;
+		return (true);
 	}
 	m_freem(m);
+
+	return (true);
 }
 
 static int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202204120805.23C85Fn2012519>