1b2bdc62aSAdrian Chadd /*- 2b2bdc62aSAdrian Chadd * Copyright (c) 2010-2011 Juniper Networks, Inc. 3b2bdc62aSAdrian Chadd * All rights reserved. 4b2bdc62aSAdrian Chadd * 5b2bdc62aSAdrian Chadd * This software was developed by Robert N. M. Watson under contract 6b2bdc62aSAdrian Chadd * to Juniper Networks, Inc. 7b2bdc62aSAdrian Chadd * 8b2bdc62aSAdrian Chadd * Redistribution and use in source and binary forms, with or without 9b2bdc62aSAdrian Chadd * modification, are permitted provided that the following conditions 10b2bdc62aSAdrian Chadd * are met: 11b2bdc62aSAdrian Chadd * 1. Redistributions of source code must retain the above copyright 12b2bdc62aSAdrian Chadd * notice, this list of conditions and the following disclaimer. 13b2bdc62aSAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright 14b2bdc62aSAdrian Chadd * notice, this list of conditions and the following disclaimer in the 15b2bdc62aSAdrian Chadd * documentation and/or other materials provided with the distribution. 16b2bdc62aSAdrian Chadd * 17b2bdc62aSAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18b2bdc62aSAdrian Chadd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19b2bdc62aSAdrian Chadd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20b2bdc62aSAdrian Chadd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21b2bdc62aSAdrian Chadd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22b2bdc62aSAdrian Chadd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23b2bdc62aSAdrian Chadd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24b2bdc62aSAdrian Chadd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25b2bdc62aSAdrian Chadd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26b2bdc62aSAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27b2bdc62aSAdrian Chadd * SUCH DAMAGE. 28b2bdc62aSAdrian Chadd */ 29b2bdc62aSAdrian Chadd 30b2bdc62aSAdrian Chadd #include <sys/cdefs.h> 31b2bdc62aSAdrian Chadd 32b2bdc62aSAdrian Chadd __FBSDID("$FreeBSD$"); 33b2bdc62aSAdrian Chadd 34b2bdc62aSAdrian Chadd #include "opt_inet6.h" 35b2bdc62aSAdrian Chadd #include "opt_pcbgroup.h" 36b2bdc62aSAdrian Chadd 37b2bdc62aSAdrian Chadd #ifndef PCBGROUP 38b2bdc62aSAdrian Chadd #error "options RSS depends on options PCBGROUP" 39b2bdc62aSAdrian Chadd #endif 40b2bdc62aSAdrian Chadd 41b2bdc62aSAdrian Chadd #include <sys/param.h> 42b2bdc62aSAdrian Chadd #include <sys/mbuf.h> 43b2bdc62aSAdrian Chadd #include <sys/socket.h> 44b2bdc62aSAdrian Chadd #include <sys/priv.h> 45b2bdc62aSAdrian Chadd #include <sys/kernel.h> 46b2bdc62aSAdrian Chadd #include <sys/smp.h> 47b2bdc62aSAdrian Chadd #include <sys/sysctl.h> 48b2bdc62aSAdrian Chadd #include <sys/sbuf.h> 49b2bdc62aSAdrian Chadd 50b2bdc62aSAdrian Chadd #include <net/if.h> 51b2bdc62aSAdrian Chadd #include <net/if_var.h> 52b2bdc62aSAdrian Chadd #include <net/netisr.h> 53b2bdc62aSAdrian Chadd #include <net/rss_config.h> 54b2bdc62aSAdrian Chadd 55b2bdc62aSAdrian Chadd #include <netinet/in.h> 56b2bdc62aSAdrian Chadd #include <netinet/in_pcb.h> 57b2bdc62aSAdrian Chadd #include <netinet6/in6_rss.h> 58b2bdc62aSAdrian Chadd #include <netinet/in_var.h> 59b2bdc62aSAdrian Chadd 60b2bdc62aSAdrian Chadd /* for software rss hash support */ 61b2bdc62aSAdrian Chadd #include <netinet/ip.h> 62b2bdc62aSAdrian Chadd #include <netinet/tcp.h> 63b2bdc62aSAdrian Chadd #include <netinet/udp.h> 64b2bdc62aSAdrian Chadd 65b2bdc62aSAdrian Chadd /* 66b2bdc62aSAdrian Chadd * Hash an IPv6 2-tuple. 67b2bdc62aSAdrian Chadd */ 68b2bdc62aSAdrian Chadd uint32_t 69b2bdc62aSAdrian Chadd rss_hash_ip6_2tuple(const struct in6_addr *src, const struct in6_addr *dst) 70b2bdc62aSAdrian Chadd { 71b2bdc62aSAdrian Chadd uint8_t data[sizeof(*src) + sizeof(*dst)]; 72b2bdc62aSAdrian Chadd u_int datalen; 73b2bdc62aSAdrian Chadd 74b2bdc62aSAdrian Chadd datalen = 0; 75b2bdc62aSAdrian Chadd bcopy(src, &data[datalen], sizeof(*src)); 76b2bdc62aSAdrian Chadd datalen += sizeof(*src); 77b2bdc62aSAdrian Chadd bcopy(dst, &data[datalen], sizeof(*dst)); 78b2bdc62aSAdrian Chadd datalen += sizeof(*dst); 79b2bdc62aSAdrian Chadd return (rss_hash(datalen, data)); 80b2bdc62aSAdrian Chadd } 81b2bdc62aSAdrian Chadd 82b2bdc62aSAdrian Chadd /* 83b2bdc62aSAdrian Chadd * Hash an IPv6 4-tuple. 84b2bdc62aSAdrian Chadd */ 85b2bdc62aSAdrian Chadd uint32_t 86b2bdc62aSAdrian Chadd rss_hash_ip6_4tuple(const struct in6_addr *src, u_short srcport, 87b2bdc62aSAdrian Chadd const struct in6_addr *dst, u_short dstport) 88b2bdc62aSAdrian Chadd { 89b2bdc62aSAdrian Chadd uint8_t data[sizeof(*src) + sizeof(*dst) + sizeof(srcport) + 90b2bdc62aSAdrian Chadd sizeof(dstport)]; 91b2bdc62aSAdrian Chadd u_int datalen; 92b2bdc62aSAdrian Chadd 93b2bdc62aSAdrian Chadd datalen = 0; 94b2bdc62aSAdrian Chadd bcopy(src, &data[datalen], sizeof(*src)); 95b2bdc62aSAdrian Chadd datalen += sizeof(*src); 96b2bdc62aSAdrian Chadd bcopy(dst, &data[datalen], sizeof(*dst)); 97b2bdc62aSAdrian Chadd datalen += sizeof(*dst); 98b2bdc62aSAdrian Chadd bcopy(&srcport, &data[datalen], sizeof(srcport)); 99b2bdc62aSAdrian Chadd datalen += sizeof(srcport); 100b2bdc62aSAdrian Chadd bcopy(&dstport, &data[datalen], sizeof(dstport)); 101b2bdc62aSAdrian Chadd datalen += sizeof(dstport); 102b2bdc62aSAdrian Chadd return (rss_hash(datalen, data)); 103b2bdc62aSAdrian Chadd } 104*20dbdf88SAdrian Chadd 105*20dbdf88SAdrian Chadd /* 106*20dbdf88SAdrian Chadd * Calculate an appropriate ipv6 2-tuple or 4-tuple given the given 107*20dbdf88SAdrian Chadd * IPv6 source/destination address, UDP or TCP source/destination ports 108*20dbdf88SAdrian Chadd * and the protocol type. 109*20dbdf88SAdrian Chadd * 110*20dbdf88SAdrian Chadd * The protocol code may wish to do a software hash of the given 111*20dbdf88SAdrian Chadd * tuple. This depends upon the currently configured RSS hash types. 112*20dbdf88SAdrian Chadd * 113*20dbdf88SAdrian Chadd * This assumes that the packet in question isn't a fragment. 114*20dbdf88SAdrian Chadd * 115*20dbdf88SAdrian Chadd * It also assumes the packet source/destination address 116*20dbdf88SAdrian Chadd * are in "incoming" packet order (ie, source is "far" address.) 117*20dbdf88SAdrian Chadd */ 118*20dbdf88SAdrian Chadd int 119*20dbdf88SAdrian Chadd rss_proto_software_hash_v6(const struct in6_addr *s, const struct in6_addr *d, 120*20dbdf88SAdrian Chadd u_short sp, u_short dp, int proto, 121*20dbdf88SAdrian Chadd uint32_t *hashval, uint32_t *hashtype) 122*20dbdf88SAdrian Chadd { 123*20dbdf88SAdrian Chadd uint32_t hash; 124*20dbdf88SAdrian Chadd 125*20dbdf88SAdrian Chadd /* 126*20dbdf88SAdrian Chadd * Next, choose the hash type depending upon the protocol 127*20dbdf88SAdrian Chadd * identifier. 128*20dbdf88SAdrian Chadd */ 129*20dbdf88SAdrian Chadd if ((proto == IPPROTO_TCP) && 130*20dbdf88SAdrian Chadd (rss_gethashconfig() & RSS_HASHTYPE_RSS_TCP_IPV6)) { 131*20dbdf88SAdrian Chadd hash = rss_hash_ip6_4tuple(s, sp, d, dp); 132*20dbdf88SAdrian Chadd *hashval = hash; 133*20dbdf88SAdrian Chadd *hashtype = M_HASHTYPE_RSS_TCP_IPV6; 134*20dbdf88SAdrian Chadd return (0); 135*20dbdf88SAdrian Chadd } else if ((proto == IPPROTO_UDP) && 136*20dbdf88SAdrian Chadd (rss_gethashconfig() & RSS_HASHTYPE_RSS_UDP_IPV6)) { 137*20dbdf88SAdrian Chadd hash = rss_hash_ip6_4tuple(s, sp, d, dp); 138*20dbdf88SAdrian Chadd *hashval = hash; 139*20dbdf88SAdrian Chadd *hashtype = M_HASHTYPE_RSS_UDP_IPV6; 140*20dbdf88SAdrian Chadd return (0); 141*20dbdf88SAdrian Chadd } else if (rss_gethashconfig() & RSS_HASHTYPE_RSS_IPV6) { 142*20dbdf88SAdrian Chadd /* RSS doesn't hash on other protocols like SCTP; so 2-tuple */ 143*20dbdf88SAdrian Chadd hash = rss_hash_ip6_2tuple(s, d); 144*20dbdf88SAdrian Chadd *hashval = hash; 145*20dbdf88SAdrian Chadd *hashtype = M_HASHTYPE_RSS_IPV6; 146*20dbdf88SAdrian Chadd return (0); 147*20dbdf88SAdrian Chadd } 148*20dbdf88SAdrian Chadd 149*20dbdf88SAdrian Chadd /* No configured available hashtypes! */ 150*20dbdf88SAdrian Chadd printf("%s: no available hashtypes!\n", __func__); 151*20dbdf88SAdrian Chadd return (-1); 152*20dbdf88SAdrian Chadd } 153