Пример #1
0
    def test_route_nhg_exhaust(self, dvs, testlog):
        """
        Test the situation of exhausting ECMP group, assume SAI_SWITCH_ATTR_NUMBER_OF_ECMP_GROUPS is 512

        In order to achieve that, we will config
            1. 9 ports
            2. 512 routes with different nexthop group

        See Also
        --------
        SwitchStateBase::set_number_of_ecmp_groups()
        https://github.com/Azure/sonic-sairedis/blob/master/vslib/src/SwitchStateBase.cpp

        """

        # TODO: check ECMP 512

        def port_name(i):
            return "Ethernet" + str(i * 4)

        def port_ip(i):
            return "10.0.0." + str(i * 2)

        def peer_ip(i):
            return "10.0.0." + str(i * 2 + 1)

        def port_ipprefix(i):
            return port_ip(i) + "/31"

        def port_mac(i):
            return "00:00:00:00:00:0" + str(i)

        def gen_ipprefix(r):
            """ Construct route like 2.X.X.0/24 """
            ip = ipaddress.IPv4Address(IP_INTEGER_BASE + r * 256)
            ip = str(ip)
            ipprefix = ip + "/24"
            return ipprefix

        def gen_nhg_fvs(binary):
            nexthop = []
            ifname = []
            for i in range(MAX_PORT_COUNT):
                if binary[i] == '1':
                    nexthop.append(peer_ip(i))
                    ifname.append(port_name(i))

            nexthop = ','.join(nexthop)
            ifname = ','.join(ifname)
            fvs = swsscommon.FieldValuePairs([("nexthop", nexthop),
                                              ("ifname", ifname)])
            return fvs

        def asic_route_exists(keys, ipprefix):
            for k in keys:
                rt_key = json.loads(k)

                if rt_key['dest'] == ipprefix:
                    return k
            else:
                return None

        def asic_route_nhg_fvs(k):
            fvs = asic_db.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY",
                                    k)
            if not fvs:
                return None

            print(fvs)
            nhgid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID")
            if nhgid is None:
                return None

            fvs = asic_db.get_entry(
                "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP", nhgid)
            return fvs

        MAX_ECMP_COUNT = 512
        MAX_PORT_COUNT = 10
        if sys.version_info < (3, 0):
            IP_INTEGER_BASE = int(ipaddress.IPv4Address(unicode("2.2.2.0")))
        else:
            IP_INTEGER_BASE = int(ipaddress.IPv4Address(str("2.2.2.0")))

        config_db = dvs.get_config_db()
        fvs = {"NULL": "NULL"}

        for i in range(MAX_PORT_COUNT):
            config_db.create_entry("INTERFACE", port_name(i), fvs)
            config_db.create_entry(
                "INTERFACE", "{}|{}".format(port_name(i), port_ipprefix(i)),
                fvs)
            dvs.runcmd("config interface startup " + port_name(i))
            dvs.runcmd("arp -s {} {}".format(peer_ip(i), port_mac(i)))
            assert dvs.servers[i].runcmd("ip link set down dev eth0") == 0
            assert dvs.servers[i].runcmd("ip link set up dev eth0") == 0

        app_db = dvs.get_app_db()
        asic_db = dvs.get_asic_db()
        ps = swsscommon.ProducerStateTable(app_db.db_connection, "ROUTE_TABLE")

        # Add first batch of routes with unique nexthop groups in AppDB
        route_count = 0
        r = 0
        asic_routes_count = len(
            asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY"))
        while route_count < MAX_ECMP_COUNT:
            r += 1
            fmt = '{{0:0{}b}}'.format(MAX_PORT_COUNT)
            binary = fmt.format(r)
            # We need at least 2 ports for a nexthop group
            if binary.count('1') <= 1:
                continue
            fvs = gen_nhg_fvs(binary)
            route_ipprefix = gen_ipprefix(route_count)
            ps.set(route_ipprefix, fvs)
            route_count += 1

        # Wait and check ASIC DB the count of nexthop groups used
        asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP",
                                MAX_ECMP_COUNT)

        # Wait and check ASIC DB the count of routes
        asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY",
                                asic_routes_count + MAX_ECMP_COUNT)
        asic_routes_count += MAX_ECMP_COUNT

        # Add second batch of routes with unique nexthop groups in AppDB
        # Add more routes with new nexthop group in AppDBdd
        route_ipprefix = gen_ipprefix(route_count)
        base_ipprefix = route_ipprefix
        base = route_count
        route_count = 0
        while route_count < 10:
            r += 1
            fmt = '{{0:0{}b}}'.format(MAX_PORT_COUNT)
            binary = fmt.format(r)
            # We need at least 2 ports for a nexthop group
            if binary.count('1') <= 1:
                continue
            fvs = gen_nhg_fvs(binary)
            route_ipprefix = gen_ipprefix(base + route_count)
            ps.set(route_ipprefix, fvs)
            route_count += 1
        last_ipprefix = route_ipprefix

        # Wait until we get expected routes and check ASIC DB on the count of nexthop groups used, and it should not increase
        keys = asic_db.wait_for_n_keys(
            "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY", asic_routes_count + 10)
        asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP",
                                MAX_ECMP_COUNT)

        # Check the route points to next hop group
        # Note: no need to wait here
        k = asic_route_exists(keys, "2.2.2.0/24")
        assert k is not None
        fvs = asic_route_nhg_fvs(k)
        assert fvs is not None

        # Check the second batch does not point to next hop group
        k = asic_route_exists(keys, base_ipprefix)
        assert k is not None
        fvs = asic_route_nhg_fvs(k)
        assert not (fvs)

        # Remove first batch of routes with unique nexthop groups in AppDB
        route_count = 0
        r = 0
        while route_count < MAX_ECMP_COUNT:
            r += 1
            fmt = '{{0:0{}b}}'.format(MAX_PORT_COUNT)
            binary = fmt.format(r)
            # We need at least 2 ports for a nexthop group
            if binary.count('1') <= 1:
                continue
            route_ipprefix = gen_ipprefix(route_count)
            ps._del(route_ipprefix)
            route_count += 1

        # Wait and check the second batch points to next hop group
        # Check ASIC DB on the count of nexthop groups used, and it should not increase or decrease
        asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP",
                                10)
        keys = asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
        k = asic_route_exists(keys, base_ipprefix)
        assert k is not None
        fvs = asic_route_nhg_fvs(k)
        assert fvs is not None
        k = asic_route_exists(keys, last_ipprefix)
        assert k is not None
        fvs = asic_route_nhg_fvs(k)
        assert fvs is not None
Пример #2
0
 def add_neighbor(self, interface, ip, mac):
     tbl = swsscommon.ProducerStateTable(self.pdb, "NEIGH_TABLE")
     fvs = swsscommon.FieldValuePairs([("neigh", mac),
                                       ("family", "IPv4")])
     tbl.set(interface + ":" + ip, fvs)
     time.sleep(1)
Пример #3
0
def create_entry_pst(db, table, separator, key, pairs):
    tbl = swsscommon.ProducerStateTable(db, table)
    create_entry(tbl, key, pairs)
