Page MenuHomeFreeBSD

D60552.id189300.diff
No OneTemporary

D60552.id189300.diff

diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c
--- a/sys/dev/wg/if_wg.c
+++ b/sys/dev/wg/if_wg.c
@@ -43,6 +43,7 @@
#include <netinet6/in6_var.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
+#include <netinet/ip_encap.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <netinet/udp_var.h>
@@ -1833,6 +1834,8 @@
CURVNET_SET(if_getvnet(ifp));
M_SETFIB(m, if_getfib(ifp));
+ if (V_encap_hash_inbound)
+ encap_set_flowid(m, af);
#ifdef DEV_NETMAP
if ((if_getcapenable(ifp) & IFCAP_NETMAP) != 0)
wg_deliver_netmap(ifp, m, af);
diff --git a/sys/net/if_geneve.c b/sys/net/if_geneve.c
--- a/sys/net/if_geneve.c
+++ b/sys/net/if_geneve.c
@@ -68,6 +68,7 @@
#include <netinet/in_var.h>
#include <netinet/in_pcb.h>
#include <netinet/ip.h>
+#include <netinet/ip_encap.h>
#include <netinet/ip_var.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
@@ -3063,6 +3064,8 @@
if (proto == GENEVE_PROTO_ETHER)
(*ifp->if_input)(ifp, m);
else {
+ if (V_encap_hash_inbound)
+ encap_set_flowid(m, af);
BPF_MTAP2(ifp, &af, sizeof(af), m);
netisr_dispatch_src(info.isr, (uintptr_t)xgnvso, m);
}
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -727,6 +727,8 @@
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
M_SETFIB(m, ifp->if_fib);
+ if (V_encap_hash_inbound)
+ encap_set_flowid(m, af);
netisr_dispatch(isr, m);
return;
drop:
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -830,6 +830,8 @@
m_clrprotoflags(m);
m->m_pkthdr.rcvif = ifp;
M_SETFIB(m, ifp->if_fib);
+ if (V_encap_hash_inbound)
+ encap_set_flowid(m, af);
#ifdef MAC
mac_ifnet_create_mbuf(ifp, m);
#endif
diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -67,6 +67,7 @@
#include <netinet/in_fib.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
+#include <netinet/ip_encap.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
@@ -1781,6 +1782,8 @@
*/
af = ovpn_get_af(m);
if (af != 0) {
+ if (V_encap_hash_inbound)
+ encap_set_flowid(m, af);
BPF_MTAP2(sc->ifp, &af, sizeof(af), m);
if (V_async_netisr_queue)
netisr_queue(af == AF_INET ? NETISR_IP : NETISR_IPV6, m);
diff --git a/sys/netinet/ip_encap.h b/sys/netinet/ip_encap.h
--- a/sys/netinet/ip_encap.h
+++ b/sys/netinet/ip_encap.h
@@ -37,6 +37,8 @@
#ifdef _KERNEL
+#include <net/vnet.h>
+
int encap4_input(struct mbuf **, int *, int);
int encap6_input(struct mbuf **, int *, int);
@@ -76,6 +78,11 @@
int ip6_encap_unregister_srcaddr(const struct srcaddrtab *);
int ip_encap_detach(const struct encaptab *);
int ip6_encap_detach(const struct encaptab *);
+
+VNET_DECLARE(bool, encap_hash_inbound);
+#define V_encap_hash_inbound VNET(encap_hash_inbound)
+
+bool encap_set_flowid(struct mbuf *, int);
#endif
#endif /*_NETINET_IP_ENCAP_H_*/
diff --git a/sys/netinet/ip_encap.c b/sys/netinet/ip_encap.c
--- a/sys/netinet/ip_encap.c
+++ b/sys/netinet/ip_encap.c
@@ -71,21 +71,33 @@
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/socket.h>
+#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_var.h>
+#include <net/vnet.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_encap.h>
+#include <netinet/in_rss.h>
#ifdef INET6
+#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
+#include <netinet6/in6_rss.h>
#endif
static MALLOC_DEFINE(M_NETADDR, "encap_export_host",
"Export host address structure");
+SYSCTL_DECL(_net_route);
+VNET_DEFINE(bool, encap_hash_inbound) = false;
+SYSCTL_BOOL(_net_route, OID_AUTO, hash_inbound, CTLFLAG_RW | CTLFLAG_VNET,
+ &VNET_NAME(encap_hash_inbound), false,
+ "Compute flowid for packets received over tunnel interfaces");
+
struct encaptab {
CK_LIST_ENTRY(encaptab) chain;
int proto;
@@ -410,3 +422,53 @@
return (IPPROTO_DONE);
}
#endif /* INET6 */
+
+/*
+ * Set the flowid of a decapsulated IP packet from its inner addresses.
+ *
+ * flowid of an incoming packet computed over the outer tunnel tuple,
+ * which is the same for every flow a peer. Hashing the inner addresses
+ * instead to make the mpath (and RSS, if enabled) work properly.
+ *
+ * Callers must check the V_encap_hash_inbound sysctl before calling.
+ */
+bool
+encap_set_flowid(struct mbuf *m, int af)
+{
+ uint32_t flowid, hashtype;
+
+ M_ASSERTPKTHDR(m);
+
+ switch (af) {
+#ifdef INET
+ case AF_INET: {
+ const struct ip *ip;
+
+ if (m->m_len < sizeof(*ip))
+ return (false);
+ ip = mtod(m, const struct ip *);
+ flowid = rss_hash_ip4_2tuple(ip->ip_src, ip->ip_dst);
+ hashtype = M_HASHTYPE_RSS_IPV4;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ const struct ip6_hdr *ip6;
+
+ if (m->m_len < sizeof(*ip6))
+ return (false);
+ ip6 = mtod(m, const struct ip6_hdr *);
+ flowid = rss_hash_ip6_2tuple(&ip6->ip6_src, &ip6->ip6_dst);
+ hashtype = M_HASHTYPE_RSS_IPV6;
+ break;
+ }
+#endif
+ default:
+ return (false);
+ }
+
+ m->m_pkthdr.flowid = flowid;
+ M_HASHTYPE_SET(m, hashtype);
+ return (true);
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 10, 11:37 PM (8 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40572135
Default Alt Text
D60552.id189300.diff (5 KB)

Event Timeline