-static void
-acl_fill_5tuple (acl_main_t * am, vlib_buffer_t * b0, int is_ip6,
- int is_input, int is_l2_path, fa_5tuple_t * p5tuple_pkt)
-{
- int l3_offset = ethernet_buffer_header_size(b0);
- int l4_offset;
- u16 ports[2];
- u16 proto;
- /* IP4 and IP6 protocol numbers of ICMP */
- static u8 icmp_protos[] = { IP_PROTOCOL_ICMP, IP_PROTOCOL_ICMP6 };
-
- if (is_input && !(is_l2_path))
- {
- l3_offset = 0;
- }
-
- /* key[0..3] contains src/dst address and is cleared/set below */
- /* Remainder of the key and per-packet non-key data */
- p5tuple_pkt->kv.key[4] = 0;
- p5tuple_pkt->kv.value = 0;
-
- if (is_ip6)
- {
- clib_memcpy (&p5tuple_pkt->addr,
- get_ptr_to_offset (b0,
- offsetof (ip6_header_t,
- src_address) + l3_offset),
- sizeof (p5tuple_pkt->addr));
- proto =
- *(u8 *) get_ptr_to_offset (b0,
- offsetof (ip6_header_t,
- protocol) + l3_offset);
- l4_offset = l3_offset + sizeof (ip6_header_t);
-#ifdef FA_NODE_VERBOSE_DEBUG
- clib_warning ("ACL_FA_NODE_DBG: proto: %d, l4_offset: %d", proto,
- l4_offset);
-#endif
- /* IP6 EH handling is here, increment l4_offset if needs to, update the proto */
- int need_skip_eh = clib_bitmap_get (am->fa_ipv6_known_eh_bitmap, proto);
- if (PREDICT_FALSE (need_skip_eh))
- {
- while (need_skip_eh && offset_within_packet (b0, l4_offset))
- {
- /* Fragment header needs special handling */
- if (PREDICT_FALSE(ACL_EH_FRAGMENT == proto))
- {
- proto = *(u8 *) get_ptr_to_offset (b0, l4_offset);
- u16 frag_offset;
- clib_memcpy (&frag_offset, get_ptr_to_offset (b0, 2 + l4_offset), sizeof(frag_offset));
- frag_offset = ntohs(frag_offset) >> 3;
- if (frag_offset)
- {
- p5tuple_pkt->pkt.is_nonfirst_fragment = 1;
- /* invalidate L4 offset so we don't try to find L4 info */
- l4_offset += b0->current_length;
- }
- else
- {
- /* First fragment: skip the frag header and move on. */
- l4_offset += 8;
- }
- }
- else
- {
- u8 nwords = *(u8 *) get_ptr_to_offset (b0, 1 + l4_offset);
- proto = *(u8 *) get_ptr_to_offset (b0, l4_offset);
- l4_offset += 8 * (1 + (u16) nwords);
- }
-#ifdef FA_NODE_VERBOSE_DEBUG
- clib_warning ("ACL_FA_NODE_DBG: new proto: %d, new offset: %d",
- proto, l4_offset);
-#endif
- need_skip_eh =
- clib_bitmap_get (am->fa_ipv6_known_eh_bitmap, proto);
- }
- }
- }
- else
- {
- p5tuple_pkt->kv.key[0] = 0;
- p5tuple_pkt->kv.key[1] = 0;
- p5tuple_pkt->kv.key[2] = 0;
- p5tuple_pkt->kv.key[3] = 0;
- clib_memcpy (&p5tuple_pkt->addr[0].ip4,
- get_ptr_to_offset (b0,
- offsetof (ip4_header_t,
- src_address) + l3_offset),
- sizeof (p5tuple_pkt->addr[0].ip4));
- clib_memcpy (&p5tuple_pkt->addr[1].ip4,
- get_ptr_to_offset (b0,
- offsetof (ip4_header_t,
- dst_address) + l3_offset),
- sizeof (p5tuple_pkt->addr[1].ip4));
- proto =
- *(u8 *) get_ptr_to_offset (b0,
- offsetof (ip4_header_t,
- protocol) + l3_offset);
- l4_offset = l3_offset + sizeof (ip4_header_t);
- u16 flags_and_fragment_offset;
- clib_memcpy (&flags_and_fragment_offset,
- get_ptr_to_offset (b0,
- offsetof (ip4_header_t,
- flags_and_fragment_offset)) + l3_offset,
- sizeof(flags_and_fragment_offset));
- flags_and_fragment_offset = ntohs (flags_and_fragment_offset);
-
- /* non-initial fragments have non-zero offset */
- if ((PREDICT_FALSE(0xfff & flags_and_fragment_offset)))