Implement mbuf hashing routines for IP over infiniband, IPoIB.
No functional change intended. Differential Revision: https://reviews.freebsd.org/D26254 Reviewed by: melifaro@ MFC after: 1 week Sponsored by: Mellanox Technologies // NVIDIA Networking
This commit is contained in:
parent
9d40cf60d6
commit
2ae634c6db
@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/fnv_hash.h>
|
#include <sys/fnv_hash.h>
|
||||||
|
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
|
#include <net/infiniband.h>
|
||||||
|
|
||||||
#if defined(INET) || defined(INET6)
|
#if defined(INET) || defined(INET6)
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -42,7 +43,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const void *
|
static const void *
|
||||||
m_ether_tcpip_hash_gethdr(const struct mbuf *m, const u_int off,
|
m_common_hash_gethdr(const struct mbuf *m, const u_int off,
|
||||||
const u_int len, void *buf)
|
const u_int len, void *buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -65,9 +66,19 @@ m_ether_tcpip_hash_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
m_ether_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
m_infiniband_tcpip_hash_init(void)
|
||||||
const uint32_t key)
|
|
||||||
{
|
{
|
||||||
|
uint32_t seed;
|
||||||
|
|
||||||
|
seed = arc4random();
|
||||||
|
return (fnv_32_buf(&seed, sizeof(seed), FNV1_32_INIT));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
m_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
||||||
|
uint32_t p, int off, const uint16_t etype)
|
||||||
|
{
|
||||||
|
#if defined(INET) || defined(INET6)
|
||||||
union {
|
union {
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
struct ip ip;
|
struct ip ip;
|
||||||
@ -75,49 +86,19 @@ m_ether_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
|||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
struct ip6_hdr ip6;
|
struct ip6_hdr ip6;
|
||||||
#endif
|
#endif
|
||||||
struct ether_vlan_header vlan;
|
|
||||||
uint32_t port;
|
uint32_t port;
|
||||||
} buf;
|
} buf;
|
||||||
const struct ether_header *eh;
|
|
||||||
const struct ether_vlan_header *vlan;
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
const struct ip *ip;
|
const struct ip *ip;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
const struct ip6_hdr *ip6;
|
const struct ip6_hdr *ip6;
|
||||||
#endif
|
#endif
|
||||||
uint32_t p;
|
#endif
|
||||||
int off;
|
|
||||||
uint16_t etype;
|
|
||||||
|
|
||||||
p = key;
|
|
||||||
off = sizeof(*eh);
|
|
||||||
if (m->m_len < off)
|
|
||||||
goto done;
|
|
||||||
eh = mtod(m, struct ether_header *);
|
|
||||||
etype = ntohs(eh->ether_type);
|
|
||||||
if (flags & MBUF_HASHFLAG_L2) {
|
|
||||||
p = fnv_32_buf(&eh->ether_shost, ETHER_ADDR_LEN, p);
|
|
||||||
p = fnv_32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p);
|
|
||||||
}
|
|
||||||
/* Special handling for encapsulating VLAN frames */
|
|
||||||
if ((m->m_flags & M_VLANTAG) && (flags & MBUF_HASHFLAG_L2)) {
|
|
||||||
p = fnv_32_buf(&m->m_pkthdr.ether_vtag,
|
|
||||||
sizeof(m->m_pkthdr.ether_vtag), p);
|
|
||||||
} else if (etype == ETHERTYPE_VLAN) {
|
|
||||||
vlan = m_ether_tcpip_hash_gethdr(m, off, sizeof(*vlan), &buf);
|
|
||||||
if (vlan == NULL)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (flags & MBUF_HASHFLAG_L2)
|
|
||||||
p = fnv_32_buf(&vlan->evl_tag, sizeof(vlan->evl_tag), p);
|
|
||||||
etype = ntohs(vlan->evl_proto);
|
|
||||||
off += sizeof(*vlan) - sizeof(*eh);
|
|
||||||
}
|
|
||||||
switch (etype) {
|
switch (etype) {
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
case ETHERTYPE_IP:
|
case ETHERTYPE_IP:
|
||||||
ip = m_ether_tcpip_hash_gethdr(m, off, sizeof(*ip), &buf);
|
ip = m_common_hash_gethdr(m, off, sizeof(*ip), &buf);
|
||||||
if (ip == NULL)
|
if (ip == NULL)
|
||||||
break;
|
break;
|
||||||
if (flags & MBUF_HASHFLAG_L3) {
|
if (flags & MBUF_HASHFLAG_L3) {
|
||||||
@ -136,7 +117,7 @@ m_ether_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
|||||||
if (iphlen < sizeof(*ip))
|
if (iphlen < sizeof(*ip))
|
||||||
break;
|
break;
|
||||||
off += iphlen;
|
off += iphlen;
|
||||||
ports = m_ether_tcpip_hash_gethdr(m,
|
ports = m_common_hash_gethdr(m,
|
||||||
off, sizeof(*ports), &buf);
|
off, sizeof(*ports), &buf);
|
||||||
if (ports == NULL)
|
if (ports == NULL)
|
||||||
break;
|
break;
|
||||||
@ -150,7 +131,7 @@ m_ether_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
|||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
case ETHERTYPE_IPV6:
|
case ETHERTYPE_IPV6:
|
||||||
ip6 = m_ether_tcpip_hash_gethdr(m, off, sizeof(*ip6), &buf);
|
ip6 = m_common_hash_gethdr(m, off, sizeof(*ip6), &buf);
|
||||||
if (ip6 == NULL)
|
if (ip6 == NULL)
|
||||||
break;
|
break;
|
||||||
if (flags & MBUF_HASHFLAG_L3) {
|
if (flags & MBUF_HASHFLAG_L3) {
|
||||||
@ -169,6 +150,62 @@ m_ether_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done:
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
m_ether_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
||||||
|
uint32_t p)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct ether_vlan_header vlan;
|
||||||
|
} buf;
|
||||||
|
const struct ether_header *eh;
|
||||||
|
const struct ether_vlan_header *vlan;
|
||||||
|
int off;
|
||||||
|
uint16_t etype;
|
||||||
|
|
||||||
|
off = sizeof(*eh);
|
||||||
|
if (m->m_len < off)
|
||||||
|
return (p);
|
||||||
|
eh = mtod(m, struct ether_header *);
|
||||||
|
etype = ntohs(eh->ether_type);
|
||||||
|
if (flags & MBUF_HASHFLAG_L2) {
|
||||||
|
p = fnv_32_buf(&eh->ether_shost, ETHER_ADDR_LEN, p);
|
||||||
|
p = fnv_32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p);
|
||||||
|
}
|
||||||
|
/* Special handling for encapsulating VLAN frames */
|
||||||
|
if ((m->m_flags & M_VLANTAG) && (flags & MBUF_HASHFLAG_L2)) {
|
||||||
|
p = fnv_32_buf(&m->m_pkthdr.ether_vtag,
|
||||||
|
sizeof(m->m_pkthdr.ether_vtag), p);
|
||||||
|
} else if (etype == ETHERTYPE_VLAN) {
|
||||||
|
vlan = m_common_hash_gethdr(m, off, sizeof(*vlan), &buf);
|
||||||
|
if (vlan == NULL)
|
||||||
|
return (p);
|
||||||
|
|
||||||
|
if (flags & MBUF_HASHFLAG_L2)
|
||||||
|
p = fnv_32_buf(&vlan->evl_tag, sizeof(vlan->evl_tag), p);
|
||||||
|
etype = ntohs(vlan->evl_proto);
|
||||||
|
off += sizeof(*vlan) - sizeof(*eh);
|
||||||
|
}
|
||||||
|
return (m_tcpip_hash(flags, m, p, off, etype));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
m_infiniband_tcpip_hash(const uint32_t flags, const struct mbuf *m,
|
||||||
|
uint32_t p)
|
||||||
|
{
|
||||||
|
const struct infiniband_header *ibh;
|
||||||
|
int off;
|
||||||
|
uint16_t etype;
|
||||||
|
|
||||||
|
off = sizeof(*ibh);
|
||||||
|
if (m->m_len < off)
|
||||||
|
return (p);
|
||||||
|
ibh = mtod(m, struct infiniband_header *);
|
||||||
|
etype = ntohs(ibh->ib_protocol);
|
||||||
|
if (flags & MBUF_HASHFLAG_L2)
|
||||||
|
p = fnv_32_buf(&ibh->ib_hwaddr, INFINIBAND_ADDR_LEN, p);
|
||||||
|
|
||||||
|
return (m_tcpip_hash(flags, m, p, off, etype));
|
||||||
|
}
|
||||||
|
@ -1455,14 +1455,16 @@ rt_m_getfib(struct mbuf *m)
|
|||||||
((_m)->m_pkthdr.fibnum) = (_fib); \
|
((_m)->m_pkthdr.fibnum) = (_fib); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* flags passed as first argument for "m_ether_tcpip_hash()" */
|
/* flags passed as first argument for "m_xxx_tcpip_hash()" */
|
||||||
#define MBUF_HASHFLAG_L2 (1 << 2)
|
#define MBUF_HASHFLAG_L2 (1 << 2)
|
||||||
#define MBUF_HASHFLAG_L3 (1 << 3)
|
#define MBUF_HASHFLAG_L3 (1 << 3)
|
||||||
#define MBUF_HASHFLAG_L4 (1 << 4)
|
#define MBUF_HASHFLAG_L4 (1 << 4)
|
||||||
|
|
||||||
/* mbuf hashing helper routines */
|
/* mbuf hashing helper routines */
|
||||||
uint32_t m_ether_tcpip_hash_init(void);
|
uint32_t m_ether_tcpip_hash_init(void);
|
||||||
uint32_t m_ether_tcpip_hash(const uint32_t, const struct mbuf *, const uint32_t);
|
uint32_t m_ether_tcpip_hash(const uint32_t, const struct mbuf *, uint32_t);
|
||||||
|
uint32_t m_infiniband_tcpip_hash_init(void);
|
||||||
|
uint32_t m_infiniband_tcpip_hash(const uint32_t, const struct mbuf *, uint32_t);
|
||||||
|
|
||||||
#ifdef MBUF_PROFILING
|
#ifdef MBUF_PROFILING
|
||||||
void m_profile(struct mbuf *m);
|
void m_profile(struct mbuf *m);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user