The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/uipc_mbufhash.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $      */
    2 
    3 /*
    4  * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
    5  * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org>
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  */
   19 
   20 #include <sys/cdefs.h>
   21 __FBSDID("$FreeBSD$");
   22 
   23 #include "opt_inet.h"
   24 #include "opt_inet6.h"
   25 
   26 #include <sys/param.h>
   27 #include <sys/mbuf.h>
   28 #include <sys/fnv_hash.h>
   29 
   30 #include <net/ethernet.h>
   31 #include <net/infiniband.h>
   32 
   33 #if defined(INET) || defined(INET6)
   34 #include <netinet/in.h>
   35 #endif
   36 
   37 #ifdef INET
   38 #include <netinet/ip.h>
   39 #endif
   40 
   41 #ifdef INET6
   42 #include <netinet/ip6.h>
   43 #endif
   44 
   45 static const void *
   46 m_common_hash_gethdr(const struct mbuf *m, const u_int off,
   47     const u_int len, void *buf)
   48 {
   49 
   50         if (m->m_pkthdr.len < (off + len)) {
   51                 return (NULL);
   52         } else if (m->m_len < (off + len)) {
   53                 m_copydata(m, off, len, buf);
   54                 return (buf);
   55         }
   56         return (mtod(m, char *) + off);
   57 }
   58 
   59 uint32_t
   60 m_ether_tcpip_hash_init(void)
   61 {
   62         uint32_t seed;
   63 
   64         seed = arc4random();
   65         return (fnv_32_buf(&seed, sizeof(seed), FNV1_32_INIT));
   66 }
   67 
   68 uint32_t
   69 m_infiniband_tcpip_hash_init(void)
   70 {
   71         uint32_t seed;
   72 
   73         seed = arc4random();
   74         return (fnv_32_buf(&seed, sizeof(seed), FNV1_32_INIT));
   75 }
   76 
   77 static inline uint32_t
   78 m_tcpip_hash(const uint32_t flags, const struct mbuf *m,
   79     uint32_t p, int off, const uint16_t etype)
   80 {
   81 #if defined(INET) || defined(INET6)
   82         union {
   83 #ifdef INET
   84                 struct ip ip;
   85 #endif
   86 #ifdef INET6
   87                 struct ip6_hdr ip6;
   88 #endif
   89                 uint32_t port;
   90         } buf;
   91 #ifdef INET
   92         const struct ip *ip;
   93 #endif
   94 #ifdef INET6
   95         const struct ip6_hdr *ip6;
   96 #endif
   97 #endif
   98         switch (etype) {
   99 #ifdef INET
  100         case ETHERTYPE_IP:
  101                 ip = m_common_hash_gethdr(m, off, sizeof(*ip), &buf);
  102                 if (ip == NULL)
  103                         break;
  104                 if (flags & MBUF_HASHFLAG_L3) {
  105                         p = fnv_32_buf(&ip->ip_src, sizeof(struct in_addr), p);
  106                         p = fnv_32_buf(&ip->ip_dst, sizeof(struct in_addr), p);
  107                 }
  108                 if (flags & MBUF_HASHFLAG_L4) {
  109                         const uint32_t *ports;
  110                         int iphlen;
  111 
  112                         switch (ip->ip_p) {
  113                         case IPPROTO_TCP:
  114                         case IPPROTO_UDP:
  115                         case IPPROTO_SCTP:
  116                                 iphlen = ip->ip_hl << 2;
  117                                 if (iphlen < sizeof(*ip))
  118                                         break;
  119                                 off += iphlen;
  120                                 ports = m_common_hash_gethdr(m,
  121                                     off, sizeof(*ports), &buf);
  122                                 if (ports == NULL)
  123                                         break;
  124                                 p = fnv_32_buf(ports, sizeof(*ports), p);
  125                                 break;
  126                         default:
  127                                 break;
  128                         }
  129                 }
  130                 break;
  131 #endif
  132 #ifdef INET6
  133         case ETHERTYPE_IPV6:
  134                 ip6 = m_common_hash_gethdr(m, off, sizeof(*ip6), &buf);
  135                 if (ip6 == NULL)
  136                         break;
  137                 if (flags & MBUF_HASHFLAG_L3) {
  138                         p = fnv_32_buf(&ip6->ip6_src, sizeof(struct in6_addr), p);
  139                         p = fnv_32_buf(&ip6->ip6_dst, sizeof(struct in6_addr), p);
  140                 }
  141                 if (flags & MBUF_HASHFLAG_L4) {
  142                         uint32_t flow;
  143 
  144                         /* IPv6 flow label */
  145                         flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
  146                         p = fnv_32_buf(&flow, sizeof(flow), p);
  147                 }
  148                 break;
  149 #endif
  150         default:
  151                 break;
  152         }
  153         return (p);
  154 }
  155 
  156 uint32_t
  157 m_ether_tcpip_hash(const uint32_t flags, const struct mbuf *m,
  158     uint32_t p)
  159 {
  160         union {
  161                 struct ether_vlan_header vlan;
  162         } buf;
  163         const struct ether_header *eh;
  164         const struct ether_vlan_header *vlan;
  165         int off;
  166         uint16_t etype;
  167 
  168         off = sizeof(*eh);
  169         if (m->m_len < off)
  170                 return (p);
  171         eh = mtod(m, struct ether_header *);
  172         etype = ntohs(eh->ether_type);
  173         if (flags & MBUF_HASHFLAG_L2) {
  174                 p = fnv_32_buf(&eh->ether_shost, ETHER_ADDR_LEN, p);
  175                 p = fnv_32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p);
  176         }
  177         /* Special handling for encapsulating VLAN frames */
  178         if ((m->m_flags & M_VLANTAG) && (flags & MBUF_HASHFLAG_L2)) {
  179                 p = fnv_32_buf(&m->m_pkthdr.ether_vtag,
  180                     sizeof(m->m_pkthdr.ether_vtag), p);
  181         } else if (etype == ETHERTYPE_VLAN) {
  182                 vlan = m_common_hash_gethdr(m, off, sizeof(*vlan), &buf);
  183                 if (vlan == NULL)
  184                         return (p);
  185 
  186                 if (flags & MBUF_HASHFLAG_L2)
  187                         p = fnv_32_buf(&vlan->evl_tag, sizeof(vlan->evl_tag), p);
  188                 etype = ntohs(vlan->evl_proto);
  189                 off += sizeof(*vlan) - sizeof(*eh);
  190         }
  191         return (m_tcpip_hash(flags, m, p, off, etype));
  192 }
  193 
  194 uint32_t
  195 m_infiniband_tcpip_hash(const uint32_t flags, const struct mbuf *m,
  196     uint32_t p)
  197 {
  198         const struct infiniband_header *ibh;
  199         int off;
  200         uint16_t etype;
  201 
  202         off = sizeof(*ibh);
  203         if (m->m_len < off)
  204                 return (p);
  205         ibh = mtod(m, struct infiniband_header *);
  206         etype = ntohs(ibh->ib_protocol);
  207         if (flags & MBUF_HASHFLAG_L2)
  208                 p = fnv_32_buf(&ibh->ib_hwaddr, INFINIBAND_ADDR_LEN, p);
  209 
  210         return (m_tcpip_hash(flags, m, p, off, etype));
  211 }

Cache object: f1ef84302167fa3f1e3680ea24e27071


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.