}
static void
-make_address_mask(ip46_address_t *addr, u8 is_ipv6, u8 prefix_len)
+make_ip6_address_mask(ip6_address_t *addr, u8 prefix_len)
{
- if (is_ipv6) {
- ip6_address_mask_from_width(&addr->ip6, prefix_len);
- } else {
- /* FIXME: this may not be correct way */
- ip6_address_mask_from_width(&addr->ip6, prefix_len + 3*32);
- ip46_address_mask_ip4(addr);
- }
+ ip6_address_mask_from_width(addr, prefix_len);
+}
+
+
+/* Maybe should be moved into the core somewhere */
+always_inline void
+ip4_address_mask_from_width (ip4_address_t * a, u32 width)
+{
+ int i, byte, bit, bitnum;
+ ASSERT (width <= 32);
+ memset (a, 0, sizeof (a[0]));
+ for (i = 0; i < width; i++)
+ {
+ bitnum = (7 - (i & 7));
+ byte = i / 8;
+ bit = 1 << bitnum;
+ a->as_u8[byte] |= bit;
+ }
+}
+
+
+static void
+make_ip4_address_mask(ip4_address_t *addr, u8 prefix_len)
+{
+ ip4_address_mask_from_width(addr, prefix_len);
}
static u8
}
static void
-make_mask_and_match_from_rule(fa_5tuple_t *mask, acl_rule_t *r, hash_ace_info_t *hi, int match_nonfirst_fragment)
+make_mask_and_match_from_rule(fa_5tuple_t *mask, acl_rule_t *r, hash_ace_info_t *hi)
{
memset(mask, 0, sizeof(*mask));
memset(&hi->match, 0, sizeof(hi->match));
mask->pkt.is_ip6 = 1;
hi->match.pkt.is_ip6 = r->is_ipv6;
-
- make_address_mask(&mask->addr[0], r->is_ipv6, r->src_prefixlen);
- hi->match.addr[0] = r->src;
- make_address_mask(&mask->addr[1], r->is_ipv6, r->dst_prefixlen);
- hi->match.addr[1] = r->dst;
+ if (r->is_ipv6) {
+ make_ip6_address_mask(&mask->ip6_addr[0], r->src_prefixlen);
+ hi->match.ip6_addr[0] = r->src.ip6;
+ make_ip6_address_mask(&mask->ip6_addr[1], r->dst_prefixlen);
+ hi->match.ip6_addr[1] = r->dst.ip6;
+ } else {
+ memset(hi->match.l3_zero_pad, 0, sizeof(hi->match.l3_zero_pad));
+ make_ip4_address_mask(&mask->ip4_addr[0], r->src_prefixlen);
+ hi->match.ip4_addr[0] = r->src.ip4;
+ make_ip4_address_mask(&mask->ip4_addr[1], r->dst_prefixlen);
+ hi->match.ip4_addr[1] = r->dst.ip4;
+ }
if (r->proto != 0) {
mask->l4.proto = ~0; /* L4 proto needs to be matched */
hi->match.l4.proto = r->proto;
- if (match_nonfirst_fragment) {
- /* match the non-first fragments only */
- mask->pkt.is_nonfirst_fragment = 1;
- hi->match.pkt.is_nonfirst_fragment = 1;
- } else {
- /* Calculate the src/dst port masks and make the src/dst port matches accordingly */
- hi->src_portrange_not_powerof2 = make_port_mask(&mask->l4.port[0], r->src_port_or_type_first, r->src_port_or_type_last);
- hi->match.l4.port[0] = r->src_port_or_type_first & mask->l4.port[0];
- hi->dst_portrange_not_powerof2 = make_port_mask(&mask->l4.port[1], r->dst_port_or_code_first, r->dst_port_or_code_last);
- hi->match.l4.port[1] = r->dst_port_or_code_first & mask->l4.port[1];
- /* L4 info must be valid in order to match */
- mask->pkt.l4_valid = 1;
- hi->match.pkt.l4_valid = 1;
- /* And we must set the mask to check that it is an initial fragment */
- mask->pkt.is_nonfirst_fragment = 1;
- hi->match.pkt.is_nonfirst_fragment = 0;
- if ((r->proto == IPPROTO_TCP) && (r->tcp_flags_mask != 0)) {
- /* if we want to match on TCP flags, they must be masked off as well */
- mask->pkt.tcp_flags = r->tcp_flags_mask;
- hi->match.pkt.tcp_flags = r->tcp_flags_value;
- /* and the flags need to be present within the packet being matched */
- mask->pkt.tcp_flags_valid = 1;
- hi->match.pkt.tcp_flags_valid = 1;
- }
+
+ /* Calculate the src/dst port masks and make the src/dst port matches accordingly */
+ hi->src_portrange_not_powerof2 = make_port_mask(&mask->l4.port[0], r->src_port_or_type_first, r->src_port_or_type_last);
+ hi->match.l4.port[0] = r->src_port_or_type_first & mask->l4.port[0];
+ hi->dst_portrange_not_powerof2 = make_port_mask(&mask->l4.port[1], r->dst_port_or_code_first, r->dst_port_or_code_last);
+ hi->match.l4.port[1] = r->dst_port_or_code_first & mask->l4.port[1];
+ /* L4 info must be valid in order to match */
+ mask->pkt.l4_valid = 1;
+ hi->match.pkt.l4_valid = 1;
+ /* And we must set the mask to check that it is an initial fragment */
+ mask->pkt.is_nonfirst_fragment = 1;
+ hi->match.pkt.is_nonfirst_fragment = 0;
+ if ((r->proto == IPPROTO_TCP) && (r->tcp_flags_mask != 0)) {
+ /* if we want to match on TCP flags, they must be masked off as well */
+ mask->pkt.tcp_flags = r->tcp_flags_mask;
+ hi->match.pkt.tcp_flags = r->tcp_flags_value;
+ /* and the flags need to be present within the packet being matched */
+ mask->pkt.tcp_flags_valid = 1;
+ hi->match.pkt.tcp_flags_valid = 1;
}
}
/* Sanitize the mask and the match */
ace_info.acl_index = acl_index;
ace_info.ace_index = i;
- make_mask_and_match_from_rule(&mask, &a->rules[i], &ace_info, 0);
+ make_mask_and_match_from_rule(&mask, &a->rules[i], &ace_info);
ace_info.mask_type_index = assign_mask_type_index(am, &mask);
/* assign the mask type index for matching itself */
ace_info.match.pkt.mask_type_index_lsb = ace_info.mask_type_index;
/* Ensure a given index is set in the mask type index bitmap for this ACL */
ha->mask_type_index_bitmap = clib_bitmap_set(ha->mask_type_index_bitmap, ace_info.mask_type_index, 1);
vec_add1(ha->rules, ace_info);
- if (am->l4_match_nonfirst_fragment) {
- /* add the second rule which matches the noninitial fragments with the respective mask */
- make_mask_and_match_from_rule(&mask, &a->rules[i], &ace_info, 1);
- ace_info.mask_type_index = assign_mask_type_index(am, &mask);
- ace_info.match.pkt.mask_type_index_lsb = ace_info.mask_type_index;
- DBG("ACE: %d (non-initial frags) mask_type_index: %d", i, ace_info.mask_type_index);
- /* Ensure a given index is set in the mask type index bitmap for this ACL */
- ha->mask_type_index_bitmap = clib_bitmap_set(ha->mask_type_index_bitmap, ace_info.mask_type_index, 1);
- vec_add1(ha->rules, ace_info);
- }
}
/*
* if an ACL is applied somewhere, fill the corresponding lookup data structures.
({
vlib_cli_output(vm, " %3d: %016llx %016llx %016llx %016llx %016llx %016llx refcount %d",
mte - am->ace_mask_type_pool,
- mte->mask.kv.key[0], mte->mask.kv.key[1], mte->mask.kv.key[2],
- mte->mask.kv.key[3], mte->mask.kv.key[4], mte->mask.kv.value, mte->refcount);
+ mte->mask.kv_40_8.key[0], mte->mask.kv_40_8.key[1], mte->mask.kv_40_8.key[2],
+ mte->mask.kv_40_8.key[3], mte->mask.kv_40_8.key[4], mte->mask.kv_40_8.value, mte->refcount);
}));
/* *INDENT-ON* */
}
}
void
-acl_plugin_show_tables_applied_info (u32 sw_if_index)
+acl_plugin_show_tables_applied_info (u32 lc_index)
{
acl_main_t *am = &acl_main;
vlib_main_t *vm = am->vlib_main;
- u32 swi; //, j;
- vlib_cli_output (vm, "Applied lookup entries for interfaces");
+ u32 lci, j;
+ vlib_cli_output (vm, "Applied lookup entries for lookup contexts");
- for (swi = 0;
- (swi < vec_len (am->input_lc_index_by_sw_if_index))
- || (swi < vec_len (am->output_lc_index_by_sw_if_index)); swi++)
+ for (lci = 0;
+ (lci < vec_len(am->applied_hash_acl_info_by_lc_index)); lci++)
{
- if ((sw_if_index != ~0) && (sw_if_index != swi))
+ if ((lc_index != ~0) && (lc_index != lci))
{
continue;
}
-/*
- vlib_cli_output (vm, "sw_if_index %d:", swi);
- if (swi < vec_len (am->input_applied_hash_acl_info_by_sw_if_index))
+ vlib_cli_output (vm, "lc_index %d:", lci);
+ if (lci < vec_len (am->applied_hash_acl_info_by_lc_index))
{
applied_hash_acl_info_t *pal =
- &am->input_applied_hash_acl_info_by_sw_if_index[swi];
- vlib_cli_output (vm, " input lookup mask_type_index_bitmap: %U",
+ &am->applied_hash_acl_info_by_lc_index[lci];
+ vlib_cli_output (vm, " lookup mask_type_index_bitmap: %U",
format_bitmap_hex, pal->mask_type_index_bitmap);
- vlib_cli_output (vm, " input applied acls: %U", format_vec32,
+ vlib_cli_output (vm, " applied acls: %U", format_vec32,
pal->applied_acls, "%d");
}
- if (swi < vec_len (am->input_hash_entry_vec_by_sw_if_index))
+ if (lci < vec_len (am->hash_entry_vec_by_lc_index))
{
- vlib_cli_output (vm, " input lookup applied entries:");
+ vlib_cli_output (vm, " lookup applied entries:");
for (j = 0;
- j < vec_len (am->input_hash_entry_vec_by_sw_if_index[swi]);
+ j < vec_len (am->hash_entry_vec_by_lc_index[lci]);
j++)
{
acl_plugin_print_pae (vm, j,
- &am->input_hash_entry_vec_by_sw_if_index
- [swi][j]);
+ &am->hash_entry_vec_by_lc_index
+ [lci][j]);
}
}
-
- if (swi < vec_len (am->output_applied_hash_acl_info_by_sw_if_index))
- {
- applied_hash_acl_info_t *pal =
- &am->output_applied_hash_acl_info_by_sw_if_index[swi];
- vlib_cli_output (vm, " output lookup mask_type_index_bitmap: %U",
- format_bitmap_hex, pal->mask_type_index_bitmap);
- vlib_cli_output (vm, " output applied acls: %U", format_vec32,
- pal->applied_acls, "%d");
- }
- if (swi < vec_len (am->output_hash_entry_vec_by_sw_if_index))
- {
- vlib_cli_output (vm, " output lookup applied entries:");
- for (j = 0;
- j < vec_len (am->output_hash_entry_vec_by_sw_if_index[swi]);
- j++)
- {
- acl_plugin_print_pae (vm, j,
- &am->output_hash_entry_vec_by_sw_if_index
- [swi][j]);
- }
- }
-*/
}
}