Пример #4
0
    def _test_sub_port_intf_oper_down_with_pending_neigh_route_tasks(
            self,
            dvs,
            sub_port_intf_name,
            nhop_num=3,
            create_intf_on_parent_port=False):
        substrs = sub_port_intf_name.split(VLAN_SUB_INTERFACE_SEPARATOR)
        parent_port = substrs[0]
        vlan_id = substrs[1]
        assert len(vlan_id) == 2

        if parent_port.startswith(ETHERNET_PREFIX):
            parent_port_prefix = ETHERNET_PREFIX
        else:
            assert parent_port.startswith(LAG_PREFIX)
            parent_port_prefix = LAG_PREFIX
        parent_port_idx_base = self.get_parent_port_index(parent_port)

        # Set parent ports admin status up
        parent_port_idx = parent_port_idx_base
        for i in range(0, nhop_num):
            port_name = "{}{}".format(parent_port_prefix, parent_port_idx)
            self.set_parent_port_admin_status(dvs, port_name, "up")

            parent_port_idx += (4 if parent_port_prefix == ETHERNET_PREFIX else
                                1)

        ifnames = []
        # Create sub port interfaces
        ifnames.extend(
            self.create_nhg_router_intfs(dvs, parent_port_prefix,
                                         parent_port_idx_base, int(vlan_id),
                                         nhop_num))
        # Create router interfaces on parent ports
        if create_intf_on_parent_port == True:
            ifnames.extend(
                self.create_nhg_router_intfs(dvs, parent_port_prefix,
                                             parent_port_idx_base, 0,
                                             nhop_num))

        # Bring parent port oper status down one at a time
        # Verify next hop group members created after processing pending tasks
        parent_port_idx = parent_port_idx_base
        for i in range(0, nhop_num):
            port_name = "{}{}".format(parent_port_prefix, parent_port_idx)
            self.set_parent_port_oper_status(dvs, port_name, "down")

            # Verify parent port oper status down
            fv_dict = {
                "oper_status": "down",
            }
            if parent_port_prefix == ETHERNET_PREFIX:
                self.check_sub_port_intf_fvs(self.app_db, APP_PORT_TABLE_NAME,
                                             port_name, fv_dict)
            else:
                self.check_sub_port_intf_fvs(self.app_db, APP_LAG_TABLE_NAME,
                                             port_name, fv_dict)

            # Mimic pending neighbor task
            nhop_ips = []
            nhop_cnt = len(self.asic_db.get_keys(ASIC_NEXT_HOP_TABLE))
            # Create next hop objects on sub port interfaces
            nhop_ips.extend(
                self.create_nhg_next_hop_objs(dvs, parent_port_prefix,
                                              parent_port_idx_base,
                                              int(vlan_id), nhop_num))
            # Create next hop objects on router interfaces
            if create_intf_on_parent_port == True:
                nhop_ips.extend(
                    self.create_nhg_next_hop_objs(dvs, parent_port_prefix,
                                                  parent_port_idx_base, 0,
                                                  nhop_num))
            self.asic_db.wait_for_n_keys(
                ASIC_NEXT_HOP_TABLE, nhop_cnt +
                nhop_num if create_intf_on_parent_port == False else nhop_cnt +
                nhop_num * 2)

            # Mimic pending multi-next-hop route entry task
            rt_tbl = swsscommon.ProducerStateTable(self.app_db.db_connection,
                                                   APP_ROUTE_TABLE_NAME)
            fvs = swsscommon.FieldValuePairs([("nexthop", ",".join(nhop_ips)),
                                              ("ifname", ",".join(ifnames))])
            ip_prefix = "2.2.2.0/24"
            rt_tbl.set(ip_prefix, fvs)

            # Verify route entry created in ASIC_DB and get next hop group oid
            nhg_oid = self.get_ip_prefix_nhg_oid(ip_prefix)

            # Verify next hop group of the specified oid created in ASIC_DB
            self.check_sub_port_intf_key_existence(self.asic_db,
                                                   ASIC_NEXT_HOP_GROUP_TABLE,
                                                   nhg_oid)

            # Verify next hop group member # created in ASIC_DB
            nhg_member_oids = self.asic_db.wait_for_n_keys(ASIC_NEXT_HOP_GROUP_MEMBER_TABLE, \
                                                           (nhop_num - 1) - i if create_intf_on_parent_port == False else ((nhop_num - 1) - i) * 2)

            # Verify that next hop group members all belong to the next hop group of the specified oid
            fv_dict = {
                "SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID": nhg_oid,
            }
            for nhg_member_oid in nhg_member_oids:
                self.check_sub_port_intf_fvs(self.asic_db,
                                             ASIC_NEXT_HOP_GROUP_MEMBER_TABLE,
                                             nhg_member_oid, fv_dict)

            nhop_cnt = len(self.asic_db.get_keys(ASIC_NEXT_HOP_TABLE))
            # Remove next hop objects on sub port interfaces
            self.remove_nhg_next_hop_objs(dvs, parent_port_prefix,
                                          parent_port_idx_base, int(vlan_id),
                                          nhop_num)
            # Remove next hop objects on router interfaces
            if create_intf_on_parent_port == True:
                self.remove_nhg_next_hop_objs(dvs, parent_port_prefix,
                                              parent_port_idx_base, 0,
                                              nhop_num)
            # Remove ecmp route entry
            rt_tbl._del(ip_prefix)
            # Removal of next hop objects indicates the proper removal of route entry, nhg, and nhg members
            self.asic_db.wait_for_n_keys(
                ASIC_NEXT_HOP_TABLE, nhop_cnt -
                nhop_num if create_intf_on_parent_port == False else nhop_cnt -
                nhop_num * 2)

            parent_port_idx += (4 if parent_port_prefix == ETHERNET_PREFIX else
                                1)

        # Clean up
        rif_cnt = len(self.asic_db.get_keys(ASIC_RIF_TABLE))
        # Remove sub port interfaces
        self.remove_nhg_router_intfs(dvs,
                                     parent_port_prefix, parent_port_idx_base,
                                     int(vlan_id), nhop_num)
        # Remove router interfaces on parent ports
        if create_intf_on_parent_port == True:
            self.remove_nhg_router_intfs(dvs, parent_port_prefix,
                                         parent_port_idx_base, 0, nhop_num)
        self.asic_db.wait_for_n_keys(
            ASIC_RIF_TABLE, rif_cnt -
            nhop_num if create_intf_on_parent_port == False else rif_cnt -
            nhop_num * 2)

        # Make sure parent port oper status is up
        parent_port_idx = parent_port_idx_base
        for i in range(0, nhop_num):
            port_name = "{}{}".format(parent_port_prefix, parent_port_idx)
            self.set_parent_port_oper_status(dvs, port_name, "up")

            parent_port_idx += (4 if parent_port_prefix == ETHERNET_PREFIX else
                                1)
Пример #5
0
    def test_route_fgnhg_warm_reboot(self, dvs, testlog):
        dvs.runcmd("swssloglevel -l INFO -c orchagent")
        app_db = dvs.get_app_db()
        asic_db = dvs.get_asic_db()
        config_db = dvs.get_config_db()
        state_db = dvs.get_state_db()
        fvs_nul = {"NULL": "NULL"}
        NUM_NHs = 6
        fg_nhg_name = "fgnhg_v4"
        fg_nhg_prefix = "2.2.2.0/24"
        bucket_size = 60
        ip_to_if_map = {}

        fvs = {"bucket_size": str(bucket_size)}
        create_entry(config_db, FG_NHG, fg_nhg_name, fvs)

        fvs = {"FG_NHG": fg_nhg_name}
        create_entry(config_db, FG_NHG_PREFIX, fg_nhg_prefix, fvs)

        for i in range(0,NUM_NHs):
            if_name_key = "Ethernet" + str(i*4)
            vlan_name_key = "Vlan" + str((i+1)*4)
            ip_pref_key = vlan_name_key + "|10.0.0." + str(i*2) + "/31"
            fvs = {"vlanid": str((i+1)*4)}
            create_entry(config_db, VLAN_TB, vlan_name_key, fvs)
            fvs = {"tagging_mode": "untagged"}
            create_entry(config_db, VLAN_MEMB_TB, vlan_name_key + "|" + if_name_key, fvs)
            create_entry(config_db, VLAN_IF_TB, vlan_name_key, fvs_nul)
            create_entry(config_db, VLAN_IF_TB, ip_pref_key, fvs_nul)
            dvs.runcmd("config interface startup " + if_name_key)
            dvs.servers[i].runcmd("ip link set down dev eth0") == 0
            dvs.servers[i].runcmd("ip link set up dev eth0") == 0
            bank = 0
            if i >= NUM_NHs/2:
                bank = 1
            fvs = {"FG_NHG": fg_nhg_name, "bank": str(bank), "link": if_name_key}
            create_entry(config_db, FG_NHG_MEMBER, "10.0.0." + str(1 + i*2), fvs)
            ip_to_if_map["10.0.0." + str(1 + i*2)] = vlan_name_key

        # Wait for the software to receive the entries
        time.sleep(1)

        ps = swsscommon.ProducerStateTable(app_db.db_connection, ROUTE_TB)
        fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.7,10.0.0.9,10.0.0.11"),
            ("ifname", "Vlan16,Vlan20,Vlan24")])
        ps.set(fg_nhg_prefix, fvs)
        # No ASIC_DB entry we can wait for since ARP is not resolved yet,
        # We just use sleep so that the sw receives this entry
        time.sleep(1)

        asic_nh_count = len(asic_db.get_keys(ASIC_NH_TB))
        dvs.runcmd("arp -s 10.0.0.1 00:00:00:00:00:01")
        dvs.runcmd("arp -s 10.0.0.3 00:00:00:00:00:02")
        dvs.runcmd("arp -s 10.0.0.5 00:00:00:00:00:03")
        dvs.runcmd("arp -s 10.0.0.7 00:00:00:00:00:04")
        dvs.runcmd("arp -s 10.0.0.9 00:00:00:00:00:05")
        dvs.runcmd("arp -s 10.0.0.11 00:00:00:00:00:06")
        asic_db.wait_for_n_keys(ASIC_NH_TB, asic_nh_count + 6)

        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size)
        nhgid = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix, bucket_size)

        nh_oid_map = get_nh_oid_map(asic_db)

        # Now that ARP was resolved, 10.0.0.7 should be added as a valid fg nhg member
        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        
        run_warm_reboot(dvs)

        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size)
        nhgid = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix, bucket_size)

        nh_oid_map = get_nh_oid_map(asic_db)

        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down 1 next hop in bank 1
        nh_memb_exp_count = {"10.0.0.7":30,"10.0.0.11":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down 2 next hop and bring up 1 next hop in bank 1
        nh_memb_exp_count = {"10.0.0.9":60}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring up 1 next hop in bank 1
        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring up some next-hops in bank 0 for the 1st time
        nh_memb_exp_count = {"10.0.0.1":10,"10.0.0.3":10,"10.0.0.5":10,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        run_warm_reboot(dvs)

        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size)
        nhgid = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix, bucket_size)

        nh_oid_map = get_nh_oid_map(asic_db)

        nh_memb_exp_count = {"10.0.0.1":10,"10.0.0.3":10,"10.0.0.5":10,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)
Пример #6
0
    def test_CrmIpv6Route(self, dvs, testlog):

        # Enable IPv6 routing
        dvs.runcmd("sysctl net.ipv6.conf.all.disable_ipv6=0")
        time.sleep(2)

        config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB,
                                           dvs.redis_sock, 0)
        intf_tbl = swsscommon.Table(config_db, "INTERFACE")
        fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
        intf_tbl.set("Ethernet0", fvs)
        intf_tbl.set("Ethernet0|fc00::1/126", fvs)
        dvs.port_admin_set("Ethernet0", "up")

        dvs.servers[0].runcmd("ifconfig eth0 inet6 add fc00::2/126")
        dvs.servers[0].runcmd("ip -6 route add default via fc00::1")

        crm_update(dvs, "polling_interval", "1")

        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_IPV6_ROUTE_ENTRY',
                            '1000')

        # get neighbor and arp entry
        dvs.servers[0].runcmd("ping6 -c 4 fc00::1")

        db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
        ps = swsscommon.ProducerStateTable(db, "ROUTE_TABLE")
        fvs = swsscommon.FieldValuePairs([("nexthop", "fc00::2"),
                                          ("ifname", "Ethernet0")])

        time.sleep(2)

        # get counters
        used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_ipv6_route_used')
        avail_counter = getCrmCounterValue(dvs, 'STATS',
                                           'crm_stats_ipv6_route_available')

        # add route and update available counter
        ps.set("2001::/64", fvs)
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_IPV6_ROUTE_ENTRY',
                            '999')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv6_route_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv6_route_available')

        assert new_used_counter - used_counter == 1
        assert avail_counter - new_avail_counter == 1

        # remove route and update available counter
        ps._del("2001::/64")
        dvs.runcmd(
            "ip -6 neigh del fc00::2 lladdr 11:22:33:44:55:66 dev Ethernet0")
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_IPV6_ROUTE_ENTRY',
                            '1000')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv6_route_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv6_route_available')

        assert new_used_counter == used_counter
        assert new_avail_counter == avail_counter

        marker = dvs.add_log_marker()
        crm_update(dvs, "polling_interval", "2")
        crm_update(dvs, "ipv6_route_high_threshold", "90")
        crm_update(dvs, "ipv6_route_threshold_type", "free")
        time.sleep(2)
        check_syslog(dvs, marker, "IPV6_ROUTE THRESHOLD_EXCEEDED for TH_FREE",
                     1)

        intf_tbl._del("Ethernet0|fc00::1/126")
        time.sleep(2)
