- return ((vec_len (v) > sw_if_index) && vec_elt (v, sw_if_index));
-}
-
-static int
-etype_whitelist_add_sessions (acl_main_t * am, u32 sw_if_index, int is_input,
- u32 etype_table_index)
-{
- vnet_classify_main_t *cm = &vnet_classify_main;
- u16 **v = is_input
- ? am->input_etype_whitelist_by_sw_if_index
- : am->output_etype_whitelist_by_sw_if_index;
- u8 *match = ethertype_mask;
-
- int i;
- int rv = 0;
- u16 *whitelist = vec_elt (v, sw_if_index);
- u32 next = ~0; /* permit */
- for (i = 0; i < vec_len (whitelist); i++)
- {
- /* big-endian */
- match[12] = (whitelist[i] >> 8) & 0xff;
- match[13] = whitelist[i] & 0xff;
- rv = rv
- || vnet_classify_add_del_session (cm, etype_table_index, match, next,
- whitelist[i], 0, 0, 0, 1);
- }
-
- /* restore the mask */
- match[12] = 0xff;
- match[13] = 0xff;
- return rv;
-}
-
-static int
-acl_hook_l2_input_classify (acl_main_t * am, u32 sw_if_index)
-{
- vnet_classify_main_t *cm = &vnet_classify_main;
- u32 ip4_table_index = ~0;
- u32 ip6_table_index = ~0;
- u32 dot1q_table_index = ~0;
- u32 dot1ad_table_index = ~0;
- u32 etype_table_index = ~0;
- int rv;
-
- void *prevheap = clib_mem_set_heap (cm->vlib_main->heap_base);
-
- /* in case there were previous tables attached */
- acl_unhook_l2_input_classify (am, sw_if_index);
- rv =
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_input_classify_next_acl_ip4,
- &ip4_table_index, 1);
- if (rv)
- goto done;
-
- rv =
- acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
- sizeof (ip6_5tuple_mask) - 1, ~0,
- am->l2_input_classify_next_acl_ip6,
- &ip6_table_index, 1);
- if (rv)
- {
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_input_classify_next_acl_ip4,
- &ip4_table_index, 0);
- goto done;
- }
-
- if (intf_has_etype_whitelist (am, sw_if_index, 1))
- {
- acl_classify_add_del_table_tiny (cm, ethertype_mask, sizeof (ethertype_mask) - 1, ~0, 0, /* drop if no match */
- &etype_table_index, 1);
- etype_whitelist_add_sessions (am, sw_if_index, 1, etype_table_index);
- }
-
- rv =
- acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask,
- sizeof (dot1ad_5tuple_mask) - 1,
- etype_table_index, ~0,
- &dot1ad_table_index, 1);
- rv =
- acl_classify_add_del_table_tiny (cm, dot1q_5tuple_mask,
- sizeof (dot1q_5tuple_mask) - 1,
- dot1ad_table_index, ~0,
- &dot1q_table_index, 1);
- if (rv)
- {
- acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask,
- sizeof (dot1ad_5tuple_mask) - 1, ~0,
- ~0, &dot1ad_table_index, 0);
- acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
- sizeof (ip6_5tuple_mask) - 1, ~0,
- am->l2_input_classify_next_acl_ip6,
- &ip6_table_index, 0);
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_input_classify_next_acl_ip4,
- &ip4_table_index, 0);
- goto done;
- }
-
- rv =
- vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
- ip6_table_index, dot1q_table_index);
-
- if (rv)
- {
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_input_classify_next_acl_ip4,
- &ip4_table_index, 0);
- acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
- sizeof (ip6_5tuple_mask) - 1, ~0,
- am->l2_input_classify_next_acl_ip6,
- &ip6_table_index, 0);
- acl_classify_add_del_table_tiny (cm, dot1q_5tuple_mask,
- sizeof (dot1q_5tuple_mask) - 1, ~0,
- ~0, &dot1q_table_index, 0);
- acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask,
- sizeof (dot1ad_5tuple_mask) - 1, ~0,
- ~0, &dot1ad_table_index, 0);
- goto done;
- }
-
- /* add sessions to vlan tables per ethernet_type */
- acl_add_vlan_session (am, dot1q_table_index, 0, 0, 0);
- acl_add_vlan_session (am, dot1q_table_index, 0, 0, 1);
- acl_add_vlan_session (am, dot1ad_table_index, 0, 1, 0);
- acl_add_vlan_session (am, dot1ad_table_index, 0, 1, 1);
-
- am->acl_ip4_input_classify_table_by_sw_if_index[sw_if_index] =
- ip4_table_index;
- am->acl_ip6_input_classify_table_by_sw_if_index[sw_if_index] =
- ip6_table_index;
- am->acl_dot1q_input_classify_table_by_sw_if_index[sw_if_index] =
- dot1q_table_index;
- am->acl_dot1ad_input_classify_table_by_sw_if_index[sw_if_index] =
- dot1ad_table_index;
- am->acl_dot1ad_input_classify_table_by_sw_if_index[sw_if_index] =
- dot1ad_table_index;
- am->acl_etype_input_classify_table_by_sw_if_index[sw_if_index] =
- etype_table_index;
-
- vnet_l2_input_classify_enable_disable (sw_if_index, 1);
-done:
- clib_mem_set_heap (prevheap);
- return rv;
-}
-
-static int
-acl_hook_l2_output_classify (acl_main_t * am, u32 sw_if_index)
-{
- vnet_classify_main_t *cm = &vnet_classify_main;
- u32 ip4_table_index = ~0;
- u32 ip6_table_index = ~0;
- u32 dot1q_table_index = ~0;
- u32 dot1ad_table_index = ~0;
- u32 etype_table_index = ~0;
- int rv;
-
- void *prevheap = clib_mem_set_heap (cm->vlib_main->heap_base);
-
- /* in case there were previous tables attached */
- acl_unhook_l2_output_classify (am, sw_if_index);
- rv =
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_output_classify_next_acl_ip4,
- &ip4_table_index, 1);
- if (rv)
- goto done;
- rv =
- acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
- sizeof (ip6_5tuple_mask) - 1, ~0,
- am->l2_output_classify_next_acl_ip6,
- &ip6_table_index, 1);
- if (rv)
- {
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_output_classify_next_acl_ip4,
- &ip4_table_index, 0);
- goto done;
- }
-
- if (intf_has_etype_whitelist (am, sw_if_index, 0))
- {
- acl_classify_add_del_table_tiny (cm, ethertype_mask, sizeof (ethertype_mask) - 1, ~0, 0, /* drop if no match */
- &etype_table_index, 1);
- etype_whitelist_add_sessions (am, sw_if_index, 0, etype_table_index);
- }
-
-
- rv =
- acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask,
- sizeof (dot1ad_5tuple_mask) - 1,
- etype_table_index, ~0,
- &dot1ad_table_index, 1);
- rv =
- acl_classify_add_del_table_tiny (cm, dot1q_5tuple_mask,
- sizeof (dot1q_5tuple_mask) - 1,
- dot1ad_table_index, ~0,
- &dot1q_table_index, 1);
- if (rv)
- {
- acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask,
- sizeof (dot1ad_5tuple_mask) - 1, ~0,
- ~0, &dot1ad_table_index, 0);
- acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
- sizeof (ip6_5tuple_mask) - 1, ~0,
- am->l2_output_classify_next_acl_ip6,
- &ip6_table_index, 0);
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_output_classify_next_acl_ip4,
- &ip4_table_index, 0);
- goto done;
- }
-
- rv =
- vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
- ip6_table_index, dot1q_table_index);
-/*
- clib_warning
- ("ACL enabling on interface sw_if_index %d, setting tables to the following: ip4: %d ip6: %d\n",
- sw_if_index, ip4_table_index, ip6_table_index);
-*/
- if (rv)
- {
- acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask,
- sizeof (ip6_5tuple_mask) - 1, ~0,
- am->l2_output_classify_next_acl_ip6,
- &ip6_table_index, 0);
- acl_classify_add_del_table_tiny (cm, ip4_5tuple_mask,
- sizeof (ip4_5tuple_mask) - 1, ~0,
- am->l2_output_classify_next_acl_ip4,
- &ip4_table_index, 0);
- acl_classify_add_del_table_tiny (cm, dot1q_5tuple_mask,
- sizeof (dot1q_5tuple_mask) - 1, ~0,
- ~0, &dot1q_table_index, 0);
- acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask,
- sizeof (dot1ad_5tuple_mask) - 1, ~0,
- ~0, &dot1ad_table_index, 0);
- goto done;
- }
-
- /* add sessions to vlan tables per ethernet_type */
- acl_add_vlan_session (am, dot1q_table_index, 1, 0, 0);
- acl_add_vlan_session (am, dot1q_table_index, 1, 0, 1);
- acl_add_vlan_session (am, dot1ad_table_index, 1, 1, 0);
- acl_add_vlan_session (am, dot1ad_table_index, 1, 1, 1);
-
- am->acl_ip4_output_classify_table_by_sw_if_index[sw_if_index] =
- ip4_table_index;
- am->acl_ip6_output_classify_table_by_sw_if_index[sw_if_index] =
- ip6_table_index;
- am->acl_dot1q_output_classify_table_by_sw_if_index[sw_if_index] =
- dot1q_table_index;
- am->acl_dot1ad_output_classify_table_by_sw_if_index[sw_if_index] =
- dot1ad_table_index;
- am->acl_etype_output_classify_table_by_sw_if_index[sw_if_index] =
- etype_table_index;
-
- vnet_l2_output_classify_enable_disable (sw_if_index, 1);
-done:
- clib_mem_set_heap (prevheap);
- return rv;