Esempio n. 1
0
    def test_fgnhg_more_nhs_nondiv_bucket_size(self, dvs, testlog):
        '''
        Test Fine Grained ECMP with a greater number of FG members and
        bigger bucket size, such that the no. of nhs are not divisible by
        bucket size. Use a different physical interface type for dynamicitiy.
        '''
        app_db = dvs.get_app_db()
        asic_db = dvs.get_asic_db()
        config_db = dvs.get_config_db()
        state_db = dvs.get_state_db()

        fg_nhg_name = "fgnhg_v4"
        fg_nhg_prefix = "3.3.3.0/24"
        # Test with non-divisible bucket size
        bucket_size = 128
        NUM_NHs = 10

        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))
        ip_to_if_map = create_interface_n_fg_ecmp_config(
            dvs, 0, NUM_NHs, fg_nhg_name)
        asic_db.wait_for_n_keys(ASIC_NH_TB, asic_nh_count + NUM_NHs)

        # Program the route
        ps = swsscommon.ProducerStateTable(app_db.db_connection, ROUTE_TB)
        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)

        # The route had been created 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, fg_nhg_prefix, 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)

        # Remove route
        # remove prefix entry
        asic_rt_key = get_asic_route_key(asic_db, fg_nhg_prefix)
        ps._del(fg_nhg_prefix)
        asic_db.wait_for_deleted_entry(ASIC_ROUTE_TB, asic_rt_key)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, 0)
        asic_db.wait_for_n_keys(ASIC_NHG, 0)

        # cleanup all config
        remove_interface_n_fg_ecmp_config(dvs, 0, NUM_NHs, fg_nhg_name)
        remove_entry(config_db, FG_NHG_PREFIX, fg_nhg_prefix)
Esempio n. 2
0
def create_entry(tbl, key, pairs):
    fvs = swsscommon.FieldValuePairs(pairs)
    tbl.set(key, fvs)

    # FIXME: better to wait until DB create them
    time.sleep(1)
 def create_acl_table(self, dvs, table_name, ports):
     tbl = swsscommon.Table(self.cdb, "ACL_TABLE")
     fvs = swsscommon.FieldValuePairs([("POLICY_DESC", "LAG_ACL_TEST"),
                                       ("TYPE", "L3"), ("PORTS", ports)])
     tbl.set(table_name, fvs)
     time.sleep(1)
Esempio n. 4
0
    def test_V6AclRuleL4DstPortRange(self, dvs, testlog):
        """
        hmset ACL_RULE|test-aclv6|test_rule10 priority 1010 PACKET_ACTION DROP L4_DST_PORT_RANGE 101-200
        """

        self.setup_db(dvs)
        db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        # create acl rule
        tbl = swsscommon.Table(db, "ACL_RULE")
        fvs = swsscommon.FieldValuePairs([("priority", "1010"),
                                          ("PACKET_ACTION", "DROP"),
                                          ("L4_DST_PORT_RANGE", "101-200")])
        tbl.set("test-aclv6|test_rule10", fvs)

        time.sleep(1)

        test_acl_table_id = self.get_acl_table_id(dvs)

        # check acl table in asic db
        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
        keys = atbl.getKeys()

        acl_entry = [
            k for k in keys if k not in dvs.asicdb.default_acl_entries
        ]
        assert len(acl_entry) == 1

        (status, fvs) = atbl.get(acl_entry[0])
        assert status == True
        assert len(fvs) == 6
        for fv in fvs:
            if fv[0] == "SAI_ACL_ENTRY_ATTR_TABLE_ID":
                assert fv[1] == test_acl_table_id
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_ADMIN_STATE":
                assert fv[1] == "true"
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_PRIORITY":
                assert fv[1] == "1010"
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_COUNTER":
                assert True
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_FIELD_ACL_RANGE_TYPE":
                aclrange = fv[1]
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION":
                assert fv[1] == "SAI_PACKET_ACTION_DROP"
            else:
                assert False

        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_RANGE")
        aclrange_obj = aclrange.split(":", 1)[1]

        (status, fvs) = atbl.get(aclrange_obj)
        assert status == True
        assert len(fvs) == 2
        for fv in fvs:
            if fv[0] == "SAI_ACL_RANGE_ATTR_TYPE":
                assert fv[1] == "SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE"
            elif fv[0] == "SAI_ACL_RANGE_ATTR_LIMIT":
                assert fv[1] == "101,200"
            else:
                assert False

        # remove acl rule
        tbl._del("test-aclv6|test_rule10")

        time.sleep(1)

        (status, fvs) = atbl.get(acl_entry[0])
        assert status == False
Esempio n. 5
0
 def create_vlan_member_tagged(self, vlan, interface):
     tbl = swsscommon.Table(self.cdb, "VLAN_MEMBER")
     fvs = swsscommon.FieldValuePairs([("tagging_mode", "tagged")])
     tbl.set("Vlan" + vlan + "|" + interface, fvs)
     time.sleep(1)
