Page MenuHomeFreeBSD

D60552.id189292.diff
No OneTemporary

D60552.id189292.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,12 @@
CURVNET_SET(if_getvnet(ifp));
M_SETFIB(m, if_getfib(ifp));
+ m = encap_set_flowid(m, af);
+ if (m == NULL) {
+ CURVNET_RESTORE();
+ NET_EPOCH_EXIT(et);
+ goto error;
+ }
#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,9 @@
if (proto == GENEVE_PROTO_ETHER)
(*ifp->if_input)(ifp, m);
else {
+ m = encap_set_flowid(m, af);
+ if (m == NULL)
+ goto out;
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,9 @@
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
M_SETFIB(m, ifp->if_fib);
+ m = encap_set_flowid(m, af);
+ if (m == NULL)
+ goto drop;
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,9 @@
m_clrprotoflags(m);
m->m_pkthdr.rcvif = ifp;
M_SETFIB(m, ifp->if_fib);
+ m = encap_set_flowid(m, af);
+ if (m == NULL)
+ goto drop;
#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>
@@ -1780,17 +1781,27 @@
* keepalive).
*/
af = ovpn_get_af(m);
- if (af != 0) {
- BPF_MTAP2(sc->ifp, &af, sizeof(af), m);
- if (V_async_netisr_queue)
- netisr_queue(af == AF_INET ? NETISR_IP : NETISR_IPV6, m);
- else
- netisr_dispatch(af == AF_INET ? NETISR_IP : NETISR_IPV6, m);
- } else {
- OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if (af == 0)
+ goto error;
+
+ m = encap_set_flowid(m, af);
+ if (m == NULL) {
+ OVPN_COUNTER_ADD(sc, nomem_data_pkts_in, 1);
if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
- m_freem(m);
+ return;
}
+
+ BPF_MTAP2(sc->ifp, &af, sizeof(af), m);
+ if (V_async_netisr_queue)
+ netisr_queue(af == AF_INET ? NETISR_IP : NETISR_IPV6, m);
+ else
+ netisr_dispatch(af == AF_INET ? NETISR_IP : NETISR_IPV6, m);
+ return;
+
+error:
+ OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
+ if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
+ m_freem(m);
}
static struct ovpn_kkey *
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
@@ -76,6 +76,8 @@
int ip6_encap_unregister_srcaddr(const struct srcaddrtab *);
int ip_encap_detach(const struct encaptab *);
int ip6_encap_detach(const struct encaptab *);
+
+struct mbuf *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
@@ -60,6 +60,7 @@
#include "opt_inet.h"
#include "opt_inet6.h"
+#include "opt_rss.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -71,21 +72,40 @@
#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/in_fib.h>
+#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_encap.h>
+#ifdef RSS
+#include <netinet/in_rss.h>
+#endif
#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet6/in6_fib.h>
#include <netinet6/ip6_var.h>
+#ifdef RSS
+#include <netinet6/in6_rss.h>
+#endif
#endif
static MALLOC_DEFINE(M_NETADDR, "encap_export_host",
"Export host address structure");
+SYSCTL_DECL(_net_route);
+VNET_DEFINE_STATIC(bool, encap_hash_inbound) = false;
+#define V_encap_hash_inbound VNET(encap_hash_inbound)
+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 +430,66 @@
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.
+ */
+struct mbuf *
+encap_set_flowid(struct mbuf *m, int af)
+{
+ uint32_t flowid, hashtype;
+
+ M_ASSERTPKTHDR(m);
+
+ if (!V_encap_hash_inbound)
+ return (m);
+
+ switch (af) {
+#ifdef INET
+ case AF_INET: {
+ const struct ip *ip;
+
+ m = m_pullup(m, sizeof(*ip));
+ if (m == NULL)
+ return (NULL);
+ ip = mtod(m, const struct ip *);
+#ifdef RSS
+ flowid = rss_hash_ip4_2tuple(ip->ip_src, ip->ip_dst);
+ hashtype = M_HASHTYPE_RSS_IPV4;
+#else
+ flowid = fib4_calc_software_hash(ip->ip_src, ip->ip_dst, 0, 0,
+ 0, &hashtype);
+#endif
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ const struct ip6_hdr *ip6;
+
+ m = m_pullup(m, sizeof(*ip6));
+ if (m == NULL)
+ return (NULL);
+ ip6 = mtod(m, const struct ip6_hdr *);
+#ifdef RSS
+ flowid = rss_hash_ip6_2tuple(&ip6->ip6_src, &ip6->ip6_dst);
+ hashtype = M_HASHTYPE_RSS_IPV6;
+#else
+ flowid = fib6_calc_software_hash(&ip6->ip6_src, &ip6->ip6_dst,
+ 0, 0, 0, &hashtype);
+#endif
+ break;
+ }
+#endif
+ default:
+ return (m);
+ }
+
+ m->m_pkthdr.flowid = flowid;
+ M_HASHTYPE_SET(m, hashtype);
+ return (m);
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 10, 11:42 PM (15 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40572441
Default Alt Text
D60552.id189292.diff (6 KB)

Event Timeline