+static void
+validate_and_reset_acl_counters (acl_main_t * am, u32 acl_index)
+{
+ int i;
+ /* counters are set as vectors [acl#] pointing to vectors of [acl rule] */
+ acl_plugin_counter_lock (am);
+
+ int old_len = vec_len (am->combined_acl_counters);
+
+ vec_validate (am->combined_acl_counters, acl_index);
+
+ for (i = old_len; i < vec_len (am->combined_acl_counters); i++)
+ {
+ am->combined_acl_counters[i].name = 0;
+ /* filled in once only */
+ am->combined_acl_counters[i].stat_segment_name = (void *)
+ format (0, "/acl/%d/matches%c", i, 0);
+ i32 rule_count = vec_len (am->acls[i].rules);
+ /* Validate one extra so we always have at least one counter for an ACL */
+ vlib_validate_combined_counter (&am->combined_acl_counters[i],
+ rule_count);
+ vlib_clear_combined_counters (&am->combined_acl_counters[i]);
+ }
+
+ /* (re)validate for the actual ACL that is getting added/updated */
+ i32 rule_count = vec_len (am->acls[acl_index].rules);
+ /* Validate one extra so we always have at least one counter for an ACL */
+ vlib_validate_combined_counter (&am->combined_acl_counters[acl_index],
+ rule_count);
+ vlib_clear_combined_counters (&am->combined_acl_counters[acl_index]);
+ acl_plugin_counter_unlock (am);
+}
+
+static int
+acl_api_ip4_invalid_prefix (void *ip4_pref_raw, u8 ip4_prefix_len)
+{
+ ip4_address_t ip4_addr;
+ ip4_address_t ip4_mask;
+ ip4_address_t ip4_masked_addr;
+
+ memcpy (&ip4_addr, ip4_pref_raw, sizeof (ip4_addr));
+ ip4_preflen_to_mask (ip4_prefix_len, &ip4_mask);
+ ip4_masked_addr.as_u32 = ip4_addr.as_u32 & ip4_mask.as_u32;
+ int ret = (ip4_masked_addr.as_u32 != ip4_addr.as_u32);
+ if (ret)
+ {
+ clib_warning
+ ("inconsistent addr %U for prefix len %d; (%U when masked)",
+ format_ip4_address, ip4_pref_raw, ip4_prefix_len, format_ip4_address,
+ &ip4_masked_addr);
+ }
+ return ret;
+}
+
+static int
+acl_api_ip6_invalid_prefix (void *ip6_pref_raw, u8 ip6_prefix_len)
+{
+ ip6_address_t ip6_addr;
+ ip6_address_t ip6_mask;
+ ip6_address_t ip6_masked_addr;
+
+ memcpy (&ip6_addr, ip6_pref_raw, sizeof (ip6_addr));
+ ip6_preflen_to_mask (ip6_prefix_len, &ip6_mask);
+ ip6_masked_addr.as_u64[0] = ip6_addr.as_u64[0] & ip6_mask.as_u64[0];
+ ip6_masked_addr.as_u64[1] = ip6_addr.as_u64[1] & ip6_mask.as_u64[1];
+ int ret = ((ip6_masked_addr.as_u64[0] != ip6_addr.as_u64[0])
+ || (ip6_masked_addr.as_u64[1] != ip6_addr.as_u64[1]));
+ if (ret)
+ {
+ clib_warning
+ ("inconsistent addr %U for prefix len %d; (%U when masked)",
+ format_ip6_address, ip6_pref_raw, ip6_prefix_len, format_ip6_address,
+ &ip6_masked_addr);
+ }
+ return ret;
+}