Esempio n. 6
0
    def test_InsertAclRuleBetweenPriorities(self, dvs, testlog):
        self.setup_db(dvs)
        db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        bind_ports = ["Ethernet0", "Ethernet4"]
        # create ACL_TABLE in config db
        tbl = swsscommon.Table(db, "ACL_TABLE")
        fvs = swsscommon.FieldValuePairs([("policy_desc", "test"),
                                          ("type", "L3"),
                                          ("ports", ",".join(bind_ports))])
        tbl.set("test_insert", fvs)

        time.sleep(2)

        num_rules = 0
        #create ACL rules
        tbl = swsscommon.Table(db, "ACL_RULE")
        rules = [[("PRIORITY", "10"), ("PACKET_ACTION", "DROP"),
                  ("SRC_IP", "10.0.0.0/32")],
                 [("PRIORITY", "20"), ("PACKET_ACTION", "DROP"),
                  ("DST_IP", "104.44.94.0/23")],
                 [("PRIORITY", "30"), ("PACKET_ACTION", "DROP"),
                  ("DST_IP", "192.168.0.16/32")],
                 [("PRIORITY", "40"), ("PACKET_ACTION", "FORWARD"),
                  ("DST_IP", "100.64.0.0/10")]]
        #used to verify how ACL rules are programmed in ASICDB
        verifs = [{
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '10',
            'SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP':
            '10.0.0.0&mask:255.255.255.255',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_DROP'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '20',
            'SAI_ACL_ENTRY_ATTR_FIELD_DST_IP':
            '104.44.94.0&mask:255.255.254.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_DROP'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '30',
            'SAI_ACL_ENTRY_ATTR_FIELD_DST_IP':
            '192.168.0.16&mask:255.255.255.255',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_DROP'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '40',
            'SAI_ACL_ENTRY_ATTR_FIELD_DST_IP':
            '100.64.0.0&mask:255.192.0.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_FORWARD'
        }]
        #insert rules
        for rule in rules:
            fvs = swsscommon.FieldValuePairs(rule)
            num_rules += 1
            tbl.set("test_insert|acl_test_rule%s" % num_rules, fvs)

        time.sleep(1)

        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
        keys = atbl.getKeys()

        #assert that first set of rules are programmed
        acl_entry = [
            k for k in keys if k not in dvs.asicdb.default_acl_entries
        ]
        assert len(acl_entry) == num_rules

        #insert new rule with odd priority
        tbl = swsscommon.Table(db, "ACL_RULE")
        insertrule = [("PRIORITY", "21"), ("PACKET_ACTION", "DROP"),
                      ("ETHER_TYPE", "4660")]
        #create verification for that rule
        verifs.append({
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '21',
            'SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE':
            '4660&mask:0xffff',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_DROP'
        })
        rules.append(insertrule)
        fvs = swsscommon.FieldValuePairs(insertrule)
        num_rules += 1
        tbl.set("test_insert|acl_test_rule%s" % num_rules, fvs)

        time.sleep(1)

        #assert all rules are programmed
        keys = atbl.getKeys()
        acl_entry = [
            k for k in keys if k not in dvs.asicdb.default_acl_entries
        ]
        assert len(acl_entry) == num_rules

        #match each entry to its corresponding verification
        matched_rules = 0
        for entry in acl_entry:
            (status, fvs) = atbl.get(entry)
            assert status == True
            assert len(fvs) == 6
            #helper function
            if self.check_rule_existence(dict(fvs), rules, verifs):
                matched_rules += 1

        assert num_rules == matched_rules

        #cleanup
        while num_rules > 0:
            tbl._del("test_insert|acl_test_rule%s" % num_rules)
            num_rules -= 1

        time.sleep(1)

        (status, fvs) = atbl.get(acl_entry[0])
        assert status == False

        tbl = swsscommon.Table(db, "ACL_TABLE")
        tbl._del("test_insert")

        time.sleep(1)

        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE")
        keys = atbl.getKeys()
        # only the default table was left
        assert len(keys) >= 1
Esempio n. 7
0
    def test_AclRuleInOutPorts(self, dvs, testlog):
        """
        hmset ACL_RULE|test|acl_test_rule priority 55 PACKET_ACTION FORWARD IN_PORTS Ethernet0,Ethernet4 OUT_PORTS Ethernet8,Ethernet12
        """

        self.setup_db(dvs)
        db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        # create acl rule
        tbl = swsscommon.Table(db, "ACL_RULE")
        fvs = swsscommon.FieldValuePairs([("priority", "55"),
                                          ("PACKET_ACTION", "FORWARD"),
                                          ("IN_PORTS", "Ethernet0,Ethernet4"),
                                          ("OUT_PORTS", "Ethernet8,Ethernet12")
                                          ])
        tbl.set("test|acl_test_rule", fvs)

        time.sleep(1)

        test_acl_table_id = self.get_acl_table_id(dvs)

        # check acl table in asic db
        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
        keys = atbl.getKeys()

        acl_entry = [
            k for k in keys if k not in dvs.asicdb.default_acl_entries
        ]
        assert len(acl_entry) == 1

        (status, fvs) = atbl.get(acl_entry[0])
        assert status == True
        assert len(fvs) == 7
        for fv in fvs:
            if fv[0] == "SAI_ACL_ENTRY_ATTR_TABLE_ID":
                assert fv[1] == test_acl_table_id
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_ADMIN_STATE":
                assert fv[1] == "true"
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_PRIORITY":
                assert fv[1] == "55"
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_COUNTER":
                assert True
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS":
                assert fv[1].startswith("2:")
                assert dvs.asicdb.portnamemap["Ethernet0"] in fv[1]
                assert dvs.asicdb.portnamemap["Ethernet4"] in fv[1]
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS":
                assert fv[1].startswith("2:")
                assert dvs.asicdb.portnamemap["Ethernet8"] in fv[1]
                assert dvs.asicdb.portnamemap["Ethernet12"] in fv[1]
            elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION":
                assert fv[1] == "SAI_PACKET_ACTION_FORWARD"
            else:
                assert False

        # remove acl rule
        tbl._del("test|acl_test_rule")

        time.sleep(1)

        (status, fvs) = atbl.get(acl_entry[0])
        assert status == False
Esempio n. 8
0
    def test_CrmIpv6Neighbor(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.runcmd("config interface startup Ethernet0")

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

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

        time.sleep(2)

        # get counters
        used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_ipv6_neighbor_used')
        avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv6_neighbor_available')

        # add neighbor and update available counter
        dvs.runcmd(
            "ip -6 neigh replace fc00::2 lladdr 11:22:33:44:55:66 dev Ethernet0"
        )
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_IPV6_NEIGHBOR_ENTRY',
                            '999')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv6_neighbor_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv6_neighbor_available')

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

        # remove neighbor and update available counter
        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_NEIGHBOR_ENTRY',
                            '1000')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv6_neighbor_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv6_neighbor_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 ipv6 neighbor high 90")
        dvs.runcmd("crm config thresholds ipv6 neighbor type free")
        time.sleep(2)
        check_syslog(dvs, marker,
                     "IPV6_NEIGHBOR THRESHOLD_EXCEEDED for TH_FREE", 1)

        intf_tbl._del("Ethernet0|fc00::1/126")
        time.sleep(2)
