summaryrefslogtreecommitdiffstats
path: root/src/plugins/acl/public_inlines.h
diff options
context:
space:
mode:
authorAndrew Yourtchenko <ayourtch@gmail.com>2018-06-12 15:15:49 +0200
committerDamjan Marion <dmarion@me.com>2018-06-13 12:13:11 +0000
commitc7d50970d4ed8a4889b4374e6a1559aef7d3dcc0 (patch)
tree1fc664442e2e94cac0edffe73d24e76367fc417e /src/plugins/acl/public_inlines.h
parenteaba9340dab289109106bed3a0d4c76496e496e5 (diff)
acl-plugin: change the src/dst L3 info in 5tuple struct to be always contiguous with L4 data
Using ip46_address_t was convenient from operational point of view but created some difficulties dealing with IPv4 addresses - the extra 3x of u32 padding are costly, and the "holes" mean we can not use the smaller key-value data structures for the lookup. This commit changes the 5tuple layout for the IPv4 case, such that the src/dst addresses directly precede the L4 information. That will allow to treat the same data within 40x8 key-value structure as a 16x8 key-value structure starting with 24 byte offset. Change-Id: Ifea8d266ca0b9c931d44440bf6dc62446c1a83ec Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
Diffstat (limited to 'src/plugins/acl/public_inlines.h')
-rw-r--r--src/plugins/acl/public_inlines.h84
1 files changed, 34 insertions, 50 deletions
diff --git a/src/plugins/acl/public_inlines.h b/src/plugins/acl/public_inlines.h
index e7b085271f6..6b464b36b7a 100644
--- a/src/plugins/acl/public_inlines.h
+++ b/src/plugins/acl/public_inlines.h
@@ -214,11 +214,11 @@ acl_fill_5tuple (acl_main_t * am, vlib_buffer_t * b0, int is_ip6,
if (is_ip6)
{
- clib_memcpy (&p5tuple_pkt->addr,
+ clib_memcpy (&p5tuple_pkt->ip6_addr,
get_ptr_to_offset (b0,
offsetof (ip6_header_t,
src_address) + l3_offset),
- sizeof (p5tuple_pkt->addr));
+ sizeof (p5tuple_pkt->ip6_addr));
proto =
*(u8 *) get_ptr_to_offset (b0,
offsetof (ip6_header_t,
@@ -270,18 +270,12 @@ acl_fill_5tuple (acl_main_t * am, vlib_buffer_t * b0, int is_ip6,
}
else
{
- ip46_address_mask_ip4(&p5tuple_pkt->addr[0]);
- ip46_address_mask_ip4(&p5tuple_pkt->addr[1]);
- clib_memcpy (&p5tuple_pkt->addr[0].ip4,
+ memset(p5tuple_pkt->l3_zero_pad, 0, sizeof(p5tuple_pkt->l3_zero_pad));
+ clib_memcpy (&p5tuple_pkt->ip4_addr,
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));
+ sizeof (p5tuple_pkt->ip4_addr));
proto =
*(u8 *) get_ptr_to_offset (b0,
offsetof (ip4_header_t,
@@ -359,16 +353,29 @@ acl_plugin_fill_5tuple_inline (u32 lc_index, vlib_buffer_t * b0, int is_ip6,
always_inline int
-fa_acl_match_addr (ip46_address_t * addr1, ip46_address_t * addr2,
- int prefixlen, int is_ip6)
+fa_acl_match_ip4_addr (ip4_address_t * addr1, ip4_address_t * addr2,
+ int prefixlen)
{
if (prefixlen == 0)
{
/* match any always succeeds */
return 1;
}
- if (is_ip6)
+ uint32_t a1 = clib_net_to_host_u32 (addr1->as_u32);
+ uint32_t a2 = clib_net_to_host_u32 (addr2->as_u32);
+ uint32_t mask0 = 0xffffffff - ((1 << (32 - prefixlen)) - 1);
+ return (a1 & mask0) == a2;
+}
+
+always_inline int
+fa_acl_match_ip6_addr (ip6_address_t * addr1, ip6_address_t * addr2,
+ int prefixlen)
+{
+ if (prefixlen == 0)
{
+ /* match any always succeeds */
+ return 1;
+ }
if (memcmp (addr1, addr2, prefixlen / 8))
{
/* If the starting full bytes do not match, no point in bittwidling the thumbs further */
@@ -386,14 +393,6 @@ fa_acl_match_addr (ip46_address_t * addr1, ip46_address_t * addr2,
/* The prefix fits into integer number of bytes, so nothing left to do */
return 1;
}
- }
- else
- {
- uint32_t a1 = clib_net_to_host_u32 (addr1->ip4.as_u32);
- uint32_t a2 = clib_net_to_host_u32 (addr2->ip4.as_u32);
- uint32_t mask0 = 0xffffffff - ((1 << (32 - prefixlen)) - 1);
- return (a1 & mask0) == a2;
- }
}
always_inline int
@@ -424,41 +423,26 @@ single_acl_match_5tuple (acl_main_t * am, u32 acl_index, fa_5tuple_t * pkt_5tupl
for (i = 0; i < a->count; i++)
{
r = a->rules + i;
-#ifdef FA_NODE_VERBOSE_DEBUG
- clib_warning("ACL_FA_NODE_DBG acl %d rule %d tag %s", acl_index, i, a->tag);
-#endif
if (is_ip6 != r->is_ipv6)
{
continue;
}
- if (!fa_acl_match_addr
- (&pkt_5tuple->addr[1], &r->dst, r->dst_prefixlen, is_ip6))
+ if (is_ip6) {
+ if (!fa_acl_match_ip6_addr
+ (&pkt_5tuple->ip6_addr[1], &r->dst.ip6, r->dst_prefixlen))
continue;
-
-#ifdef FA_NODE_VERBOSE_DEBUG
- clib_warning
- ("ACL_FA_NODE_DBG acl %d rule %d pkt dst addr %U match rule addr %U/%d",
- acl_index, i, format_ip46_address, &pkt_5tuple->addr[1],
- r->is_ipv6 ? IP46_TYPE_IP6: IP46_TYPE_IP4, format_ip46_address,
- &r->dst, r->is_ipv6 ? IP46_TYPE_IP6: IP46_TYPE_IP4,
- r->dst_prefixlen);
-#endif
-
- if (!fa_acl_match_addr
- (&pkt_5tuple->addr[0], &r->src, r->src_prefixlen, is_ip6))
+ if (!fa_acl_match_ip6_addr
+ (&pkt_5tuple->ip6_addr[0], &r->src.ip6, r->src_prefixlen))
+ continue;
+ } else {
+ if (!fa_acl_match_ip4_addr
+ (&pkt_5tuple->ip4_addr[1], &r->dst.ip4, r->dst_prefixlen))
+ continue;
+ if (!fa_acl_match_ip4_addr
+ (&pkt_5tuple->ip4_addr[0], &r->src.ip4, r->src_prefixlen))
continue;
+ }
-#ifdef FA_NODE_VERBOSE_DEBUG
- clib_warning
- ("ACL_FA_NODE_DBG acl %d rule %d pkt src addr %U match rule addr %U/%d",
- acl_index, i, format_ip46_address, &pkt_5tuple->addr[0],
- r->is_ipv6 ? IP46_TYPE_IP6: IP46_TYPE_IP4, format_ip46_address,
- &r->src, r->is_ipv6 ? IP46_TYPE_IP6: IP46_TYPE_IP4,
- r->src_prefixlen);
- clib_warning
- ("ACL_FA_NODE_DBG acl %d rule %d trying to match pkt proto %d with rule %d",
- acl_index, i, pkt_5tuple->l4.proto, r->proto);
-#endif
if (r->proto)
{
if (pkt_5tuple->l4.proto != r->proto)