summaryrefslogtreecommitdiffstats
path: root/test/test_container.py
blob: 474805333c5f3ec76703125cbcca978bdb91a12a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
""" Container integration tests """

import unittest
from framework import VppTestCase, VppTestRunner, running_extended_tests
from scapy.layers.l2 import Ether
from scapy.packet import Raw
from scapy.layers.inet import IP, UDP, TCP
from scapy.packet import Packet
from socket import inet_pton, AF_INET, AF_INET6
from scapy.layers.inet6 import IPv6, ICMPv6Unknown, ICMPv6EchoRequest
from scapy.layers.inet6 import ICMPv6EchoReply, IPv6ExtHdrRouting
from scapy.layers.inet6 import IPv6ExtHdrFragment
from pprint import pprint
from random import randint
from util import L4_Conn


class Conn(L4_Conn):
    # for now same as L4_Conn
    pass


@unittest.skipUnless(running_extended_tests, "part of extended tests")
class ContainerIntegrationTestCase(VppTestCase):
    """ Container integration extended testcases """

    @classmethod
    def setUpClass(cls):
        super(ContainerIntegrationTestCase, cls).setUpClass()
        # create pg0 and pg1
        cls.create_pg_interfaces(range(2))
        for i in cls.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.config_ip6()
            i.resolve_arp()
            i.resolve_ndp()

    @classmethod
    def tearDownClass(cls):
        super(ContainerIntegrationTestCase, cls).tearDownClass()

    def tearDown(self):
        """Run standard test teardown and log various show commands
        """
        super(ContainerIntegrationTestCase, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show ip neighbors"))

    def run_basic_conn_test(self, af, acl_side):
        """ Basic connectivity test """
        conn1 = Conn(self, self.pg0, self.pg1, af, UDP, 42001, 4242)
        conn1.send_through(0)
        # the return packets should pass
        conn1.send_through(1)

    def run_negative_conn_test(self, af, acl_side):
        """ Packets with local spoofed address """
        conn1 = Conn(self, self.pg0, self.pg1, af, UDP, 42001, 4242)
        try:
            p2 = conn1.send_through(0).command()
        except:
            # If we asserted while waiting, it's good.
            # the conn should have timed out.
            p2 = None
        self.assert_equal(p2, None, ": packet should have been dropped")

    def test_0010_basic_conn_test(self):
        """ IPv4 basic connectivity test """
        self.run_basic_conn_test(AF_INET, 0)

    def test_0011_basic_conn_test(self):
        """ IPv6 basic connectivity test """
        self.run_basic_conn_test(AF_INET6, 0)

    def test_0050_loopback_prepare_test(self):
        """ Create loopbacks overlapping with remote addresses """
        self.create_loopback_interfaces(2)
        for i in range(2):
            intf = self.lo_interfaces[i]
            intf.admin_up()
            intf.local_ip4 = self.pg_interfaces[i].remote_ip4
            intf.local_ip4_prefix_len = 32
            intf.config_ip4()
            intf.local_ip6 = self.pg_interfaces[i].remote_ip6
            intf.local_ip6_prefix_len = 128
            intf.config_ip6()

    def test_0110_basic_conn_test(self):
        """ IPv4 local-spoof connectivity test """
        self.run_negative_conn_test(AF_INET, 0)

    def test_0111_basic_conn_test(self):
        """ IPv6 local-spoof connectivity test """
        self.run_negative_conn_test(AF_INET, 1)

    def test_0200_basic_conn_test(self):
        """ Configure container commands """
        for i in range(2):
            for addr in [self.pg_interfaces[i].remote_ip4,
                         self.pg_interfaces[i].remote_ip6]:
                self.vapi.ppcli("ip container " + addr + " " +
                                self.pg_interfaces[i].name)
                self.vapi.ppcli("stn rule address " + addr +
                                " interface " + self.pg_interfaces[i].name)

    def test_0210_basic_conn_test(self):
        """ IPv4 test after configuring container """
        self.run_basic_conn_test(AF_INET, 0)

    def test_0211_basic_conn_test(self):
        """ IPv6 test after configuring container """
        self.run_basic_conn_test(AF_INET, 1)

    def test_0300_unconfigure_commands(self):
        """ Unconfigure container commands """
        for i in range(2):
            for addr in [self.pg_interfaces[i].remote_ip4,
                         self.pg_interfaces[i].remote_ip6]:
                self.vapi.ppcli("ip container " + addr + " " +
                                self.pg_interfaces[i].name +
                                " del")
                self.vapi.ppcli("stn rule address " + addr +
                                " interface " + self.pg_interfaces[i].name +
                                " del")

    def test_0410_spoof_test(self):
        """ IPv4 local-spoof after unconfig test """
        self.run_negative_conn_test(AF_INET, 0)

    def test_0411_spoof_test(self):
        """ IPv6 local-spoof after unconfig test """
        self.run_negative_conn_test(AF_INET, 1)
class="cm">*/ applied_hash_ace_entry_t **hash_entry_vec_by_lc_index; applied_hash_acl_info_t *applied_hash_acl_info_by_lc_index; /* Corresponding lookup context indices for in/out lookups per sw_if_index */ u32 *input_lc_index_by_sw_if_index; u32 *output_lc_index_by_sw_if_index; /* context user id for interface ACLs */ u32 interface_acl_user_id; macip_acl_list_t *macip_acls; /* Pool of MAC-IP ACLs */ /* ACLs associated with interfaces */ u32 **input_acl_vec_by_sw_if_index; u32 **output_acl_vec_by_sw_if_index; /* interfaces on which given ACLs are applied */ u32 **input_sw_if_index_vec_by_acl; u32 **output_sw_if_index_vec_by_acl; /* bitmaps 1=sw_if_index has in/out ACL processing enabled */ uword *in_acl_on_sw_if_index; uword *out_acl_on_sw_if_index; /* lookup contexts where a given ACL is used */ u32 **lc_index_vec_by_acl; /* input and output policy epochs by interface */ u32 *input_policy_epoch_by_sw_if_index; u32 *output_policy_epoch_by_sw_if_index; /* whether we need to take the epoch of the session into account */ int reclassify_sessions; /* Total count of interface+direction pairs enabled */ u32 fa_total_enabled_count; /* Do we use hash-based ACL matching or linear */ int use_hash_acl_matching; /* Do we use the TupleMerge for hash ACLs or not */ int use_tuple_merge; /* Max collision vector length before splitting the tuple */ #define TM_SPLIT_THRESHOLD 39 int tuple_merge_split_threshold; /* a pool of all mask types present in all ACEs */ ace_mask_type_entry_t *ace_mask_type_pool; /* vec of vectors of all info of all mask types present in ACEs contained in each lc_index */ hash_applied_mask_info_t **hash_applied_mask_info_vec_by_lc_index; /* * Classify tables used to grab the packets for the ACL check, * and serving as the 5-tuple session tables at the same time */ u32 *acl_ip4_input_classify_table_by_sw_if_index; u32 *acl_ip6_input_classify_table_by_sw_if_index; 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; u32 *acl_etype_input_classify_table_by_sw_if_index; u32 *acl_etype_output_classify_table_by_sw_if_index; u16 **input_etype_whitelist_by_sw_if_index; u16 **output_etype_whitelist_by_sw_if_index; /* MACIP (input) ACLs associated with the interfaces */ u32 *macip_acl_by_sw_if_index; /* Vector of interfaces on which given MACIP ACLs are applied */ u32 **sw_if_index_vec_by_macip_acl; /* bitmaps when set the processing is enabled on the interface */ uword *fa_in_acl_on_sw_if_index; uword *fa_out_acl_on_sw_if_index; /* bihash holding all of the sessions */ int fa_sessions_hash_is_initialized; clib_bihash_40_8_t fa_ip6_sessions_hash; clib_bihash_16_8_t fa_ip4_sessions_hash; /* The process node which orchestrates the cleanup */ u32 fa_cleaner_node_index; /* FA session timeouts, in seconds */ u32 session_timeout_sec[ACL_N_TIMEOUTS]; /* total session adds/dels */ u64 fa_session_total_adds; u64 fa_session_total_dels; /* how many sessions went into purgatory */ u64 fa_session_total_deactivations; /* EH values that we can skip over */ uword *fa_ipv6_known_eh_bitmap; /* whether to match L4 ACEs with ports on the non-initial fragment */ int l4_match_nonfirst_fragment; /* conn table per-interface conn table parameters */ u32 fa_conn_table_hash_num_buckets; uword fa_conn_table_hash_memory_size; u64 fa_conn_table_max_entries; int trace_sessions; int trace_acl; /* * If the cleaner has to delete more than this number * of connections, it halves the sleep time. */ #define ACL_FA_DEFAULT_MAX_DELETED_SESSIONS_PER_INTERVAL 100 u64 fa_max_deleted_sessions_per_interval; /* * If the cleaner deletes less than these connections, * it increases the wait time by the "increment" */ #define ACL_FA_DEFAULT_MIN_DELETED_SESSIONS_PER_INTERVAL 1 u64 fa_min_deleted_sessions_per_interval; #define ACL_FA_DEFAULT_CLEANER_WAIT_TIME_INCREMENT 0.1 f64 fa_cleaner_wait_time_increment; u64 fa_current_cleaner_timer_wait_interval; int fa_interrupt_generation; /* per-worker data related t conn management */ acl_fa_per_worker_data_t *per_worker_data; /* Configured session timeout */ u64 session_timeout[ACL_N_TIMEOUTS]; /* Counters for the cleaner thread */ #define foreach_fa_cleaner_counter \ _(fa_cleaner_cnt_delete_by_sw_index, "delete_by_sw_index events") \ _(fa_cleaner_cnt_delete_by_sw_index_ok, "delete_by_sw_index handled ok") \ _(fa_cleaner_cnt_unknown_event, "unknown events received") \ _(fa_cleaner_cnt_timer_restarted, "session idle timers restarted") \ _(fa_cleaner_cnt_wait_with_timeout, "event wait with timeout called") \ _(fa_cleaner_cnt_wait_without_timeout, "event wait w/o timeout called") \ _(fa_cleaner_cnt_event_cycles, "total event cycles") \ /* end of counters */ #define _(id, desc) u32 id; foreach_fa_cleaner_counter #undef _ /* convenience */ vlib_main_t * vlib_main; vnet_main_t * vnet_main; /* logging */ vlib_log_class_t log_default; } acl_main_t; #define acl_log_err(...) \ vlib_log(VLIB_LOG_LEVEL_ERR, acl_main.log_default, __VA_ARGS__) #define acl_log_warn(...) \ vlib_log(VLIB_LOG_LEVEL_WARNING, acl_main.log_default, __VA_ARGS__) #define acl_log_notice(...) \ vlib_log(VLIB_LOG_LEVEL_NOTICE, acl_main.log_default, __VA_ARGS__) #define acl_log_info(...) \ vlib_log(VLIB_LOG_LEVEL_INFO, acl_main.log_default, __VA_ARGS__) #define foreach_acl_eh \ _(HOPBYHOP , 0 , "IPv6ExtHdrHopByHop") \ _(ROUTING , 43 , "IPv6ExtHdrRouting") \ _(DESTOPT , 60 , "IPv6ExtHdrDestOpt") \ _(FRAGMENT , 44 , "IPv6ExtHdrFragment") \ _(MOBILITY , 135, "Mobility Header") \ _(HIP , 139, "Experimental use Host Identity Protocol") \ _(SHIM6 , 140, "Shim6 Protocol") \ _(EXP1 , 253, "Use for experimentation and testing") \ _(EXP2 , 254, "Use for experimentation and testing") /* "No Next Header" is not a header. Also, Fragment header needs special processing. _(NONEXT , 59 , "NoNextHdr") \ ESP is hiding its internal format, so no point in trying to go past it. _(ESP , 50 , "EncapsulatingSecurityPayload") \ AH has a special treatment of its length, it is in 32-bit words, not 64-bit words like the rest. _(AUTH , 51 , "Authentication Header") \ */ typedef enum { #define _(N, v, s) ACL_EH_##N = v, foreach_acl_eh #undef _ } acl_eh_t; extern acl_main_t acl_main; void *acl_plugin_set_heap(); typedef enum { ACL_FA_REQ_SESS_RESCHEDULE = 0, ACL_FA_N_REQ, } acl_fa_sess_req_t; void aclp_post_session_change_request(acl_main_t *am, u32 target_thread, u32 target_session, acl_fa_sess_req_t request_type); void aclp_swap_wip_and_pending_session_change_requests(acl_main_t *am, u32 target_thread); #endif