Пример #7
0
    def test_CrmNexthopGroupMember(self, dvs, testlog):

        # down, then up to generate port up signal
        dvs.servers[0].runcmd("ip link set down dev eth0") == 0
        dvs.servers[1].runcmd("ip link set down dev eth0") == 0
        dvs.servers[0].runcmd("ip link set up dev eth0") == 0
        dvs.servers[1].runcmd("ip link set up dev eth0") == 0

        config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB,
                                           dvs.redis_sock, 0)
        intf_tbl = swsscommon.Table(config_db, "INTERFACE")
        fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
        intf_tbl.set("Ethernet0", fvs)
        intf_tbl.set("Ethernet4", fvs)
        intf_tbl.set("Ethernet0|10.0.0.0/31", fvs)
        intf_tbl.set("Ethernet4|10.0.0.2/31", fvs)
        dvs.port_admin_set("Ethernet0", "up")
        dvs.port_admin_set("Ethernet4", "up")

        crm_update(dvs, "polling_interval", "1")

        dvs.setReadOnlyAttr(
            'SAI_OBJECT_TYPE_SWITCH',
            'SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY', '1000')

        # add neighbors
        dvs.runcmd(
            "ip neigh replace 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")
        dvs.runcmd(
            "ip neigh replace 10.0.0.3 lladdr 11:22:33:44:55:66 dev Ethernet4")

        db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
        ps = swsscommon.ProducerStateTable(db, "ROUTE_TABLE")
        fvs = swsscommon.FieldValuePairs([("nexthop", "10.0.0.1,10.0.0.3"),
                                          ("ifname", "Ethernet0,Ethernet4")])

        time.sleep(2)

        # get counters
        used_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_nexthop_group_member_used')
        avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_nexthop_group_member_available')

        # add route and update available counter
        ps.set("2.2.2.0/24", fvs)
        dvs.setReadOnlyAttr(
            'SAI_OBJECT_TYPE_SWITCH',
            'SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY', '998')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_nexthop_group_member_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_nexthop_group_member_available')

        assert new_used_counter - used_counter == 2
        assert avail_counter - new_avail_counter == 2

        # remove route and update available counter
        ps._del("2.2.2.0/24")
        dvs.runcmd(
            "ip neigh del 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")
        dvs.runcmd(
            "ip neigh del 10.0.0.3 lladdr 11:22:33:44:55:66 dev Ethernet4")
        dvs.setReadOnlyAttr(
            'SAI_OBJECT_TYPE_SWITCH',
            'SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY', '1000')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_nexthop_group_member_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_nexthop_group_member_available')

        assert new_used_counter == used_counter
        assert new_avail_counter == avail_counter

        marker = dvs.add_log_marker()
        crm_update(dvs, "polling_interval", "2")
        crm_update(dvs, "nexthop_group_member_high_threshold", "90")
        crm_update(dvs, "nexthop_group_member_threshold_type", "free")
        time.sleep(2)
        check_syslog(dvs, marker,
                     "NEXTHOP_GROUP_MEMBER THRESHOLD_EXCEEDED for TH_FREE", 1)

        intf_tbl._del("Ethernet0|10.0.0.0/31")
        intf_tbl._del("Ethernet4|10.0.0.2/31")
        time.sleep(2)
