* Do a software calculation of the RSS for the given mbuf. * * This is typically used by the input path to recalculate the RSS after * some form of packet processing (eg de-capsulation, IP fragment reassembly.) * * dir is the packet direction - RSS_HASH_PKT_INGRESS for incoming and * RSS_HASH_PKT_EGRESS for outgoing. * * Returns 0 if a hash was done, -1 if no hash was done, +1 if * the mb
| 212 | * assign flowid/flowtype as appropriate. |
| 213 | */ |
| 214 | int |
| 215 | rss_mbuf_software_hash_v6(const struct mbuf *m, int dir, uint32_t *hashval, |
| 216 | uint32_t *hashtype) |
| 217 | { |
| 218 | const struct ip6_hdr *ip6; |
| 219 | const struct ip6_frag *ip6f; |
| 220 | const struct tcphdr *th; |
| 221 | const struct udphdr *uh; |
| 222 | uint32_t flowtype; |
| 223 | uint8_t proto; |
| 224 | int off, newoff; |
| 225 | int nxt; |
| 226 | |
| 227 | /* |
| 228 | * XXX For now this only handles hashing on incoming mbufs. |
| 229 | */ |
| 230 | if (dir != RSS_HASH_PKT_INGRESS) { |
| 231 | RSS_DEBUG("called on EGRESS packet!\n"); |
| 232 | return (-1); |
| 233 | } |
| 234 | |
| 235 | off = sizeof(struct ip6_hdr); |
| 236 | |
| 237 | /* |
| 238 | * First, validate that the mbuf we have is long enough |
| 239 | * to have an IPv6 header in it. |
| 240 | */ |
| 241 | if (m->m_pkthdr.len < off) { |
| 242 | RSS_DEBUG("short mbuf pkthdr\n"); |
| 243 | return (-1); |
| 244 | } |
| 245 | if (m->m_len < off) { |
| 246 | RSS_DEBUG("short mbuf len\n"); |
| 247 | return (-1); |
| 248 | } |
| 249 | |
| 250 | /* Ok, let's dereference that */ |
| 251 | ip6 = mtod(m, struct ip6_hdr *); |
| 252 | proto = ip6->ip6_nxt; |
| 253 | |
| 254 | /* |
| 255 | * Find the beginning of the TCP/UDP header. |
| 256 | * |
| 257 | * If this is a fragment then it shouldn't be four-tuple |
| 258 | * hashed just yet. Once it's reassembled into a full |
| 259 | * frame it should be re-hashed. |
| 260 | */ |
| 261 | while (proto != IPPROTO_FRAGMENT) { |
| 262 | newoff = ip6_nexthdr(m, off, proto, &nxt); |
| 263 | if (newoff < 0) |
| 264 | break; |
| 265 | off = newoff; |
| 266 | proto = nxt; |
| 267 | } |
| 268 | |
| 269 | /* |
| 270 | * Ignore the fragment header if this is an "atomic" fragment |
| 271 | * (offset and m bit set to 0) |
no test coverage detected