* 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
| 209 | * assign flowid/flowtype as appropriate. |
| 210 | */ |
| 211 | int |
| 212 | rss_mbuf_software_hash_v4(const struct mbuf *m, int dir, uint32_t *hashval, |
| 213 | uint32_t *hashtype) |
| 214 | { |
| 215 | const struct ip *ip; |
| 216 | const struct tcphdr *th; |
| 217 | const struct udphdr *uh; |
| 218 | uint32_t flowid; |
| 219 | uint32_t flowtype; |
| 220 | uint8_t proto; |
| 221 | int iphlen; |
| 222 | int is_frag = 0; |
| 223 | |
| 224 | /* |
| 225 | * XXX For now this only handles hashing on incoming mbufs. |
| 226 | */ |
| 227 | if (dir != RSS_HASH_PKT_INGRESS) { |
| 228 | RSS_DEBUG("called on EGRESS packet!\n"); |
| 229 | return (-1); |
| 230 | } |
| 231 | |
| 232 | /* |
| 233 | * First, validate that the mbuf we have is long enough |
| 234 | * to have an IPv4 header in it. |
| 235 | */ |
| 236 | if (m->m_pkthdr.len < (sizeof(struct ip))) { |
| 237 | RSS_DEBUG("short mbuf pkthdr\n"); |
| 238 | return (-1); |
| 239 | } |
| 240 | if (m->m_len < (sizeof(struct ip))) { |
| 241 | RSS_DEBUG("short mbuf len\n"); |
| 242 | return (-1); |
| 243 | } |
| 244 | |
| 245 | /* Ok, let's dereference that */ |
| 246 | ip = mtod(m, struct ip *); |
| 247 | proto = ip->ip_p; |
| 248 | iphlen = ip->ip_hl << 2; |
| 249 | |
| 250 | /* |
| 251 | * If this is a fragment then it shouldn't be four-tuple |
| 252 | * hashed just yet. Once it's reassembled into a full |
| 253 | * frame it should be re-hashed. |
| 254 | */ |
| 255 | if (ip->ip_off & htons(IP_MF | IP_OFFMASK)) |
| 256 | is_frag = 1; |
| 257 | |
| 258 | /* |
| 259 | * If the mbuf flowid/flowtype matches the packet type, |
| 260 | * and we don't support the 4-tuple version of the given protocol, |
| 261 | * then signal to the owner that it can trust the flowid/flowtype |
| 262 | * details. |
| 263 | * |
| 264 | * This is a little picky - eg, if TCPv4 / UDPv4 hashing |
| 265 | * is supported but we got a TCP/UDP frame only 2-tuple hashed, |
| 266 | * then we shouldn't just "trust" the 2-tuple hash. We need |
| 267 | * a 4-tuple hash. |
| 268 | */ |
no test coverage detected