Пример #8
0
    def test_PortAutoNegWarm(self, dvs, testlog):

        db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
        cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        sdb = swsscommon.DBConnector(6, dvs.redis_sock, 0)

        tbl = swsscommon.ProducerStateTable(db, "PORT_TABLE")
        ctbl = swsscommon.Table(cdb, "PORT")
        stbl = swsscommon.Table(sdb, "PORT_TABLE")

        # set autoneg = true and speed = 1000
        fvs = swsscommon.FieldValuePairs([("autoneg", "on"),
                                          ("speed", "1000")])
        ctbl.set("Ethernet0", fvs)

        time.sleep(1)

        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT")
        (status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
        assert status == True

        assert "SAI_PORT_ATTR_AUTO_NEG_MODE" in [fv[0] for fv in fvs]
        assert "SAI_PORT_ATTR_ADVERTISED_SPEED" in [fv[0] for fv in fvs]
        for fv in fvs:
            if fv[0] == "SAI_PORT_ATTR_AUTO_NEG_MODE":
                assert fv[1] == "true"
            elif fv[0] == "SAI_PORT_ATTR_ADVERTISED_SPEED":
                assert fv[1] == "1:1000"

        # set speed = 100
        fvs = swsscommon.FieldValuePairs([("speed", "100")])

        ctbl.set("Ethernet0", fvs)

        time.sleep(1)

        (status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
        assert status == True

        for fv in fvs:
            if fv[0] == "SAI_PORT_ATTR_AUTO_NEG_MODE":
                assert fv[1] == "true"
            elif fv[0] == "SAI_PORT_ATTR_ADVERTISED_SPEED":
                assert fv[1] == "1:100"

        # set admin up
        cfvs = swsscommon.FieldValuePairs([("admin_status", "up")])
        ctbl.set("Ethernet0", cfvs)

        # enable warm restart
        (exitcode, result) = dvs.runcmd("config warm_restart enable swss")
        assert exitcode == 0

        # freeze orchagent for warm restart
        (exitcode, result) = dvs.runcmd("/usr/bin/orchagent_restart_check")
        assert result == "RESTARTCHECK succeeded\n"
        time.sleep(2)

        try:
            # restart orchagent
            # clean port state
            dvs.stop_swss()
            ports = stbl.getKeys()
            for port in ports:
                stbl._del(port)
            dvs.start_swss()
            time.sleep(2)

            # check ASIC DB after warm restart
            (status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
            assert status == True

            assert "SAI_PORT_ATTR_AUTO_NEG_MODE" in [fv[0] for fv in fvs]
            assert "SAI_PORT_ATTR_ADVERTISED_SPEED" in [fv[0] for fv in fvs]
            for fv in fvs:
                if fv[0] == "SAI_PORT_ATTR_AUTO_NEG_MODE":
                    assert fv[1] == "true"
                elif fv[0] == "SAI_PORT_ATTR_ADVERTISED_SPEED":
                    assert fv[1] == "1:100"

        finally:
            # disable warm restart
            dvs.runcmd("config warm_restart disable swss")
            # slow down crm polling
            dvs.runcmd("crm config polling interval 10000")
Пример #9
0
    def test_PortAutoNegCold(self, dvs, testlog):

        db = swsscommon.DBConnector(0, dvs.redis_sock, 0)

        tbl = swsscommon.ProducerStateTable(db, "PORT_TABLE")

        # set autoneg = true and speed = 1000
        fvs = swsscommon.FieldValuePairs([("autoneg", "on"),
                                          ("speed", "1000")])

        tbl.set("Ethernet0", fvs)

        time.sleep(1)

        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT")
        (status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
        assert status == True

        assert "SAI_PORT_ATTR_AUTO_NEG_MODE" in [fv[0] for fv in fvs]
        assert "SAI_PORT_ATTR_ADVERTISED_SPEED" in [fv[0] for fv in fvs]
        for fv in fvs:
            if fv[0] == "SAI_PORT_ATTR_AUTO_NEG_MODE":
                assert fv[1] == "true"
            elif fv[0] == "SAI_PORT_ATTR_ADVERTISED_SPEED":
                assert fv[1] == "1:1000"

        # set speed = 100
        fvs = swsscommon.FieldValuePairs([("speed", "100")])

        tbl.set("Ethernet0", fvs)

        time.sleep(1)

        (status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
        assert status == True

        for fv in fvs:
            if fv[0] == "SAI_PORT_ATTR_AUTO_NEG_MODE":
                assert fv[1] == "true"
            elif fv[0] == "SAI_PORT_ATTR_ADVERTISED_SPEED":
                assert fv[1] == "1:100"

        # change autoneg to false
        fvs = swsscommon.FieldValuePairs([("autoneg", "off")])

        tbl.set("Ethernet0", fvs)

        time.sleep(1)

        (status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
        assert status == True

        assert "SAI_PORT_ATTR_AUTO_NEG_MODE" in [fv[0] for fv in fvs]
        assert "SAI_PORT_ATTR_ADVERTISED_SPEED" in [fv[0] for fv in fvs]
        assert "SAI_PORT_ATTR_SPEED" in [fv[0] for fv in fvs]
        for fv in fvs:
            if fv[0] == "SAI_PORT_ATTR_AUTO_NEG_MODE":
                assert fv[1] == "false"
            elif fv[0] == "SAI_PORT_ATTR_ADVERTISED_SPEED":
                assert fv[1] == "1:100"
            elif fv[0] == "SAI_PORT_ATTR_SPEED":
                assert fv[1] == "100"

        # set speed = 1000
        fvs = swsscommon.FieldValuePairs([("speed", "1000")])

        tbl.set("Ethernet0", fvs)

        time.sleep(1)

        (status, fvs) = atbl.get(dvs.asicdb.portnamemap["Ethernet0"])
        assert status == True

        for fv in fvs:
            if fv[0] == "SAI_PORT_ATTR_AUTO_NEG_MODE":
                assert fv[1] == "false"
            elif fv[0] == "SAI_PORT_ATTR_ADVERTISED_SPEED":
                assert fv[1] == "1:100"
            elif fv[0] == "SAI_PORT_ATTR_SPEED":
                assert fv[1] == "1000"
    def test_Portchannel_oper_down(self, dvs, testlog):

        self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)
        self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        self.pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0)

        # Create 4 PortChannels
        tbl = swsscommon.Table(self.cdb, "PORTCHANNEL")
        fvs = swsscommon.FieldValuePairs([("admin_status", "up"),
                                          ("mtu", "9100"),
                                          ("oper_status", "up")])

        tbl.set("PortChannel001", fvs)
        time.sleep(1)
        tbl.set("PortChannel002", fvs)
        time.sleep(1)
        tbl.set("PortChannel003", fvs)
        time.sleep(1)
        tbl.set("PortChannel004", fvs)
        time.sleep(1)

        tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_MEMBER")
        fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
        tbl.set("PortChannel001|Ethernet0", fvs)
        time.sleep(1)
        tbl.set("PortChannel002|Ethernet4", fvs)
        time.sleep(1)
        tbl.set("PortChannel003|Ethernet8", fvs)
        time.sleep(1)
        tbl.set("PortChannel004|Ethernet12", fvs)
        time.sleep(1)

        tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_INTERFACE")
        fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
        tbl.set("PortChannel001", fvs)
        tbl.set("PortChannel001|40.0.0.0/31", fvs)
        time.sleep(1)
        tbl.set("PortChannel002", fvs)
        tbl.set("PortChannel002|40.0.0.2/31", fvs)
        time.sleep(1)
        tbl.set("PortChannel003", fvs)
        tbl.set("PortChannel003|40.0.0.4/31", fvs)
        time.sleep(1)
        tbl.set("PortChannel004", fvs)
        tbl.set("PortChannel004|40.0.0.6/31", fvs)
        time.sleep(1)

        # check application database
        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 1
        assert intf_entries[0] == "40.0.0.0/31"
        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel002")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 1
        assert intf_entries[0] == "40.0.0.2/31"
        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel003")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 1
        assert intf_entries[0] == "40.0.0.4/31"
        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel004")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 1
        assert intf_entries[0] == "40.0.0.6/31"

        # set oper_status for PortChannels
        ps = swsscommon.ProducerStateTable(self.pdb, "LAG_TABLE")
        fvs = swsscommon.FieldValuePairs([("admin_status", "up"),
                                          ("mtu", "9100"),
                                          ("oper_status", "up")])
        ps.set("PortChannel001", fvs)
        ps.set("PortChannel002", fvs)
        ps.set("PortChannel003", fvs)
        ps.set("PortChannel004", fvs)
        time.sleep(1)

        dvs.runcmd("arp -s 40.0.0.1 00:00:00:00:00:01")
        time.sleep(1)
        dvs.runcmd("arp -s 40.0.0.3 00:00:00:00:00:03")
        time.sleep(1)
        dvs.runcmd("arp -s 40.0.0.5 00:00:00:00:00:05")
        time.sleep(1)
        dvs.runcmd("arp -s 40.0.0.7 00:00:00:00:00:07")
        time.sleep(1)

        ps = swsscommon.ProducerStateTable(self.pdb, "ROUTE_TABLE")
        fvs = swsscommon.FieldValuePairs([
            ("nexthop", "40.0.0.1,40.0.0.3,40.0.0.5,40.0.0.7"),
            ("ifname",
             "PortChannel001,PortChannel002,PortChannel003,PortChannel004")
        ])

        ps.set("2.2.2.0/24", fvs)
        time.sleep(1)

        # check if route has propagated to ASIC DB
        re_tbl = swsscommon.Table(self.adb,
                                  "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")

        found_route = False
        for key in re_tbl.getKeys():
            route = json.loads(key)
            if route["dest"] == "2.2.2.0/24":
                found_route = True
                break

        assert found_route

        # check if route points to next hop group
        nhg_tbl = swsscommon.Table(
            self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP")
        (status, fvs) = re_tbl.get(key)
        for v in fvs:
            if v[0] == "SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID":
                nhg_id = v[1]

        (status, fvs) = nhg_tbl.get(nhg_id)
        assert status

        # check if next hop group consists of 4 members
        nhg_member_tbl = swsscommon.Table(
            self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER")
        keys = nhg_member_tbl.getKeys()
        assert len(keys) == 4

        for key in keys:
            (status, fvs) = nhg_member_tbl.get(key)
            for v in fvs:
                if v[0] == "SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID":
                    assert v[1] == nhg_id

        # bring PortChannel down
        dvs.servers[0].runcmd("ip link set down dev eth0")
        time.sleep(1)
        ps = swsscommon.ProducerStateTable(self.pdb, "LAG_TABLE")
        fvs = swsscommon.FieldValuePairs([("admin_status", "up"),
                                          ("mtu", "9100"),
                                          ("oper_status", "down")])
        ps.set("PortChannel001", fvs)
        time.sleep(1)

        # check if next hop group consists of 3 member
        keys = nhg_member_tbl.getKeys()
        assert len(keys) == 3

        # remove IP address
        tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_INTERFACE")
        tbl._del("PortChannel001|40.0.0.0/31")
        tbl._del("PortChannel002|40.0.0.2/31")
        tbl._del("PortChannel003|40.0.0.4/31")
        tbl._del("PortChannel004|40.0.0.6/31")
        time.sleep(1)

        # check application database
        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 0

        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel002")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 0

        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel003")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 0

        tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel004")
        intf_entries = tbl.getKeys()
        assert len(intf_entries) == 0

        # remove PortChannel members
        tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_MEMBER")
        tbl._del("PortChannel001|Ethernet0")
        tbl._del("PortChannel002|Ethernet4")
        tbl._del("PortChannel003|Ethernet8")
        tbl._del("PortChannel004|Ethernet12")
        time.sleep(1)

        # remove PortChannel
        tbl = swsscommon.Table(self.cdb, "PORTCHANNEL")
        tbl._del("PortChannel001")
        tbl._del("PortChannel002")
        tbl._del("PortChannel003")
        tbl._del("PortChannel004")
        time.sleep(1)

        # Restore eth0 up
        dvs.servers[0].runcmd("ip link set up dev eth0")
        time.sleep(1)
Пример #11
0
    def test_AclTableCreationBeforeLAG(self, dvs):
        # prepare db and tables
        self.clean_up_left_over(dvs)
        db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)
        apldb = swsscommon.DBConnector(0, dvs.redis_sock, 0)

        # create acl table
        tbl = swsscommon.Table(db, "ACL_TABLE")
        bind_ports = ["PortChannel0003"]
        fvs = swsscommon.FieldValuePairs([("policy_desc", "test_negative"),
                                          ("type", "L3"),
                                          ("ports", ",".join(bind_ports))])
        tbl.set("test_LAG_2", fvs)
        time.sleep(1)

        # check acl table in asic db
        test_acl_table_id = self.get_acl_table_id(dvs, adb)

        # check acl table group in asic db
        self.verify_acl_group_num(adb, 0)

        # get acl table group ids and verify the id numbers
        atbl = swsscommon.Table(adb,
                                "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP")
        acl_group_ids = atbl.getKeys()
        assert len(acl_group_ids) == 0

        # check acl table group member
        self.verify_acl_group_member(adb, acl_group_ids, test_acl_table_id)

        # get lad ids
        atbl_lag = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_LAG")
        lag_ids = atbl_lag.getKeys()
        assert len(lag_ids) == 0

        # check port binding
        self.verify_acl_lag_binding(adb, lag_ids)

        # create port channel
        ps = swsscommon.ProducerStateTable(apldb, "LAG_TABLE")
        fvs = swsscommon.FieldValuePairs([("admin", "up"), ("mtu", "1500")])
        ps.set("PortChannel0003", fvs)

        # create port channel member
        ps = swsscommon.ProducerStateTable(apldb, "LAG_MEMBER_TABLE")
        fvs = swsscommon.FieldValuePairs([("status", "enabled")])
        ps.set("PortChannel0003:Ethernet20", fvs)
        time.sleep(1)

        # notify aclorch that port channel configured
        stdb = swsscommon.DBConnector(6, dvs.redis_sock, 0)
        ps = swsscommon.ProducerStateTable(stdb, "LAG_TABLE")
        fvs = swsscommon.FieldValuePairs([("state", "ok")])
        ps.set("PortChannel0003", fvs)
        time.sleep(1)

        # check acl table in asic db
        test_acl_table_id = self.get_acl_table_id(dvs, adb)

        # check acl table group in asic db
        self.verify_acl_group_num(adb, 1)

        # get acl table group ids and verify the id numbers
        atbl = swsscommon.Table(adb,
                                "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP")
        acl_group_ids = atbl.getKeys()
        assert len(acl_group_ids) == 1

        # check acl table group member
        self.verify_acl_group_member(adb, acl_group_ids, test_acl_table_id)

        # get lad ids
        atbl_lag = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_LAG")
        lag_ids = atbl_lag.getKeys()
        assert len(lag_ids) == 1

        # check port binding
        self.verify_acl_lag_binding(adb, lag_ids)

        tbl = swsscommon.Table(db, "ACL_TABLE")
        tbl._del("test_LAG_2")
    def test_Portchannel(self, dvs, testlog):

        # create port channel
        db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
        ps = swsscommon.ProducerStateTable(db, "LAG_TABLE")
        fvs = swsscommon.FieldValuePairs([("admin", "up"), ("mtu", "1500")])

        ps.set("PortChannel0001", fvs)

        # create port channel member
        ps = swsscommon.ProducerStateTable(db, "LAG_MEMBER_TABLE")
        fvs = swsscommon.FieldValuePairs([("status", "enabled")])

        ps.set("PortChannel0001:Ethernet0", fvs)

        time.sleep(1)

        # check asic db
        asicdb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        lagtbl = swsscommon.Table(asicdb, "ASIC_STATE:SAI_OBJECT_TYPE_LAG")
        lags = lagtbl.getKeys()
        assert len(lags) == 1

        lagmtbl = swsscommon.Table(asicdb,
                                   "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER")
        lagms = lagmtbl.getKeys()
        assert len(lagms) == 1

        (status, fvs) = lagmtbl.get(lagms[0])
        fvs = dict(fvs)
        assert status
        assert "SAI_LAG_MEMBER_ATTR_LAG_ID" in fvs
        assert fvs.pop("SAI_LAG_MEMBER_ATTR_LAG_ID") == lags[0]
        assert "SAI_LAG_MEMBER_ATTR_PORT_ID" in fvs
        assert dvs.asicdb.portoidmap[fvs.pop(
            "SAI_LAG_MEMBER_ATTR_PORT_ID")] == "Ethernet0"
        assert "SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE" in fvs
        assert fvs.pop("SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE") == "false"
        assert "SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE" in fvs
        assert fvs.pop("SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE") == "false"
        assert not fvs

        ps = swsscommon.ProducerStateTable(db, "LAG_MEMBER_TABLE")
        fvs = swsscommon.FieldValuePairs([("status", "disabled")])

        ps.set("PortChannel0001:Ethernet0", fvs)

        time.sleep(1)

        lagmtbl = swsscommon.Table(asicdb,
                                   "ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER")
        lagms = lagmtbl.getKeys()
        assert len(lagms) == 1

        (status, fvs) = lagmtbl.get(lagms[0])
        fvs = dict(fvs)
        assert status
        assert "SAI_LAG_MEMBER_ATTR_LAG_ID" in fvs
        assert fvs.pop("SAI_LAG_MEMBER_ATTR_LAG_ID") == lags[0]
        assert "SAI_LAG_MEMBER_ATTR_PORT_ID" in fvs
        assert dvs.asicdb.portoidmap[fvs.pop(
            "SAI_LAG_MEMBER_ATTR_PORT_ID")] == "Ethernet0"
        assert "SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE" in fvs
        assert fvs.pop("SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE") == "true"
        assert "SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE" in fvs
        assert fvs.pop("SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE") == "true"
        assert not fvs

        # remove port channel member
        ps = swsscommon.ProducerStateTable(db, "LAG_MEMBER_TABLE")
        ps._del("PortChannel0001:Ethernet0")

        # remove port channel
        ps = swsscommon.ProducerStateTable(db, "LAG_TABLE")
        ps._del("PortChannel0001")

        time.sleep(1)

        # check asic db
        lags = lagtbl.getKeys()
        assert len(lags) == 0

        lagms = lagmtbl.getKeys()
        assert len(lagms) == 0
Пример #13
0
def test_CrmNexthopGroupMember(dvs, testlog):

    # down, then up to generate port up signal
    dvs.servers[0].runcmd("ip link set down dev eth0") == 0
    dvs.servers[1].runcmd("ip link set down dev eth0") == 0
    dvs.servers[0].runcmd("ip link set up dev eth0") == 0
    dvs.servers[1].runcmd("ip link set up dev eth0") == 0

    dvs.runcmd("ifconfig Ethernet0 10.0.0.0/31 up")
    dvs.runcmd("ifconfig Ethernet4 10.0.0.2/31 up")

    dvs.runcmd("crm config polling interval 1")

    setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                    'SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY',
                    '1000')

    # add neighbors
    dvs.runcmd(
        "ip neigh replace 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")
    dvs.runcmd(
        "ip neigh replace 10.0.0.3 lladdr 11:22:33:44:55:66 dev Ethernet4")

    db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
    ps = swsscommon.ProducerStateTable(db, "ROUTE_TABLE")
    fvs = swsscommon.FieldValuePairs([("nexthop", "10.0.0.1,10.0.0.3"),
                                      ("ifname", "Ethernet0,Ethernet4")])

    time.sleep(2)

    # get counters
    used_counter = getCrmCounterValue(dvs, 'STATS',
                                      'crm_stats_nexthop_group_member_used')
    avail_counter = getCrmCounterValue(
        dvs, 'STATS', 'crm_stats_nexthop_group_member_available')

    # add route and update available counter
    ps.set("2.2.2.0/24", fvs)
    setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                    'SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY',
                    '998')

    time.sleep(2)

    # get counters
    new_used_counter = getCrmCounterValue(
        dvs, 'STATS', 'crm_stats_nexthop_group_member_used')
    new_avail_counter = getCrmCounterValue(
        dvs, 'STATS', 'crm_stats_nexthop_group_member_available')

    assert new_used_counter - used_counter == 2
    assert avail_counter - new_avail_counter == 2

    # remove route and update available counter
    ps._del("2.2.2.0/24")
    dvs.runcmd("ip neigh del 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")
    dvs.runcmd("ip neigh del 10.0.0.3 lladdr 11:22:33:44:55:66 dev Ethernet4")
    setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                    'SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY',
                    '1000')

    time.sleep(2)

    # get counters
    new_used_counter = getCrmCounterValue(
        dvs, 'STATS', 'crm_stats_nexthop_group_member_used')
    new_avail_counter = getCrmCounterValue(
        dvs, 'STATS', 'crm_stats_nexthop_group_member_available')

    assert new_used_counter == used_counter
    assert new_avail_counter == avail_counter
Пример #14
0
def test_CrmIpv6Route(dvs, testlog):

    # Enable IPv6 routing
    dvs.runcmd("sysctl net.ipv6.conf.all.disable_ipv6=0")
    time.sleep(2)

    dvs.runcmd("ifconfig Ethernet0 inet6 add fc00::1/126 up")

    dvs.servers[0].runcmd("ifconfig eth0 inet6 add fc00::2/126")
    dvs.servers[0].runcmd("ip -6 route add default via fc00::1")

    dvs.runcmd("crm config polling interval 1")

    setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                    'SAI_SWITCH_ATTR_AVAILABLE_IPV6_ROUTE_ENTRY', '1000')

    # get neighbor and arp entry
    dvs.servers[0].runcmd("ping6 -c 4 fc00::1")

    db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
    ps = swsscommon.ProducerStateTable(db, "ROUTE_TABLE")
    fvs = swsscommon.FieldValuePairs([("nexthop", "fc00::2"),
                                      ("ifname", "Ethernet0")])

    time.sleep(2)

    # get counters
    used_counter = getCrmCounterValue(dvs, 'STATS',
                                      'crm_stats_ipv6_route_used')
    avail_counter = getCrmCounterValue(dvs, 'STATS',
                                       'crm_stats_ipv6_route_available')

    # add route and update available counter
    ps.set("2001::/64", fvs)
    setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                    'SAI_SWITCH_ATTR_AVAILABLE_IPV6_ROUTE_ENTRY', '999')

    time.sleep(2)

    # get counters
    new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_ipv6_route_used')
    new_avail_counter = getCrmCounterValue(dvs, 'STATS',
                                           'crm_stats_ipv6_route_available')

    assert new_used_counter - used_counter == 1
    assert avail_counter - new_avail_counter == 1

    # remove route and update available counter
    ps._del("2001::/64")
    dvs.runcmd(
        "ip -6 neigh del fc00::2 lladdr 11:22:33:44:55:66 dev Ethernet0")
    setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                    'SAI_SWITCH_ATTR_AVAILABLE_IPV6_ROUTE_ENTRY', '1000')

    time.sleep(2)

    # get counters
    new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_ipv6_route_used')
    new_avail_counter = getCrmCounterValue(dvs, 'STATS',
                                           'crm_stats_ipv6_route_available')

    assert new_used_counter == used_counter
    assert new_avail_counter == avail_counter
