From 8daa80a4adfd82a19017c2c12554a8a43dddccd7 Mon Sep 17 00:00:00 2001 From: Pavel Kotucek Date: Mon, 25 Sep 2017 09:44:05 +0200 Subject: [PATCH] ACL plugin support tagged subinterfaces Change-Id: I92b351895c7efb26533c05512b91ead8ddbfb9c8 Signed-off-by: Pavel Kotucek --- src/plugins/acl/acl.c | 346 +++++++++++++++++--- src/plugins/acl/acl.h | 5 + test/test_acl_plugin_macip.py | 722 ++++++++++++++++++++++++++++-------------- test/vpp_papi_provider.py | 17 + 4 files changed, 820 insertions(+), 270 deletions(-) diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c index 50e9557db38..dc7f1ebcdb5 100644 --- a/src/plugins/acl/acl.c +++ b/src/plugins/acl/acl.c @@ -318,12 +318,14 @@ acl_del_list (u32 acl_list_index) /* Some aids in ASCII graphing the content */ #define XX "\377" #define __ "\000" +#define DOT1AD "\210\250" +#define DOT1Q "\201\00" #define _(x) #define v u8 ip4_5tuple_mask[] = -_(" dmac smac etype ") -_(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v __ __ v + _(" dmac smac etype ") + _(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v __ __ v _(" v ihl totlen ") _(0x0000) __ __ __ __ @@ -349,8 +351,8 @@ _(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v __ __ v _(padeth) __ __; - u8 ip6_5tuple_mask[] = - _(" dmac smac etype ") + u8 ip6_5tuple_mask[] = + _(" dmac smac etype ") _(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v __ __ v _(" v tc + flow ") _(0x0000) __ __ __ __ @@ -369,12 +371,29 @@ _(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v __ __ v _("L4T/U sport dport ") _(tcpudp) XX XX XX XX _(padpad) __ __ __ __ _(padeth) __ __; + u8 dot1q_5tuple_mask[] = + _(" dmac smac dot1q etype ") + _(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v DOT1Q __ __ v XX XX v + _(padpad) __ __ __ __ + _(padpad) __ __ __ __ + _(padpad) __ __ __ __ + _(padeth) __ __; + + u8 dot1ad_5tuple_mask[] = + _(" dmac smac dot1ad etype ") + _(ether) __ __ __ __ __ __ v __ __ __ __ __ __ v DOT1AD __ __ DOT1Q __ __ v XX XX v + _(padpad) __ __ __ __ + _(padpad) __ __ __ __ + _(padeth) __ __; + #undef XX #undef __ +#undef DOT1AD +#undef DOT1Q #undef _ #undef v - static int count_skip (u8 * p, u32 size) +static int count_skip (u8 * p, u32 size) { u64 *p64 = (u64 *) p; /* Be tolerant to null pointer */ @@ -443,19 +462,24 @@ acl_classify_add_del_table_small (vnet_classify_main_t * cm, u8 * mask, return ret; } - static int acl_unhook_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; void *oldheap = acl_set_heap(am); vec_validate_init_empty (am->acl_ip4_input_classify_table_by_sw_if_index, sw_if_index, ~0); vec_validate_init_empty (am->acl_ip6_input_classify_table_by_sw_if_index, sw_if_index, ~0); + vec_validate_init_empty (am->acl_dot1q_input_classify_table_by_sw_if_index, + sw_if_index, ~0); + vec_validate_init_empty (am->acl_dot1ad_input_classify_table_by_sw_if_index, + sw_if_index, ~0); /* switch to global heap while calling vnet_* functions */ clib_mem_set_heap (cm->vlib_main->heap_base); @@ -481,6 +505,26 @@ acl_unhook_l2_input_classify (acl_main_t * am, u32 sw_if_index) am->l2_input_classify_next_acl_ip6, &ip6_table_index, 0); } + if (am->acl_dot1q_input_classify_table_by_sw_if_index[sw_if_index] != ~0) + { + dot1q_table_index = + am->acl_dot1q_input_classify_table_by_sw_if_index[sw_if_index]; + am->acl_dot1q_input_classify_table_by_sw_if_index[sw_if_index] = ~0; + acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask, + sizeof (ip6_5tuple_mask) - 1, ~0, + ~0, + &dot1q_table_index, 0); + } + if (am->acl_dot1ad_input_classify_table_by_sw_if_index[sw_if_index] != ~0) + { + dot1ad_table_index = + am->acl_dot1ad_input_classify_table_by_sw_if_index[sw_if_index]; + am->acl_dot1ad_input_classify_table_by_sw_if_index[sw_if_index] = ~0; + acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask, + sizeof (dot1ad_5tuple_mask) - 1, ~0, + ~0, + &dot1ad_table_index, 0); + } clib_mem_set_heap (oldheap); return 0; } @@ -491,12 +535,18 @@ acl_unhook_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; void *oldheap = acl_set_heap(am); vec_validate_init_empty (am->acl_ip4_output_classify_table_by_sw_if_index, sw_if_index, ~0); vec_validate_init_empty (am->acl_ip6_output_classify_table_by_sw_if_index, sw_if_index, ~0); + vec_validate_init_empty (am->acl_dot1q_output_classify_table_by_sw_if_index, + sw_if_index, ~0); + vec_validate_init_empty (am->acl_dot1ad_output_classify_table_by_sw_if_index, + sw_if_index, ~0); /* switch to global heap while calling vnet_* functions */ clib_mem_set_heap (cm->vlib_main->heap_base); @@ -523,16 +573,76 @@ acl_unhook_l2_output_classify (acl_main_t * am, u32 sw_if_index) am->l2_output_classify_next_acl_ip6, &ip6_table_index, 0); } + if (am->acl_dot1q_output_classify_table_by_sw_if_index[sw_if_index] != ~0) + { + dot1q_table_index = + am->acl_dot1q_output_classify_table_by_sw_if_index[sw_if_index]; + am->acl_dot1q_output_classify_table_by_sw_if_index[sw_if_index] = ~0; + acl_classify_add_del_table_tiny (cm, ip6_5tuple_mask, + sizeof (ip6_5tuple_mask) - 1, ~0, + ~0, + &dot1q_table_index, 0); + } + if (am->acl_dot1ad_output_classify_table_by_sw_if_index[sw_if_index] != ~0) + { + dot1ad_table_index = + am->acl_dot1ad_output_classify_table_by_sw_if_index[sw_if_index]; + am->acl_dot1ad_output_classify_table_by_sw_if_index[sw_if_index] = ~0; + acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask, + sizeof (dot1ad_5tuple_mask) - 1, ~0, + ~0, + &dot1ad_table_index, 0); + } clib_mem_set_heap (oldheap); return 0; } +static void +acl_add_vlan_session(acl_main_t * am, u32 table_index, u8 is_output, u8 is_dot1ad, u8 is_ip6) +{ + vnet_classify_main_t *cm = &vnet_classify_main; + u8 *match; + u32 next_acl; + u8 idx; + u8 session_idx; + + if (is_ip6) + { + next_acl = (is_output)?am->l2_output_classify_next_acl_ip6:am->l2_input_classify_next_acl_ip6; + } + else + { + next_acl = (is_output)?am->l2_output_classify_next_acl_ip4:am->l2_input_classify_next_acl_ip4; + } + match = (is_dot1ad)?dot1ad_5tuple_mask:dot1q_5tuple_mask; + idx = (is_dot1ad)?20:16; + + /* add sessions to vlan tables per ethernet_type */ + if (is_ip6) + { + match[idx] = 0x86; + match[idx+1] = 0xdd; + session_idx = 1; + } + else + { + match[idx] = 0x08; + match[idx+1] = 0x00; + session_idx = 0; + } + vnet_classify_add_del_session (cm, table_index, match, next_acl, + session_idx, 0, 0, 0, 1); + memset (&match[idx], 0x00, 2); +} + 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; int rv; void *prevheap = clib_mem_set_heap (cm->vlib_main->heap_base); @@ -546,6 +656,7 @@ acl_hook_l2_input_classify (acl_main_t * am, u32 sw_if_index) &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, @@ -559,26 +670,68 @@ acl_hook_l2_input_classify (acl_main_t * am, u32 sw_if_index) &ip4_table_index, 0); goto done; } + + rv = + acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask, + sizeof (dot1ad_5tuple_mask) - 1, ~0, + ~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, ~0); + 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, 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, 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; vnet_l2_input_classify_enable_disable (sw_if_index, 1); done: @@ -592,6 +745,8 @@ 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; int rv; void *prevheap = clib_mem_set_heap (cm->vlib_main->heap_base); @@ -618,9 +773,35 @@ acl_hook_l2_output_classify (acl_main_t * am, u32 sw_if_index) &ip4_table_index, 0); goto done; } + + rv = + acl_classify_add_del_table_tiny (cm, dot1ad_5tuple_mask, + sizeof (dot1ad_5tuple_mask) - 1, ~0, + ~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, ~0); + 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); @@ -634,13 +815,31 @@ acl_hook_l2_output_classify (acl_main_t * am, u32 sw_if_index) 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; vnet_l2_output_classify_enable_disable (sw_if_index, 1); done: @@ -648,8 +847,6 @@ done: return rv; } - - int acl_interface_in_enable_disable (acl_main_t * am, u32 sw_if_index, int enable_disable) @@ -917,6 +1114,8 @@ typedef struct u32 count; u32 table_index; u32 arp_table_index; + u32 dot1q_table_index; + u32 dot1ad_table_index; } macip_match_type_t; static u32 @@ -1007,6 +1206,8 @@ macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index) mvec[match_type_index].prefix_len = a->rules[i].src_prefixlen; mvec[match_type_index].is_ipv6 = a->rules[i].is_ipv6; mvec[match_type_index].table_index = ~0; + mvec[match_type_index].dot1q_table_index = ~0; + mvec[match_type_index].dot1ad_table_index = ~0; } mvec[match_type_index].count++; } @@ -1047,8 +1248,36 @@ macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index) int mask_len; int is6 = mt->is_ipv6; int l3_src_offs = get_l3_src_offset(is6); - memset (mask, 0, sizeof (mask)); - memcpy (&mask[6], mt->mac_mask, 6); + int tags; + u32 *last_tag_table; + + /* + * create chained tables for VLAN (no-tags, dot1q and dot1ad) packets + */ + l3_src_offs += 8; + for (tags = 2; tags >= 0; tags--) + { + memset (mask, 0, sizeof (mask)); + memcpy (&mask[6], mt->mac_mask, 6); + switch (tags) + { + case 0: + default: + memset (&mask[12], 0xff, 2); /* ethernet protocol */ + last_tag_table = &mt->table_index; + break; + case 1: + memset (&mask[12], 0xff, 2); /* VLAN tag1 */ + memset (&mask[16], 0xff, 2); /* ethernet protocol */ + last_tag_table = &mt->dot1q_table_index; + break; + case 2: + memset (&mask[12], 0xff, 2); /* VLAN tag1 */ + memset (&mask[16], 0xff, 2); /* VLAN tag2 */ + memset (&mask[20], 0xff, 2); /* ethernet protocol */ + last_tag_table = &mt->dot1ad_table_index; + break; + } for (i = 0; i < (mt->prefix_len / 8); i++) { mask[l3_src_offs + i] = 0xff; @@ -1065,9 +1294,13 @@ macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index) mask_len = ((l3_src_offs + ((mt->prefix_len+7) / 8) + (sizeof (u32x4)-1))/sizeof(u32x4)) * sizeof (u32x4); acl_classify_add_del_table_small (cm, mask, mask_len, last_table, - (~0 == last_table) ? 0 : ~0, &mt->table_index, + (~0 == last_table) ? 0 : ~0, last_tag_table, 1); - last_table = mt->table_index; + last_table = *last_tag_table; + + memset (&mask[12], 0, sizeof (mask)-12); + l3_src_offs -= 4; + } } a->ip4_table_index = last_table; a->ip6_table_index = last_table; @@ -1080,30 +1313,63 @@ macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index) u32 metadata = 0; int is6 = a->rules[i].is_ipv6; int l3_src_offs = get_l3_src_offset(is6); - memset (mask, 0, sizeof (mask)); - memcpy (&mask[6], a->rules[i].src_mac, 6); - memset (&mask[12], 0xff, 2); /* ethernet protocol */ - if (is6) - { - memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip6, 16); - mask[12] = 0x86; - mask[13] = 0xdd; - } - else - { - memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip4, 4); - mask[12] = 0x08; - mask[13] = 0x00; - } + u32 tag_table; + int tags, eth; + match_type_index = - macip_find_match_type (mvec, a->rules[i].src_mac_mask, - a->rules[i].src_prefixlen, - a->rules[i].is_ipv6); + macip_find_match_type (mvec, a->rules[i].src_mac_mask, + a->rules[i].src_prefixlen, + a->rules[i].is_ipv6); ASSERT(match_type_index != ~0); - /* add session to table mvec[match_type_index].table_index; */ - vnet_classify_add_del_session (cm, mvec[match_type_index].table_index, - mask, a->rules[i].is_permit ? ~0 : 0, i, - 0, action, metadata, 1); + + l3_src_offs += 8; + for (tags = 2; tags >= 0; tags--) + { + memset (mask, 0, sizeof (mask)); + memcpy (&mask[6], a->rules[i].src_mac, 6); + switch (tags) + { + case 0: + default: + tag_table = mvec[match_type_index].table_index; + eth = 12; + break; + case 1: + tag_table = mvec[match_type_index].dot1q_table_index; + mask[12] = 0x81; + mask[13] = 0x00; + eth = 16; + break; + case 2: + tag_table = mvec[match_type_index].dot1ad_table_index; + mask[12] = 0x88; + mask[13] = 0xa8; + mask[16] = 0x81; + mask[17] = 0x00; + eth = 20; + break; + } + if (is6) + { + memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip6, 16); + mask[eth] = 0x86; + mask[eth+1] = 0xdd; + } + else + { + memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip4, 4); + mask[eth] = 0x08; + mask[eth+1] = 0x00; + } + + /* add session to table mvec[match_type_index].table_index; */ + vnet_classify_add_del_session (cm, tag_table, + mask, a->rules[i].is_permit ? ~0 : 0, i, + 0, action, metadata, 1); + memset (&mask[12], 0, sizeof (mask)-12); + l3_src_offs -= 4; + } + /* add ARP table entry too */ if (!is6 && (mvec[match_type_index].arp_table_index != ~0)) { diff --git a/src/plugins/acl/acl.h b/src/plugins/acl/acl.h index bed22e5fc89..d38c12990de 100644 --- a/src/plugins/acl/acl.h +++ b/src/plugins/acl/acl.h @@ -179,6 +179,11 @@ typedef struct { u32 *acl_ip4_output_classify_table_by_sw_if_index; u32 *acl_ip6_output_classify_table_by_sw_if_index; + u32 *acl_dot1q_input_classify_table_by_sw_if_index; + u32 *acl_dot1ad_input_classify_table_by_sw_if_index; + u32 *acl_dot1q_output_classify_table_by_sw_if_index; + u32 *acl_dot1ad_output_classify_table_by_sw_if_index; + /* MACIP (input) ACLs associated with the interfaces */ u32 *macip_acl_by_sw_if_index; diff --git a/test/test_acl_plugin_macip.py b/test/test_acl_plugin_macip.py index f10d6cc60d5..d27458d7df0 100644 --- a/test/test_acl_plugin_macip.py +++ b/test/test_acl_plugin_macip.py @@ -9,16 +9,16 @@ from socket import inet_ntop, inet_pton, AF_INET, AF_INET6 from struct import * from scapy.packet import Raw from scapy.layers.l2 import Ether -from scapy.layers.inet import IP, UDP, TCP +from scapy.layers.inet import IP, UDP from scapy.layers.inet6 import IPv6 from framework import VppTestCase, VppTestRunner, running_extended_tests from vpp_lo_interface import VppLoInterface +from vpp_papi_provider import L2_VTR_OP +from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint -class TestMACIP(VppTestCase): - """MACIP Test Case""" - +class MethodHolder(VppTestCase): DEBUG = False BRIDGED = True @@ -27,6 +27,11 @@ class TestMACIP(VppTestCase): IS_IP4 = False IS_IP6 = True + DOT1AD = "dot1ad" + DOT1Q = "dot1q" + PERMIT_TAGS = True + DENY_TAGS = False + # rule types DENY = 0 PERMIT = 1 @@ -49,19 +54,36 @@ class TestMACIP(VppTestCase): class VppTestCase) before running the test case, set test case related variables and configure VPP. """ - super(TestMACIP, cls).setUpClass() + super(MethodHolder, cls).setUpClass() cls.pg_if_packet_sizes = [64, 512, 1518, 9018] # packet sizes - cls.bd_id = 10 - cls.remote_hosts_count = 250 + cls.bd_id = 111 + cls.remote_hosts_count = 200 try: - # create 3 pg interfaces, 1 loopback interface - cls.create_pg_interfaces(range(3)) + # create 4 pg interfaces, 1 loopback interface + cls.create_pg_interfaces(range(4)) cls.create_loopback_interfaces(range(1)) + # create 2 subinterfaces + cls.subifs = [ + VppDot1QSubint(cls, cls.pg1, 10), + VppDot1ADSubint(cls, cls.pg2, 20, 300, 400), + VppDot1QSubint(cls, cls.pg3, 30), + VppDot1ADSubint(cls, cls.pg3, 40, 600, 700)] + + cls.subifs[0].set_vtr(L2_VTR_OP.L2_POP_1, + inner=10, push1q=1) + cls.subifs[1].set_vtr(L2_VTR_OP.L2_POP_2, + outer=300, inner=400, push1q=1) + cls.subifs[2].set_vtr(L2_VTR_OP.L2_POP_1, + inner=30, push1q=1) + cls.subifs[3].set_vtr(L2_VTR_OP.L2_POP_2, + outer=600, inner=700, push1q=1) + cls.interfaces = list(cls.pg_interfaces) cls.interfaces.extend(cls.lo_interfaces) + cls.interfaces.extend(cls.subifs) for i in cls.interfaces: i.admin_up() @@ -73,12 +95,18 @@ class TestMACIP(VppTestCase): cls.pg0.sw_if_index, bd_id=cls.bd_id) cls.vapi.sw_interface_set_l2_bridge( cls.pg1.sw_if_index, bd_id=cls.bd_id) + cls.vapi.sw_interface_set_l2_bridge( + cls.subifs[0].sw_if_index, bd_id=cls.bd_id) + cls.vapi.sw_interface_set_l2_bridge( + cls.subifs[1].sw_if_index, bd_id=cls.bd_id) - # Configure IPv4 addresses on loop interface and routed interface + # Configure IPv4/6 addresses on loop interface and routed interface cls.loop0.config_ip4() cls.loop0.config_ip6() cls.pg2.config_ip4() cls.pg2.config_ip6() + cls.pg3.config_ip4() + cls.pg3.config_ip6() # Configure MAC address binding to IPv4 neighbors on loop0 cls.loop0.generate_remote_hosts(cls.remote_hosts_count) @@ -90,22 +118,35 @@ class TestMACIP(VppTestCase): cls.loop0.configure_ipv4_neighbors() cls.loop0.configure_ipv6_neighbors() + + # configure MAC address on pg3 + cls.pg3.resolve_arp() + cls.pg3.resolve_ndp() + + # configure MAC address on subifs + for i in cls.subifs: + i.config_ip4() + i.resolve_arp() + i.config_ip6() + # configure MAC address on pg2 cls.pg2.resolve_arp() cls.pg2.resolve_ndp() # Loopback BVI interface has remote hosts - # one half of hosts are behind pg0 second behind pg1 - half = cls.remote_hosts_count // 2 - cls.pg0.remote_hosts = cls.loop0.remote_hosts[:half] - cls.pg1.remote_hosts = cls.loop0.remote_hosts[half:] + # one half of hosts are behind pg0 second behind pg1,pg2,pg3 subifs + cls.pg0.remote_hosts = cls.loop0.remote_hosts[:100] + cls.subifs[0].remote_hosts = cls.loop0.remote_hosts[100:125] + cls.subifs[1].remote_hosts = cls.loop0.remote_hosts[125:150] + cls.subifs[2].remote_hosts = cls.loop0.remote_hosts[150:175] + cls.subifs[3].remote_hosts = cls.loop0.remote_hosts[175:] except Exception: super(TestMACIP, cls).tearDownClass() raise def setUp(self): - super(TestMACIP, self).setUp() + super(MethodHolder, self).setUp() self.reset_packet_infos() del self.ACLS[:] @@ -113,13 +154,16 @@ class TestMACIP(VppTestCase): """ Show various debug prints after each test. """ - super(TestMACIP, self).tearDown() + super(MethodHolder, self).tearDown() if not self.vpp_dead: self.logger.info(self.vapi.ppcli("show interface address")) self.logger.info(self.vapi.ppcli("show hardware")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip acl")) self.logger.info(self.vapi.ppcli("sh acl-plugin macip interface")) self.logger.info(self.vapi.ppcli("sh classify tables verbose")) + self.logger.info(self.vapi.ppcli("sh acl-plugin acl")) + self.logger.info(self.vapi.ppcli("sh acl-plugin interface")) + self.logger.info(self.vapi.ppcli("sh acl-plugin tables")) # print self.vapi.ppcli("show interface address") # print self.vapi.ppcli("show hardware") # print self.vapi.ppcli("sh acl-plugin macip interface") @@ -217,13 +261,13 @@ class TestMACIP(VppTestCase): src_mac += 1099511627776 return acls - def apply_rules(self, acls): + def apply_macip_rules(self, acls): for acl in acls: reply = self.vapi.macip_acl_add(acl) self.assertEqual(reply.retval, 0) self.ACLS.append(reply.acl_index) - def verify_acls(self, acl_count, rules_count, expected_count=2): + def verify_macip_acls(self, acl_count, rules_count, expected_count=2): reply = self.macip_acl_dump_debug() for acl in range(2, (acl_count+1) * 2): self.assertEqual(reply[acl - 2].count, rules_count[acl/2-1]) @@ -243,8 +287,18 @@ class TestMACIP(VppTestCase): reply = self.vapi.macip_acl_dump() self.assertEqual(len(reply), 0) + intf_acls = self.vapi.ppcli("sh acl-plugin interface").split( + "\nsw_if_index") + for i_a in intf_acls: + ia = i_a.split(":") + if len(ia) == 3: + sw_if_index = int(ia[0]) + acl_index = int(ia[2]) + self.vapi.acl_interface_add_del(sw_if_index, acl_index, 0) + self.vapi.acl_del(acl_index) + def create_stream(self, mac_type, ip_type, packet_count, - src_ip_if, dst_ip_if, bridged_routed, is_ip6): + src_if, dst_if, traffic, is_ip6, tags=PERMIT_TAGS): # exact MAC and exact IP # exact MAC and subnet of IPs # exact MAC and wildcard IP @@ -256,15 +310,16 @@ class TestMACIP(VppTestCase): # OUI restricted MAC and wildcard IP packets = [] - rules = [] + macip_rules = [] + acl_rules = [] ip_permit = "" mac_permit = "" dst_mac = "" mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" for p in range(0, packet_count): - remote_dst_index = p % len(dst_ip_if.remote_hosts) - remote_dst_host = dst_ip_if.remote_hosts[remote_dst_index] + remote_dst_index = p % len(dst_if.remote_hosts) + remote_dst_host = dst_if.remote_hosts[remote_dst_index] dst_port = 1234 + p src_port = 4321 + p @@ -276,14 +331,14 @@ class TestMACIP(VppTestCase): if not is_permit and mac_type == self.WILD_MAC: denyIP = True - if bridged_routed == self.BRIDGED: + if traffic == self.BRIDGED: if is_permit: src_mac = remote_dst_host._mac dst_mac = 'de:ad:00:00:00:00' src_ip4 = remote_dst_host.ip4 - dst_ip4 = src_ip_if.remote_ip4 + dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 - dst_ip6 = src_ip_if.remote_ip6 + dst_ip6 = src_if.remote_ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: @@ -298,16 +353,16 @@ class TestMACIP(VppTestCase): if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 - dst_ip4 = src_ip_if.remote_ip4 + dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 - dst_ip6 = src_ip_if.remote_ip6 + dst_ip6 = src_if.remote_ip6 else: if is_permit: src_mac = remote_dst_host._mac - dst_mac = src_ip_if.local_mac - src_ip4 = src_ip_if.remote_ip4 + dst_mac = src_if.local_mac + src_ip4 = src_if.remote_ip4 dst_ip4 = remote_dst_host.ip4 - src_ip6 = src_ip_if.remote_ip6 + src_ip6 = src_if.remote_ip6 dst_ip6 = remote_dst_host.ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac @@ -324,12 +379,12 @@ class TestMACIP(VppTestCase): if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 - dst_ip4 = src_ip_if.remote_ip4 + dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 - dst_ip6 = src_ip_if.remote_ip6 + dst_ip6 = src_if.remote_ip6 if is_permit: - info = self.create_packet_info(src_ip_if, dst_ip_if) + info = self.create_packet_info(src_if, dst_if) payload = self.info_to_payload(info) else: payload = "to be blocked" @@ -379,10 +434,34 @@ class TestMACIP(VppTestCase): packet[Raw].load += " mac:"+src_mac size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)] + if isinstance(src_if, VppSubInterface): + size = size + 4 + if isinstance(src_if, VppDot1QSubint): + if src_if is self.subifs[0]: + if tags == self.PERMIT_TAGS: + packet = src_if.add_dot1q_layer(packet, 10) + else: + packet = src_if.add_dot1q_layer(packet, 11) + else: + if tags == self.PERMIT_TAGS: + packet = src_if.add_dot1q_layer(packet, 30) + else: + packet = src_if.add_dot1q_layer(packet, 33) + elif isinstance(src_if, VppDot1ADSubint): + if src_if is self.subifs[1]: + if tags == self.PERMIT_TAGS: + packet = src_if.add_dot1ad_layer(packet, 300, 400) + else: + packet = src_if.add_dot1ad_layer(packet, 333, 444) + else: + if tags == self.PERMIT_TAGS: + packet = src_if.add_dot1ad_layer(packet, 600, 700) + else: + packet = src_if.add_dot1ad_layer(packet, 666, 777) self.extend_packet(packet, size) packets.append(packet) - # create suitable rule + # create suitable MACIP rule if mac_type == self.EXACT_MAC: mac_rule = src_mac mac_mask = "ff:ff:ff:ff:ff:ff" @@ -422,38 +501,77 @@ class TestMACIP(VppTestCase): prefix_len = 64 if is_ip6 else 16 ip_rule = inet_pton(AF_INET6 if is_ip6 else AF_INET, ip) + # create suitable ACL rule + if is_permit: + rule_l4_sport = packet[UDP].sport + rule_l4_dport = packet[UDP].dport + rule_family = AF_INET6 if packet.haslayer(IPv6) else AF_INET + rule_prefix_len = 128 if packet.haslayer(IPv6) else 32 + rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP + if packet.haslayer(IPv6): + rule_l4_proto = packet[UDP].overload_fields[IPv6]['nh'] + else: + rule_l4_proto = packet[IP].proto + + acl_rule = { + 'is_permit': is_permit, + 'is_ipv6': is_ip6, + 'src_ip_addr': inet_pton(rule_family, + packet[rule_l3_layer].src), + 'src_ip_prefix_len': rule_prefix_len, + 'dst_ip_addr': inet_pton(rule_family, + packet[rule_l3_layer].dst), + 'dst_ip_prefix_len': rule_prefix_len, + 'srcport_or_icmptype_first': rule_l4_sport, + 'srcport_or_icmptype_last': rule_l4_sport, + 'dstport_or_icmpcode_first': rule_l4_dport, + 'dstport_or_icmpcode_last': rule_l4_dport, + 'proto': rule_l4_proto} + acl_rules.append(acl_rule) + if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0: continue if is_permit: - rule = ({'is_permit': is_permit, - 'is_ipv6': is_ip6, - 'src_ip_addr': ip_rule, - 'src_ip_prefix_len': prefix_len, - 'src_mac': mac_rule.replace(':', '').decode('hex'), - 'src_mac_mask': mac_mask.replace(':', '').decode( - 'hex')}) - rules.append(rule) + macip_rule = ({ + 'is_permit': is_permit, + 'is_ipv6': is_ip6, + 'src_ip_addr': ip_rule, + 'src_ip_prefix_len': prefix_len, + 'src_mac': mac_rule.replace(':', '').decode('hex'), + 'src_mac_mask': mac_mask.replace(':', '').decode('hex')}) + macip_rules.append(macip_rule) # deny all other packets if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP): - rule = ({'is_permit': 0, - 'is_ipv6': is_ip6, - 'src_ip_addr': "", - 'src_ip_prefix_len': 0, - 'src_mac': "", - 'src_mac_mask': ""}) - rules.append(rule) - - return {'stream': packets, 'rules': rules} + macip_rule = ({'is_permit': 0, + 'is_ipv6': is_ip6, + 'src_ip_addr': "", + 'src_ip_prefix_len': 0, + 'src_mac': "", + 'src_mac_mask': ""}) + macip_rules.append(macip_rule) + + acl_rule = {'is_permit': 0, + 'is_ipv6': is_ip6} + acl_rules.append(acl_rule) + return {'stream': packets, + 'macip_rules': macip_rules, + 'acl_rules': acl_rules} def verify_capture(self, stream, capture, is_ip6): - p_l3 = IPv6 if is_ip6 else IP - if self.DEBUG: - for p in stream: - print p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst - - acls = self.macip_acl_dump_debug() + """ + :param stream: + :param capture: + :param is_ip6: + :return: + """ + # p_l3 = IPv6 if is_ip6 else IP + # if self.DEBUG: + # for p in stream: + # print p[Ether].src, p[Ether].dst, p[p_l3].src, p[p_l3].dst + # + # acls = self.macip_acl_dump_debug() # TODO : verify # for acl in acls: @@ -468,64 +586,112 @@ class TestMACIP(VppTestCase): # data = p[Raw].load.split(':',1)[1] # print p[p_l3].src, data - def run_traffic(self, mac_type, ip_type, bridged_routed, is_ip6, packets, - do_not_expected_capture=False): + def run_traffic(self, mac_type, ip_type, traffic, is_ip6, packets, + do_not_expected_capture=False, tags=None, + apply_rules=True, isMACIP=True, permit_tags=PERMIT_TAGS): self.reset_packet_infos() - tx_if = self.pg0 if bridged_routed == self.BRIDGED else self.pg2 - rx_if = self.pg2 if bridged_routed == self.BRIDGED else self.pg0 + if tags is None: + tx_if = self.pg0 if traffic == self.BRIDGED else self.pg3 + rx_if = self.pg3 if traffic == self.BRIDGED else self.pg0 + src_if = self.pg3 + dst_if = self.loop0 + else: + if tags == self.DOT1Q: + if traffic == self.BRIDGED: + tx_if = self.subifs[0] + rx_if = self.pg0 + src_if = self.subifs[0] + dst_if = self.loop0 + else: + tx_if = self.subifs[2] + rx_if = self.pg0 + src_if = self.subifs[2] + dst_if = self.loop0 + elif tags == self.DOT1AD: + if traffic == self.BRIDGED: + tx_if = self.subifs[1] + rx_if = self.pg0 + src_if = self.subifs[1] + dst_if = self.loop0 + else: + tx_if = self.subifs[3] + rx_if = self.pg0 + src_if = self.subifs[3] + dst_if = self.loop0 + else: + return test_dict = self.create_stream(mac_type, ip_type, packets, - self.pg2, self.loop0, - bridged_routed, - is_ip6) - - reply = self.vapi.macip_acl_add(test_dict['rules']) - self.assertEqual(reply.retval, 0) - acl_index = reply.acl_index + src_if, dst_if, + traffic, is_ip6, + tags=permit_tags) - self.vapi.macip_acl_interface_add_del(sw_if_index=tx_if.sw_if_index, - acl_index=acl_index) - reply = self.vapi.macip_acl_interface_get() - self.assertEqual(reply.acls[tx_if.sw_if_index], acl_index) - self.ACLS.append(reply.acls[tx_if.sw_if_index]) + if apply_rules: + if isMACIP: + reply = self.vapi.macip_acl_add(test_dict['macip_rules']) + else: + reply = self.vapi.acl_add_replace(acl_index=4294967295, + r=test_dict['acl_rules']) + self.assertEqual(reply.retval, 0) + acl_index = reply.acl_index + + if isMACIP: + self.vapi.macip_acl_interface_add_del( + sw_if_index=tx_if.sw_if_index, + acl_index=acl_index) + reply = self.vapi.macip_acl_interface_get() + self.assertEqual(reply.acls[tx_if.sw_if_index], acl_index) + self.ACLS.append(reply.acls[tx_if.sw_if_index]) + else: + self.vapi.acl_interface_add_del( + sw_if_index=tx_if.sw_if_index, acl_index=acl_index) + else: + self.vapi.macip_acl_interface_add_del( + sw_if_index=tx_if.sw_if_index, + acl_index=0) - tx_if.add_stream(test_dict['stream']) + if not isinstance(src_if, VppSubInterface): + tx_if.add_stream(test_dict['stream']) + else: + tx_if.parent.add_stream(test_dict['stream']) self.pg_enable_capture(self.pg_interfaces) self.pg_start() if do_not_expected_capture: rx_if.get_capture(0) else: - packet_count = self.get_packet_count_for_if_idx( - self.loop0.sw_if_index) - if mac_type == self.WILD_MAC and ip_type == self.WILD_IP: - packet_count = packets if bridged_routed else packet_count - capture = rx_if.get_capture(packet_count) + if traffic == self.BRIDGED and mac_type == self.WILD_MAC and \ + ip_type == self.WILD_IP: + capture = rx_if.get_capture(packets) + else: + capture = rx_if.get_capture( + self.get_packet_count_for_if_idx(dst_if.sw_if_index)) self.verify_capture(test_dict['stream'], capture, is_ip6) + if not isMACIP: + self.vapi.acl_interface_add_del(sw_if_index=tx_if.sw_if_index, + acl_index=acl_index, is_add=0) + self.vapi.acl_del(acl_index) def run_test_acls(self, mac_type, ip_type, acl_count, rules_count, traffic=None, ip=None): - self.apply_rules(self.create_rules(mac_type, ip_type, acl_count, - rules_count)) - self.verify_acls(acl_count, rules_count) + self.apply_macip_rules(self.create_rules(mac_type, ip_type, acl_count, + rules_count)) + self.verify_macip_acls(acl_count, rules_count) if traffic is not None: self.run_traffic(self.EXACT_MAC, self.EXACT_IP, traffic, ip, 9) + +class TestMACIP_IP4(MethodHolder): + """MACIP with IP4 traffic""" + def test_acl_bridged_ip4_exactMAC_exactIP(self): """ IP4 MACIP exactMAC|exactIP ACL bridged traffic """ self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9) - def test_acl_bridged_ip6_exactMAC_exactIP(self): - """ IP6 MACIP exactMAC|exactIP ACL bridged traffic - """ - - self.run_traffic(self.EXACT_MAC, self.EXACT_IP, - self.BRIDGED, self.IS_IP6, 9) - def test_acl_bridged_ip4_exactMAC_subnetIP(self): """ IP4 MACIP exactMAC|subnetIP ACL bridged traffic """ @@ -533,13 +699,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9) - def test_acl_bridged_ip6_exactMAC_subnetIP(self): - """ IP6 MACIP exactMAC|subnetIP ACL bridged traffic - """ - - self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, - self.BRIDGED, self.IS_IP6, 9) - def test_acl_bridged_ip4_exactMAC_wildIP(self): """ IP4 MACIP exactMAC|wildIP ACL bridged traffic """ @@ -547,13 +706,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9) - def test_acl_bridged_ip6_exactMAC_wildIP(self): - """ IP6 MACIP exactMAC|wildIP ACL bridged traffic - """ - - self.run_traffic(self.EXACT_MAC, self.WILD_IP, - self.BRIDGED, self.IS_IP6, 9) - def test_acl_bridged_ip4_ouiMAC_exactIP(self): """ IP4 MACIP ouiMAC|exactIP ACL bridged traffic """ @@ -561,13 +713,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 3) - def test_acl_bridged_ip6_ouiMAC_exactIP(self): - """ IP6 MACIP oui_MAC|exactIP ACL bridged traffic - """ - - self.run_traffic(self.OUI_MAC, self.EXACT_IP, - self.BRIDGED, self.IS_IP6, 9) - def test_acl_bridged_ip4_ouiMAC_subnetIP(self): """ IP4 MACIP ouiMAC|subnetIP ACL bridged traffic """ @@ -575,13 +720,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9) - def test_acl_bridged_ip6_ouiMAC_subnetIP(self): - """ IP6 MACIP ouiMAC|subnetIP ACL bridged traffic - """ - - self.run_traffic(self.OUI_MAC, self.SUBNET_IP, - self.BRIDGED, self.IS_IP6, 9) - def test_acl_bridged_ip4_ouiMAC_wildIP(self): """ IP4 MACIP ouiMAC|wildIP ACL bridged traffic """ @@ -589,13 +727,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.OUI_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP4, 9) - def test_acl_bridged_ip6_ouiMAC_wildIP(self): - """ IP6 MACIP ouiMAC|wildIP ACL bridged traffic - """ - - self.run_traffic(self.OUI_MAC, self.WILD_IP, - self.BRIDGED, self.IS_IP6, 9) - def test_ac_bridgedl_ip4_wildMAC_exactIP(self): """ IP4 MACIP wildcardMAC|exactIP ACL bridged traffic """ @@ -603,13 +734,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.BRIDGED, self.IS_IP4, 9) - def test_acl_bridged_ip6_wildMAC_exactIP(self): - """ IP6 MACIP wildcardMAC|exactIP ACL bridged traffic - """ - - self.run_traffic(self.WILD_MAC, self.EXACT_IP, - self.BRIDGED, self.IS_IP6, 9) - def test_acl_bridged_ip4_wildMAC_subnetIP(self): """ IP4 MACIP wildcardMAC|subnetIP ACL bridged traffic """ @@ -617,20 +741,148 @@ class TestMACIP(VppTestCase): self.run_traffic(self.WILD_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9) - def test_acl_bridged_ip6_wildMAC_subnetIP(self): - """ IP6 MACIP wildcardMAC|subnetIP ACL bridged traffic + def test_acl_bridged_ip4_wildMAC_wildIP(self): + """ IP4 MACIP wildcardMAC|wildIP ACL bridged traffic + """ + + self.run_traffic(self.WILD_MAC, self.WILD_IP, + self.BRIDGED, self.IS_IP4, 9) + + def test_acl_routed_ip4_exactMAC_exactIP(self): + """ IP4 MACIP exactMAC|exactIP ACL routed traffic + """ + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_routed_ip4_exactMAC_subnetIP(self): + """ IP4 MACIP exactMAC|subnetIP ACL routed traffic + """ + self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_routed_ip4_exactMAC_wildIP(self): + """ IP4 MACIP exactMAC|wildIP ACL routed traffic + """ + self.run_traffic(self.EXACT_MAC, self.WILD_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_routed_ip4_ouiMAC_exactIP(self): + """ IP4 MACIP ouiMAC|exactIP ACL routed traffic + """ + + self.run_traffic(self.OUI_MAC, self.EXACT_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_routed_ip4_ouiMAC_subnetIP(self): + """ IP4 MACIP ouiMAC|subnetIP ACL routed traffic + """ + + self.run_traffic(self.OUI_MAC, self.SUBNET_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_routed_ip4_ouiMAC_wildIP(self): + """ IP4 MACIP ouiMAC|wildIP ACL routed traffic + """ + + self.run_traffic(self.OUI_MAC, self.WILD_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_routed_ip4_wildMAC_exactIP(self): + """ IP4 MACIP wildcardMAC|exactIP ACL routed traffic + """ + + self.run_traffic(self.WILD_MAC, self.EXACT_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_routed_ip4_wildMAC_subnetIP(self): + """ IP4 MACIP wildcardMAC|subnetIP ACL routed traffic """ self.run_traffic(self.WILD_MAC, self.SUBNET_IP, - self.BRIDGED, self.IS_IP6, 9) + self.ROUTED, self.IS_IP4, 9) - def test_acl_bridged_ip4_wildMAC_wildIP(self): - """ IP4 MACIP wildcardMAC|wildIP ACL bridged traffic + def test_acl_routed_ip4_wildMAC_wildIP(self): + """ IP4 MACIP wildcardMAC|wildIP ACL """ self.run_traffic(self.WILD_MAC, self.WILD_IP, + self.ROUTED, self.IS_IP4, 9) + + def test_acl_replace_traffic_ip4(self): + """ MACIP replace ACL with IP4 traffic + """ + self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.BRIDGED, self.IS_IP4, 9) + r = self.create_rules() + # replace acls #2, #3 with new + reply = self.vapi.macip_acl_add_replace(r[0], 0) + self.assertEqual(reply.retval, 0) + self.assertEqual(reply.acl_index, 0) + + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, + self.BRIDGED, self.IS_IP4, 9, True) + + +class TestMACIP_IP6(MethodHolder): + """MACIP with IP6 traffic""" + + def test_acl_bridged_ip6_exactMAC_exactIP(self): + """ IP6 MACIP exactMAC|exactIP ACL bridged traffic + """ + + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, + self.BRIDGED, self.IS_IP6, 9) + + def test_acl_bridged_ip6_exactMAC_subnetIP(self): + """ IP6 MACIP exactMAC|subnetIP ACL bridged traffic + """ + + self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, + self.BRIDGED, self.IS_IP6, 9) + + def test_acl_bridged_ip6_exactMAC_wildIP(self): + """ IP6 MACIP exactMAC|wildIP ACL bridged traffic + """ + + self.run_traffic(self.EXACT_MAC, self.WILD_IP, + self.BRIDGED, self.IS_IP6, 9) + + def test_acl_bridged_ip6_ouiMAC_exactIP(self): + """ IP6 MACIP oui_MAC|exactIP ACL bridged traffic + """ + + self.run_traffic(self.OUI_MAC, self.EXACT_IP, + self.BRIDGED, self.IS_IP6, 9) + + def test_acl_bridged_ip6_ouiMAC_subnetIP(self): + """ IP6 MACIP ouiMAC|subnetIP ACL bridged traffic + """ + + self.run_traffic(self.OUI_MAC, self.SUBNET_IP, + self.BRIDGED, self.IS_IP6, 9) + + def test_acl_bridged_ip6_ouiMAC_wildIP(self): + """ IP6 MACIP ouiMAC|wildIP ACL bridged traffic + """ + + self.run_traffic(self.OUI_MAC, self.WILD_IP, + self.BRIDGED, self.IS_IP6, 9) + + def test_acl_bridged_ip6_wildMAC_exactIP(self): + """ IP6 MACIP wildcardMAC|exactIP ACL bridged traffic + """ + + self.run_traffic(self.WILD_MAC, self.EXACT_IP, + self.BRIDGED, self.IS_IP6, 9) + + def test_acl_bridged_ip6_wildMAC_subnetIP(self): + """ IP6 MACIP wildcardMAC|subnetIP ACL bridged traffic + """ + + self.run_traffic(self.WILD_MAC, self.SUBNET_IP, + self.BRIDGED, self.IS_IP6, 9) + def test_acl_bridged_ip6_wildMAC_wildIP(self): """ IP6 MACIP wildcardMAC|wildIP ACL bridged traffic """ @@ -638,12 +890,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.WILD_MAC, self.WILD_IP, self.BRIDGED, self.IS_IP6, 9) - def test_acl_routed_ip4_exactMAC_exactIP(self): - """ IP4 MACIP exactMAC|exactIP ACL routed traffic - """ - self.run_traffic(self.EXACT_MAC, self.EXACT_IP, - self.ROUTED, self.IS_IP4, 9) - def test_acl_routed_ip6_exactMAC_exactIP(self): """ IP6 MACIP exactMAC|exactIP ACL routed traffic """ @@ -651,12 +897,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip4_exactMAC_subnetIP(self): - """ IP4 MACIP exactMAC|subnetIP ACL routed traffic - """ - self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, - self.ROUTED, self.IS_IP4, 9) - def test_acl_routed_ip6_exactMAC_subnetIP(self): """ IP6 MACIP exactMAC|subnetIP ACL routed traffic """ @@ -664,12 +904,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.EXACT_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip4_exactMAC_wildIP(self): - """ IP4 MACIP exactMAC|wildIP ACL routed traffic - """ - self.run_traffic(self.EXACT_MAC, self.WILD_IP, - self.ROUTED, self.IS_IP4, 9) - def test_acl_routed_ip6_exactMAC_wildIP(self): """ IP6 MACIP exactMAC|wildIP ACL routed traffic """ @@ -677,13 +911,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.EXACT_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip4_ouiMAC_exactIP(self): - """ IP4 MACIP ouiMAC|exactIP ACL routed traffic - """ - - self.run_traffic(self.OUI_MAC, self.EXACT_IP, - self.ROUTED, self.IS_IP4, 9) - def test_acl_routed_ip6_ouiMAC_exactIP(self): """ IP6 MACIP ouiMAC|exactIP ACL routed traffic """ @@ -691,13 +918,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.OUI_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip4_ouiMAC_subnetIP(self): - """ IP4 MACIP ouiMAC|subnetIP ACL routed traffic - """ - - self.run_traffic(self.OUI_MAC, self.SUBNET_IP, - self.ROUTED, self.IS_IP4, 9) - def test_acl_routed_ip6_ouiMAC_subnetIP(self): """ IP6 MACIP ouiMAC|subnetIP ACL routed traffic """ @@ -705,13 +925,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.OUI_MAC, self.SUBNET_IP, self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip4_ouiMAC_wildIP(self): - """ IP4 MACIP ouiMAC|wildIP ACL routed traffic - """ - - self.run_traffic(self.OUI_MAC, self.WILD_IP, - self.ROUTED, self.IS_IP4, 9) - def test_acl_routed_ip6_ouiMAC_wildIP(self): """ IP6 MACIP ouiMAC|wildIP ACL routed traffic """ @@ -719,13 +932,6 @@ class TestMACIP(VppTestCase): self.run_traffic(self.OUI_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip4_wildMAC_exactIP(self): - """ IP4 MACIP wildcardMAC|exactIP ACL routed traffic - """ - - self.run_traffic(self.WILD_MAC, self.EXACT_IP, - self.ROUTED, self.IS_IP4, 9) - def test_acl_routed_ip6_wildMAC_exactIP(self): """ IP6 MACIP wildcardMAC|exactIP ACL routed traffic """ @@ -733,20 +939,39 @@ class TestMACIP(VppTestCase): self.run_traffic(self.WILD_MAC, self.EXACT_IP, self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip4_wildMAC_subnetIP(self): - """ IP4 MACIP wildcardMAC|subnetIP ACL routed traffic + def test_acl_routed_ip6_wildMAC_subnetIP(self): + """ IP6 MACIP wildcardMAC|subnetIP ACL routed traffic """ self.run_traffic(self.WILD_MAC, self.SUBNET_IP, - self.ROUTED, self.IS_IP4, 9) + self.ROUTED, self.IS_IP6, 9) - def test_acl_routed_ip6_wildMAC_subnetIP(self): - """ IP6 MACIP wildcardMAC|subnetIP ACL routed traffic + def test_acl_routed_ip6_wildMAC_wildIP(self): + """ IP6 MACIP wildcardMAC|wildIP ACL """ - self.run_traffic(self.WILD_MAC, self.SUBNET_IP, + self.run_traffic(self.WILD_MAC, self.WILD_IP, self.ROUTED, self.IS_IP6, 9) + def test_acl_replace_traffic_ip6(self): + """ MACIP replace ACL with IP6 traffic + """ + self.run_traffic(self.OUI_MAC, self.SUBNET_IP, + self.BRIDGED, self.IS_IP6, 9) + + r = self.create_rules() + # replace acls #2, #3 with new + reply = self.vapi.macip_acl_add_replace(r[0], 0) + self.assertEqual(reply.retval, 0) + self.assertEqual(reply.acl_index, 0) + + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, + self.BRIDGED, self.IS_IP6, 9, True) + + +class TestMACIP(MethodHolder): + """MACIP Tests""" + def test_acl_1_2(self): """ MACIP ACL with 2 entries """ @@ -818,7 +1043,7 @@ class TestMACIP(VppTestCase): r1 = self.create_rules(acl_count=3, rules_count=[2, 2, 2]) r2 = self.create_rules(mac_type=self.OUI_MAC, ip_type=self.SUBNET_IP) - self.apply_rules(r1) + self.apply_macip_rules(r1) acls_before = self.macip_acl_dump_debug() @@ -853,43 +1078,14 @@ class TestMACIP(VppTestCase): self.assertNotEqual(len(acl1.r), len(acl2.r)) self.assertNotEqual(acl1.r, acl2.r) - def test_acl_replace_traffic_ip4(self): - """ MACIP replace ACL with IP4 traffic - """ - self.run_traffic(self.OUI_MAC, self.SUBNET_IP, - self.BRIDGED, self.IS_IP4, 9) - - r = self.create_rules() - # replace acls #2, #3 with new - reply = self.vapi.macip_acl_add_replace(r[0], 0) - self.assertEqual(reply.retval, 0) - self.assertEqual(reply.acl_index, 0) - - self.run_traffic(self.EXACT_MAC, self.EXACT_IP, - self.BRIDGED, self.IS_IP4, 9, True) - - def test_acl_replace_traffic_ip6(self): - """ MACIP replace ACL with IP6 traffic - """ - self.run_traffic(self.OUI_MAC, self.SUBNET_IP, - self.BRIDGED, self.IS_IP6, 9) - - r = self.create_rules() - # replace acls #2, #3 with new - reply = self.vapi.macip_acl_add_replace(r[0], 0) - self.assertEqual(reply.retval, 0) - self.assertEqual(reply.acl_index, 0) - - self.run_traffic(self.EXACT_MAC, self.EXACT_IP, - self.BRIDGED, self.IS_IP6, 9, True) - def test_delete_intf(self): """ MACIP ACL delete intf with acl """ intf_count = len(self.interfaces)+1 intf = [] - self.apply_rules(self.create_rules(acl_count=3, rules_count=[3, 5, 4])) + self.apply_macip_rules(self.create_rules(acl_count=3, + rules_count=[3, 5, 4])) intf.append(VppLoInterface(self, 0)) intf.append(VppLoInterface(self, 1)) @@ -942,19 +1138,85 @@ class TestMACIP(VppTestCase): self.assertEqual(len([x for x in reply.acls if x != 4294967295]), 0) - def test_acl_routed_ip4_wildMAC_wildIP(self): - """ IP4 MACIP wildcardMAC|wildIP ACL - """ - self.run_traffic(self.WILD_MAC, self.WILD_IP, - self.ROUTED, self.IS_IP4, 9) +class TestACL_dot1q_bridged(MethodHolder): + """ACL on dot1q bridged subinterfaces Tests""" - def test_acl_routed_ip6_wildMAC_wildIP(self): - """ IP6 MACIP wildcardMAC|wildIP ACL - """ + def test_acl_bridged_ip4_subif_dot1q(self): + """ IP4 ACL SubIf Dot1Q bridged traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, + self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False) - self.run_traffic(self.WILD_MAC, self.WILD_IP, - self.ROUTED, self.IS_IP6, 9) + def test_acl_bridged_ip6_subif_dot1q(self): + """ IP6 ACL SubIf Dot1Q bridged traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, + self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False) + + +class TestACL_dot1ad_bridged(MethodHolder): + """ACL on dot1ad bridged subinterfaces Tests""" + + def test_acl_bridged_ip4_subif_dot1ad(self): + """ IP4 ACL SubIf Dot1AD bridged traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, + self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False) + + def test_acl_bridged_ip6_subif_dot1ad(self): + """ IP6 ACL SubIf Dot1AD bridged traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.BRIDGED, + self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False) + + +class TestACL_dot1q_routed(MethodHolder): + """ACL on dot1q routed subinterfaces Tests""" + + def test_acl_routed_ip4_subif_dot1q(self): + """ IP4 ACL SubIf Dot1Q routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP4, 9, tags=self.DOT1Q, isMACIP=False) + + def test_acl_routed_ip6_subif_dot1q(self): + """ IP6 ACL SubIf Dot1Q routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP6, 9, tags=self.DOT1Q, isMACIP=False) + + def test_acl_routed_ip4_subif_dot1q_deny_by_tags(self): + """ IP4 ACL SubIf wrong tags Dot1Q routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP4, 9, True, tags=self.DOT1Q, isMACIP=False, + permit_tags=self.DENY_TAGS) + + def test_acl_routed_ip6_subif_dot1q_deny_by_tags(self): + """ IP6 ACL SubIf wrong tags Dot1Q routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP6, 9, True, tags=self.DOT1Q, isMACIP=False, + permit_tags=self.DENY_TAGS) + + +class TestACL_dot1ad_routed(MethodHolder): + """ACL on dot1ad routed subinterfaces Tests""" + + def test_acl_routed_ip6_subif_dot1ad(self): + """ IP6 ACL SubIf Dot1AD routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP6, 9, tags=self.DOT1AD, isMACIP=False) + + def test_acl_routed_ip4_subif_dot1ad(self): + """ IP4 ACL SubIf Dot1AD routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP4, 9, tags=self.DOT1AD, isMACIP=False) + + def test_acl_routed_ip6_subif_dot1ad_deny_by_tags(self): + """ IP6 ACL SubIf wrong tags Dot1AD routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP6, 9, True, tags=self.DOT1AD, isMACIP=False, + permit_tags=self.DENY_TAGS) + + def test_acl_routed_ip4_subif_dot1ad_deny_by_tags(self): + """ IP4 ACL SubIf wrong tags Dot1AD routed traffic""" + self.run_traffic(self.EXACT_MAC, self.EXACT_IP, self.ROUTED, + self.IS_IP4, 9, True, tags=self.DOT1AD, isMACIP=False, + permit_tags=self.DENY_TAGS) if __name__ == '__main__': diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index 495db95052e..5085ff2801e 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -2493,6 +2493,23 @@ class VppPapiProvider(object): 'acls': acls}, expected_retval=expected_retval) + def acl_interface_add_del(self, + sw_if_index, + acl_index, + is_add=1): + """ Add/Delete ACL to/from interface + + :param sw_if_index: + :param acl_index: + :param is_add: (Default value = 1) + """ + + return self.api(self.papi.acl_interface_add_del, + {'is_add': is_add, + 'is_input': 1, + 'sw_if_index': sw_if_index, + 'acl_index': acl_index}) + def acl_dump(self, acl_index, expected_retval=0): return self.api(self.papi.acl_dump, {'acl_index': acl_index}, -- 2.16.6