Esempio n. 9
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")
        dvs.runcmd("crm config 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()
        dvs.runcmd("crm config polling interval 2")
        dvs.runcmd("crm config thresholds fdb high 90")
        dvs.runcmd("crm config thresholds fdb 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")
Esempio n. 10
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.runcmd("config interface startup Ethernet0")

        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")

        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()
        dvs.runcmd("crm config polling interval 2")
        dvs.runcmd("crm config thresholds ipv6 route high 90")
        dvs.runcmd("crm config thresholds ipv6 route 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)
Esempio n. 11
0
    def test_CrmIpv4Nexthop(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|10.0.0.0/31", fvs)
        intf_tbl.set("Ethernet0", fvs)
        dvs.runcmd("config interface startup Ethernet0")

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

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

        time.sleep(2)

        # get counters
        used_counter = getCrmCounterValue(dvs, 'STATS',
                                          'crm_stats_ipv4_nexthop_used')
        avail_counter = getCrmCounterValue(dvs, 'STATS',
                                           'crm_stats_ipv4_nexthop_available')

        # add nexthop and update available counter
        dvs.runcmd(
            "ip neigh replace 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_IPV4_NEXTHOP_ENTRY',
                            '999')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv4_nexthop_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv4_nexthop_available')

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

        # remove nexthop and update available counter
        dvs.runcmd(
            "ip neigh del 10.0.0.1 lladdr 11:22:33:44:55:66 dev Ethernet0")
        dvs.setReadOnlyAttr('SAI_OBJECT_TYPE_SWITCH',
                            'SAI_SWITCH_ATTR_AVAILABLE_IPV4_NEXTHOP_ENTRY',
                            '1000')

        time.sleep(2)

        # get counters
        new_used_counter = getCrmCounterValue(dvs, 'STATS',
                                              'crm_stats_ipv4_nexthop_used')
        new_avail_counter = getCrmCounterValue(
            dvs, 'STATS', 'crm_stats_ipv4_nexthop_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 nexthop high 90")
        dvs.runcmd("crm config thresholds ipv4 nexthop type free")
        time.sleep(2)
        check_syslog(dvs, marker,
                     "IPV4_NEXTHOP THRESHOLD_EXCEEDED for TH_FREE", 1)

        intf_tbl._del("Ethernet0|10.0.0.0/31")
        time.sleep(2)
def set_statedb_nat_restore_done():
    statedb = swsscommon.DBConnector("STATE_DB", 0)
    tbl = swsscommon.Table(statedb, "NAT_RESTORE_TABLE")
    fvs = swsscommon.FieldValuePairs([("restored", "true")])
    tbl.set("Flags", fvs)
    return
Esempio n. 13
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)
Esempio n. 14
0
    def test_fgnhg_matchmode_nexthop_multi_route(self, dvs, testlog):
        '''
        Test route/nh transitions to/from Fine Grained ECMP and Regular ECMP.
        Create multiple prefixes pointing to the Fine Grained nhs and ensure 
        fine grained ECMP ASIC objects were created for this scenario as expected.
        '''
        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"}

        fg_nhg_name = "fgnhg_v4"
        fg_nhg_prefix = "3.3.3.0/24"
        # Test with non-divisible bucket size
        bucket_size = 128
        NUM_NHs = 4
        NUM_NHs_non_fgnhg = 2

        nh_oid_map = {}

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

        asic_nh_count = len(asic_db.get_keys(ASIC_NH_TB))
        ip_to_if_map = create_interface_n_fg_ecmp_config(
            dvs, 0, NUM_NHs, fg_nhg_name)

        # Create 2 more interface + IPs for non-fine grained ECMP validation
        for i in range(NUM_NHs, NUM_NHs + NUM_NHs_non_fgnhg):
            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)
            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 + NUM_NHs_non_fgnhg)

        # Program the route
        ps = swsscommon.ProducerStateTable(app_db.db_connection, ROUTE_TB)
        fvs = swsscommon.FieldValuePairs([("nexthop", "10.0.0.1,10.0.0.5"),
                                          ("ifname", "Ethernet0,Ethernet8")])
        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)

        # The route had been created with 0 members in bank
        nh_memb_exp_count = {"10.0.0.1": 64, "10.0.0.5": 64}
        validate_fine_grained_asic_n_state_db_entries(
            asic_db, state_db, ip_to_if_map, fg_nhg_prefix, nh_memb_exp_count,
            nh_oid_map, nhgid, bucket_size)

        # Add a 2nd prefix associated with the same set of next-hops
        fg_nhg_prefix_2 = "5.5.5.0/16"
        fvs = swsscommon.FieldValuePairs([("nexthop", "10.0.0.1,10.0.0.5"),
                                          ("ifname", "Ethernet0,Ethernet8")])
        ps.set(fg_nhg_prefix_2, fvs)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size * 2)
        nhgid_2 = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix_2,
                                                      bucket_size)
        nh_memb_exp_count = {"10.0.0.1": 64, "10.0.0.5": 64}
        validate_fine_grained_asic_n_state_db_entries(
            asic_db, state_db, ip_to_if_map, fg_nhg_prefix_2,
            nh_memb_exp_count, nh_oid_map, nhgid_2, bucket_size)

        # Add a 3rd prefix with a next-hop(10.0.0.9) not defined for FG ECMP
        # Should end up as regular ECMP
        fg_nhg_prefix_3 = "6.6.6.0/16"
        fvs = swsscommon.FieldValuePairs([
            ("nexthop", "10.0.0.1,10.0.0.5,10.0.0.9"),
            ("ifname", "Ethernet0,Ethernet8,Ethernet16")
        ])
        ps.set(fg_nhg_prefix_3, fvs)
        validate_asic_nhg_regular_ecmp(asic_db, fg_nhg_prefix_3)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size * 2 + 3)
        # Remove the 10.0.0.9 next-hop, it should now transition to Fine Grained ECMP
        fvs = swsscommon.FieldValuePairs([("nexthop", "10.0.0.1,10.0.0.5"),
                                          ("ifname", "Ethernet0,Ethernet8")])
        ps.set(fg_nhg_prefix_3, fvs)
        nhgid_3 = validate_asic_nhg_fine_grained_ecmp(asic_db, fg_nhg_prefix_3,
                                                      bucket_size)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size * 3)
        nh_memb_exp_count = {"10.0.0.1": 64, "10.0.0.5": 64}
        validate_fine_grained_asic_n_state_db_entries(
            asic_db, state_db, ip_to_if_map, fg_nhg_prefix_3,
            nh_memb_exp_count, nh_oid_map, nhgid_3, bucket_size)
        # Add the 10.0.0.9 next-hop again, it should transition back to regular ECMP
        fvs = swsscommon.FieldValuePairs([
            ("nexthop", "10.0.0.1,10.0.0.5,10.0.0.9"),
            ("ifname", "Ethernet0,Ethernet8,Ethernet16")
        ])
        ps.set(fg_nhg_prefix_3, fvs)
        validate_asic_nhg_regular_ecmp(asic_db, fg_nhg_prefix_3)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size * 2 + 3)
        # Delete the prefix
        asic_rt_key = get_asic_route_key(asic_db, fg_nhg_prefix_3)
        ps._del(fg_nhg_prefix_3)
        asic_db.wait_for_deleted_entry(ASIC_ROUTE_TB, asic_rt_key)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size * 2)

        # Change FG nhs for one route, ensure that the other route nh is unaffected
        nh_memb_exp_count = {
            "10.0.0.1": 32,
            "10.0.0.3": 32,
            "10.0.0.5": 32,
            "10.0.0.7": 32
        }
        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)
        nh_memb_exp_count = {"10.0.0.1": 64, "10.0.0.5": 64}
        validate_fine_grained_asic_n_state_db_entries(
            asic_db, state_db, ip_to_if_map, fg_nhg_prefix_2,
            nh_memb_exp_count, nh_oid_map, nhgid_2, bucket_size)

        # Remove route
        # remove prefix entry
        asic_rt_key = get_asic_route_key(asic_db, fg_nhg_prefix)
        ps._del(fg_nhg_prefix)
        asic_db.wait_for_deleted_entry(ASIC_ROUTE_TB, asic_rt_key)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, bucket_size)
        # Ensure that 2nd route is still here and then delete it
        nh_memb_exp_count = {"10.0.0.1": 64, "10.0.0.5": 64}
        validate_fine_grained_asic_n_state_db_entries(
            asic_db, state_db, ip_to_if_map, fg_nhg_prefix_2,
            nh_memb_exp_count, nh_oid_map, nhgid_2, bucket_size)
        # Delete the 2nd route as well
        asic_rt_key = get_asic_route_key(asic_db, fg_nhg_prefix_2)
        ps._del(fg_nhg_prefix_2)
        asic_db.wait_for_deleted_entry(ASIC_ROUTE_TB, asic_rt_key)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, 0)
        asic_db.wait_for_n_keys(ASIC_NHG, 0)

        # cleanup all entries
        remove_interface_n_fg_ecmp_config(dvs, 0, NUM_NHs + NUM_NHs_non_fgnhg,
                                          fg_nhg_name)