def delete_entry_pst(db, table, key):
    tbl = swsscommon.ProducerStateTable(db, table)
    tbl._del(key)
    time.sleep(1)
Пример #16
0
 def create_fdb(self, vlan, mac, interface):
     tbl = swsscommon.ProducerStateTable(self.pdb, "FDB_TABLE")
     fvs = swsscommon.FieldValuePairs([("port", interface),
                                       ("type", "dynamic")])
     tbl.set("Vlan" + vlan + ":" + mac, fvs)
     time.sleep(1)
Пример #17
0
 def __init__(self, database: conftest.DVSDatabase, table_name: str):
     self.table = swsscommon.ProducerStateTable(database.db_connection,
                                                table_name)
Пример #18
0
 def remove_fdb(self, vlan, mac):
     tbl = swsscommon.ProducerStateTable(self.pdb, "FDB_TABLE")
     tbl._del("Vlan" + vlan + ":" + mac)
     time.sleep(1)
Пример #19
0
    def test_CrmFdbEntry(self, dvs, testlog):

        # disable ipv6 on Ethernet8 neighbor as once ipv6 link-local address is
        # configured, server 2 will send packet which can switch to learn another
        # mac and fail the test.
        dvs.servers[2].runcmd("sysctl -w net.ipv6.conf.eth0.disable_ipv6=1")
        crm_update(dvs, "polling_interval", "1")

        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY', '1000')

        time.sleep(2)

        # get counters
        used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_fdb_entry_used')
        avail_counter = getCrmCounterValue(dvs, 'STATS',
                                           'crm_stats_fdb_entry_available')

        app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
        cfg_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock,
                                        0)

        # create a FDB entry
        tbl = swsscommon.ProducerStateTable(app_db, "FDB_TABLE")
        fvs = swsscommon.FieldValuePairs([("port", "Ethernet8"),
                                          ("type", "dynamic")])
        tbl.set("Vlan2:52-54-00-25-06-E9", fvs)

        # create vlan
        tbl = swsscommon.Table(cfg_db, "VLAN")
        fvs = swsscommon.FieldValuePairs([("vlanid", "2")])
        tbl.set("Vlan2", fvs)

        # create vlan member
        tbl = swsscommon.Table(cfg_db, "VLAN_MEMBER")
        fvs = swsscommon.FieldValuePairs([("tagging_mode", "untagged")])
        tbl.set("Vlan2|Ethernet8", fvs)

        # update available counter
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY', '999')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_fdb_entry_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_fdb_entry_available')

        assert new_used_counter - used_counter == 1
        assert avail_counter - new_avail_counter == 1

        # update available counter
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY', '1000')

        time.sleep(2)

        # get counters
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_fdb_entry_available')

        assert new_avail_counter == avail_counter

        marker = dvs.add_log_marker()
        crm_update(dvs, "polling_interval", "2")
        crm_update(dvs, "fdb_entry_high_threshold", "90")
        crm_update(dvs, "fdb_entry_threshold_type", "free")
        time.sleep(2)
        check_syslog(dvs, marker, "FDB_ENTRY THRESHOLD_EXCEEDED for TH_FREE",
                     1)

        # enable ipv6 on server 2
        dvs.servers[2].runcmd("sysctl -w net.ipv6.conf.eth0.disable_ipv6=0")
Пример #20
0
 def create_port_channel_member(self, channel, interface):
     tbl = swsscommon.ProducerStateTable(self.pdb, "LAG_MEMBER_TABLE")
     fvs = swsscommon.FieldValuePairs([("status", "enabled")])
     tbl.set("PortChannel" + channel + ":" + interface, fvs)
     time.sleep(1)
