diff options
author | Benoît Ganne <bganne@cisco.com> | 2023-08-02 11:31:46 +0200 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2024-02-22 08:24:02 +0000 |
commit | 89c7b545dd3333092e718e2a9194ed72c27a54f7 (patch) | |
tree | 33d3982d43df469e5ab2f5eea5ac0df699241e47 /src/vnet | |
parent | 8074fc6209c97eba0d4d5e8391cae0f5fb61a5c4 (diff) |
ip6: ECMP hash support for ipv6 fragments
Type: improvement
Change-Id: I41f70e5977fedbf0050205ebe52126ef373ebc06
Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/ip/ip6_inlines.h | 31 | ||||
-rw-r--r-- | src/vnet/ip/ip6_packet.h | 7 |
2 files changed, 27 insertions, 11 deletions
diff --git a/src/vnet/ip/ip6_inlines.h b/src/vnet/ip/ip6_inlines.h index 4a2b91b9ec9..9bd475224eb 100644 --- a/src/vnet/ip/ip6_inlines.h +++ b/src/vnet/ip/ip6_inlines.h @@ -49,31 +49,40 @@ always_inline u32 ip6_compute_flow_hash (const ip6_header_t * ip, flow_hash_config_t flow_hash_config) { - tcp_header_t *tcp; - udp_header_t *udp = (void *) (ip + 1); - gtpv1u_header_t *gtpu = (void *) (udp + 1); + const tcp_header_t *tcp; + const udp_header_t *udp = (void *) (ip + 1); + const gtpv1u_header_t *gtpu = (void *) (udp + 1); u64 a, b, c; u64 t1, t2; u32 t3; uword is_tcp_udp = 0; - uword is_udp = ip->protocol == IP_PROTOCOL_UDP; u8 protocol = ip->protocol; + uword is_udp = protocol == IP_PROTOCOL_UDP; - if (PREDICT_TRUE ((ip->protocol == IP_PROTOCOL_TCP) || is_udp)) + if (PREDICT_TRUE ((protocol == IP_PROTOCOL_TCP) || is_udp)) { is_tcp_udp = 1; tcp = (void *) (ip + 1); } - else if (ip->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) + else { - ip6_hop_by_hop_header_t *hbh = (ip6_hop_by_hop_header_t *) (ip + 1); - if ((hbh->protocol == IP_PROTOCOL_TCP) || - (hbh->protocol == IP_PROTOCOL_UDP)) + const void *cur = ip + 1; + if (protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) + { + const ip6_hop_by_hop_header_t *hbh = cur; + protocol = hbh->protocol; + cur += (hbh->length + 1) * 8; + } + if (protocol == IP_PROTOCOL_IPV6_FRAGMENTATION) + { + const ip6_fragment_ext_header_t *frag = cur; + protocol = frag->protocol; + } + else if (protocol == IP_PROTOCOL_TCP || protocol == IP_PROTOCOL_UDP) { is_tcp_udp = 1; - tcp = (tcp_header_t *) ((u8 *) hbh + ((hbh->length + 1) << 3)); + tcp = cur; } - protocol = hbh->protocol; } t1 = (ip->src_address.as_u64[0] ^ ip->src_address.as_u64[1]); diff --git a/src/vnet/ip/ip6_packet.h b/src/vnet/ip/ip6_packet.h index e71604ce7d3..c506792ddcf 100644 --- a/src/vnet/ip/ip6_packet.h +++ b/src/vnet/ip/ip6_packet.h @@ -441,6 +441,13 @@ typedef CLIB_PACKED (struct { }) ip6_router_alert_option_t; typedef CLIB_PACKED (struct { + u8 protocol; + u8 reserved; + u16 fragoff; + u32 id; +}) ip6_fragment_ext_header_t; + +typedef CLIB_PACKED (struct { u8 next_hdr; /* Length of this header plus option data in 8 byte units. */ u8 n_data_u64s; |