Esempio n. 15
0
def test_evpnFdb(dvs, testlog):
    vxlan_obj = VxlanTunnel()
    helper = VxlanEvpnHelper()
    dvs.setup_db()

    dvs.clear_fdb()
    time.sleep(2)

    #Find switch_id
    switch_id = dvs.getSwitchOid()
    print("Switch_id=" + str(switch_id))

    vlan_before = helper.how_many_entries_exist(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN")

    # create vlan
    print("Creating Vlan3")
    dvs.create_vlan("3")
    time.sleep(2)

    vlan_after = helper.how_many_entries_exist(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN")
    assert vlan_after - vlan_before == 1, "The Vlan3 wasn't created"
    print("Vlan3 is created")

    # Find the vlan_oid to be used in DB communications
    vlan_oid_3 = dvs.getVlanOid("3")
    assert vlan_oid_3 is not None, "Could not find Vlan_oid"
    print("Vlan-3 vlan_oid=" + str(vlan_oid_3))

    bp_before = helper.how_many_entries_exist(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT")
    vm_before = helper.how_many_entries_exist(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN_MEMBER")

    print("Making Ethernet0 as a member of Vlan3")
    dvs.create_vlan_member("3", "Ethernet0")
    time.sleep(2)

    # check that the vlan information was propagated
    bp_after = helper.how_many_entries_exist(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT")
    vm_after = helper.how_many_entries_exist(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN_MEMBER")

    assert bp_after - bp_before == 1, "The bridge port wasn't created"
    assert vm_after - vm_before == 1, "The vlan member wasn't added"
    print("Ethernet0 is a member of Vlan3")

    # Get mapping between interface name and its bridge port_id
    iface_2_bridge_port_id = dvs.get_map_iface_bridge_port_id(dvs.adb)

    #create SIP side of tunnel
    source_tnl_name = "source_vtep_name"
    source_tnl_ip = "7.7.7.7"
    vxlan_obj.create_vxlan_tunnel(dvs, source_tnl_name, source_tnl_ip)
    time.sleep(1)

    nvo_name = "evpn_nvo"
    vxlan_obj.create_evpn_nvo(dvs, nvo_name, source_tnl_name)
    time.sleep(1)

    map_name_vlan_3 = "map_3_3"
    vxlan_obj.create_vxlan_tunnel_map(dvs, source_tnl_name, map_name_vlan_3,
                                      "3", "Vlan3")
    time.sleep(1)

    remote_ip_6 = "6.6.6.6"
    vxlan_obj.create_evpn_remote_vni(dvs, "Vlan3", remote_ip_6, "3")
    remote_ip_8 = "8.8.8.8"
    vxlan_obj.create_evpn_remote_vni(dvs, "Vlan3", remote_ip_8, "3")
    time.sleep(1)

    #UT-1 Evpn Mac add from remote when tunnels are already created
    mac = "52:54:00:25:06:E9"
    print("Creating Evpn FDB Vlan3:" + mac.lower() + ":6.6.6.6 in APP-DB")
    helper.create_entry_pst(dvs.pdb, "VXLAN_FDB_TABLE", "Vlan3:" + mac.lower(),
                            [("remote_vtep", remote_ip_6), ("type", "dynamic"),
                             ("vni", "3")])
    time.sleep(1)

    tnl_bp_oid_6 = get_vxlan_p2p_tunnel_bp(dvs.adb, remote_ip_6)

    # check that the FDB entry is inserted into ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", mac), ("bvid", vlan_oid_3)], [
            ("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC"),
            ("SAI_FDB_ENTRY_ATTR_ALLOW_MAC_MOVE", "true"),
            ("SAI_FDB_ENTRY_ATTR_ENDPOINT_IP", remote_ip_6),
            ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", str(tnl_bp_oid_6)),
        ])
    assert ok == True, str(extra)
    print("EVPN FDB Vlan3:" + mac.lower() + ":" + remote_ip_6 +
          " is created in ASIC-DB")

    time.sleep(1)

    #UT-2 Evpn Mac del from remote
    mac = "52:54:00:25:06:E9"
    print("Deleting Evpn FDB Vlan3:" + mac.lower() + ":6.6.6.6 in APP-DB")
    helper.delete_entry_pst(dvs.pdb, "VXLAN_FDB_TABLE", "Vlan3:" + mac.lower())
    time.sleep(1)

    # check that the FDB entry is deleted from ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", mac), ("bvid", vlan_oid_3)], [
            ("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC"),
            ("SAI_FDB_ENTRY_ATTR_ALLOW_MAC_MOVE", "true"),
            ("SAI_FDB_ENTRY_ATTR_ENDPOINT_IP", remote_ip_6),
            ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", str(tnl_bp_oid_6)),
        ])
    assert ok == False, str(extra)
    print("EVPN FDB Vlan3:" + mac.lower() + ":" + remote_ip_6 +
          " is deleted from ASIC-DB")

    time.sleep(1)

    #UT-3 Evpn Mac add from remote when local mac is already present
    mac = "52:54:00:25:06:E9"

    print("Creating Local dynamic FDB Vlan3:" + mac.lower() +
          ":Ethernet0 in APP-DB")
    # Create Dynamic MAC entry in APP DB
    helper.create_entry_pst(dvs.pdb, "FDB_TABLE", "Vlan3:" + mac.lower(), [
        ("port", "Ethernet0"),
        ("type", "dynamic"),
    ])

    time.sleep(1)
    #raw_input("Check ASIC_DB.........")

    # check that the FDB entry was added in ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", mac), ("bvid", vlan_oid_3)],
        [("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC"),
         ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID",
          iface_2_bridge_port_id["Ethernet0"])])
    assert ok, str(extra)
    print("Dynamic FDB Vlan3:" + mac.lower() +
          ":Ethernet0 is created in Asic-DB")

    # check that the FDB entry was added in STATE DB
    mac1_found, extra = dvs.is_table_entry_exists(dvs.sdb, "FDB_TABLE",
                                                  "Vlan3:" + mac.lower(), [
                                                      ("port", "Ethernet0"),
                                                      ("type", "dynamic"),
                                                  ])
    assert mac1_found, str(extra)
    print("FDB Vlan3:" + mac + ":Ethernet0 is created in STATE-DB")

    print("Creating Evpn FDB Vlan3:" + mac.lower() + ":6.6.6.6 in APP-DB")
    helper.create_entry_pst(dvs.pdb, "VXLAN_FDB_TABLE", "Vlan3:" + mac.lower(),
                            [("remote_vtep", remote_ip_6), ("type", "dynamic"),
                             ("vni", "3")])
    time.sleep(1)

    # check that the FDB entry is inserted into ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", mac), ("bvid", str(dvs.getVlanOid("3")))], [
            ("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC"),
            ("SAI_FDB_ENTRY_ATTR_ALLOW_MAC_MOVE", "true"),
            ("SAI_FDB_ENTRY_ATTR_ENDPOINT_IP", remote_ip_6),
            ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", str(tnl_bp_oid_6)),
        ])
    assert ok, str(extra)
    print("EVPN FDB Vlan3:" + mac.lower() + ":" + remote_ip_6 +
          " is created in ASIC-DB")

    # check that the Local FDB entry is deleted from STATE DB
    mac1_found, extra = dvs.is_table_entry_exists(dvs.sdb, "FDB_TABLE",
                                                  "Vlan3:" + mac.lower(), [
                                                      ("port", "Ethernet0"),
                                                      ("type", "dynamic"),
                                                  ])
    assert mac1_found == False, str(extra)
    print("FDB Vlan3:" + mac + ":Ethernet0 is deleted from STATE-DB")

    time.sleep(1)

    #UT-4 Evpn Sticky Mac add from remote
    mac = "52:54:00:25:06:E9"
    print("Creating Evpn Sticky FDB Vlan3:" + mac.lower() +
          ":6.6.6.6 in APP-DB")
    helper.create_entry_pst(dvs.pdb, "VXLAN_FDB_TABLE", "Vlan3:" + mac.lower(),
                            [("remote_vtep", remote_ip_6), ("type", "static"),
                             ("vni", "3")])
    time.sleep(1)

    # check that the FDB entry is inserted into ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", mac), ("bvid", str(dvs.getVlanOid("3")))], [
            ("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC"),
            ("SAI_FDB_ENTRY_ATTR_ENDPOINT_IP", remote_ip_6),
            ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", str(tnl_bp_oid_6)),
        ])
    assert ok, str(extra)
    print("EVPN Sticky FDB Vlan3:" + mac.lower() + ":" + remote_ip_6 +
          " is created in ASIC-DB")

    #raw_input("Check ASIC_DB.........")

    #UT-8 Evpn Mac add from remote when tunnels are already created
    mac = "52:54:00:25:06:E9"
    print("Creating Evpn FDB Vlan3:" + mac.lower() + ":6.6.6.6 in APP-DB")
    helper.create_entry_pst(dvs.pdb, "VXLAN_FDB_TABLE", "Vlan3:" + mac.lower(),
                            [("remote_vtep", remote_ip_6), ("type", "dynamic"),
                             ("vni", "3")])
    time.sleep(1)

    #raw_input("Check ASIC_DB.........")

    # check that the FDB entry is inserted into ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", mac), ("bvid", vlan_oid_3)], [
            ("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC"),
            ("SAI_FDB_ENTRY_ATTR_ALLOW_MAC_MOVE", "true"),
            ("SAI_FDB_ENTRY_ATTR_ENDPOINT_IP", remote_ip_6),
            ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", str(tnl_bp_oid_6)),
        ])
    assert ok == True, str(extra)
    print("EVPN FDB Vlan3:" + mac.lower() + ":" + remote_ip_6 +
          " is created in ASIC-DB")

    time.sleep(1)

    tnl_bp_oid_8 = get_vxlan_p2p_tunnel_bp(dvs.adb, remote_ip_8)

    print("Creating Evpn FDB Vlan3:" + mac.lower() + ":8.8.8.8 in APP-DB")
    helper.create_entry_pst(dvs.pdb, "VXLAN_FDB_TABLE", "Vlan3:" + mac.lower(),
                            [("remote_vtep", remote_ip_8), ("type", "dynamic"),
                             ("vni", "3")])
    time.sleep(1)

    #raw_input("Check ASIC_DB.........")

    # check that the FDB entry is inserted into ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", mac), ("bvid", vlan_oid_3)], [
            ("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC"),
            ("SAI_FDB_ENTRY_ATTR_ALLOW_MAC_MOVE", "true"),
            ("SAI_FDB_ENTRY_ATTR_ENDPOINT_IP", remote_ip_8),
            ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID", str(tnl_bp_oid_8)),
        ])
    assert ok == True, str(extra)
    print("EVPN FDB Vlan3:" + mac.lower() + ":" + remote_ip_8 +
          " is created in ASIC-DB")

    time.sleep(1)

    #UT-9 Local mac move (delete and learn) when remote is already added
    mac = "52:54:00:25:06:E9"
    print("Deleting FDB Vlan3:52-54-00-25-06-E9:8.8.8.8 in ASIC-DB")
    helper.delete_entry_tbl(
        dvs.adb, "ASIC_STATE",
        "SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"" + vlan_oid_3 +
        "\",\"mac\":\"" + mac + "\",\"switch_id\":\"" + switch_id + "\"}")

    ntf = swsscommon.NotificationProducer(dvs.adb, "NOTIFICATIONS")
    fvp = swsscommon.FieldValuePairs()
    ntf_data = "[{\"fdb_entry\":\"{\\\"bvid\\\":\\\"" + vlan_oid_3 + "\\\",\\\"mac\\\":\\\"" + mac + "\\\",\\\"switch_id\\\":\\\"" + switch_id + "\\\"}\",\"fdb_event\":\"SAI_FDB_EVENT_AGED\",\"list\":[{\"id\":\"SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID\",\"value\":\"" + str(
        tnl_bp_oid_8) + "\"}]}]"
    ntf.send("fdb_event", ntf_data, fvp)

    time.sleep(2)

    #raw_input("Check ASIC_DB.........")

    print("Creating FDB Vlan3:52-54-00-25-06-E9:Ethernet0 in ASIC-DB")
    helper.create_entry_tbl(
        dvs.adb, "ASIC_STATE", "SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"" +
        vlan_oid_3 + "\",\"mac\":\"52:54:00:25:06:E9\",\"switch_id\":\"" +
        switch_id + "\"}", [
            ("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC"),
            ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID",
             iface_2_bridge_port_id["Ethernet0"]),
        ])

    ntf = swsscommon.NotificationProducer(dvs.adb, "NOTIFICATIONS")
    fvp = swsscommon.FieldValuePairs()
    ntf_data = "[{\"fdb_entry\":\"{\\\"bvid\\\":\\\"" + vlan_oid_3 + "\\\",\\\"mac\\\":\\\"52:54:00:25:06:E9\\\",\\\"switch_id\\\":\\\"" + switch_id + "\\\"}\",\"fdb_event\":\"SAI_FDB_EVENT_LEARNED\",\"list\":[{\"id\":\"SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID\",\"value\":\"" + iface_2_bridge_port_id[
        "Ethernet0"] + "\"}]}]"
    ntf.send("fdb_event", ntf_data, fvp)

    time.sleep(2)

    #raw_input("Check ASIC_DB.........")

    # check that the FDB entry was added in ASIC DB
    ok, extra = dvs.is_fdb_entry_exists(
        dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
        [("mac", "52:54:00:25:06:E9"), ("bvid", vlan_oid_3)],
        [("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC"),
         ("SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID",
          iface_2_bridge_port_id["Ethernet0"])])
    assert ok, str(extra)
    print("FDB Vlan3:52-54-00-25-06-E9:Ethernet0 is created in ASIC-DB")

    # check that the FDB entry was added in STATE DB
    mac1_found, extra = dvs.is_table_entry_exists(dvs.sdb, "FDB_TABLE",
                                                  "Vlan3:52:54:00:25:06:e9", [
                                                      ("port", "Ethernet0"),
                                                      ("type", "dynamic"),
                                                  ])
    assert mac1_found, str(extra)
    print("FDB Vlan3:52-54-00-25-06-E9:Ethernet0 is created in STATE-DB")

    dvs.remove_vlan_member("3", "Ethernet0")
    dvs.remove_vlan("3")