Пример #21
0
    def test_CrmResetThresholdExceedCount(self, dvs, testlog):

        config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB,
                                           dvs.redis_sock, 0)
        intf_tbl = swsscommon.Table(config_db, "INTERFACE")
        fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
        intf_tbl.set("Ethernet0", fvs)
        intf_tbl.set("Ethernet0|10.0.0.0/31", fvs)
        dvs.port_admin_set("Ethernet0", "up")

        crm_update(dvs, "polling_interval", "1")

        # add static neighbor
        dvs.runcmd(
            "ip neigh replace 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")

        db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
        ps = swsscommon.ProducerStateTable(db, "ROUTE_TABLE")
        fvs = swsscommon.FieldValuePairs([("nexthop", "10.0.0.1"),
                                          ("ifname", "Ethernet0")])

        # add route to make sure used count at least 1 and update available counter
        ps.set("2.2.2.0/24", fvs)
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_IPV4_ROUTE_ENTRY',
                            '1000')

        time.sleep(2)

        # get counters
        used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_ipv4_route_used')
        avail_counter = getCrmCounterValue(dvs, 'STATS',
                                           'crm_stats_ipv4_route_available')

        crm_update(dvs, "ipv4_route_low_threshold", "0")

        # for changing to free type will rest crm threshold exceed count, previous type can not be same free type
        crm_update(dvs, "ipv4_route_threshold_type", "percentage")

        # trigger exceed high threshold of free type
        marker = dvs.add_log_marker()
        crm_update(dvs, "ipv4_route_high_threshold", str(avail_counter))
        crm_update(dvs, "ipv4_route_threshold_type", "free")
        time.sleep(20)
        check_syslog(dvs, marker, "IPV4_ROUTE THRESHOLD_EXCEEDED for TH_FREE",
                     1)

        # crm threshold exceed count will be reset when threshold type changed
        marker = dvs.add_log_marker()
        crm_update(dvs, "ipv4_route_high_threshold", str(used_counter))
        crm_update(dvs, "ipv4_route_threshold_type", "used")
        time.sleep(2)
        check_syslog(dvs, marker, "IPV4_ROUTE THRESHOLD_EXCEEDED for TH_USED",
                     1)

        # remove route
        ps._del("2.2.2.0/24")
        dvs.runcmd(
            "ip neigh del 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")

        intf_tbl._del("Ethernet0|10.0.0.0/31")
        time.sleep(2)
Пример #22
0
 def remove_port_channel_member(self, channel, interface):
     tbl = swsscommon.ProducerStateTable(self.pdb, "LAG_MEMBER_TABLE")
     tbl._del("PortChannel" + channel + ":" + interface)
     time.sleep(1)
