X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip6_packet.h;h=c1bd2aa3bf7a5cd265e548bbaee984523ed55e1d;hb=038e1dfbd;hp=b1c9be4d19932a62efcaee8b269fc619fd924adc;hpb=d69f4396bfe6b41ca04b7fc1496475f0a635b0da;p=vpp.git diff --git a/src/vnet/ip/ip6_packet.h b/src/vnet/ip/ip6_packet.h index b1c9be4d199..c1bd2aa3bf7 100644 --- a/src/vnet/ip/ip6_packet.h +++ b/src/vnet/ip/ip6_packet.h @@ -75,7 +75,7 @@ typedef enum } ip46_type_t; /* *INDENT-OFF* */ -typedef CLIB_PACKED (union { +typedef CLIB_PACKED (union ip46_address_t_ { struct { u32 pad[3]; ip4_address_t ip4; @@ -95,6 +95,35 @@ typedef CLIB_PACKED (union { && ((a1)->as_u64[1] == (a2)->as_u64[1])) #define ip46_address_initializer {{{ 0 }}} +static_always_inline int +ip46_address_is_equal_v4 (const ip46_address_t * ip46, + const ip4_address_t * ip4) +{ + return (ip46->ip4.as_u32 == ip4->as_u32); +} + +static_always_inline int +ip46_address_is_equal_v6 (const ip46_address_t * ip46, + const ip6_address_t * ip6) +{ + return ((ip46->ip6.as_u64[0] == ip6->as_u64[0]) && + (ip46->ip6.as_u64[1] == ip6->as_u64[1])); +} + +static_always_inline void +ip46_address_copy (ip46_address_t * dst, const ip46_address_t * src) +{ + dst->as_u64[0] = src->as_u64[0]; + dst->as_u64[1] = src->as_u64[1]; +} + +static_always_inline void +ip46_address_set_ip6 (ip46_address_t * dst, const ip6_address_t * src) +{ + dst->as_u64[0] = src->as_u64[0]; + dst->as_u64[1] = src->as_u64[1]; +} + always_inline ip46_address_t to_ip46 (u32 is_ipv6, u8 * buf) { @@ -167,6 +196,13 @@ ip46_address_is_multicast (const ip46_address_t * a) ip6_address_is_multicast (&a->ip6); } +always_inline void +ip6_address_copy (ip6_address_t * dst, const ip6_address_t * src) +{ + dst->as_u64[0] = src->as_u64[0]; + dst->as_u64[1] = src->as_u64[1]; +} + always_inline void ip6_set_reserved_multicast_address (ip6_address_t * a, ip6_multicast_address_scope_t scope, @@ -189,23 +225,6 @@ ip6_set_solicited_node_multicast_address (ip6_address_t * a, u32 id) a->as_u32[3] = clib_host_to_net_u32 (id); } -always_inline void -ip6_link_local_address_from_ethernet_address (ip6_address_t * a, - const u8 * ethernet_address) -{ - a->as_u64[0] = a->as_u64[1] = 0; - a->as_u16[0] = clib_host_to_net_u16 (0xfe80); - /* Always set locally administered bit (6). */ - a->as_u8[0x8] = ethernet_address[0] | (1 << 6); - a->as_u8[0x9] = ethernet_address[1]; - a->as_u8[0xa] = ethernet_address[2]; - a->as_u8[0xb] = 0xff; - a->as_u8[0xc] = 0xfe; - a->as_u8[0xd] = ethernet_address[3]; - a->as_u8[0xe] = ethernet_address[4]; - a->as_u8[0xf] = ethernet_address[5]; -} - always_inline void ip6_multicast_ethernet_address (u8 * ethernet_address, u32 group_id) { @@ -266,7 +285,7 @@ ip6_address_mask_from_width (ip6_address_t * a, u32 width) { int i, byte, bit, bitnum; ASSERT (width <= 128); - memset (a, 0, sizeof (a[0])); + clib_memset (a, 0, sizeof (a[0])); for (i = 0; i < width; i++) { bitnum = (7 - (i & 7)); @@ -333,6 +352,18 @@ ip6_is_solicited_node_multicast_address (const ip6_address_t * a) && a->as_u8[12] == 0xff); } +always_inline u32 +ip6_address_hash_to_u32 (const ip6_address_t * a) +{ + return (a->as_u32[0] ^ a->as_u32[1] ^ a->as_u32[2] ^ a->as_u32[3]); +} + +always_inline u64 +ip6_address_hash_to_u64 (const ip6_address_t * a) +{ + return (a->as_u64[0] ^ a->as_u64[1]); +} + typedef struct { /* 4 bit version, 8 bit traffic class and 20 bit flow label. */ @@ -352,13 +383,13 @@ typedef struct ip6_address_t src_address, dst_address; } ip6_header_t; -always_inline u8 +always_inline ip_dscp_t ip6_traffic_class (const ip6_header_t * i) { return (i->ip_version_traffic_class_and_flow_label & 0x0FF00000) >> 20; } -static_always_inline u8 +static_always_inline ip_dscp_t ip6_traffic_class_network_order (const ip6_header_t * ip6) { return (clib_net_to_host_u32 (ip6->ip_version_traffic_class_and_flow_label) @@ -366,7 +397,7 @@ ip6_traffic_class_network_order (const ip6_header_t * ip6) } static_always_inline void -ip6_set_traffic_class_network_order (ip6_header_t * ip6, u8 dscp) +ip6_set_traffic_class_network_order (ip6_header_t * ip6, ip_dscp_t dscp) { u32 tmp = clib_net_to_host_u32 (ip6->ip_version_traffic_class_and_flow_label); @@ -480,16 +511,36 @@ typedef CLIB_PACKED (struct { u8 n_data_u64s; }) ip6_ext_header_t; +#define foreach_ext_hdr_type \ + _(IP6_HOP_BY_HOP_OPTIONS) \ + _(IPV6_ROUTE) \ + _(IPV6_FRAGMENTATION) \ + _(IPSEC_ESP) \ + _(IPSEC_AH) \ + _(IP6_DESTINATION_OPTIONS) \ + _(MOBILITY) \ + _(HIP) \ + _(SHIM6) + always_inline u8 ip6_ext_hdr(u8 nexthdr) { +#ifdef CLIB_HAVE_VEC128 + static const u8x16 ext_hdr_types = { +#define _(x) IP_PROTOCOL_##x, + foreach_ext_hdr_type +#undef _ + }; + + return !u8x16_is_all_zero (ext_hdr_types == u8x16_splat (nexthdr)); +#else /* * find out if nexthdr is an extension header or a protocol */ - return (nexthdr == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) || - (nexthdr == IP_PROTOCOL_IPV6_FRAGMENTATION) || - (nexthdr == IP_PROTOCOL_IPSEC_AH) || - (nexthdr == IP_PROTOCOL_IPV6_ROUTE) || - (nexthdr == IP_PROTOCOL_IP6_DESTINATION_OPTIONS); + return 0 +#define _(x) || (nexthdr == IP_PROTOCOL_##x) + foreach_ext_hdr_type; +#undef _ +#endif } #define ip6_ext_header_len(p) ((((ip6_ext_header_t *)(p))->n_data_u64s+1) << 3)