Esempio n. 16
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.runcmd("config interface startup Ethernet0")
        dvs.runcmd("config interface startup Ethernet4")

        dvs.runcmd("crm config 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()
        dvs.runcmd("crm config polling interval 2")
        dvs.runcmd("crm config thresholds nexthop group member high 90")
        dvs.runcmd("crm config thresholds nexthop group member 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)
Esempio n. 17
0
 def create_dot1p_profile(self):
     tbl = swsscommon.Table(self.config_db, CFG_DOT1P_TO_TC_MAP_TABLE_NAME)
     fvs = swsscommon.FieldValuePairs(DOT1P_TO_TC_MAP.items())
     tbl.set(CFG_DOT1P_TO_TC_MAP_KEY, fvs)
     time.sleep(1)
Esempio n. 18
0
    def test_CrmAcl(self, dvs, testlog):

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

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

        bind_ports = ["Ethernet0", "Ethernet4"]

        old_table_used_counter = getCrmCounterValue(
            dvs, 'ACL_STATS:INGRESS:PORT', 'crm_stats_acl_table_used')

        # create ACL table
        ttbl = swsscommon.Table(db, "ACL_TABLE")
        fvs = swsscommon.FieldValuePairs([("policy_desc", "test"),
                                          ("type", "L3"),
                                          ("ports", ",".join(bind_ports))])
        ttbl.set("test", fvs)

        # create ACL rule
        rtbl = swsscommon.Table(db, "ACL_RULE")
        fvs = swsscommon.FieldValuePairs([("priority", "55"),
                                          ("PACKET_ACTION", "FORWARD"),
                                          ("L4_SRC_PORT", "65000")])
        rtbl.set("test|acl_test_rule", fvs)

        time.sleep(2)

        new_table_used_counter = getCrmCounterValue(
            dvs, 'ACL_STATS:INGRESS:PORT', 'crm_stats_acl_table_used')
        table_used_counter = new_table_used_counter - old_table_used_counter
        assert table_used_counter == 1

        # get ACL table key
        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE")
        acl_tables = [
            k for k in atbl.getKeys() if k not in dvs.asicdb.default_acl_tables
        ]
        key = "ACL_TABLE_STATS:{0}".format(acl_tables[0].replace('oid:', ''))

        entry_used_counter = getCrmCounterValue(dvs, key,
                                                'crm_stats_acl_entry_used')
        assert entry_used_counter == 1

        cnt_used_counter = getCrmCounterValue(dvs, key,
                                              'crm_stats_acl_counter_used')
        assert entry_used_counter == 1

        # remove ACL rule
        rtbl._del("test|acl_test_rule")

        time.sleep(2)

        entry_used_counter = getCrmCounterValue(dvs, key,
                                                'crm_stats_acl_entry_used')
        assert entry_used_counter == 0

        cnt_used_counter = getCrmCounterValue(dvs, key,
                                              'crm_stats_acl_counter_used')
        assert cnt_used_counter == 0

        # remove ACL table
        ttbl._del("test")

        time.sleep(2)

        new_table_used_counter = getCrmCounterValue(
            dvs, 'ACL_STATS:INGRESS:PORT', 'crm_stats_acl_table_used')
        table_used_counter = new_table_used_counter - old_table_used_counter
        assert table_used_counter == 0

        counters_db = swsscommon.DBConnector(swsscommon.COUNTERS_DB,
                                             dvs.redis_sock, 0)
        crm_stats_table = swsscommon.Table(counters_db, 'CRM')
        keys = crm_stats_table.getKeys()
        assert key not in keys
Esempio n. 19
0
    def test_RulesWithDiffMaskLengths(self, dvs, testlog):
        self.setup_db(dvs)
        db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        bind_ports = ["Ethernet0", "Ethernet4"]
        # create ACL_TABLE in config db
        tbl = swsscommon.Table(db, "ACL_TABLE")
        fvs = swsscommon.FieldValuePairs([("policy_desc", "test"),
                                          ("type", "L3"),
                                          ("ports", ",".join(bind_ports))])
        tbl.set("test_subnet", fvs)

        time.sleep(2)

        subnet_mask_rules = 0
        #create ACL rules
        tbl = swsscommon.Table(db, "ACL_RULE")
        rules = [[("PRIORITY", "10"), ("PACKET_ACTION", "FORWARD"),
                  ("SRC_IP", "23.103.0.0/18")],
                 [("PRIORITY", "20"), ("PACKET_ACTION", "FORWARD"),
                  ("SRC_IP", "104.44.94.0/23")],
                 [("PRIORITY", "30"), ("PACKET_ACTION", "FORWARD"),
                  ("DST_IP", "172.16.0.0/12")],
                 [("PRIORITY", "40"), ("PACKET_ACTION", "FORWARD"),
                  ("DST_IP", "100.64.0.0/10")],
                 [("PRIORITY", "50"), ("PACKET_ACTION", "FORWARD"),
                  ("DST_IP", "104.146.32.0/19")],
                 [("PRIORITY", "60"), ("PACKET_ACTION", "FORWARD"),
                  ("SRC_IP", "21.0.0.0/8")]]
        #used to verify how ACL rules are programmed in ASICDB
        #order must match the list of rules
        verifs = [{
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '10',
            'SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP':
            '23.103.0.0&mask:255.255.192.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_FORWARD'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '20',
            'SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP':
            '104.44.94.0&mask:255.255.254.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_FORWARD'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '30',
            'SAI_ACL_ENTRY_ATTR_FIELD_DST_IP':
            '172.16.0.0&mask:255.240.0.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_FORWARD'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '40',
            'SAI_ACL_ENTRY_ATTR_FIELD_DST_IP':
            '100.64.0.0&mask:255.192.0.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_FORWARD'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '50',
            'SAI_ACL_ENTRY_ATTR_FIELD_DST_IP':
            '104.146.32.0&mask:255.255.224.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_FORWARD'
        }, {
            'SAI_ACL_ENTRY_ATTR_PRIORITY':
            '60',
            'SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP':
            '21.0.0.0&mask:255.0.0.0',
            'SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION':
            'SAI_PACKET_ACTION_FORWARD'
        }]
        #insert rules
        for rule in rules:
            fvs = swsscommon.FieldValuePairs(rule)
            subnet_mask_rules += 1
            tbl.set("test_subnet|acl_test_rule%s" % subnet_mask_rules, fvs)

        time.sleep(1)

        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
        keys = atbl.getKeys()

        acl_entry = [
            k for k in keys if k not in dvs.asicdb.default_acl_entries
        ]
        assert len(acl_entry) == subnet_mask_rules

        #match each entry to its corresponding verification
        matched_masks = 0
        for entry in acl_entry:
            (status, fvs) = atbl.get(entry)
            assert status == True
            assert len(fvs) == 6
            #helper function
            if self.check_rule_existence(dict(fvs), rules, verifs):
                matched_masks += 1

        assert matched_masks == subnet_mask_rules

        while subnet_mask_rules > 0:
            tbl._del("test_subnet|acl_test_rule%s" % subnet_mask_rules)
            subnet_mask_rules -= 1

        time.sleep(1)

        (status, fvs) = atbl.get(acl_entry[0])
        assert status == False

        tbl = swsscommon.Table(db, "ACL_TABLE")
        tbl._del("test_subnet")

        time.sleep(1)

        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE")
        keys = atbl.getKeys()
        assert len(keys) >= 1
    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 route entry
        ps = swsscommon.ProducerStateTable(self.pdb, "ROUTE_TABLE")
        ps._del("2.2.2.0/24")
        time.sleep(1)

        # 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 router interfaces
        tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_INTERFACE")
        tbl._del("PortChannel001")
        tbl._del("PortChannel002")
        tbl._del("PortChannel003")
        tbl._del("PortChannel004")
        time.sleep(1)

        # check application database
        tbl = swsscommon.Table(self.pdb, "INTF_TABLE")
        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)
Esempio n. 21
0
    def test_V6AclTableCreation(self, dvs, testlog):

        self.setup_db(dvs)
        db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
        adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

        bind_ports = ["Ethernet0", "Ethernet4", "Ethernet8"]
        # create ACL_TABLE in config db
        tbl = swsscommon.Table(db, "ACL_TABLE")
        fvs = swsscommon.FieldValuePairs([("policy_desc", "testv6"),
                                          ("type", "L3V6"),
                                          ("ports", ",".join(bind_ports))])
        tbl.set("test-aclv6", fvs)

        time.sleep(1)

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

        # check acl table group in asic db
        atbl = swsscommon.Table(adb,
                                "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP")
        acl_table_groups = atbl.getKeys()
        assert len(acl_table_groups) == 3

        for k in acl_table_groups:
            (status, fvs) = atbl.get(k)
            assert status == True

            for fv in fvs:
                if fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_ACL_STAGE":
                    assert fv[1] == "SAI_ACL_STAGE_INGRESS"
                elif fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_ACL_BIND_POINT_TYPE_LIST":
                    assert fv[1] == "1:SAI_ACL_BIND_POINT_TYPE_PORT"
                elif fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_TYPE":
                    assert fv[1] == "SAI_ACL_TABLE_GROUP_TYPE_PARALLEL"
                else:
                    assert False

        # check acl table group member
        atbl = swsscommon.Table(
            adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP_MEMBER")
        keys = atbl.getKeys()
        # three ports
        assert len(keys) == 3

        member_groups = []
        for k in keys:
            (status, fvs) = atbl.get(k)
            assert status == True

            assert len(fvs) == 3
            for fv in fvs:
                if fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_ACL_TABLE_GROUP_ID":
                    assert fv[1] in acl_table_groups
                    member_groups.append(fv[1])
                elif fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_ACL_TABLE_ID":
                    assert fv[1] == test_acl_table_id
                elif fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_PRIORITY":
                    assert True
                else:
                    assert False

        assert set(member_groups) == set(acl_table_groups)

        # check port binding
        atbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT")

        port_groups = []
        for p in [dvs.asicdb.portnamemap[portname] for portname in bind_ports]:
            (status, fvs) = atbl.get(p)
            for fv in fvs:
                if fv[0] == "SAI_PORT_ATTR_INGRESS_ACL":
                    assert fv[1] in acl_table_groups
                    port_groups.append(fv[1])

        assert set(port_groups) == set(acl_table_groups)
    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
Esempio n. 23
0
 def create_vlan(self, vlan):
     tbl = swsscommon.Table(self.cdb, "VLAN")
     fvs = swsscommon.FieldValuePairs([("vlanid", vlan)])
     tbl.set("Vlan" + vlan, fvs)
     time.sleep(1)
Esempio n. 24
0
def create_entry(tbl, key, pairs):
    fvs = swsscommon.FieldValuePairs(pairs)
    tbl.set(key, fvs)
    time.sleep(1)
Esempio n. 25
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)
Esempio n. 26
0
 def setup_mirrorv6_mode(self, mode):
     tbl = swsscommon.Table(self.sdb, "SWITCH_CAPABILITY")
     fvs = swsscommon.FieldValuePairs([("mirror_v6_table_mode", mode)])
     tbl.set("switch", fvs)
     time.sleep(1)
 def add_port_channel_members(self, dvs, lag, members):
     tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_MEMBER")
     fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
     for member in members:
         tbl.set(lag + "|" + member, fvs)
         time.sleep(1)
Esempio n. 28
0
 def table_set(t, state):
     fvs = swsscommon.FieldValuePairs([("status", state)])
     t.set("123", fvs)
 def create_port_channel(self, dvs, alias):
     tbl = swsscommon.Table(self.cdb, "PORTCHANNEL")
     fvs = swsscommon.FieldValuePairs([("admin_status", "up"),
                                       ("mtu", "9100")])
     tbl.set(alias, fvs)
     time.sleep(1)
Esempio n. 30
0
def fine_grained_ecmp_base_test(dvs, match_mode):
    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), "match_mode": match_mode}
    create_entry(config_db, FG_NHG, fg_nhg_name, fvs)

    if match_mode == 'route-based':
        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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  nh_memb_exp_count,
                                                  nh_oid_map, nhgid,
                                                  bucket_size)

    # Test warm reboot
    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, fg_nhg_prefix,
                                                  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)

    # Test warm reboot
    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
    }
    validate_fine_grained_asic_n_state_db_entries(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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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, fg_nhg_prefix,
                                                  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)

    if match_mode == 'route-based':
        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, fg_nhg_prefix, nh_memb_exp_count,
            nh_oid_map, nhgid, bucket_size)

        # remove fgnhg prefix: The fine grained route should transition to regular ECMP/route
        remove_entry(config_db, "FG_NHG_PREFIX", fg_nhg_prefix)

        # Validate regular ECMP
        validate_asic_nhg_regular_ecmp(asic_db, fg_nhg_prefix)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, 3)
        state_db.wait_for_n_keys("FG_ROUTE_TABLE", 0)

        # remove prefix entry
        asic_rt_key = get_asic_route_key(asic_db, fg_nhg_prefix)
        ps._del(fg_nhg_prefix)
        asic_db.wait_for_deleted_entry(ASIC_ROUTE_TB, asic_rt_key)
        asic_db.wait_for_n_keys(ASIC_NHG_MEMB, 0)

    # Cleanup all FG, arp and interface
    remove_entry(config_db, "FG_NHG", fg_nhg_name)

    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))