Пример #23
0
    def test_route_fgnhg(self, dvs, testlog):
        app_db = dvs.get_app_db()
        asic_db = dvs.get_asic_db()
        config_db = dvs.get_config_db()
        state_db = dvs.get_state_db()
        fvs_nul = {"NULL": "NULL"}
        NUM_NHs = 6
        fg_nhg_name = "fgnhg_v4"
        fg_nhg_prefix = "2.2.2.0/24"
        bucket_size = 60
        ip_to_if_map = {}

        fvs = {"bucket_size": str(bucket_size)}
        create_entry(config_db, FG_NHG, fg_nhg_name, fvs)

        fvs = {"FG_NHG": fg_nhg_name}
        create_entry(config_db, FG_NHG_PREFIX, fg_nhg_prefix, fvs)

        for i in range(0,NUM_NHs):
            if_name_key = "Ethernet" + str(i*4)
            vlan_name_key = "Vlan" + str((i+1)*4)
            ip_pref_key = vlan_name_key + "|10.0.0." + str(i*2) + "/31"
            fvs = {"vlanid": str((i+1)*4)}
            create_entry(config_db, VLAN_TB, vlan_name_key, fvs)
            fvs = {"tagging_mode": "untagged"}
            create_entry(config_db, VLAN_MEMB_TB, vlan_name_key + "|" + if_name_key, fvs)
            create_entry(config_db, VLAN_IF_TB, vlan_name_key, fvs_nul)
            create_entry(config_db, VLAN_IF_TB, ip_pref_key, fvs_nul)
            dvs.runcmd("config interface startup " + if_name_key)
            dvs.servers[i].runcmd("ip link set down dev eth0") == 0
            dvs.servers[i].runcmd("ip link set up dev eth0") == 0
            bank = 0
            if i >= NUM_NHs/2:
                bank = 1
            fvs = {"FG_NHG": fg_nhg_name, "bank": str(bank), "link": if_name_key}
            create_entry(config_db, FG_NHG_MEMBER, "10.0.0." + str(1 + i*2), fvs)
            ip_to_if_map["10.0.0." + str(1 + i*2)] = vlan_name_key

        # Wait for the software to receive the entries
        time.sleep(1)

        ps = swsscommon.ProducerStateTable(app_db.db_connection, ROUTE_TB)
        fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.7,10.0.0.9,10.0.0.11"),
            ("ifname", "Vlan16,Vlan20,Vlan24")])
        ps.set(fg_nhg_prefix, fvs)
        # No ASIC_DB entry we can wait for since ARP is not resolved yet,
        # We just use sleep so that the sw receives this entry
        time.sleep(1)

        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)
        rtbl = swsscommon.Table(adb, ASIC_ROUTE_TB)
        keys = rtbl.getKeys()
        found_route = False
        for k in keys:
            rt_key = json.loads(k)

            if rt_key['dest'] == fg_nhg_prefix:
                found_route = True
                break

        # Since we didn't populate ARP yet, the route shouldn't be programmed
        assert (found_route == False)

        asic_nh_count = len(asic_db.get_keys(ASIC_NH_TB))
        dvs.runcmd("arp -s 10.0.0.1 00:00:00:00:00:01")
        dvs.runcmd("arp -s 10.0.0.3 00:00:00:00:00:02")
        dvs.runcmd("arp -s 10.0.0.5 00:00:00:00:00:03")
        dvs.runcmd("arp -s 10.0.0.9 00:00:00:00:00:05")
        dvs.runcmd("arp -s 10.0.0.11 00:00:00:00:00:06")
        asic_db.wait_for_n_keys(ASIC_NH_TB, asic_nh_count + 5)

        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size)
        nhgid = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix, bucket_size)

        nh_oid_map = get_nh_oid_map(asic_db)

        ### Test scenarios with bank 0 having 0 members up and only bank 1 having members
        # ARP is not resolved for 10.0.0.7, so fg nhg should be created without 10.0.0.7
        nh_memb_exp_count = {"10.0.0.9":30,"10.0.0.11":30}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Resolve ARP for 10.0.0.7
        asic_nh_count = len(asic_db.get_keys(ASIC_NH_TB))
        dvs.runcmd("arp -s 10.0.0.7 00:00:00:00:00:04")
        asic_db.wait_for_n_keys(ASIC_NH_TB, asic_nh_count + 1)
        nh_oid_map = get_nh_oid_map(asic_db)

        # Now that ARP was resolved, 10.0.0.7 should be added as a valid fg nhg member
        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down 1 next hop in bank 1
        nh_memb_exp_count = {"10.0.0.7":30,"10.0.0.11":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down 2 next hop and bring up 1 next hop in bank 1
        nh_memb_exp_count = {"10.0.0.9":60}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring up 1 next hop in bank 1
        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring up some next-hops in bank 0 for the 1st time
        nh_memb_exp_count = {"10.0.0.1":10,"10.0.0.3":10,"10.0.0.5":10,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down 1 next-hop from bank 0, and 2 next-hops from bank 1
        nh_memb_exp_count = {"10.0.0.1":15,"10.0.0.5":15,"10.0.0.11":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down 1 member and bring up 1 member in bank 0 at the same time
        nh_memb_exp_count = {"10.0.0.1":15,"10.0.0.3":15,"10.0.0.11":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down 2 members and bring up 1 member in bank 0 at the same time
        nh_memb_exp_count = {"10.0.0.5":30,"10.0.0.11":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring up 2 members and bring down 1 member in bank 0 at the same time
        nh_memb_exp_count = {"10.0.0.1":15,"10.0.0.3":15,"10.0.0.11":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bringup arbitrary # of next-hops from both banks at the same time
        nh_memb_exp_count = {"10.0.0.1":10,"10.0.0.3":10,"10.0.0.5":10,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring all next-hops in bank 1 down
        nh_memb_exp_count = {"10.0.0.1":20,"10.0.0.3":20,"10.0.0.5":20}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Make next-hop changes to bank 0 members, given bank 1 is still down
        nh_memb_exp_count = {"10.0.0.1":30,"10.0.0.5":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bringup 1 member in bank 1 again
        nh_memb_exp_count = {"10.0.0.1":15,"10.0.0.5":15,"10.0.0.11":30}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Test 2nd,3rd memb up in bank
        nh_memb_exp_count = {"10.0.0.1":15,"10.0.0.5":15,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # bring all links down one by one
        shutdown_link(dvs, app_db, 0)
        shutdown_link(dvs, app_db, 1)
        nh_memb_exp_count = {"10.0.0.5":30,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        shutdown_link(dvs, app_db, 2)
        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        shutdown_link(dvs, app_db, 3)
        nh_memb_exp_count = {"10.0.0.9":30,"10.0.0.11":30}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        shutdown_link(dvs, app_db, 4)
        nh_memb_exp_count = {"10.0.0.11":60}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Bring down last link, there shouldn't be a crash or other bad orchagent state because of this
        shutdown_link(dvs, app_db, 5)
        # Nothing to check for in this case, sleep 1s for the shutdown to reach sw
        time.sleep(1)

        # bring all links up one by one
        startup_link(dvs, app_db, 3)
        startup_link(dvs, app_db, 4)
        nh_memb_exp_count = {"10.0.0.7":30,"10.0.0.9":30}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        startup_link(dvs, app_db, 5)
        # Perform a route table update, Update the route to contain 10.0.0.3 as well, since Ethernet4 associated with it
        # is link down, it should make no difference
        fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.1,10.0.0.3,10.0.0.5,10.0.0.7,10.0.0.9,10.0.0.11"),
            ("ifname","Vlan4,Vlan8,Vlan12,Vlan16,Vlan20,Vlan24")])
        ps.set(fg_nhg_prefix, fvs)

        # 10.0.0.11 associated with newly brought up link 5 should be updated in FG ecmp
        # 10.0.0.3 addition per above route table change should have no effect
        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        startup_link(dvs, app_db, 2)
        nh_memb_exp_count = {"10.0.0.5":30,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        startup_link(dvs, app_db, 0)
        nh_memb_exp_count = {"10.0.0.1":15,"10.0.0.5":15,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # remove fgnhg member
        remove_entry(config_db, "FG_NHG_MEMBER", "10.0.0.1")
        nh_memb_exp_count = {"10.0.0.5":30,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # add fgnhg member
        fvs = {"FG_NHG": fg_nhg_name, "bank": "0"}
        create_entry(config_db, FG_NHG_MEMBER, "10.0.0.1", fvs)
        nh_memb_exp_count = {"10.0.0.1":15,"10.0.0.5":15,"10.0.0.7":10,"10.0.0.9":10,"10.0.0.11":10}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Remove route
        asic_rt_key = get_asic_route_key(asic_db, fg_nhg_prefix)
        ps._del(fg_nhg_prefix)

        # validate routes and nhg member in asic db, route entry in state db are removed
        asic_db.wait_for_deleted_entry(ASIC_ROUTE_TB, asic_rt_key)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, 0)
        state_db.wait_for_n_keys("FG_ROUTE_TABLE", 0)

        remove_entry(config_db, "FG_NHG_PREFIX", fg_nhg_prefix)
        # Nothing we can wait for in terms of db entries, we sleep here
        # to give the sw enough time to delete the entry
        time.sleep(1)

        # Add an ECMP route, since we deleted the FG_NHG_PREFIX it should see
        # standard(non-Fine grained) ECMP behavior
        fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.7,10.0.0.9,10.0.0.11"),
            ("ifname", "Vlan16,Vlan20,Vlan24")])
        ps.set(fg_nhg_prefix, fvs)
        validate_asic_nhg_regular_ecmp(asic_db, fg_nhg_prefix)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, 3)

        # add fgnhg prefix: The regular route should transition to fine grained ECMP
        fvs = {"FG_NHG": fg_nhg_name}
        create_entry(config_db, FG_NHG_PREFIX, fg_nhg_prefix, fvs)

        # Validate the transistion to Fine Grained ECMP
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size)
        nhgid = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix, bucket_size)

        nh_oid_map = {}
        nh_oid_map = get_nh_oid_map(asic_db)

        nh_memb_exp_count = {"10.0.0.7":20,"10.0.0.9":20,"10.0.0.11":20}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        fgnhg_clean_up(config_db, asic_db, app_db, state_db, fg_nhg_name, fg_nhg_prefix, 3)
        
        # clean up nh entries
        for i in range(0,NUM_NHs):
            if_name_key = "Ethernet" + str(i*4)
            vlan_name_key = "Vlan" + str((i+1)*4)
            ip_pref_key = vlan_name_key + "|10.0.0." + str(i*2) + "/31"
            remove_entry(config_db, VLAN_IF_TB, ip_pref_key)
            remove_entry(config_db, VLAN_IF_TB, vlan_name_key)
            remove_entry(config_db, VLAN_MEMB_TB, vlan_name_key + "|" + if_name_key)
            remove_entry(config_db, VLAN_TB, vlan_name_key)
            dvs.runcmd("config interface shutdown " + if_name_key)
            dvs.servers[i].runcmd("ip link set down dev eth0") == 0
            remove_entry(config_db, "FG_NHG_MEMBER", "10.0.0." + str(1 + i*2))

        ### Create new set of entries with a greater number of FG members and
        ### bigger bucket size such that the # of nhs are not divisible by
        ### bucket size. Different physical interface type for dynamicitiy.
        fg_nhg_name = "new_fgnhg_v4"
        fg_nhg_prefix = "3.3.3.0/24"
        # Test with non-divisible bucket size
        bucket_size = 128
        NUM_NHs = 10

        ip_to_if_map = {}
        nh_oid_map = {}

        # Initialize base config
        fvs = {"bucket_size": str(bucket_size)}
        create_entry(config_db, FG_NHG, fg_nhg_name, fvs)

        fvs = {"FG_NHG": fg_nhg_name}
        create_entry(config_db, FG_NHG_PREFIX, fg_nhg_prefix, fvs)

        asic_nh_count = len(asic_db.get_keys(ASIC_NH_TB))
        for i in range(0,NUM_NHs):
            if_name_key = "Ethernet" + str(i*4)
            ip_pref_key = "Ethernet" + str(i*4) + "|10.0.0." + str(i*2) + "/31"
            create_entry(config_db, IF_TB, if_name_key, fvs_nul)
            create_entry(config_db, IF_TB, ip_pref_key, fvs_nul)
            dvs.runcmd("config interface startup " + if_name_key)
            shutdown_link(dvs, app_db, i)
            startup_link(dvs, app_db, i)
            bank = 1
            if i >= NUM_NHs/2:
                bank = 0
            fvs = {"FG_NHG": fg_nhg_name, "bank": str(bank)}
            create_entry(config_db, FG_NHG_MEMBER, "10.0.0." + str(1 + i*2), fvs)
            ip_to_if_map["10.0.0." + str(1 + i*2)] = if_name_key
            dvs.runcmd("arp -s 10.0.0." + str(1 + i*2) + " 00:00:00:00:00:" + str(1 + i*2))

        asic_db.wait_for_n_keys(ASIC_NH_TB, asic_nh_count + NUM_NHs)

        # Program the route
        fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.1,10.0.0.11"),
            ("ifname", "Ethernet0,Ethernet20")])
        ps.set(fg_nhg_prefix, fvs)

        # Validate that the correct ASIC DB elements were setup per Fine Grained ECMP
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size)
        nhgid = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix, bucket_size)

        nh_oid_map = get_nh_oid_map(asic_db)

        # Test addition of route with 0 members in bank
        nh_memb_exp_count = {"10.0.0.1":64,"10.0.0.11":64}
        validate_fine_grained_asic_n_state_db_entries(asic_db, state_db, ip_to_if_map,
                                nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Add 2 nhs to both bank 0 and bank 1
        nh_memb_exp_count = {"10.0.0.1":22,"10.0.0.3":21,"10.0.0.5":21,"10.0.0.11":22,
                "10.0.0.13":21,"10.0.0.15":21}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Add 2 more nhs to both bank 0 and bank 1
        nh_memb_exp_count = {"10.0.0.1":13,"10.0.0.3":13,"10.0.0.5":13,"10.0.0.7":12,
                "10.0.0.9":13,"10.0.0.11":13,"10.0.0.13":13,"10.0.0.15":13,"10.0.0.17":12,"10.0.0.19":13}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Remove 1 nh from bank 0 and remove 2 nhs from bank 1
        nh_memb_exp_count = {"10.0.0.3":16,"10.0.0.5":16,"10.0.0.7":16,"10.0.0.9":16,
                "10.0.0.11":22,"10.0.0.13":21,"10.0.0.19":21}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Remove 1 nh from bank 0 and add 1 nh to bank 1
        nh_memb_exp_count = {"10.0.0.3":22,"10.0.0.7":21,"10.0.0.9":21,"10.0.0.13":16,
                "10.0.0.15":16,"10.0.0.17":16,"10.0.0.19":16}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Remove 2 nh from bank 0 and remove 3 nh from bank 1
        nh_memb_exp_count = {"10.0.0.7":64,"10.0.0.11":64}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Add 2 nhs to bank 0 and remove all nh from bank 1
        nh_memb_exp_count = {"10.0.0.5":42,"10.0.0.7":44,"10.0.0.9":42}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)

        # Add 2 nhs to bank 0 and add 1 nh to bank 1
        nh_memb_exp_count = {"10.0.0.1":12,"10.0.0.3":13,"10.0.0.5":13,"10.0.0.7":13,
                "10.0.0.9":13,"10.0.0.11":64}
        program_route_and_validate_fine_grained_ecmp(app_db.db_connection, asic_db, state_db, ip_to_if_map,
                            fg_nhg_prefix, nh_memb_exp_count, nh_oid_map, nhgid, bucket_size)
        
        fgnhg_clean_up(config_db, asic_db, app_db, state_db, fg_nhg_name, fg_nhg_prefix, 6)
        # clean up nh entries
        for i in range(0,NUM_NHs):
            if_name_key = "Ethernet" + str(i*4)
            ip_pref_key = "Ethernet" + str(i*4) + "|10.0.0." + str(i*2) + "/31"
            remove_entry(config_db, IF_TB, ip_pref_key)
            remove_entry(config_db, IF_TB, vlan_name_key)
            dvs.runcmd("config interface shutdown " + if_name_key)
            dvs.servers[i].runcmd("ip link set down dev eth0") == 0
            remove_entry(config_db, "FG_NHG_MEMBER", "10.0.0." + str(1 + i*2))
Пример #24
0
    def test_add_remove_trap(self, dvs):
        """Test steps:
               1. Enable trap_flow_counter
               2. Remove a COPP trap
               3. Verify counter is automatically unbind
               4. Add the COPP trap back
               5. Verify counter is added back

        Args:
            dvs (object): virtual switch object
        """
        self.setup_dbs(dvs)
        meta_data = counter_group_meta['trap_flow_counter']
        self.set_flex_counter_group_status(meta_data['key'],
                                           meta_data['name_map'])

        removed_trap = None
        changed_group = None
        trap_ids = None
        copp_groups = self.app_db.db_connection.keys('COPP_TABLE:*')
        for copp_group in copp_groups:
            trap_ids = self.app_db.db_connection.hget(copp_group, 'trap_ids')
            if trap_ids and ',' in trap_ids:
                trap_ids = [x.strip() for x in trap_ids.split(',')]
                removed_trap = trap_ids.pop()
                changed_group = copp_group.split(':')[1]
                break

        if not removed_trap:
            pytest.skip(
                'There is not copp group with more than 1 traps, skip rest of the test'
            )

        oid = None
        for _ in range(NUMBER_OF_RETRIES):
            counters_keys = self.counters_db.db_connection.hgetall(
                meta_data['name_map'])
            if removed_trap in counters_keys:
                oid = counters_keys[removed_trap]
                break
            else:
                time.sleep(1)

        assert oid, 'trap counter is not created for {}'.format(removed_trap)
        self.wait_for_id_list(meta_data['group_name'], removed_trap, oid)

        app_copp_table = swsscommon.ProducerStateTable(
            self.app_db.db_connection, 'COPP_TABLE')
        app_copp_table.set(changed_group, [('trap_ids', ','.join(trap_ids))])
        self.wait_for_id_list_remove(meta_data['group_name'], removed_trap,
                                     oid)
        counters_keys = self.counters_db.db_connection.hgetall(
            meta_data['name_map'])
        assert removed_trap not in counters_keys

        trap_ids.append(removed_trap)
        app_copp_table.set(changed_group, [('trap_ids', ','.join(trap_ids))])

        oid = None
        for _ in range(NUMBER_OF_RETRIES):
            counters_keys = self.counters_db.db_connection.hgetall(
                meta_data['name_map'])
            if removed_trap in counters_keys:
                oid = counters_keys[removed_trap]
                break
            else:
                time.sleep(1)

        assert oid, 'Add trap {}, but trap counter is not created'.format(
            removed_trap)
        self.wait_for_id_list(meta_data['group_name'], removed_trap, oid)
        self.set_flex_counter_group_status(meta_data['key'],
                                           meta_data['name_map'], 'disable')
Пример #25
0
    def create_and_test_tunnel(self, db, asicdb, tunnel_name, **kwargs):
        """ Create tunnel and verify all needed enties in ASIC DB exists """

        is_symmetric_tunnel = "src_ip" in kwargs

        decap_dscp_to_tc_map_oid = None
        decap_tc_to_pg_map_oid = None
        skip_tunnel_creation = False

        if "decap_dscp_to_tc_map_oid" in kwargs:
            decap_dscp_to_tc_map_oid = kwargs.pop("decap_dscp_to_tc_map_oid")

        if "decap_tc_to_pg_map_oid" in kwargs:
            decap_tc_to_pg_map_oid = kwargs.pop("decap_tc_to_pg_map_oid")

        if "skip_tunnel_creation" in kwargs:
            skip_tunnel_creation = kwargs.pop("skip_tunnel_creation")

        if not skip_tunnel_creation:
            fvs = create_fvs(**kwargs)
            # create tunnel entry in DB
            ps = swsscommon.ProducerStateTable(
                db, self.APP_TUNNEL_DECAP_TABLE_NAME)
            ps.set(tunnel_name, fvs)

        # wait till config will be applied
        time.sleep(1)

        # check asic db table
        tunnel_table = swsscommon.Table(asicdb, self.ASIC_TUNNEL_TABLE)

        tunnels = tunnel_table.getKeys()
        assert len(tunnels) == 1

        tunnel_sai_obj = tunnels[0]

        status, fvs = tunnel_table.get(tunnel_sai_obj)

        assert status == True
        # 6 parameters to check in case of decap tunnel
        # + 1 (SAI_TUNNEL_ATTR_ENCAP_SRC_IP) in case of symmetric tunnel
        expected_len = 7 if is_symmetric_tunnel else 6

        expected_ecn_mode = self.ecn_modes_map[kwargs["ecn_mode"]]
        expected_dscp_mode = self.dscp_modes_map[kwargs["dscp_mode"]]
        expected_ttl_mode = self.ttl_modes_map[kwargs["ttl_mode"]]

        if decap_dscp_to_tc_map_oid:
            expected_len += 1
        if decap_tc_to_pg_map_oid:
            expected_len += 1

        assert len(fvs) == expected_len

        for field, value in fvs:
            if field == "SAI_TUNNEL_ATTR_TYPE":
                assert value == "SAI_TUNNEL_TYPE_IPINIP"
            elif field == "SAI_TUNNEL_ATTR_ENCAP_SRC_IP":
                assert value == kwargs["src_ip"]
            elif field == "SAI_TUNNEL_ATTR_DECAP_ECN_MODE":
                assert value == expected_ecn_mode
            elif field == "SAI_TUNNEL_ATTR_DECAP_TTL_MODE":
                assert value == expected_ttl_mode
            elif field == "SAI_TUNNEL_ATTR_DECAP_DSCP_MODE":
                assert value == expected_dscp_mode
            elif field == "SAI_TUNNEL_ATTR_OVERLAY_INTERFACE":
                assert self.check_interface_exists_in_asicdb(asicdb, value)
            elif field == "SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE":
                assert self.check_interface_exists_in_asicdb(asicdb, value)
            elif field == "SAI_TUNNEL_ATTR_DECAP_QOS_DSCP_TO_TC_MAP":
                assert value == decap_dscp_to_tc_map_oid
            elif field == "SAI_TUNNEL_ATTR_DECAP_QOS_TC_TO_PRIORITY_GROUP_MAP":
                assert value == decap_tc_to_pg_map_oid
            else:
                assert False, "Field %s is not tested" % field
        src_ip = kwargs["src_ip"] if "src_ip" in kwargs else None
        self.check_tunnel_termination_entry_exists_in_asicdb(
            asicdb, tunnel_sai_obj, kwargs["dst_ip"].split(","), src_ip)
Пример #26
0
 def create_entry_pst(self, db, table, key, pairs):
     tbl = swsscommon.ProducerStateTable(db, table)
     self.create_entry(tbl, key, pairs)
Пример #27
0
 def remove_neighbor(self, interface, ip):
     tbl = swsscommon.ProducerStateTable(self.pdb, "NEIGH_TABLE")
     tbl._del(interface + ":" + ip)
     time.sleep(1)
Пример #28
0
 def remove_entry_pst(self, db, table, key):
     tbl = swsscommon.ProducerStateTable(db, table)
     self.remove_entry(tbl, key)
Пример #29
0
    def test_CrmIpv4Route(self, dvs, testlog):

        config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB,
                                           dvs.redis_sock, 0)
        intf_tbl = swsscommon.Table(config_db, "INTERFACE")
        fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
        intf_tbl.set("Ethernet0", fvs)
        intf_tbl.set("Ethernet0|10.0.0.0/31", fvs)
        dvs.runcmd("ifconfig Ethernet0 up")

        dvs.runcmd("crm config polling interval 1")

        setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                        'SAI_SWITCH_ATTR_AVAILABLE_IPV4_ROUTE_ENTRY', '1000')

        # add static neighbor
        dvs.runcmd(
            "ip neigh replace 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")

        db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
        ps = swsscommon.ProducerStateTable(db, "ROUTE_TABLE")
        fvs = swsscommon.FieldValuePairs([("nexthop", "10.0.0.1"),
                                          ("ifname", "Ethernet0")])

        time.sleep(2)

        # get counters
        used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_ipv4_route_used')
        avail_counter = getCrmCounterValue(dvs, 'STATS',
                                           'crm_stats_ipv4_route_available')

        # add route and update available counter
        ps.set("2.2.2.0/24", fvs)
        setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                        'SAI_SWITCH_ATTR_AVAILABLE_IPV4_ROUTE_ENTRY', '999')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv4_route_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv4_route_available')

        assert new_used_counter - used_counter == 1
        assert avail_counter - new_avail_counter == 1

        # remove route and update available counter
        ps._del("2.2.2.0/24")
        dvs.runcmd(
            "ip neigh del 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")
        setReadOnlyAttr(dvs, 'SAI_OBJECT_TYPE_SWITCH',
                        'SAI_SWITCH_ATTR_AVAILABLE_IPV4_ROUTE_ENTRY', '1000')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv4_route_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv4_route_available')

        assert new_used_counter == used_counter
        assert new_avail_counter == avail_counter

        marker = dvs.add_log_marker()
        dvs.runcmd("crm config polling interval 2")
        dvs.runcmd("crm config thresholds ipv4 route high 90")
        dvs.runcmd("crm config thresholds ipv4 route type free")
        time.sleep(2)
        check_syslog(dvs, marker, "IPV4_ROUTE THRESHOLD_EXCEEDED for TH_FREE",
                     1)

        intf_tbl._del("Ethernet0|10.0.0.0/31")
        time.sleep(2)
Пример #30
0
    def test_route_nhg(self, dvs, testlog):
        config_db = dvs.get_config_db()
        fvs = {"NULL": "NULL"}
        config_db.create_entry("INTERFACE", "Ethernet0", fvs)
        config_db.create_entry("INTERFACE", "Ethernet4", fvs)
        config_db.create_entry("INTERFACE", "Ethernet8", fvs)
        config_db.create_entry("INTERFACE", "Ethernet0|10.0.0.0/31", fvs)
        config_db.create_entry("INTERFACE", "Ethernet4|10.0.0.2/31", fvs)
        config_db.create_entry("INTERFACE", "Ethernet8|10.0.0.4/31", fvs)
        dvs.runcmd("config interface startup Ethernet0")
        dvs.runcmd("config interface startup Ethernet4")
        dvs.runcmd("config interface startup Ethernet8")

        dvs.runcmd("arp -s 10.0.0.1 00:00:00:00:00:01")
        dvs.runcmd("arp -s 10.0.0.3 00:00:00:00:00:02")
        dvs.runcmd("arp -s 10.0.0.5 00:00:00:00:00:03")

        assert dvs.servers[0].runcmd("ip link set down dev eth0") == 0
        assert dvs.servers[1].runcmd("ip link set down dev eth0") == 0
        assert dvs.servers[2].runcmd("ip link set down dev eth0") == 0

        assert dvs.servers[0].runcmd("ip link set up dev eth0") == 0
        assert dvs.servers[1].runcmd("ip link set up dev eth0") == 0
        assert dvs.servers[2].runcmd("ip link set up dev eth0") == 0

        app_db = dvs.get_app_db()
        ps = swsscommon.ProducerStateTable(app_db.db_connection, "ROUTE_TABLE")

        asic_db = dvs.get_asic_db()
        asic_routes_count = len(
            asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY"))

        fvs = swsscommon.FieldValuePairs([
            ("nexthop", "10.0.0.1,10.0.0.3,10.0.0.5"),
            ("ifname", "Ethernet0,Ethernet4,Ethernet8")
        ])
        ps.set("2.2.2.0/24", fvs)

        # check if route was propagated to ASIC DB

        asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY",
                                asic_routes_count + 1)
        keys = asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")

        found_route = False
        for k in keys:
            rt_key = json.loads(k)

            if rt_key['dest'] == "2.2.2.0/24":
                found_route = True
                break

        assert found_route

        # assert the route points to next hop group
        fvs = asic_db.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY", k)

        nhgid = fvs["SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID"]

        fvs = asic_db.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP",
                                nhgid)

        assert bool(fvs)

        keys = asic_db.get_keys(
            "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER")

        assert len(keys) == 3

        for k in keys:
            fvs = asic_db.get_entry(
                "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER", k)

            assert fvs[
                "SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"] == nhgid

        # bring links down one-by-one
        for i in [0, 1, 2]:
            dvs.servers[i].runcmd("ip link set down dev eth0") == 0

            time.sleep(1)

            fvs = app_db.get_entry("PORT_TABLE", "Ethernet%d" % (i * 4))

            assert bool(fvs)
            assert fvs["oper_status"] == "down"

            keys = asic_db.get_keys(
                "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER")

            assert len(keys) == 2 - i

        # bring links up one-by-one
        for i in [0, 1, 2]:
            dvs.servers[i].runcmd("ip link set up dev eth0") == 0

            time.sleep(1)

            fvs = app_db.get_entry("PORT_TABLE", "Ethernet%d" % (i * 4))

            assert bool(fvs)
            assert fvs["oper_status"] == "up"

            keys = asic_db.get_keys(
                "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER")

            assert len(keys) == i + 1

            for k in keys:
                fvs = asic_db.get_entry(
                    "ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER", k)
                assert fvs[
                    "SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"] == nhgid

        # Remove route 2.2.2.0/24
        ps._del("2.2.2.0/24")

        # Wait for route 2.2.2.0/24 to be removed
        asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY",
                                asic_routes_count)