From a5f21ff0f59e7ed7b2123cb507477cc6a6b100cd Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Sat, 10 Oct 2020 06:17:03 -0700 Subject: [PATCH 01/31] Code changes to support IPv6 Link local enchancements Signed-off-by: Akhilesh Samineni --- cfgmgr/Makefile.am | 4 +- cfgmgr/intfmgr.cpp | 228 +++++++++++++++++++++++++++++++++++++-- cfgmgr/intfmgr.h | 10 +- cfgmgr/intfmgrd.cpp | 15 +++ fpmsyncd/routesync.cpp | 5 + neighsyncd/neighsync.cpp | 3 - orchagent/intfsorch.cpp | 66 ++++++++++-- orchagent/intfsorch.h | 2 + orchagent/neighorch.cpp | 13 +++ orchagent/routeorch.cpp | 35 +++--- orchagent/routeorch.h | 4 +- orchagent/vrforch.cpp | 15 +++ 12 files changed, 367 insertions(+), 33 deletions(-) diff --git a/cfgmgr/Makefile.am b/cfgmgr/Makefile.am index d1ea5978c1..91d0eeb928 100644 --- a/cfgmgr/Makefile.am +++ b/cfgmgr/Makefile.am @@ -39,8 +39,8 @@ portmgrd_LDADD = -lswsscommon $(SAIMETA_LIBS) intfmgrd_SOURCES = intfmgrd.cpp intfmgr.cpp $(top_srcdir)/orchagent/orch.cpp $(top_srcdir)/orchagent/request_parser.cpp shellcmd.h intfmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) -intfmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) -intfmgrd_LDADD = -lswsscommon $(SAIMETA_LIBS) +intfmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(LIBNL_CPPFLAGS) +intfmgrd_LDADD = -lswsscommon $(SAIMETA_LIBS) $(LIBNL_LIBS) buffermgrd_SOURCES = buffermgrd.cpp buffermgr.cpp buffermgrdyn.cpp $(top_srcdir)/orchagent/orch.cpp $(top_srcdir)/orchagent/request_parser.cpp shellcmd.h buffermgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) diff --git a/cfgmgr/intfmgr.cpp b/cfgmgr/intfmgr.cpp index b40f55692a..a182e58663 100644 --- a/cfgmgr/intfmgr.cpp +++ b/cfgmgr/intfmgr.cpp @@ -9,6 +9,11 @@ #include "shellcmd.h" #include "macaddress.h" #include "warm_restart.h" +#include +#include +#include +#include "netmsg.h" +#include "linkcache.h" using namespace std; using namespace swss; @@ -16,11 +21,14 @@ using namespace swss; #define VLAN_PREFIX "Vlan" #define LAG_PREFIX "PortChannel" #define LOOPBACK_PREFIX "Loopback" +#define LINUX_LOOPBACK "lo" #define VNET_PREFIX "Vnet" #define MTU_INHERITANCE "0" #define VRF_PREFIX "Vrf" #define VRF_MGMT "mgmt" +#define ETHERNET_PREFIX "Ethernet" +#define MAX_ADDR_SIZE 64 #define LOOPBACK_DEFAULT_MTU_STR "65536" IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames) : @@ -278,6 +286,45 @@ bool IntfMgr::isIntfChangeVrf(const string &alias, const string &vrfName) return false; } +bool IntfMgr::ifManualIPv6AddrsConfigured(const string &alias) +{ + stringstream addrshow, linkshow; + string res; + int numOfAddrs, linkUp; + + addrshow << IP_CMD << " -6 address show " << alias << " | grep inet | wc -l"; + EXEC_WITH_ERROR_THROW(addrshow.str(), res); + + numOfAddrs = std::stoi(res); + + linkshow << IP_CMD << " -6 link show " << alias << " | grep UP | wc -l"; + EXEC_WITH_ERROR_THROW(linkshow.str(), res); + + linkUp = std::stoi(res); + + /* IPv6 auto link local address is removed by the kernel on link down, but manually + * configured IPv6 addresses (gloabl or link-local) are not removed on link down. + * So, to check if manual addresses are configured, check if any addresses + * are there when the link is down, or if > 1 addresses are there when the link is up */ + + if (((numOfAddrs > 1) && (linkUp)) || ((numOfAddrs) && (! linkUp))) + { + return true; + } + return false; +} + +int IntfMgr::getIntfIpv6DisableMode(const string &alias) +{ + stringstream cmd; + string res; + + cmd << "cat /proc/sys/net/ipv6/conf/" << alias << "/disable_ipv6"; + EXEC_WITH_ERROR_THROW(cmd.str(), res); + + return std::stoi(res); +} + void IntfMgr::addHostSubIntf(const string&intf, const string &subIntf, const string &vlan) { stringstream cmd; @@ -476,6 +523,7 @@ bool IntfMgr::doIntfGeneralTask(const vector& keys, string proxy_arp = ""; string grat_arp = ""; string mpls = ""; + string ipv6_link_local_mode = ""; for (auto idx : data) { @@ -506,11 +554,14 @@ bool IntfMgr::doIntfGeneralTask(const vector& keys, { mpls = value; } - - if (field == "nat_zone") + else if (field == "nat_zone") { nat_zone = value; } + else if (field == "ipv6_use_link_local_only") + { + ipv6_link_local_mode = value; + } } if (op == SET_COMMAND) @@ -551,6 +602,7 @@ bool IntfMgr::doIntfGeneralTask(const vector& keys, FieldValueTuple fvTuple("nat_zone", nat_zone); data.push_back(fvTuple); } + /* Set mpls */ if (!setIntfMpls(alias, mpls)) { @@ -562,6 +614,21 @@ bool IntfMgr::doIntfGeneralTask(const vector& keys, FieldValueTuple fvTuple("mpls", mpls); data.push_back(fvTuple); } + + /* Set ipv6 mode */ + if (!ipv6_link_local_mode.empty()) + { + if ((ipv6_link_local_mode.compare("enable") == 0) && + (getIntfIpv6DisableMode(alias) == 1)) + { + setIntfIpv6Mode(alias, ipv6_link_local_mode); + } + else if ((ipv6_link_local_mode.compare("disable") == 0) && + (ifManualIPv6AddrsConfigured(alias) == false)) + { + setIntfIpv6Mode(alias, ipv6_link_local_mode); + } + } } if (!parentAlias.empty()) @@ -684,6 +751,13 @@ bool IntfMgr::doIntfGeneralTask(const vector& keys, delLoopbackIntf(alias); m_loopbackIntfList.erase(alias); } + else + { + if (getIntfIpv6DisableMode(alias) == 0) + { + setIntfIpv6Mode(alias, "disable"); + } + } if (!parentAlias.empty()) { @@ -726,13 +800,22 @@ bool IntfMgr::doIntfAddrTask(const vector& keys, return false; } + /* Enable ipv6 on the interface in the kernel first before adding the manually + * configured address, if use-link-local-only mode is not already enabled on the interface. */ + if ((ip_prefix.isV4() == false) && + (isIpv6LinkLocalModeEnabled(alias) == false) && + (getIntfIpv6DisableMode(alias) == 1)) + { + setIntfIpv6Mode(alias, "enable"); + } + setIntfIp(alias, "add", ip_prefix); std::vector fvVector; FieldValueTuple f("family", ip_prefix.isV4() ? IPV4_NAME : IPV6_NAME); - // Don't send link local config to AppDB and Orchagent - if (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE) + // Don't send ipv4 link local config to AppDB and Orchagent + if ((ip_prefix.isV4() == false) or (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)) { FieldValueTuple s("scope", "global"); fvVector.push_back(s); @@ -745,12 +828,22 @@ bool IntfMgr::doIntfAddrTask(const vector& keys, { setIntfIp(alias, "del", ip_prefix); - // Don't send link local config to AppDB and Orchagent - if (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE) + // Don't send ipv4 link local config to AppDB and Orchagent + if ((ip_prefix.isV4() == false) or (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)) { m_appIntfTableProducer.del(appKey); m_stateIntfTable.del(keys[0] + state_db_key_delimiter + keys[1]); } + + /* If all manually configured addresses on the interface are removed, + * disable ipv6 on the interface to remove the auto link-local ipv6 address, + * provided use-link-local-only mode is not enabled on the interface. */ + if ((ip_prefix.isV4() == false) && + (isIpv6LinkLocalModeEnabled(alias) == false) && + (ifManualIPv6AddrsConfigured(alias) == false)) + { + setIntfIpv6Mode(alias, "disable"); + } } else { @@ -824,3 +917,126 @@ void IntfMgr::doTask(Consumer &consumer) setWarmReplayDoneState(); } } + +bool IntfMgr::isIpv6LinkLocalModeEnabled(const string &alias) +{ + vector fv; + Table *cfgTable; + + if (!alias.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX)) + { + cfgTable = &m_cfgVlanIntfTable; + } + else if (!alias.compare(0, strlen(LAG_PREFIX), LAG_PREFIX)) + { + cfgTable = &m_cfgLagIntfTable; + } + else if (!alias.compare(0, strlen(ETHERNET_PREFIX), ETHERNET_PREFIX)) + { + cfgTable = &m_cfgIntfTable; + } + else + { + return false; + } + if ((*cfgTable).get(alias, fv)) + { + for (auto idx : fv) + { + if (fvField(idx) == "ipv6_use_link_local_only") + { + if (fvValue(idx) == "enable") + { + return true; + } + } + } + } + return false; +} + +// Set Interface IPv6 mode +void IntfMgr::setIntfIpv6Mode(const string &port, const string &mode) +{ + stringstream cmd; + string res; + int ret; + + SWSS_LOG_INFO("Setting interface ipv6 mode on interface %s to %s", port.c_str(), mode.c_str()); + if (mode == "enable") + { + cmd << "sysctl -w net.ipv6.conf." << port << ".disable_ipv6=0"; + } + else + { + cmd << "sysctl -w net.ipv6.conf." << port << ".disable_ipv6=1"; + } + ret = swss::exec(cmd.str(), res); + if (ret) + { + SWSS_LOG_INFO("Command '%s' failed with rc %d %s", cmd.str().c_str(), ret, res.c_str()); + } +} + +void IntfMgr::onMsg(int nlmsg_type, struct nl_object *obj) +{ + char addrStr[MAX_ADDR_SIZE + 1] = {0}; + struct rtnl_addr *addr = (struct rtnl_addr *)obj; + string intfTableKey; + string stateTableKey; + string intfName; + string scope = "local"; + string family = IPV6_NAME; + + if ((nlmsg_type != RTM_NEWADDR) && + (nlmsg_type != RTM_DELADDR)) + { + return; + } + + /* Sync IPv6 Link local routes only */ + if ((rtnl_addr_get_family(addr) != AF_INET6) || + (rtnl_addr_get_scope(addr) != RT_SCOPE_LINK)) + { + return; + } + + intfName = LinkCache::getInstance().ifindexToName(rtnl_addr_get_ifindex(addr)); + if (0 != intfName.compare(0, strlen(ETHERNET_PREFIX), ETHERNET_PREFIX) && + 0 != intfName.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX) && + 0 != intfName.compare(0, strlen(LAG_PREFIX), LAG_PREFIX) && + 0 != intfName.compare(0, strlen(LINUX_LOOPBACK), LINUX_LOOPBACK)) + { + return; + } + + nl_addr2str(rtnl_addr_get_local(addr), addrStr, MAX_ADDR_SIZE); + + intfTableKey = intfName; + intfTableKey+= ":"; + intfTableKey+= addrStr; + + stateTableKey = intfName; + stateTableKey+= "|"; + stateTableKey+= addrStr; + + if (nlmsg_type == RTM_DELADDR) + { + m_appIntfTableProducer.del(intfTableKey); + m_stateIntfTable.del(stateTableKey); + + return; + } + + SWSS_LOG_INFO("IPv6 Link local address %s added on interface %s", addrStr, intfName.c_str()); + + std::vector fv; + FieldValueTuple f("family", family); + FieldValueTuple s("scope", scope); + + fv.push_back(s); + fv.push_back(f); + m_appIntfTableProducer.set(intfTableKey, fv); + m_stateIntfTable.hset(stateTableKey, "state", "ok"); +} + diff --git a/cfgmgr/intfmgr.h b/cfgmgr/intfmgr.h index 655fb4deeb..94d8daea7b 100644 --- a/cfgmgr/intfmgr.h +++ b/cfgmgr/intfmgr.h @@ -4,6 +4,7 @@ #include "dbconnector.h" #include "producerstatetable.h" #include "orch.h" +#include "netmsg.h" #include #include @@ -11,16 +12,18 @@ namespace swss { -class IntfMgr : public Orch +class IntfMgr : public Orch, public NetMsg { public: IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; + virtual void onMsg(int nlmsg_type, struct nl_object *obj); private: ProducerStateTable m_appIntfTableProducer; Table m_cfgIntfTable, m_cfgVlanIntfTable, m_cfgLagIntfTable, m_cfgLoopbackIntfTable; Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateVrfTable, m_stateIntfTable; + Table m_cfgIntfTable, m_cfgVlanIntfTable, m_cfgLagIntfTable; std::set m_subIntfList; std::set m_loopbackIntfList; @@ -56,6 +59,11 @@ class IntfMgr : public Orch bool setIntfProxyArp(const std::string &alias, const std::string &proxy_arp); bool setIntfGratArp(const std::string &alias, const std::string &grat_arp); + int getIntfIpv6DisableMode(const std::string &alias); + bool ifManualIPv6AddrsConfigured(const std::string &alias); + bool isIpv6LinkLocalModeEnabled(const std::string &alias); + void setIntfIpv6Mode(const std::string &port, const std::string &mode); + bool m_replayDone {false}; }; diff --git a/cfgmgr/intfmgrd.cpp b/cfgmgr/intfmgrd.cpp index d6ed18526e..889349fcf8 100644 --- a/cfgmgr/intfmgrd.cpp +++ b/cfgmgr/intfmgrd.cpp @@ -9,6 +9,8 @@ #include #include #include "warm_restart.h" +#include "netdispatcher.h" +#include "netlink.h" using namespace std; using namespace swss; @@ -59,6 +61,9 @@ int main(int argc, char **argv) IntfMgr intfmgr(&cfgDb, &appDb, &stateDb, cfg_intf_tables); + NetDispatcher::getInstance().registerMessageHandler(RTM_NEWADDR, &intfmgr); + NetDispatcher::getInstance().registerMessageHandler(RTM_DELADDR, &intfmgr); + // TODO: add tables in stateDB which interface depends on to monitor list std::vector cfgOrchList = {&intfmgr}; @@ -68,6 +73,12 @@ int main(int argc, char **argv) s.addSelectables(o->getSelectables()); } + NetLink netlink; + netlink.registerGroup(RTNLGRP_IPV4_IFADDR); + netlink.registerGroup(RTNLGRP_IPV6_IFADDR); + + s.addSelectable(&netlink); + SWSS_LOG_NOTICE("starting main loop"); while (true) { @@ -80,6 +91,10 @@ int main(int argc, char **argv) SWSS_LOG_NOTICE("Error: %s!", strerror(errno)); continue; } + if (sel == &netlink) + { + continue; + } if (ret == Select::TIMEOUT) { intfmgr.doTask(); diff --git a/fpmsyncd/routesync.cpp b/fpmsyncd/routesync.cpp index 9910dca07e..48a1a0df58 100644 --- a/fpmsyncd/routesync.cpp +++ b/fpmsyncd/routesync.cpp @@ -916,6 +916,11 @@ string RouteSync::getNextHopGw(struct rtnl_route *route_obj) if (addr) { char gw_ip[MAX_ADDR_SIZE + 1] = {0}; + if (nl_addr_get_prefixlen(addr) > IPV4_MAX_BITLEN + && nl_addr_get_family(addr) == AF_INET) + { + nl_addr_set_family(addr, AF_INET6); + } nl_addr2str(addr, gw_ip, MAX_ADDR_SIZE); result += gw_ip; } diff --git a/neighsyncd/neighsync.cpp b/neighsyncd/neighsync.cpp index 054f13a470..8095dc6676 100644 --- a/neighsyncd/neighsync.cpp +++ b/neighsyncd/neighsync.cpp @@ -73,9 +73,6 @@ void NeighSync::onMsg(int nlmsg_type, struct nl_object *obj) key+= ":"; nl_addr2str(rtnl_neigh_get_dst(neigh), ipStr, MAX_ADDR_SIZE); - /* Ignore IPv6 link-local addresses as neighbors */ - if (family == IPV6_NAME && IN6_IS_ADDR_LINKLOCAL(nl_addr_get_binary_addr(rtnl_neigh_get_dst(neigh)))) - return; /* Ignore IPv6 multicast link-local addresses as neighbors */ if (family == IPV6_NAME && IN6_IS_ADDR_MC_LINKLOCAL(nl_addr_get_binary_addr(rtnl_neigh_get_dst(neigh)))) return; diff --git a/orchagent/intfsorch.cpp b/orchagent/intfsorch.cpp index b270a0c5e5..f396d2b166 100644 --- a/orchagent/intfsorch.cpp +++ b/orchagent/intfsorch.cpp @@ -858,14 +858,32 @@ void IntfsOrch::doTask(Consumer &consumer) } else { - if (!setIntf(alias, vrf_id, ip_prefix_in_key ? &ip_prefix : nullptr, adminUp, mtu)) - { - it++; - continue; - } - if (gPortsOrch->getPort(alias, port)) { + if (ip_prefix_in_key) + { + string out_alias; + + if (hasIp2MeAddr(port.m_vr_id, ip_prefix, &out_alias)) + { + string vrfName = m_vrfOrch->getVRFname(port.m_vr_id); + + if (ip_prefix.getIp().getAddrScope() == IpAddress::LINK_SCOPE) + { + SWSS_LOG_INFO("Ignoring SET IP Address: %s in %s, Same IP configured in %s, vrf: %s ", + ip_prefix.to_string().c_str(), alias.c_str(), out_alias.c_str(), vrfName.empty()? "default": vrfName.c_str()); + } + else + { + SWSS_LOG_ERROR("Ignoring SET IP Address: %s in %s, Same IP configured in %s, vrf: %s ", + ip_prefix.to_string().c_str(), alias.c_str(), out_alias.c_str(), vrfName.empty()? "default": vrfName.c_str()); + } + + it = consumer.m_toSync.erase(it); + continue; + } + } + /* Set nat zone id */ if ((!nat_zone.empty()) and (port.m_nat_zone_id != nat_zone_id)) { @@ -891,6 +909,12 @@ void IntfsOrch::doTask(Consumer &consumer) gPortsOrch->setPort(alias, port); } } + + if (!setIntf(alias, vrf_id, ip_prefix_in_key ? &ip_prefix : nullptr, adminUp, mtu)) + { + it++; + continue; + } } if (mac) @@ -1216,6 +1240,36 @@ bool IntfsOrch::removeRouterIntfs(Port &port) return true; } +bool IntfsOrch::hasIp2MeAddr(sai_object_id_t in_vrf_id, const IpPrefix &in_ip_prefix, string *out_alias) +{ + sai_object_id_t vrf_id = gVirtualRouterId; + + for (auto it = m_syncdIntfses.begin(); it != m_syncdIntfses.end(); it++) + { + for (auto prefix : it->second.ip_addresses) + { + if (prefix.isAddressInSubnet(in_ip_prefix.getIp())) + { + vrf_id = m_syncdIntfses[it->first].vrf_id; + string vrfName = m_vrfOrch->getVRFname(vrf_id); + + if (vrf_id == in_vrf_id) + { + *out_alias = it->first; + + if (prefix == in_ip_prefix) + { + SWSS_LOG_NOTICE("IP2Me Matched Addr %s, Intf = %s vrf %s ", prefix.to_string().c_str(), it->first.c_str(), vrfName.c_str()); + return true; + } + } + } + } + } + + return false; +} + void IntfsOrch::addIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix) { sai_route_entry_t unicast_route_entry; diff --git a/orchagent/intfsorch.h b/orchagent/intfsorch.h index 5605abf133..f1fe1a04b2 100644 --- a/orchagent/intfsorch.h +++ b/orchagent/intfsorch.h @@ -57,6 +57,8 @@ class IntfsOrch : public Orch bool setIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr, const bool adminUp = true, const uint32_t mtu = 0); bool removeIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr); + bool hasIp2MeAddr(sai_object_id_t in_vrf_id, const IpPrefix &in_ip_prefix, string *out_alias); + void addIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix); void removeIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix); diff --git a/orchagent/neighorch.cpp b/orchagent/neighorch.cpp index acd8d8718b..691d1ea33f 100644 --- a/orchagent/neighorch.cpp +++ b/orchagent/neighorch.cpp @@ -671,6 +671,19 @@ void NeighOrch::doTask(Consumer &consumer) IpAddress ip_address(key.substr(found+1)); + /* Verify Ipv4 LinkLocal and skip neighbor entry added for RFC5549 */ + if ((ip_address.getAddrScope() == IpAddress::LINK_SCOPE) && (ip_address.isV4())) + { + /* Check if this prefix is not a configured ip, if so allow */ + IpPrefix ipll_prefix(ip_address.getV4Addr(), 16); + if (!m_intfsOrch->isPrefixSubnet (ipll_prefix, alias)) + { + SWSS_LOG_NOTICE("Skip IPv4LL neighbor %s, Intf:%s op: %s ", ip_address.to_string().c_str(), alias.c_str(), op.c_str()); + it = consumer.m_toSync.erase(it); + continue; + } + } + NeighborEntry neighbor_entry = { ip_address, alias }; if (op == SET_COMMAND) diff --git a/orchagent/routeorch.cpp b/orchagent/routeorch.cpp index 0f688a64d0..4d63c57237 100644 --- a/orchagent/routeorch.cpp +++ b/orchagent/routeorch.cpp @@ -119,23 +119,9 @@ RouteOrch::RouteOrch(DBConnector *db, vector &tableNames, SWSS_LOG_NOTICE("Create IPv6 default route with packet action drop"); - /* All the interfaces have the same MAC address and hence the same - * auto-generated link-local ipv6 address with eui64 interface-id. - * Hence add a single /128 route entry for the link-local interface - * address pointing to the CPU port. - */ - IpPrefix linklocal_prefix = getLinkLocalEui64Addr(); - - addLinkLocalRouteToMe(gVirtualRouterId, linklocal_prefix); - - /* Add fe80::/10 subnet route to forward all link-local packets - * destined to us, to CPU */ IpPrefix default_link_local_prefix("fe80::/10"); addLinkLocalRouteToMe(gVirtualRouterId, default_link_local_prefix); - - /* TODO: Add the link-local fe80::/10 route to cpu in every VRF created from - * vrforch::addOperation. */ } std::string RouteOrch::getLinkLocalEui64Addr(void) @@ -205,6 +191,27 @@ void RouteOrch::addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu", linklocal_prefix.to_string().c_str()); } +void RouteOrch::delLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix) +{ + sai_route_entry_t unicast_route_entry; + unicast_route_entry.switch_id = gSwitchId; + unicast_route_entry.vr_id = vrf_id; + copy(unicast_route_entry.destination, linklocal_prefix); + subnet(unicast_route_entry.destination, unicast_route_entry.destination); + + sai_status_t status = sai_route_api->remove_route_entry(&unicast_route_entry); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to delete link local ipv6 route %s to cpu, rv:%d", + linklocal_prefix.getIp().to_string().c_str(), status); + return; + } + + gCrmOrch->decCrmResUsedCounter(CrmResourceType::CRM_IPV6_ROUTE); + + SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu", linklocal_prefix.to_string().c_str()); +} + bool RouteOrch::hasNextHopGroup(const NextHopGroupKey& nexthops) const { return m_syncdNextHopGroups.find(nexthops) != m_syncdNextHopGroups.end(); diff --git a/orchagent/routeorch.h b/orchagent/routeorch.h index aca68624f6..af6bb15050 100644 --- a/orchagent/routeorch.h +++ b/orchagent/routeorch.h @@ -152,6 +152,9 @@ class RouteOrch : public Orch, public Subject bool createFineGrainedNextHopGroup(sai_object_id_t &next_hop_group_id, vector &nhg_attrs); bool removeFineGrainedNextHopGroup(sai_object_id_t &next_hop_group_id); + void addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix); + void delLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix); + private: SwitchOrch *m_switchOrch; NeighOrch *m_neighOrch; @@ -189,7 +192,6 @@ class RouteOrch : public Orch, public Subject bool removeLabelRoutePost(const LabelRouteBulkContext& ctx); std::string getLinkLocalEui64Addr(void); - void addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix); void doTask(Consumer& consumer); void doLabelTask(Consumer& consumer); diff --git a/orchagent/vrforch.cpp b/orchagent/vrforch.cpp index 19ca5c0fd8..435c3c34ff 100644 --- a/orchagent/vrforch.cpp +++ b/orchagent/vrforch.cpp @@ -12,6 +12,7 @@ #include "vrforch.h" #include "vxlanorch.h" #include "directory.h" +#include "routeorch.h" using namespace std; using namespace swss; @@ -20,6 +21,7 @@ extern sai_virtual_router_api_t* sai_virtual_router_api; extern sai_object_id_t gSwitchId; extern Directory gDirectory; extern PortsOrch* gPortsOrch; +extern RouteOrch* gRouteOrch; bool VRFOrch::addOperation(const Request& request) { @@ -101,6 +103,12 @@ bool VRFOrch::addOperation(const Request& request) } } + /* Add link-local fe80::/10 CPU route for the VRF. */ + IpPrefix default_link_local_prefix("fe80::/10"); + + gRouteOrch->addLinkLocalRouteToMe(router_id, default_link_local_prefix); + SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); + vrf_table_[vrf_name].vrf_id = router_id; vrf_table_[vrf_name].ref_count = 0; vrf_id_table_[router_id] = vrf_name; @@ -164,7 +172,14 @@ bool VRFOrch::delOperation(const Request& request) if (vrf_table_[vrf_name].ref_count) return false; + /* Delete link-local fe80::/10 CPU route for the VRF. */ + IpPrefix default_link_local_prefix("fe80::/10"); + sai_object_id_t router_id = vrf_table_[vrf_name].vrf_id; + + gRouteOrch->delLinkLocalRouteToMe(router_id, default_link_local_prefix); + SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); + sai_status_t status = sai_virtual_router_api->remove_virtual_router(router_id); if (status != SAI_STATUS_SUCCESS) { From b0257fccf81dd468a9f2e87a4a233613e6d5f3ec Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Tue, 20 Oct 2020 22:50:51 -0700 Subject: [PATCH 02/31] Updated pytest for ipv6 link-local. Signed-off-by: Akhilesh Samineni --- tests/test_interface.py | 269 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 245 insertions(+), 24 deletions(-) diff --git a/tests/test_interface.py b/tests/test_interface.py index ac1446481a..902f262927 100644 --- a/tests/test_interface.py +++ b/tests/test_interface.py @@ -142,10 +142,26 @@ def test_PortInterfaceAddRemoveIpv6Address(self, dvs, testlog): # check application database tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "fc00::1/126" - (status, fvs) = tbl.get(tbl.getKeys()[0]) + # contains 2 keys, global and link-local + assert len(intf_entries) == 2 + + local_index = 0 + global_index = 0 + link_local_address = "" + + if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": + global_index = 1 + link_local_address = intf_entries[0] + assert True + elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": + local_index = 1 + link_local_address = intf_entries[1] + assert True + else: + assert False + + (status, fvs) = tbl.get(tbl.getKeys()[global_index]) assert status == True assert len(fvs) == 2 for fv in fvs: @@ -156,6 +172,17 @@ def test_PortInterfaceAddRemoveIpv6Address(self, dvs, testlog): else: assert False + (status, fvs) = tbl.get(tbl.getKeys()[local_index]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "local" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + # check ASIC router interface database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") intf_entries = tbl.getKeys() @@ -174,6 +201,11 @@ def test_PortInterfaceAddRemoveIpv6Address(self, dvs, testlog): if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": assert fv[1] == "9100" + link_local_address = link_local_address.split('/') + # Stored subnet as 128 in ASIC_DB + link_local_address[1] = '128' + link_local_address = link_local_address[0] + '/' + link_local_address[1] + # check ASIC route database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") for key in tbl.getKeys(): @@ -182,8 +214,10 @@ def test_PortInterfaceAddRemoveIpv6Address(self, dvs, testlog): subnet_found = True if route["dest"] == "fc00::1/128": ip2me_found = True + if route["dest"] == link_local_address: + link_local_found = True - assert subnet_found and ip2me_found + assert subnet_found and ip2me_found and link_local_found # remove IP from interface self.remove_ip_address("Ethernet8", "fc00::1/126") @@ -212,6 +246,8 @@ def test_PortInterfaceAddRemoveIpv6Address(self, dvs, testlog): assert False if route["dest"] == "fc00::1/128": assert False + if route["dest"] == link_local_address: + assert False def test_PortInterfaceAddRemoveIpv4Address(self, dvs, testlog): self.setup_db(dvs) @@ -371,6 +407,7 @@ def test_PortInterfaceSetMtu(self, dvs, testlog): def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): self.setup_db(dvs) + # bring up interface self.set_admin_status(dvs, "Ethernet8", "up") @@ -403,10 +440,25 @@ def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "fc00::1/126" + # contains 2 keys, global and link-local + assert len(intf_entries) == 2 - (status, fvs) = tbl.get(tbl.getKeys()[0]) + local_index = 0 + global_index = 0 + link_local_address = "" + + if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": + global_index = 1 + link_local_address = intf_entries[0] + assert True + elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": + local_index = 1 + link_local_address = intf_entries[1] + assert True + else: + assert False + + (status, fvs) = tbl.get(tbl.getKeys()[global_index]) assert status == True assert len(fvs) == 2 for fv in fvs: @@ -417,6 +469,17 @@ def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): else: assert False + (status, fvs) = tbl.get(tbl.getKeys()[local_index]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "local" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + # check ASIC router interface database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") intf_entries = tbl.getKeys() @@ -437,6 +500,11 @@ def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": assert fv[1] == vrf_oid + link_local_address = link_local_address.split('/') + # Stored subnet as 128 in ASIC_DB + link_local_address[1] = '128' + link_local_address = link_local_address[0] + '/' + link_local_address[1] + # check ASIC route database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") for key in tbl.getKeys(): @@ -447,8 +515,11 @@ def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): if route["dest"] == "fc00::1/128": ip2me_found = True assert route["vr"] == vrf_oid + if route["dest"] == link_local_address: + link_local_found = True + assert route["vr"] == vrf_oid - assert subnet_found and ip2me_found + assert subnet_found and ip2me_found and link_local_found # remove IP from interface self.remove_ip_address("Ethernet8", "fc00::1/126") @@ -488,6 +559,8 @@ def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): assert False if route["dest"] == "fc00::1/128": assert False + if route["dest"] == link_local_address: + assert False def test_PortInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): self.setup_db(dvs) @@ -777,10 +850,26 @@ def test_LagInterfaceAddRemoveIpv6Address(self, dvs, testlog): # check application database tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "fc00::1/126" - (status, fvs) = tbl.get(tbl.getKeys()[0]) + # contains 2 keys, global and link-local + assert len(intf_entries) == 2 + + local_index = 0 + global_index = 0 + link_local_address = "" + + if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": + global_index = 1 + link_local_address = intf_entries[0] + assert True + elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": + local_index = 1 + link_local_address = intf_entries[1] + assert True + else: + assert False + + (status, fvs) = tbl.get(tbl.getKeys()[global_index]) assert status == True assert len(fvs) == 2 for fv in fvs: @@ -791,6 +880,17 @@ def test_LagInterfaceAddRemoveIpv6Address(self, dvs, testlog): else: assert False + (status, fvs) = tbl.get(tbl.getKeys()[local_index]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "local" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + # check ASIC router interface database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") intf_entries = tbl.getKeys() @@ -809,6 +909,11 @@ def test_LagInterfaceAddRemoveIpv6Address(self, dvs, testlog): if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": assert fv[1] == "9100" + link_local_address = link_local_address.split('/') + # Stored subnet as 128 in ASIC_DB + link_local_address[1] = '128' + link_local_address = link_local_address[0] + '/' + link_local_address[1] + # check ASIC route database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") for key in tbl.getKeys(): @@ -817,8 +922,10 @@ def test_LagInterfaceAddRemoveIpv6Address(self, dvs, testlog): subnet_found = True if route["dest"] == "fc00::1/128": ip2me_found = True + if route["dest"] == link_local_address: + link_local_found = True - assert subnet_found and ip2me_found + assert subnet_found and ip2me_found and link_local_found # remove IP from interface self.remove_ip_address("PortChannel001", "fc00::1/126") @@ -844,6 +951,8 @@ def test_LagInterfaceAddRemoveIpv6Address(self, dvs, testlog): assert False if route["dest"] == "fc00::1/128": assert False + if route["dest"] == link_local_address: + assert False # remove port channel self.remove_port_channel("PortChannel001") @@ -1033,10 +1142,26 @@ def test_LagInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): # check application database tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "fc00::1/126" - (status, fvs) = tbl.get(tbl.getKeys()[0]) + # contains 2 keys, global and link-local + assert len(intf_entries) == 2 + + local_index = 0 + global_index = 0 + link_local_address = "" + + if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": + global_index = 1 + link_local_address = intf_entries[0] + assert True + elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": + local_index = 1 + link_local_address = intf_entries[1] + assert True + else: + assert False + + (status, fvs) = tbl.get(tbl.getKeys()[global_index]) assert status == True assert len(fvs) == 2 for fv in fvs: @@ -1047,6 +1172,17 @@ def test_LagInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): else: assert False + (status, fvs) = tbl.get(tbl.getKeys()[local_index]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "local" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + # check ASIC router interface database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") intf_entries = tbl.getKeys() @@ -1066,6 +1202,12 @@ def test_LagInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): assert fv[1] == "9100" if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": assert fv[1] == vrf_oid + + link_local_address = link_local_address.split('/') + # Stored subnet as 128 in ASIC_DB + link_local_address[1] = '128' + link_local_address = link_local_address[0] + '/' + link_local_address[1] + # check ASIC route database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") for key in tbl.getKeys(): @@ -1076,8 +1218,11 @@ def test_LagInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): if route["dest"] == "fc00::1/128": ip2me_found = True assert route["vr"] == vrf_oid + if route["dest"] == link_local_address: + link_local_found = True + assert route["vr"] == vrf_oid - assert subnet_found and ip2me_found + assert subnet_found and ip2me_found and link_local_found # remove IP from interface self.remove_ip_address("PortChannel001", "fc00::1/126") @@ -1110,10 +1255,13 @@ def test_LagInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): assert False if route["dest"] == "fc00::1/128": assert False + if route["dest"] == link_local_address: + assert False # remove port channel self.remove_port_channel("PortChannel001") + def test_LagInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): self.setup_db(dvs) @@ -1287,10 +1435,26 @@ def test_VLanInterfaceAddRemoveIpv6Address(self, dvs, testlog): # check application database tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "fc00::1/126" - (status, fvs) = tbl.get(tbl.getKeys()[0]) + # contains 2 keys, global and link-local + assert len(intf_entries) == 2 + + local_index = 0 + global_index = 0 + link_local_address = "" + + if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": + global_index = 1 + link_local_address = intf_entries[0] + assert True + elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": + local_index = 1 + link_local_address = intf_entries[1] + assert True + else: + assert False + + (status, fvs) = tbl.get(tbl.getKeys()[global_index]) assert status == True assert len(fvs) == 2 for fv in fvs: @@ -1301,6 +1465,17 @@ def test_VLanInterfaceAddRemoveIpv6Address(self, dvs, testlog): else: assert False + (status, fvs) = tbl.get(tbl.getKeys()[local_index]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "local" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + # check ASIC router interface database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") intf_entries = tbl.getKeys() @@ -1317,6 +1492,11 @@ def test_VLanInterfaceAddRemoveIpv6Address(self, dvs, testlog): if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": assert fv[1] == vlan_oid + link_local_address = link_local_address.split('/') + # Stored subnet as 128 in ASIC_DB + link_local_address[1] = '128' + link_local_address = link_local_address[0] + '/' + link_local_address[1] + # check ASIC route database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") for key in tbl.getKeys(): @@ -1325,8 +1505,10 @@ def test_VLanInterfaceAddRemoveIpv6Address(self, dvs, testlog): subnet_found = True if route["dest"] == "fc00::1/128": ip2me_found = True + if route["dest"] == link_local_address: + link_local_found = True - assert subnet_found and ip2me_found + assert subnet_found and ip2me_found and link_local_found # remove IP from interface self.remove_ip_address("Vlan10", "fc00::1/126") @@ -1361,6 +1543,8 @@ def test_VLanInterfaceAddRemoveIpv6Address(self, dvs, testlog): assert False if route["dest"] == "fc00::1/128": assert False + if route["dest"] == link_local_address: + assert False def test_VLanInterfaceAddRemoveIpv4Address(self, dvs, testlog): self.setup_db(dvs) @@ -1512,10 +1696,26 @@ def test_VLanInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): # check application database tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "fc00::1/126" - (status, fvs) = tbl.get(tbl.getKeys()[0]) + # contains 2 keys, global and link-local + assert len(intf_entries) == 2 + + local_index = 0 + global_index = 0 + link_local_address = "" + + if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": + global_index = 1 + link_local_address = intf_entries[0] + assert True + elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": + local_index = 1 + link_local_address = intf_entries[1] + assert True + else: + assert False + + (status, fvs) = tbl.get(tbl.getKeys()[global_index]) assert status == True assert len(fvs) == 2 for fv in fvs: @@ -1526,6 +1726,17 @@ def test_VLanInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): else: assert False + (status, fvs) = tbl.get(tbl.getKeys()[local_index]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "local" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + # check ASIC router interface database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") intf_entries = tbl.getKeys() @@ -1544,6 +1755,11 @@ def test_VLanInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": assert fv[1] == vrf_oid + link_local_address = link_local_address.split('/') + # Stored subnet as 128 in ASIC_DB + link_local_address[1] = '128' + link_local_address = link_local_address[0] + '/' + link_local_address[1] + # check ASIC route database tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") for key in tbl.getKeys(): @@ -1554,8 +1770,11 @@ def test_VLanInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): if route["dest"] == "fc00::1/128": ip2me_found = True assert route["vr"] == vrf_oid + if route["dest"] == link_local_address: + link_local_found = True + assert route["vr"] == vrf_oid - assert subnet_found and ip2me_found + assert subnet_found and ip2me_found and link_local_found # remove IP from interface self.remove_ip_address("Vlan10", "fc00::1/126") @@ -1597,6 +1816,8 @@ def test_VLanInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): assert False if route["dest"] == "fc00::1/128": assert False + if route["dest"] == link_local_address: + assert False def test_VLanInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): self.setup_db(dvs) From c8fabd85b1661ffca93affa11725158616f9c29e Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Thu, 22 Oct 2020 00:07:00 -0700 Subject: [PATCH 03/31] Few fixes for docker-vs pytest. Signed-off-by: Akhilesh Samineni --- orchagent/routeorch.cpp | 2 ++ tests/test_interface.py | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/orchagent/routeorch.cpp b/orchagent/routeorch.cpp index 4d63c57237..b53e0809af 100644 --- a/orchagent/routeorch.cpp +++ b/orchagent/routeorch.cpp @@ -119,6 +119,8 @@ RouteOrch::RouteOrch(DBConnector *db, vector &tableNames, SWSS_LOG_NOTICE("Create IPv6 default route with packet action drop"); + /* Add fe80::/10 subnet route to forward all link-local packets + * destined to us, to CPU */ IpPrefix default_link_local_prefix("fe80::/10"); addLinkLocalRouteToMe(gVirtualRouterId, default_link_local_prefix); diff --git a/tests/test_interface.py b/tests/test_interface.py index 902f262927..99f0c75724 100644 --- a/tests/test_interface.py +++ b/tests/test_interface.py @@ -36,7 +36,7 @@ def create_vrf(self, vrf_name): tbl = swsscommon.Table(self.cdb, "VRF") fvs = swsscommon.FieldValuePairs([('empty', 'empty')]) tbl.set(vrf_name, fvs) - time.sleep(1) + time.sleep(2) tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") current_entries = set(tbl.getKeys()) @@ -46,7 +46,7 @@ def create_vrf(self, vrf_name): def remove_vrf(self, vrf_name): tbl = swsscommon.Table(self.cdb, "VRF") tbl._del(vrf_name) - time.sleep(1) + time.sleep(2) def create_l3_intf(self, interface, vrf_name): if interface.startswith("PortChannel"): @@ -63,7 +63,7 @@ def create_l3_intf(self, interface, vrf_name): fvs = swsscommon.FieldValuePairs([("vrf_name", vrf_name)]) tbl = swsscommon.Table(self.cdb, tbl_name) tbl.set(interface, fvs) - time.sleep(1) + time.sleep(2) def remove_l3_intf(self, interface): if interface.startswith("PortChannel"): @@ -76,7 +76,7 @@ def remove_l3_intf(self, interface): tbl_name = "INTERFACE" tbl = swsscommon.Table(self.cdb, tbl_name) tbl._del(interface) - time.sleep(1) + time.sleep(2) def add_ip_address(self, interface, ip): if interface.startswith("PortChannel"): @@ -90,7 +90,7 @@ def add_ip_address(self, interface, ip): tbl = swsscommon.Table(self.cdb, tbl_name) fvs = swsscommon.FieldValuePairs([("NULL", "NULL")]) tbl.set(interface + "|" + ip, fvs) - time.sleep(1) + time.sleep(2) def remove_ip_address(self, interface, ip): if interface.startswith("PortChannel"): @@ -103,7 +103,7 @@ def remove_ip_address(self, interface, ip): tbl_name = "INTERFACE" tbl = swsscommon.Table(self.cdb, tbl_name) tbl._del(interface + "|" + ip) - time.sleep(1) + time.sleep(2) def set_mtu(self, interface, mtu): if interface.startswith("PortChannel"): From 0b9e8d13ab5b4e17e4c79ac1b77a01ce67063764 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Mon, 5 Apr 2021 11:54:34 -0700 Subject: [PATCH 04/31] Corrected the changes as per design change. --- cfgmgr/Makefile.am | 4 +- cfgmgr/intfmgr.cpp | 208 +--- cfgmgr/intfmgr.h | 10 +- cfgmgr/intfmgrd.cpp | 15 - orchagent/routeorch.cpp | 12 + orchagent/routeorch.h | 3 +- orchagent/vrforch.cpp | 19 +- tests/test_interface.py | 2191 --------------------------------------- 8 files changed, 34 insertions(+), 2428 deletions(-) delete mode 100644 tests/test_interface.py diff --git a/cfgmgr/Makefile.am b/cfgmgr/Makefile.am index 91d0eeb928..d1ea5978c1 100644 --- a/cfgmgr/Makefile.am +++ b/cfgmgr/Makefile.am @@ -39,8 +39,8 @@ portmgrd_LDADD = -lswsscommon $(SAIMETA_LIBS) intfmgrd_SOURCES = intfmgrd.cpp intfmgr.cpp $(top_srcdir)/orchagent/orch.cpp $(top_srcdir)/orchagent/request_parser.cpp shellcmd.h intfmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) -intfmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(LIBNL_CPPFLAGS) -intfmgrd_LDADD = -lswsscommon $(SAIMETA_LIBS) $(LIBNL_LIBS) +intfmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) +intfmgrd_LDADD = -lswsscommon $(SAIMETA_LIBS) buffermgrd_SOURCES = buffermgrd.cpp buffermgr.cpp buffermgrdyn.cpp $(top_srcdir)/orchagent/orch.cpp $(top_srcdir)/orchagent/request_parser.cpp shellcmd.h buffermgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) diff --git a/cfgmgr/intfmgr.cpp b/cfgmgr/intfmgr.cpp index a182e58663..8b2f12c7fc 100644 --- a/cfgmgr/intfmgr.cpp +++ b/cfgmgr/intfmgr.cpp @@ -9,11 +9,6 @@ #include "shellcmd.h" #include "macaddress.h" #include "warm_restart.h" -#include -#include -#include -#include "netmsg.h" -#include "linkcache.h" using namespace std; using namespace swss; @@ -21,14 +16,11 @@ using namespace swss; #define VLAN_PREFIX "Vlan" #define LAG_PREFIX "PortChannel" #define LOOPBACK_PREFIX "Loopback" -#define LINUX_LOOPBACK "lo" #define VNET_PREFIX "Vnet" #define MTU_INHERITANCE "0" #define VRF_PREFIX "Vrf" #define VRF_MGMT "mgmt" -#define ETHERNET_PREFIX "Ethernet" -#define MAX_ADDR_SIZE 64 #define LOOPBACK_DEFAULT_MTU_STR "65536" IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector &tableNames) : @@ -286,45 +278,6 @@ bool IntfMgr::isIntfChangeVrf(const string &alias, const string &vrfName) return false; } -bool IntfMgr::ifManualIPv6AddrsConfigured(const string &alias) -{ - stringstream addrshow, linkshow; - string res; - int numOfAddrs, linkUp; - - addrshow << IP_CMD << " -6 address show " << alias << " | grep inet | wc -l"; - EXEC_WITH_ERROR_THROW(addrshow.str(), res); - - numOfAddrs = std::stoi(res); - - linkshow << IP_CMD << " -6 link show " << alias << " | grep UP | wc -l"; - EXEC_WITH_ERROR_THROW(linkshow.str(), res); - - linkUp = std::stoi(res); - - /* IPv6 auto link local address is removed by the kernel on link down, but manually - * configured IPv6 addresses (gloabl or link-local) are not removed on link down. - * So, to check if manual addresses are configured, check if any addresses - * are there when the link is down, or if > 1 addresses are there when the link is up */ - - if (((numOfAddrs > 1) && (linkUp)) || ((numOfAddrs) && (! linkUp))) - { - return true; - } - return false; -} - -int IntfMgr::getIntfIpv6DisableMode(const string &alias) -{ - stringstream cmd; - string res; - - cmd << "cat /proc/sys/net/ipv6/conf/" << alias << "/disable_ipv6"; - EXEC_WITH_ERROR_THROW(cmd.str(), res); - - return std::stoi(res); -} - void IntfMgr::addHostSubIntf(const string&intf, const string &subIntf, const string &vlan) { stringstream cmd; @@ -618,16 +571,8 @@ bool IntfMgr::doIntfGeneralTask(const vector& keys, /* Set ipv6 mode */ if (!ipv6_link_local_mode.empty()) { - if ((ipv6_link_local_mode.compare("enable") == 0) && - (getIntfIpv6DisableMode(alias) == 1)) - { - setIntfIpv6Mode(alias, ipv6_link_local_mode); - } - else if ((ipv6_link_local_mode.compare("disable") == 0) && - (ifManualIPv6AddrsConfigured(alias) == false)) - { - setIntfIpv6Mode(alias, ipv6_link_local_mode); - } + FieldValueTuple fvTuple("ipv6_use_link_local_only", ipv6_link_local_mode); + data.push_back(fvTuple); } } @@ -751,13 +696,6 @@ bool IntfMgr::doIntfGeneralTask(const vector& keys, delLoopbackIntf(alias); m_loopbackIntfList.erase(alias); } - else - { - if (getIntfIpv6DisableMode(alias) == 0) - { - setIntfIpv6Mode(alias, "disable"); - } - } if (!parentAlias.empty()) { @@ -800,15 +738,6 @@ bool IntfMgr::doIntfAddrTask(const vector& keys, return false; } - /* Enable ipv6 on the interface in the kernel first before adding the manually - * configured address, if use-link-local-only mode is not already enabled on the interface. */ - if ((ip_prefix.isV4() == false) && - (isIpv6LinkLocalModeEnabled(alias) == false) && - (getIntfIpv6DisableMode(alias) == 1)) - { - setIntfIpv6Mode(alias, "enable"); - } - setIntfIp(alias, "add", ip_prefix); std::vector fvVector; @@ -834,16 +763,6 @@ bool IntfMgr::doIntfAddrTask(const vector& keys, m_appIntfTableProducer.del(appKey); m_stateIntfTable.del(keys[0] + state_db_key_delimiter + keys[1]); } - - /* If all manually configured addresses on the interface are removed, - * disable ipv6 on the interface to remove the auto link-local ipv6 address, - * provided use-link-local-only mode is not enabled on the interface. */ - if ((ip_prefix.isV4() == false) && - (isIpv6LinkLocalModeEnabled(alias) == false) && - (ifManualIPv6AddrsConfigured(alias) == false)) - { - setIntfIpv6Mode(alias, "disable"); - } } else { @@ -917,126 +836,3 @@ void IntfMgr::doTask(Consumer &consumer) setWarmReplayDoneState(); } } - -bool IntfMgr::isIpv6LinkLocalModeEnabled(const string &alias) -{ - vector fv; - Table *cfgTable; - - if (!alias.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX)) - { - cfgTable = &m_cfgVlanIntfTable; - } - else if (!alias.compare(0, strlen(LAG_PREFIX), LAG_PREFIX)) - { - cfgTable = &m_cfgLagIntfTable; - } - else if (!alias.compare(0, strlen(ETHERNET_PREFIX), ETHERNET_PREFIX)) - { - cfgTable = &m_cfgIntfTable; - } - else - { - return false; - } - if ((*cfgTable).get(alias, fv)) - { - for (auto idx : fv) - { - if (fvField(idx) == "ipv6_use_link_local_only") - { - if (fvValue(idx) == "enable") - { - return true; - } - } - } - } - return false; -} - -// Set Interface IPv6 mode -void IntfMgr::setIntfIpv6Mode(const string &port, const string &mode) -{ - stringstream cmd; - string res; - int ret; - - SWSS_LOG_INFO("Setting interface ipv6 mode on interface %s to %s", port.c_str(), mode.c_str()); - if (mode == "enable") - { - cmd << "sysctl -w net.ipv6.conf." << port << ".disable_ipv6=0"; - } - else - { - cmd << "sysctl -w net.ipv6.conf." << port << ".disable_ipv6=1"; - } - ret = swss::exec(cmd.str(), res); - if (ret) - { - SWSS_LOG_INFO("Command '%s' failed with rc %d %s", cmd.str().c_str(), ret, res.c_str()); - } -} - -void IntfMgr::onMsg(int nlmsg_type, struct nl_object *obj) -{ - char addrStr[MAX_ADDR_SIZE + 1] = {0}; - struct rtnl_addr *addr = (struct rtnl_addr *)obj; - string intfTableKey; - string stateTableKey; - string intfName; - string scope = "local"; - string family = IPV6_NAME; - - if ((nlmsg_type != RTM_NEWADDR) && - (nlmsg_type != RTM_DELADDR)) - { - return; - } - - /* Sync IPv6 Link local routes only */ - if ((rtnl_addr_get_family(addr) != AF_INET6) || - (rtnl_addr_get_scope(addr) != RT_SCOPE_LINK)) - { - return; - } - - intfName = LinkCache::getInstance().ifindexToName(rtnl_addr_get_ifindex(addr)); - if (0 != intfName.compare(0, strlen(ETHERNET_PREFIX), ETHERNET_PREFIX) && - 0 != intfName.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX) && - 0 != intfName.compare(0, strlen(LAG_PREFIX), LAG_PREFIX) && - 0 != intfName.compare(0, strlen(LINUX_LOOPBACK), LINUX_LOOPBACK)) - { - return; - } - - nl_addr2str(rtnl_addr_get_local(addr), addrStr, MAX_ADDR_SIZE); - - intfTableKey = intfName; - intfTableKey+= ":"; - intfTableKey+= addrStr; - - stateTableKey = intfName; - stateTableKey+= "|"; - stateTableKey+= addrStr; - - if (nlmsg_type == RTM_DELADDR) - { - m_appIntfTableProducer.del(intfTableKey); - m_stateIntfTable.del(stateTableKey); - - return; - } - - SWSS_LOG_INFO("IPv6 Link local address %s added on interface %s", addrStr, intfName.c_str()); - - std::vector fv; - FieldValueTuple f("family", family); - FieldValueTuple s("scope", scope); - - fv.push_back(s); - fv.push_back(f); - m_appIntfTableProducer.set(intfTableKey, fv); - m_stateIntfTable.hset(stateTableKey, "state", "ok"); -} - diff --git a/cfgmgr/intfmgr.h b/cfgmgr/intfmgr.h index 94d8daea7b..655fb4deeb 100644 --- a/cfgmgr/intfmgr.h +++ b/cfgmgr/intfmgr.h @@ -4,7 +4,6 @@ #include "dbconnector.h" #include "producerstatetable.h" #include "orch.h" -#include "netmsg.h" #include #include @@ -12,18 +11,16 @@ namespace swss { -class IntfMgr : public Orch, public NetMsg +class IntfMgr : public Orch { public: IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector &tableNames); using Orch::doTask; - virtual void onMsg(int nlmsg_type, struct nl_object *obj); private: ProducerStateTable m_appIntfTableProducer; Table m_cfgIntfTable, m_cfgVlanIntfTable, m_cfgLagIntfTable, m_cfgLoopbackIntfTable; Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateVrfTable, m_stateIntfTable; - Table m_cfgIntfTable, m_cfgVlanIntfTable, m_cfgLagIntfTable; std::set m_subIntfList; std::set m_loopbackIntfList; @@ -59,11 +56,6 @@ class IntfMgr : public Orch, public NetMsg bool setIntfProxyArp(const std::string &alias, const std::string &proxy_arp); bool setIntfGratArp(const std::string &alias, const std::string &grat_arp); - int getIntfIpv6DisableMode(const std::string &alias); - bool ifManualIPv6AddrsConfigured(const std::string &alias); - bool isIpv6LinkLocalModeEnabled(const std::string &alias); - void setIntfIpv6Mode(const std::string &port, const std::string &mode); - bool m_replayDone {false}; }; diff --git a/cfgmgr/intfmgrd.cpp b/cfgmgr/intfmgrd.cpp index 889349fcf8..d6ed18526e 100644 --- a/cfgmgr/intfmgrd.cpp +++ b/cfgmgr/intfmgrd.cpp @@ -9,8 +9,6 @@ #include #include #include "warm_restart.h" -#include "netdispatcher.h" -#include "netlink.h" using namespace std; using namespace swss; @@ -61,9 +59,6 @@ int main(int argc, char **argv) IntfMgr intfmgr(&cfgDb, &appDb, &stateDb, cfg_intf_tables); - NetDispatcher::getInstance().registerMessageHandler(RTM_NEWADDR, &intfmgr); - NetDispatcher::getInstance().registerMessageHandler(RTM_DELADDR, &intfmgr); - // TODO: add tables in stateDB which interface depends on to monitor list std::vector cfgOrchList = {&intfmgr}; @@ -73,12 +68,6 @@ int main(int argc, char **argv) s.addSelectables(o->getSelectables()); } - NetLink netlink; - netlink.registerGroup(RTNLGRP_IPV4_IFADDR); - netlink.registerGroup(RTNLGRP_IPV6_IFADDR); - - s.addSelectable(&netlink); - SWSS_LOG_NOTICE("starting main loop"); while (true) { @@ -91,10 +80,6 @@ int main(int argc, char **argv) SWSS_LOG_NOTICE("Error: %s!", strerror(errno)); continue; } - if (sel == &netlink) - { - continue; - } if (ret == Select::TIMEOUT) { intfmgr.doTask(); diff --git a/orchagent/routeorch.cpp b/orchagent/routeorch.cpp index b53e0809af..3cf490a5fc 100644 --- a/orchagent/routeorch.cpp +++ b/orchagent/routeorch.cpp @@ -119,11 +119,23 @@ RouteOrch::RouteOrch(DBConnector *db, vector &tableNames, SWSS_LOG_NOTICE("Create IPv6 default route with packet action drop"); + /* All the interfaces have the same MAC address and hence the same + * auto-generated link-local ipv6 address with eui64 interface-id. + * Hence add a single /128 route entry for the link-local interface + * address pointing to the CPU port. + */ + IpPrefix linklocal_prefix = getLinkLocalEui64Addr(); + + addLinkLocalRouteToMe(gVirtualRouterId, linklocal_prefix); + SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu", linklocal_prefix.to_string().c_str()); + /* Add fe80::/10 subnet route to forward all link-local packets * destined to us, to CPU */ IpPrefix default_link_local_prefix("fe80::/10"); addLinkLocalRouteToMe(gVirtualRouterId, default_link_local_prefix); + SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu", default_link_local_prefix.to_string().c_str()); + } std::string RouteOrch::getLinkLocalEui64Addr(void) diff --git a/orchagent/routeorch.h b/orchagent/routeorch.h index af6bb15050..20e79699d5 100644 --- a/orchagent/routeorch.h +++ b/orchagent/routeorch.h @@ -154,6 +154,7 @@ class RouteOrch : public Orch, public Subject void addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix); void delLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix); + std::string getLinkLocalEui64Addr(void); private: SwitchOrch *m_switchOrch; @@ -191,8 +192,6 @@ class RouteOrch : public Orch, public Subject bool addLabelRoutePost(const LabelRouteBulkContext& ctx, const NextHopGroupKey &nextHops); bool removeLabelRoutePost(const LabelRouteBulkContext& ctx); - std::string getLinkLocalEui64Addr(void); - void doTask(Consumer& consumer); void doLabelTask(Consumer& consumer); }; diff --git a/orchagent/vrforch.cpp b/orchagent/vrforch.cpp index 435c3c34ff..a45b0038de 100644 --- a/orchagent/vrforch.cpp +++ b/orchagent/vrforch.cpp @@ -109,6 +109,15 @@ bool VRFOrch::addOperation(const Request& request) gRouteOrch->addLinkLocalRouteToMe(router_id, default_link_local_prefix); SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); + /* All the interfaces have the same MAC address and hence the same + * auto-generated link-local ipv6 address with eui64 interface-id. + * Hence add a single /128 route entry for the link-local interface + * address pointing to the CPU port. + */ + IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); + gRouteOrch->addLinkLocalRouteToMe(router_id, linklocal_prefix); + SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); + vrf_table_[vrf_name].vrf_id = router_id; vrf_table_[vrf_name].ref_count = 0; vrf_id_table_[router_id] = vrf_name; @@ -172,11 +181,15 @@ bool VRFOrch::delOperation(const Request& request) if (vrf_table_[vrf_name].ref_count) return false; - /* Delete link-local fe80::/10 CPU route for the VRF. */ - IpPrefix default_link_local_prefix("fe80::/10"); - sai_object_id_t router_id = vrf_table_[vrf_name].vrf_id; + /* Delete link-local ipv6 address with eui64 /128 CPU route for the VRF. */ + IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); + gRouteOrch->delLinkLocalRouteToMe(router_id, linklocal_prefix); + SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); + + /* Delete link-local fe80::/10 CPU route for the VRF. */ + IpPrefix default_link_local_prefix("fe80::/10"); gRouteOrch->delLinkLocalRouteToMe(router_id, default_link_local_prefix); SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); diff --git a/tests/test_interface.py b/tests/test_interface.py deleted file mode 100644 index 99f0c75724..0000000000 --- a/tests/test_interface.py +++ /dev/null @@ -1,2191 +0,0 @@ -import time -import json -import pytest - -from swsscommon import swsscommon - -class TestRouterInterface(object): - def setup_db(self, dvs): - self.pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0) - self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0) - self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) - - def set_admin_status(self, dvs, interface, status): - if interface.startswith("PortChannel"): - tbl_name = "PORTCHANNEL" - elif interface.startswith("Vlan"): - tbl_name = "VLAN" - else: - tbl_name = "PORT" - tbl = swsscommon.Table(self.cdb, tbl_name) - fvs = swsscommon.FieldValuePairs([("admin_status", status)]) - tbl.set(interface, fvs) - time.sleep(1) - - # when using FRR, route cannot be inserted if the neighbor is not - # connected. thus it is mandatory to force the interface up manually - if interface.startswith("PortChannel"): - dvs.runcmd("bash -c 'echo " + ("1" if status == "up" else "0") +\ - " > /sys/class/net/" + interface + "/carrier'") - time.sleep(1) - - def create_vrf(self, vrf_name): - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - initial_entries = set(tbl.getKeys()) - - tbl = swsscommon.Table(self.cdb, "VRF") - fvs = swsscommon.FieldValuePairs([('empty', 'empty')]) - tbl.set(vrf_name, fvs) - time.sleep(2) - - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - current_entries = set(tbl.getKeys()) - assert len(current_entries - initial_entries) == 1 - return list(current_entries - initial_entries)[0] - - def remove_vrf(self, vrf_name): - tbl = swsscommon.Table(self.cdb, "VRF") - tbl._del(vrf_name) - time.sleep(2) - - def create_l3_intf(self, interface, vrf_name): - if interface.startswith("PortChannel"): - tbl_name = "PORTCHANNEL_INTERFACE" - elif interface.startswith("Vlan"): - tbl_name = "VLAN_INTERFACE" - elif interface.startswith("Loopback"): - tbl_name = "LOOPBACK_INTERFACE" - else: - tbl_name = "INTERFACE" - if len(vrf_name) == 0: - fvs = swsscommon.FieldValuePairs([("NULL", "NULL")]) - else: - fvs = swsscommon.FieldValuePairs([("vrf_name", vrf_name)]) - tbl = swsscommon.Table(self.cdb, tbl_name) - tbl.set(interface, fvs) - time.sleep(2) - - def remove_l3_intf(self, interface): - if interface.startswith("PortChannel"): - tbl_name = "PORTCHANNEL_INTERFACE" - elif interface.startswith("Vlan"): - tbl_name = "VLAN_INTERFACE" - elif interface.startswith("Loopback"): - tbl_name = "LOOPBACK_INTERFACE" - else: - tbl_name = "INTERFACE" - tbl = swsscommon.Table(self.cdb, tbl_name) - tbl._del(interface) - time.sleep(2) - - def add_ip_address(self, interface, ip): - if interface.startswith("PortChannel"): - tbl_name = "PORTCHANNEL_INTERFACE" - elif interface.startswith("Vlan"): - tbl_name = "VLAN_INTERFACE" - elif interface.startswith("Loopback"): - tbl_name = "LOOPBACK_INTERFACE" - else: - tbl_name = "INTERFACE" - tbl = swsscommon.Table(self.cdb, tbl_name) - fvs = swsscommon.FieldValuePairs([("NULL", "NULL")]) - tbl.set(interface + "|" + ip, fvs) - time.sleep(2) - - def remove_ip_address(self, interface, ip): - if interface.startswith("PortChannel"): - tbl_name = "PORTCHANNEL_INTERFACE" - elif interface.startswith("Vlan"): - tbl_name = "VLAN_INTERFACE" - elif interface.startswith("Loopback"): - tbl_name = "LOOPBACK_INTERFACE" - else: - tbl_name = "INTERFACE" - tbl = swsscommon.Table(self.cdb, tbl_name) - tbl._del(interface + "|" + ip) - time.sleep(2) - - def set_mtu(self, interface, mtu): - if interface.startswith("PortChannel"): - tbl_name = "PORTCHANNEL" - elif interface.startswith("Vlan"): - tbl_name = "VLAN" - else: - tbl_name = "PORT" - tbl = swsscommon.Table(self.cdb, tbl_name) - fvs = swsscommon.FieldValuePairs([("mtu", mtu)]) - tbl.set(interface, fvs) - time.sleep(1) - - def test_PortInterfaceAddRemoveIpv6Address(self, dvs, testlog): - self.setup_db(dvs) - - # create interface - self.create_l3_intf("Ethernet8", "") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("Ethernet8") - assert status == True - for fv in fvs: - assert fv[0] != "vrf_name" - - # bring up interface - # NOTE: For IPv6, only when the interface is up will the netlink message - # get generated. - self.set_admin_status(dvs, "Ethernet8", "up") - - # assign IP to interface - self.add_ip_address("Ethernet8", "fc00::1/126") - time.sleep(2) # IPv6 netlink message needs longer time - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - - # contains 2 keys, global and link-local - assert len(intf_entries) == 2 - - local_index = 0 - global_index = 0 - link_local_address = "" - - if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": - global_index = 1 - link_local_address = intf_entries[0] - assert True - elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": - local_index = 1 - link_local_address = intf_entries[1] - assert True - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[global_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[local_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "local" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - - link_local_address = link_local_address.split('/') - # Stored subnet as 128 in ASIC_DB - link_local_address[1] = '128' - link_local_address = link_local_address[0] + '/' + link_local_address[1] - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - subnet_found = True - if route["dest"] == "fc00::1/128": - ip2me_found = True - if route["dest"] == link_local_address: - link_local_found = True - - assert subnet_found and ip2me_found and link_local_found - - # remove IP from interface - self.remove_ip_address("Ethernet8", "fc00::1/126") - - # remove interface - self.remove_l3_intf("Ethernet8") - - # bring down interface - self.set_admin_status(dvs, "Ethernet8", "down") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Ethernet8" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - assert False - if route["dest"] == "fc00::1/128": - assert False - if route["dest"] == link_local_address: - assert False - - def test_PortInterfaceAddRemoveIpv4Address(self, dvs, testlog): - self.setup_db(dvs) - - # bring up interface - self.set_admin_status(dvs, "Ethernet8", "up") - - # create interface - self.create_l3_intf("Ethernet8", "") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("Ethernet8") - assert status == True - for fv in fvs: - assert fv[0] != "vrf_name" - - # assign IP to interface - self.add_ip_address("Ethernet8", "10.0.0.4/31") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "10.0.0.4/31" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - subnet_found = True - if route["dest"] == "10.0.0.4/32": - ip2me_found = True - - assert subnet_found and ip2me_found - - # remove IP from interface - self.remove_ip_address("Ethernet8", "10.0.0.4/31") - - # remove interface - self.remove_l3_intf("Ethernet8") - - # bring down interface - self.set_admin_status(dvs, "Ethernet8", "down") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Ethernet8" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - assert False - if route["dest"] == "10.0.0.4/32": - assert False - - def test_PortInterfaceSetMtu(self, dvs, testlog): - self.setup_db(dvs) - - # create interface - self.create_l3_intf("Ethernet16", "") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("Ethernet16") - assert status == True - for fv in fvs: - assert fv[0] != "vrf_name" - - # assign IP to interface - self.add_ip_address("Ethernet16", "20.0.0.8/29") - - # configure MTU to interface - self.set_mtu("Ethernet16", "8888") - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # assert the new value set to the router interface - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "8888" - - # remove IP from interface - self.remove_ip_address("Ethernet16", "20.0.0.8/29") - - # remove interface - self.remove_l3_intf("Ethernet16") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet16") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Ethernet16" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "20.0.0.8/29": - assert False - if route["dest"] == "20.0.0.8/32": - assert False - - def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): - self.setup_db(dvs) - - - # bring up interface - self.set_admin_status(dvs, "Ethernet8", "up") - - # create vrf - vrf_oid = self.create_vrf("Vrf_0") - - # create interface with vrf - self.create_l3_intf("Ethernet8", "Vrf_0") - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("Ethernet8") - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == "Vrf_0" - vrf_found = True - break - assert vrf_found == True - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Ethernet8 | grep Vrf"]) - assert "Vrf_0" in result - - # assign IP to interface - self.add_ip_address("Ethernet8", "fc00::1/126") - time.sleep(2) # IPv6 netlink message needs longer time - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - - # contains 2 keys, global and link-local - assert len(intf_entries) == 2 - - local_index = 0 - global_index = 0 - link_local_address = "" - - if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": - global_index = 1 - link_local_address = intf_entries[0] - assert True - elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": - local_index = 1 - link_local_address = intf_entries[1] - assert True - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[global_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[local_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "local" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - link_local_address = link_local_address.split('/') - # Stored subnet as 128 in ASIC_DB - link_local_address[1] = '128' - link_local_address = link_local_address[0] + '/' + link_local_address[1] - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - subnet_found = True - assert route["vr"] == vrf_oid - if route["dest"] == "fc00::1/128": - ip2me_found = True - assert route["vr"] == vrf_oid - if route["dest"] == link_local_address: - link_local_found = True - assert route["vr"] == vrf_oid - - assert subnet_found and ip2me_found and link_local_found - - # remove IP from interface - self.remove_ip_address("Ethernet8", "fc00::1/126") - - # remove vrf from interface - self.remove_l3_intf("Ethernet8") - - # remove vrf - self.remove_vrf("Vrf_0") - - # bring down interface - self.set_admin_status(dvs, "Ethernet8", "down") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Ethernet8 | grep Vrf"]) - assert "Vrf_0" not in result - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Ethernet8" - - tbl = swsscommon.Table(self.pdb, "VRF") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - assert False - if route["dest"] == "fc00::1/128": - assert False - if route["dest"] == link_local_address: - assert False - - def test_PortInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): - self.setup_db(dvs) - - # bring up interface - self.set_admin_status(dvs, "Ethernet8", "up") - - # create vrf - vrf_oid = self.create_vrf("Vrf_0") - - # create interface with vrf - self.create_l3_intf("Ethernet8", "Vrf_0") - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("Ethernet8") - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == "Vrf_0" - vrf_found = True - break - assert vrf_found == True - - # assign IP to interface - self.add_ip_address("Ethernet8", "10.0.0.4/31") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "10.0.0.4/31" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - subnet_found = True - assert route["vr"] == vrf_oid - if route["dest"] == "10.0.0.4/32": - ip2me_found = True - assert route["vr"] == vrf_oid - - assert subnet_found and ip2me_found - - # remove IP from interface - self.remove_ip_address("Ethernet8", "10.0.0.4/31") - - # remove interface - self.remove_l3_intf("Ethernet8") - - # remove vrf - self.remove_vrf("Vrf_0") - - # bring down interface - self.set_admin_status(dvs, "Ethernet8", "down") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Ethernet8" - - tbl = swsscommon.Table(self.pdb, "VRF") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - assert False - if route["dest"] == "10.0.0.4/32": - assert False - - def test_PortInterfaceAddSameIpv4AddressWithDiffVrf(self, dvs, testlog): - self.setup_db(dvs) - - for i in [0, 4]: - # record ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - old_intf_entries = set(tbl.getKeys()) - - # record ASIC router entry database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - old_route_entries = set(tbl.getKeys()) - - intf_name = "Ethernet" + str(i) - vrf_name = "Vrf_" + str(i) - - # bring up interface - self.set_admin_status(dvs, intf_name, "up") - - # create vrf - vrf_oid = self.create_vrf(vrf_name) - - # create interface with vrf - self.create_l3_intf(intf_name, vrf_name) - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get(intf_name) - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == vrf_name - vrf_found = True - break - assert vrf_found == True - - # assign IP to interface - self.add_ip_address(intf_name, "10.0.0.4/31") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "10.0.0.4/31" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - current_intf_entries = set(tbl.getKeys()) - intf_entries = list(current_intf_entries - old_intf_entries) - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - current_route_entries = set(tbl.getKeys()) - route_entries = list(current_route_entries - old_route_entries) - - for key in route_entries: - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - subnet_found = True - assert route["vr"] == vrf_oid - if route["dest"] == "10.0.0.4/32": - ip2me_found = True - assert route["vr"] == vrf_oid - - assert subnet_found and ip2me_found - - - for i in [0, 4]: - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - old_intf_entries = set(tbl.getKeys()) - - intf_name = "Ethernet" + str(i) - vrf_name = "Vrf_" + str(i) - - # remove IP from interface - self.remove_ip_address(intf_name, "10.0.0.4/31") - - # remove interface - self.remove_l3_intf(intf_name) - - # remove vrf - self.remove_vrf(vrf_name) - - # bring down interface - self.set_admin_status(dvs, intf_name, "down") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Ethernet0" and entry[0] != "Ethernet4" - - tbl = swsscommon.Table(self.pdb, "VRF") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - assert False - if route["dest"] == "10.0.0.4/32": - assert False - - def create_port_channel(self, alias): - tbl = swsscommon.Table(self.cdb, "PORTCHANNEL") - fvs = swsscommon.FieldValuePairs([("admin_status", "up"), - ("mtu", "9100")]) - tbl.set(alias, fvs) - time.sleep(1) - - def remove_port_channel(self, alias): - tbl = swsscommon.Table(self.cdb, "PORTCHANNEL") - tbl._del(alias) - time.sleep(1) - - def add_port_channel_members(self, 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) - - def remove_port_channel_members(self, lag, members): - tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_MEMBER") - for member in members: - tbl._del(lag + "|" + member) - time.sleep(1) - - def test_LagInterfaceAddRemoveIpv6Address(self, dvs, testlog): - self.setup_db(dvs) - - # create port channel - self.create_port_channel("PortChannel001") - - # bring up interface - self.set_admin_status(dvs, "PortChannel001", "up") - - # create l3 interface - self.create_l3_intf("PortChannel001", "") - - # assign IP to interface - self.add_ip_address("PortChannel001", "fc00::1/126") - time.sleep(2) # IPv6 netlink message needs longer time - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") - intf_entries = tbl.getKeys() - - # contains 2 keys, global and link-local - assert len(intf_entries) == 2 - - local_index = 0 - global_index = 0 - link_local_address = "" - - if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": - global_index = 1 - link_local_address = intf_entries[0] - assert True - elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": - local_index = 1 - link_local_address = intf_entries[1] - assert True - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[global_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[local_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "local" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - - link_local_address = link_local_address.split('/') - # Stored subnet as 128 in ASIC_DB - link_local_address[1] = '128' - link_local_address = link_local_address[0] + '/' + link_local_address[1] - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - subnet_found = True - if route["dest"] == "fc00::1/128": - ip2me_found = True - if route["dest"] == link_local_address: - link_local_found = True - - assert subnet_found and ip2me_found and link_local_found - - # remove IP from interface - self.remove_ip_address("PortChannel001", "fc00::1/126") - - # remove interface - self.remove_l3_intf("PortChannel001") - - # 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") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "PortChannel001" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - assert False - if route["dest"] == "fc00::1/128": - assert False - if route["dest"] == link_local_address: - assert False - - # remove port channel - self.remove_port_channel("PortChannel001") - - def test_LagInterfaceAddRemoveIpv4Address(self, dvs, testlog): - self.setup_db(dvs) - - # create port channel - self.create_port_channel("PortChannel001") - - # bring up interface - self.set_admin_status(dvs, "PortChannel001", "up") - - # create l3 interface - self.create_l3_intf("PortChannel001", "") - - # assign IP to interface - self.add_ip_address("PortChannel001", "30.0.0.4/31") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "30.0.0.4/31" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "30.0.0.4/31": - subnet_found = True - if route["dest"] == "30.0.0.4/32": - ip2me_found = True - - assert subnet_found and ip2me_found - - # remove IP from interface - self.remove_ip_address("PortChannel001", "30.0.0.4/31") - - # remove l3 interface - self.remove_l3_intf("PortChannel001") - - # 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") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "PortChannel001" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "30.0.0.4/31": - assert False - if route["dest"] == "30.0.0.4/32": - assert False - - # remove port channel - self.remove_port_channel("PortChannel001") - - @pytest.mark.skip(reason="vs image issue: Azure/sonic-sairedis#574") - def test_LagInterfaceSetMtu(self, dvs, testlog): - self.setup_db(dvs) - - # create port channel - self.create_port_channel("PortChannel002") - - # add port channel members - self.add_port_channel_members("PortChannel002", ["Ethernet0", "Ethernet4"]) - - # create l3 interface - self.create_l3_intf("PortChannel002", "") - - # assign IP to interface - self.add_ip_address("PortChannel002", "40.0.0.8/29") - - # configure MTU to interface - self.set_mtu("PortChannel002", "8888") - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # assert the new value set to the router interface - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "8888" - - # check ASIC port database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT") - port_entries = tbl.getKeys() - - for key in port_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a member port configured with MTU will have six field/value tuples - if len(fvs) == 6: - for fv in fvs: - # asser the new value 8888 + 22 = 8910 set to the port - if fv[0] == "SAI_PORT_ATTR_MTU": - assert fv[1] == "8910" - - # remove IP from interface - self.remove_ip_address("PortChannel002", "40.0.0.8/29") - - # remove l3 interface - self.remove_l3_intf("PortChannel002") - - # remove port channel members - self.remove_port_channel_members("PortChannel002", ["Ethernet0", "Ethernet4"]) - - # remove port channel - self.remove_port_channel("PortChannel002") - - def test_LagInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): - self.setup_db(dvs) - - # create vrf - vrf_oid = self.create_vrf("Vrf_0") - - # create port channel - self.create_port_channel("PortChannel001") - - # bring up interface - self.set_admin_status(dvs, "PortChannel001", "up") - - # create l3 interface - self.create_l3_intf("PortChannel001", "Vrf_0") - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("PortChannel001") - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == "Vrf_0" - vrf_found = True - break - assert vrf_found == True - - # assign IP to interface - self.add_ip_address("PortChannel001", "fc00::1/126") - time.sleep(2) # IPv6 netlink message needs longer time - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") - intf_entries = tbl.getKeys() - - # contains 2 keys, global and link-local - assert len(intf_entries) == 2 - - local_index = 0 - global_index = 0 - link_local_address = "" - - if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": - global_index = 1 - link_local_address = intf_entries[0] - assert True - elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": - local_index = 1 - link_local_address = intf_entries[1] - assert True - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[global_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[local_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "local" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - link_local_address = link_local_address.split('/') - # Stored subnet as 128 in ASIC_DB - link_local_address[1] = '128' - link_local_address = link_local_address[0] + '/' + link_local_address[1] - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - subnet_found = True - assert route["vr"] == vrf_oid - if route["dest"] == "fc00::1/128": - ip2me_found = True - assert route["vr"] == vrf_oid - if route["dest"] == link_local_address: - link_local_found = True - assert route["vr"] == vrf_oid - - assert subnet_found and ip2me_found and link_local_found - - # remove IP from interface - self.remove_ip_address("PortChannel001", "fc00::1/126") - - # remove interface - self.remove_l3_intf("PortChannel001") - - # remove vrf - self.remove_vrf("Vrf_0") - - # 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") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "PortChannel001" - - tbl = swsscommon.Table(self.pdb, "VRF") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::1/126": - assert False - if route["dest"] == "fc00::1/128": - assert False - if route["dest"] == link_local_address: - assert False - - # remove port channel - self.remove_port_channel("PortChannel001") - - - def test_LagInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): - self.setup_db(dvs) - - # create port channel - self.create_port_channel("PortChannel001") - - # create vrf - vrf_oid = self.create_vrf("Vrf_0") - - # create interface with vrf - self.create_l3_intf("PortChannel001", "Vrf_0") - - # bring up interface - self.set_admin_status(dvs, "PortChannel001", "up") - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("PortChannel001") - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == "Vrf_0" - vrf_found = True - break - assert vrf_found == True - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show PortChannel001 | grep Vrf"]) - assert "Vrf_0" in result - - # assign IP to interface - self.add_ip_address("PortChannel001", "30.0.0.4/31") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "30.0.0.4/31" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one port based router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "30.0.0.4/31": - subnet_found = True - assert route["vr"] == vrf_oid - if route["dest"] == "30.0.0.4/32": - ip2me_found = True - assert route["vr"] == vrf_oid - - assert subnet_found and ip2me_found - - # remove IP from interface - self.remove_ip_address("PortChannel001", "30.0.0.4/31") - - # remove l3 interface - self.remove_l3_intf("PortChannel001") - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show PortChannel001 | grep Vrf"]) - assert "Vrf_0" not in result - - # remove vrf - self.remove_vrf("Vrf_0") - - # 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") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "PortChannel001" - - tbl = swsscommon.Table(self.pdb, "VRF") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "30.0.0.4/31": - assert False - if route["dest"] == "30.0.0.4/32": - assert False - - # remove port channel - self.remove_port_channel("PortChannel001") - - def create_vlan(self, vlan_id): - tbl = swsscommon.Table(self.cdb, "VLAN") - fvs = swsscommon.FieldValuePairs([("vlanid", vlan_id)]) - tbl.set("Vlan" + vlan_id, fvs) - time.sleep(1) - - def remove_vlan(self, vlan_id): - tbl = swsscommon.Table(self.cdb, "VLAN") - tbl._del("Vlan" + vlan_id) - time.sleep(1) - - def create_vlan_member(self, vlan_id, interface): - tbl = swsscommon.Table(self.cdb, "VLAN_MEMBER") - fvs = swsscommon.FieldValuePairs([("tagging_mode", "untagged")]) - tbl.set("Vlan" + vlan_id + "|" + interface, fvs) - time.sleep(1) - - def remove_vlan_member(self, vlan_id, interface): - tbl = swsscommon.Table(self.cdb, "VLAN_MEMBER") - tbl._del("Vlan" + vlan_id + "|" + interface) - time.sleep(1) - - def test_VLanInterfaceAddRemoveIpv6Address(self, dvs, testlog): - self.setup_db(dvs) - - # create vlan - self.create_vlan("10") - - # add vlan member - self.create_vlan_member("10", "Ethernet0") - - # bring up interface - self.set_admin_status(dvs, "Ethernet0", "up") - self.set_admin_status(dvs, "Vlan10", "up") - - # create vlan interface - self.create_l3_intf("Vlan10", "") - - # assign IP to interface - self.add_ip_address("Vlan10", "fc00::1/126") - time.sleep(2) # IPv6 netlink message needs longer time - - # check asic database and get vlan_oid - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] - assert len(vlan_entries) == 1 - vlan_oid = vlan_entries[0] - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - - # contains 2 keys, global and link-local - assert len(intf_entries) == 2 - - local_index = 0 - global_index = 0 - link_local_address = "" - - if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": - global_index = 1 - link_local_address = intf_entries[0] - assert True - elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": - local_index = 1 - link_local_address = intf_entries[1] - assert True - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[global_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[local_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "local" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one vlan router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": - assert fv[1] == vlan_oid - - link_local_address = link_local_address.split('/') - # Stored subnet as 128 in ASIC_DB - link_local_address[1] = '128' - link_local_address = link_local_address[0] + '/' + link_local_address[1] - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - subnet_found = True - if route["dest"] == "fc00::1/128": - ip2me_found = True - if route["dest"] == link_local_address: - link_local_found = True - - assert subnet_found and ip2me_found and link_local_found - - # remove IP from interface - self.remove_ip_address("Vlan10", "fc00::1/126") - - # remove interface - self.remove_l3_intf("Vlan10") - - # remove vlan member - self.remove_vlan_member("10", "Ethernet0") - - # remove vlan - self.remove_vlan("10") - - # bring down interface - self.set_admin_status(dvs, "Ethernet0", "down") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Vlan10" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - assert False - if route["dest"] == "fc00::1/128": - assert False - if route["dest"] == link_local_address: - assert False - - def test_VLanInterfaceAddRemoveIpv4Address(self, dvs, testlog): - self.setup_db(dvs) - - # create vlan - self.create_vlan("10") - - # add vlan member - self.create_vlan_member("10", "Ethernet0") - - # bring up interface - self.set_admin_status(dvs, "Ethernet0", "up") - self.set_admin_status(dvs, "Vlan10", "up") - - #create vlan interface - self.create_l3_intf("Vlan10", "") - - # assign IP to interface - self.add_ip_address("Vlan10", "10.0.0.4/31") - - # check asic database and get vlan_oid - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] - assert len(vlan_entries) == 1 - vlan_oid = vlan_entries[0] - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "10.0.0.4/31" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one vlan router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": - assert fv[1] == vlan_oid - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - subnet_found = True - if route["dest"] == "10.0.0.4/32": - ip2me_found = True - - assert subnet_found and ip2me_found - - # remove IP from interface - self.remove_ip_address("Vlan10", "10.0.0.4/31") - - # remove vlan interface - self.remove_l3_intf("Vlan10") - - # remove vlan member - self.remove_vlan_member("10", "Ethernet0") - - # remove vlan - self.remove_vlan("10") - - # bring down interface - self.set_admin_status(dvs, "Ethernet0", "down") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "VLAN_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Vlan10" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - assert False - if route["dest"] == "10.0.0.4/32": - assert False - - def test_VLanInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): - self.setup_db(dvs) - - # create vlan - self.create_vlan("10") - - # add vlan member - self.create_vlan_member("10", "Ethernet0") - - # bring up interface - self.set_admin_status(dvs, "Ethernet0", "up") - self.set_admin_status(dvs, "Vlan10", "up") - - # create vrf - vrf_oid = self.create_vrf("Vrf_0") - - # create vlan interface - self.create_l3_intf("Vlan10", "Vrf_0") - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Vlan10 | grep Vrf"]) - assert "Vrf_0" in result - - # assign IP to interface - self.add_ip_address("Vlan10", "fc00::1/126") - time.sleep(2) # IPv6 netlink message needs longer time - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("Vlan10") - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == "Vrf_0" - vrf_found = True - break - assert vrf_found == True - - # check asic database and get vlan_oid - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] - assert len(vlan_entries) == 1 - vlan_oid = vlan_entries[0] - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - - # contains 2 keys, global and link-local - assert len(intf_entries) == 2 - - local_index = 0 - global_index = 0 - link_local_address = "" - - if intf_entries[0].startswith("fe80::") and intf_entries[1] == "fc00::1/126": - global_index = 1 - link_local_address = intf_entries[0] - assert True - elif intf_entries[1].startswith("fe80::") and intf_entries[0] == "fc00::1/126": - local_index = 1 - link_local_address = intf_entries[1] - assert True - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[global_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - (status, fvs) = tbl.get(tbl.getKeys()[local_index]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "local" - elif fv[0] == "family": - assert fv[1] == "IPv6" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one vlan router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": - assert fv[1] == vlan_oid - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - link_local_address = link_local_address.split('/') - # Stored subnet as 128 in ASIC_DB - link_local_address[1] = '128' - link_local_address = link_local_address[0] + '/' + link_local_address[1] - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - subnet_found = True - assert route["vr"] == vrf_oid - if route["dest"] == "fc00::1/128": - ip2me_found = True - assert route["vr"] == vrf_oid - if route["dest"] == link_local_address: - link_local_found = True - assert route["vr"] == vrf_oid - - assert subnet_found and ip2me_found and link_local_found - - # remove IP from interface - self.remove_ip_address("Vlan10", "fc00::1/126") - - # remove vlan interface - self.remove_l3_intf("Vlan10") - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Vlan10 | grep Vrf"]) - assert "Vrf_0" not in result - - # remove vlan member - self.remove_vlan_member("10", "Ethernet0") - - # remove vlan - self.remove_vlan("10") - - # bring down interface - self.set_admin_status(dvs, "Ethernet0", "down") - - # remove vrf - self.remove_vrf("Vrf_0") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Vlan10" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::/126": - assert False - if route["dest"] == "fc00::1/128": - assert False - if route["dest"] == link_local_address: - assert False - - def test_VLanInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): - self.setup_db(dvs) - - # create vlan - self.create_vlan("10") - - # add vlan member - self.create_vlan_member("10", "Ethernet0") - - # bring up interface - self.set_admin_status(dvs, "Ethernet0", "up") - self.set_admin_status(dvs, "Vlan10", "up") - - # create vrf - vrf_oid = self.create_vrf("Vrf_0") - - # create vlan interface - self.create_l3_intf("Vlan10", "Vrf_0") - - # assign IP to interface - self.add_ip_address("Vlan10", "10.0.0.4/31") - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get("Vlan10") - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == "Vrf_0" - vrf_found = True - break - assert vrf_found == True - - # check asic database and get vlan_oid - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] - assert len(vlan_entries) == 1 - vlan_oid = vlan_entries[0] - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "10.0.0.4/31" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - intf_entries = tbl.getKeys() - # one loopback router interface one vlan router interface - assert len(intf_entries) == 2 - - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": - assert fv[1] == vlan_oid - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - subnet_found = True - assert route["vr"] == vrf_oid - if route["dest"] == "10.0.0.4/32": - ip2me_found = True - assert route["vr"] == vrf_oid - - assert subnet_found and ip2me_found - - # remove IP from interface - self.remove_ip_address("Vlan10", "10.0.0.4/31") - - # remove vlan interface - self.remove_l3_intf("Vlan10") - - # remove vlan member - self.remove_vlan_member("10", "Ethernet0") - - # remove vlan - self.remove_vlan("10") - - # bring down interface - self.set_admin_status(dvs, "Ethernet0", "down") - - # remove vrf - self.remove_vrf("Vrf_0") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "VLAN_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Vlan10" - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/31": - assert False - if route["dest"] == "10.0.0.4/32": - assert False - - def test_LoopbackInterfacesAddRemoveIpv4Address(self, dvs, testlog): - self.setup_db(dvs) - - # Create loopback interfaces - self.create_l3_intf("Loopback0", "") - self.create_l3_intf("Loopback1", "") - - # add ip address - self.add_ip_address("Loopback0", "10.1.0.1/32") - self.add_ip_address("Loopback1", "10.1.0.2/32") - - # Check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") - intf_entries = tbl.getKeys() - assert intf_entries[0] == "10.1.0.1/32" - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") - intf_entries = tbl.getKeys() - assert intf_entries[0] == "10.1.0.2/32" - - # Check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.1.0.1/32": - lo0_ip2me_found = True - if route["dest"] == "10.1.0.2/32": - lo1_ip2me_found = True - - assert lo0_ip2me_found and lo1_ip2me_found - - # Remove ip address - self.remove_ip_address("Loopback0", "10.1.0.1/32") - self.remove_ip_address("Loopback1", "10.1.0.2/32") - - # Remove interface - self.remove_l3_intf("Loopback0") - self.remove_l3_intf("Loopback1") - - # Check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # Check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.1.0.1/32": - assert False - if route["dest"] == "10.1.0.2/32": - assert False - - def test_LoopbackInterfacesAddRemoveIpv6Address(self, dvs, testlog): - self.setup_db(dvs) - - # Create loopback interfaces - self.create_l3_intf("Loopback0", "") - self.create_l3_intf("Loopback1", "") - - # add ip address - self.add_ip_address("Loopback0", "fc00::1/128") - self.add_ip_address("Loopback1", "fd00::1/128") - time.sleep(2) # IPv6 netlink message needs longer time - - # Check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") - intf_entries = tbl.getKeys() - assert intf_entries[0] == "fc00::1/128" - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") - intf_entries = tbl.getKeys() - assert intf_entries[0] == "fd00::1/128" - - # Check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::1/128": - lo0_ip2me_found = True - if route["dest"] == "fd00::1/128": - lo1_ip2me_found = True - - assert lo0_ip2me_found and lo1_ip2me_found - - # Remove ip address - self.remove_ip_address("Loopback0", "fc00::1/128") - self.remove_ip_address("Loopback1", "fd00::1/128") - - # Remove interface - self.remove_l3_intf("Loopback0") - self.remove_l3_intf("Loopback1") - - # Check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # Check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "fc00::1/128": - assert False - if route["dest"] == "fd00::1/128": - assert False - - def test_LoopbackInterfaceIpv4AddressWithVrf(self, dvs, testlog): - self.setup_db(dvs) - - for i in [0, 1]: - # record ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - old_intf_entries = set(tbl.getKeys()) - - # record ASIC router entry database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - old_route_entries = set(tbl.getKeys()) - - intf_name = "Loopback" + str(i) - vrf_name = "Vrf_" + str(i) - - # create vrf - vrf_oid = self.create_vrf(vrf_name) - - # create interface with vrf - self.create_l3_intf(intf_name, vrf_name) - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show %s | grep Vrf" % intf_name]) - assert "%s" % vrf_name in result - - # check interface's vrf - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - (status, fvs) = tbl.get(intf_name) - assert status == True - for fv in fvs: - if fv[0] == "vrf_name": - assert fv[1] == vrf_name - vrf_found = True - break - assert vrf_found == True - - # assign IP to interface - self.add_ip_address(intf_name, "10.0.0.4/32") - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) - intf_entries = tbl.getKeys() - assert len(intf_entries) == 1 - assert intf_entries[0] == "10.0.0.4/32" - - (status, fvs) = tbl.get(tbl.getKeys()[0]) - assert status == True - assert len(fvs) == 2 - for fv in fvs: - if fv[0] == "scope": - assert fv[1] == "global" - elif fv[0] == "family": - assert fv[1] == "IPv4" - else: - assert False - - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - current_intf_entries = set(tbl.getKeys()) - intf_entries = list(current_intf_entries - old_intf_entries) - for key in intf_entries: - (status, fvs) = tbl.get(key) - assert status == True - # a port based router interface has five field/value tuples - if len(fvs) == 5: - for fv in fvs: - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": - assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" - # the default MTU without any configuration is 9100 - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": - assert fv[1] == "9100" - if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": - assert fv[1] == vrf_oid - - # check ASIC route database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - current_route_entries = set(tbl.getKeys()) - route_entries = list(current_route_entries - old_route_entries) - - for key in route_entries: - route = json.loads(key) - if route["dest"] == "10.0.0.4/32": - ip2me_found = True - assert route["vr"] == vrf_oid - - assert ip2me_found - - - for i in [0, 1]: - # check ASIC router interface database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") - old_intf_entries = set(tbl.getKeys()) - - intf_name = "Loopback" + str(i) - vrf_name = "Vrf_" + str(i) - - # remove IP from interface - self.remove_ip_address(intf_name, "10.0.0.4/32") - - # remove interface - self.remove_l3_intf(intf_name) - - # remove vrf - self.remove_vrf(vrf_name) - - # check linux kernel - (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show %s | grep Vrf" % intf_name]) - assert "%s" % vrf_name not in result - - # check application database - tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - tbl = swsscommon.Table(self.pdb, "INTF_TABLE") - intf_entries = tbl.getKeys() - for entry in intf_entries: - assert entry[0] != "Loopback0" and entry[0] != "Loopback1" - - tbl = swsscommon.Table(self.pdb, "VRF") - intf_entries = tbl.getKeys() - assert len(intf_entries) == 0 - - # check ASIC database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") - for key in tbl.getKeys(): - route = json.loads(key) - if route["dest"] == "10.0.0.4/32": - assert False - - -# Add Dummy always-pass test at end as workaroud -# for issue when Flaky fail on final test it invokes module tear-down before retrying -def test_nonflaky_dummy(): - pass From 54c974bf19773c475e75a4b793c01afdc4bc5279 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Mon, 5 Apr 2021 12:03:14 -0700 Subject: [PATCH 05/31] Added the removed file. --- tests/test_interface.py | 1970 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1970 insertions(+) create mode 100644 tests/test_interface.py diff --git a/tests/test_interface.py b/tests/test_interface.py new file mode 100644 index 0000000000..ac1446481a --- /dev/null +++ b/tests/test_interface.py @@ -0,0 +1,1970 @@ +import time +import json +import pytest + +from swsscommon import swsscommon + +class TestRouterInterface(object): + def setup_db(self, dvs): + self.pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0) + self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0) + self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) + + def set_admin_status(self, dvs, interface, status): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL" + elif interface.startswith("Vlan"): + tbl_name = "VLAN" + else: + tbl_name = "PORT" + tbl = swsscommon.Table(self.cdb, tbl_name) + fvs = swsscommon.FieldValuePairs([("admin_status", status)]) + tbl.set(interface, fvs) + time.sleep(1) + + # when using FRR, route cannot be inserted if the neighbor is not + # connected. thus it is mandatory to force the interface up manually + if interface.startswith("PortChannel"): + dvs.runcmd("bash -c 'echo " + ("1" if status == "up" else "0") +\ + " > /sys/class/net/" + interface + "/carrier'") + time.sleep(1) + + def create_vrf(self, vrf_name): + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + initial_entries = set(tbl.getKeys()) + + tbl = swsscommon.Table(self.cdb, "VRF") + fvs = swsscommon.FieldValuePairs([('empty', 'empty')]) + tbl.set(vrf_name, fvs) + time.sleep(1) + + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + current_entries = set(tbl.getKeys()) + assert len(current_entries - initial_entries) == 1 + return list(current_entries - initial_entries)[0] + + def remove_vrf(self, vrf_name): + tbl = swsscommon.Table(self.cdb, "VRF") + tbl._del(vrf_name) + time.sleep(1) + + def create_l3_intf(self, interface, vrf_name): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL_INTERFACE" + elif interface.startswith("Vlan"): + tbl_name = "VLAN_INTERFACE" + elif interface.startswith("Loopback"): + tbl_name = "LOOPBACK_INTERFACE" + else: + tbl_name = "INTERFACE" + if len(vrf_name) == 0: + fvs = swsscommon.FieldValuePairs([("NULL", "NULL")]) + else: + fvs = swsscommon.FieldValuePairs([("vrf_name", vrf_name)]) + tbl = swsscommon.Table(self.cdb, tbl_name) + tbl.set(interface, fvs) + time.sleep(1) + + def remove_l3_intf(self, interface): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL_INTERFACE" + elif interface.startswith("Vlan"): + tbl_name = "VLAN_INTERFACE" + elif interface.startswith("Loopback"): + tbl_name = "LOOPBACK_INTERFACE" + else: + tbl_name = "INTERFACE" + tbl = swsscommon.Table(self.cdb, tbl_name) + tbl._del(interface) + time.sleep(1) + + def add_ip_address(self, interface, ip): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL_INTERFACE" + elif interface.startswith("Vlan"): + tbl_name = "VLAN_INTERFACE" + elif interface.startswith("Loopback"): + tbl_name = "LOOPBACK_INTERFACE" + else: + tbl_name = "INTERFACE" + tbl = swsscommon.Table(self.cdb, tbl_name) + fvs = swsscommon.FieldValuePairs([("NULL", "NULL")]) + tbl.set(interface + "|" + ip, fvs) + time.sleep(1) + + def remove_ip_address(self, interface, ip): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL_INTERFACE" + elif interface.startswith("Vlan"): + tbl_name = "VLAN_INTERFACE" + elif interface.startswith("Loopback"): + tbl_name = "LOOPBACK_INTERFACE" + else: + tbl_name = "INTERFACE" + tbl = swsscommon.Table(self.cdb, tbl_name) + tbl._del(interface + "|" + ip) + time.sleep(1) + + def set_mtu(self, interface, mtu): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL" + elif interface.startswith("Vlan"): + tbl_name = "VLAN" + else: + tbl_name = "PORT" + tbl = swsscommon.Table(self.cdb, tbl_name) + fvs = swsscommon.FieldValuePairs([("mtu", mtu)]) + tbl.set(interface, fvs) + time.sleep(1) + + def test_PortInterfaceAddRemoveIpv6Address(self, dvs, testlog): + self.setup_db(dvs) + + # create interface + self.create_l3_intf("Ethernet8", "") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Ethernet8") + assert status == True + for fv in fvs: + assert fv[0] != "vrf_name" + + # bring up interface + # NOTE: For IPv6, only when the interface is up will the netlink message + # get generated. + self.set_admin_status(dvs, "Ethernet8", "up") + + # assign IP to interface + self.add_ip_address("Ethernet8", "fc00::1/126") + time.sleep(2) # IPv6 netlink message needs longer time + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "fc00::1/126" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + subnet_found = True + if route["dest"] == "fc00::1/128": + ip2me_found = True + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Ethernet8", "fc00::1/126") + + # remove interface + self.remove_l3_intf("Ethernet8") + + # bring down interface + self.set_admin_status(dvs, "Ethernet8", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Ethernet8" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + assert False + if route["dest"] == "fc00::1/128": + assert False + + def test_PortInterfaceAddRemoveIpv4Address(self, dvs, testlog): + self.setup_db(dvs) + + # bring up interface + self.set_admin_status(dvs, "Ethernet8", "up") + + # create interface + self.create_l3_intf("Ethernet8", "") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Ethernet8") + assert status == True + for fv in fvs: + assert fv[0] != "vrf_name" + + # assign IP to interface + self.add_ip_address("Ethernet8", "10.0.0.4/31") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "10.0.0.4/31" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + subnet_found = True + if route["dest"] == "10.0.0.4/32": + ip2me_found = True + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Ethernet8", "10.0.0.4/31") + + # remove interface + self.remove_l3_intf("Ethernet8") + + # bring down interface + self.set_admin_status(dvs, "Ethernet8", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Ethernet8" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + assert False + if route["dest"] == "10.0.0.4/32": + assert False + + def test_PortInterfaceSetMtu(self, dvs, testlog): + self.setup_db(dvs) + + # create interface + self.create_l3_intf("Ethernet16", "") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Ethernet16") + assert status == True + for fv in fvs: + assert fv[0] != "vrf_name" + + # assign IP to interface + self.add_ip_address("Ethernet16", "20.0.0.8/29") + + # configure MTU to interface + self.set_mtu("Ethernet16", "8888") + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # assert the new value set to the router interface + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "8888" + + # remove IP from interface + self.remove_ip_address("Ethernet16", "20.0.0.8/29") + + # remove interface + self.remove_l3_intf("Ethernet16") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet16") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Ethernet16" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "20.0.0.8/29": + assert False + if route["dest"] == "20.0.0.8/32": + assert False + + def test_PortInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): + self.setup_db(dvs) + + # bring up interface + self.set_admin_status(dvs, "Ethernet8", "up") + + # create vrf + vrf_oid = self.create_vrf("Vrf_0") + + # create interface with vrf + self.create_l3_intf("Ethernet8", "Vrf_0") + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Ethernet8") + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == "Vrf_0" + vrf_found = True + break + assert vrf_found == True + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Ethernet8 | grep Vrf"]) + assert "Vrf_0" in result + + # assign IP to interface + self.add_ip_address("Ethernet8", "fc00::1/126") + time.sleep(2) # IPv6 netlink message needs longer time + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + + assert len(intf_entries) == 1 + assert intf_entries[0] == "fc00::1/126" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + subnet_found = True + assert route["vr"] == vrf_oid + if route["dest"] == "fc00::1/128": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Ethernet8", "fc00::1/126") + + # remove vrf from interface + self.remove_l3_intf("Ethernet8") + + # remove vrf + self.remove_vrf("Vrf_0") + + # bring down interface + self.set_admin_status(dvs, "Ethernet8", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Ethernet8 | grep Vrf"]) + assert "Vrf_0" not in result + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Ethernet8" + + tbl = swsscommon.Table(self.pdb, "VRF") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + assert False + if route["dest"] == "fc00::1/128": + assert False + + def test_PortInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): + self.setup_db(dvs) + + # bring up interface + self.set_admin_status(dvs, "Ethernet8", "up") + + # create vrf + vrf_oid = self.create_vrf("Vrf_0") + + # create interface with vrf + self.create_l3_intf("Ethernet8", "Vrf_0") + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Ethernet8") + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == "Vrf_0" + vrf_found = True + break + assert vrf_found == True + + # assign IP to interface + self.add_ip_address("Ethernet8", "10.0.0.4/31") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "10.0.0.4/31" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + subnet_found = True + assert route["vr"] == vrf_oid + if route["dest"] == "10.0.0.4/32": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Ethernet8", "10.0.0.4/31") + + # remove interface + self.remove_l3_intf("Ethernet8") + + # remove vrf + self.remove_vrf("Vrf_0") + + # bring down interface + self.set_admin_status(dvs, "Ethernet8", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Ethernet8" + + tbl = swsscommon.Table(self.pdb, "VRF") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + assert False + if route["dest"] == "10.0.0.4/32": + assert False + + def test_PortInterfaceAddSameIpv4AddressWithDiffVrf(self, dvs, testlog): + self.setup_db(dvs) + + for i in [0, 4]: + # record ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + old_intf_entries = set(tbl.getKeys()) + + # record ASIC router entry database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + old_route_entries = set(tbl.getKeys()) + + intf_name = "Ethernet" + str(i) + vrf_name = "Vrf_" + str(i) + + # bring up interface + self.set_admin_status(dvs, intf_name, "up") + + # create vrf + vrf_oid = self.create_vrf(vrf_name) + + # create interface with vrf + self.create_l3_intf(intf_name, vrf_name) + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get(intf_name) + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == vrf_name + vrf_found = True + break + assert vrf_found == True + + # assign IP to interface + self.add_ip_address(intf_name, "10.0.0.4/31") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "10.0.0.4/31" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + current_intf_entries = set(tbl.getKeys()) + intf_entries = list(current_intf_entries - old_intf_entries) + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + current_route_entries = set(tbl.getKeys()) + route_entries = list(current_route_entries - old_route_entries) + + for key in route_entries: + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + subnet_found = True + assert route["vr"] == vrf_oid + if route["dest"] == "10.0.0.4/32": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert subnet_found and ip2me_found + + + for i in [0, 4]: + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + old_intf_entries = set(tbl.getKeys()) + + intf_name = "Ethernet" + str(i) + vrf_name = "Vrf_" + str(i) + + # remove IP from interface + self.remove_ip_address(intf_name, "10.0.0.4/31") + + # remove interface + self.remove_l3_intf(intf_name) + + # remove vrf + self.remove_vrf(vrf_name) + + # bring down interface + self.set_admin_status(dvs, intf_name, "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Ethernet0" and entry[0] != "Ethernet4" + + tbl = swsscommon.Table(self.pdb, "VRF") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + assert False + if route["dest"] == "10.0.0.4/32": + assert False + + def create_port_channel(self, alias): + tbl = swsscommon.Table(self.cdb, "PORTCHANNEL") + fvs = swsscommon.FieldValuePairs([("admin_status", "up"), + ("mtu", "9100")]) + tbl.set(alias, fvs) + time.sleep(1) + + def remove_port_channel(self, alias): + tbl = swsscommon.Table(self.cdb, "PORTCHANNEL") + tbl._del(alias) + time.sleep(1) + + def add_port_channel_members(self, 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) + + def remove_port_channel_members(self, lag, members): + tbl = swsscommon.Table(self.cdb, "PORTCHANNEL_MEMBER") + for member in members: + tbl._del(lag + "|" + member) + time.sleep(1) + + def test_LagInterfaceAddRemoveIpv6Address(self, dvs, testlog): + self.setup_db(dvs) + + # create port channel + self.create_port_channel("PortChannel001") + + # bring up interface + self.set_admin_status(dvs, "PortChannel001", "up") + + # create l3 interface + self.create_l3_intf("PortChannel001", "") + + # assign IP to interface + self.add_ip_address("PortChannel001", "fc00::1/126") + time.sleep(2) # IPv6 netlink message needs longer time + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "fc00::1/126" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + subnet_found = True + if route["dest"] == "fc00::1/128": + ip2me_found = True + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("PortChannel001", "fc00::1/126") + + # remove interface + self.remove_l3_intf("PortChannel001") + + # 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") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "PortChannel001" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + assert False + if route["dest"] == "fc00::1/128": + assert False + + # remove port channel + self.remove_port_channel("PortChannel001") + + def test_LagInterfaceAddRemoveIpv4Address(self, dvs, testlog): + self.setup_db(dvs) + + # create port channel + self.create_port_channel("PortChannel001") + + # bring up interface + self.set_admin_status(dvs, "PortChannel001", "up") + + # create l3 interface + self.create_l3_intf("PortChannel001", "") + + # assign IP to interface + self.add_ip_address("PortChannel001", "30.0.0.4/31") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "30.0.0.4/31" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "30.0.0.4/31": + subnet_found = True + if route["dest"] == "30.0.0.4/32": + ip2me_found = True + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("PortChannel001", "30.0.0.4/31") + + # remove l3 interface + self.remove_l3_intf("PortChannel001") + + # 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") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "PortChannel001" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "30.0.0.4/31": + assert False + if route["dest"] == "30.0.0.4/32": + assert False + + # remove port channel + self.remove_port_channel("PortChannel001") + + @pytest.mark.skip(reason="vs image issue: Azure/sonic-sairedis#574") + def test_LagInterfaceSetMtu(self, dvs, testlog): + self.setup_db(dvs) + + # create port channel + self.create_port_channel("PortChannel002") + + # add port channel members + self.add_port_channel_members("PortChannel002", ["Ethernet0", "Ethernet4"]) + + # create l3 interface + self.create_l3_intf("PortChannel002", "") + + # assign IP to interface + self.add_ip_address("PortChannel002", "40.0.0.8/29") + + # configure MTU to interface + self.set_mtu("PortChannel002", "8888") + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # assert the new value set to the router interface + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "8888" + + # check ASIC port database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT") + port_entries = tbl.getKeys() + + for key in port_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a member port configured with MTU will have six field/value tuples + if len(fvs) == 6: + for fv in fvs: + # asser the new value 8888 + 22 = 8910 set to the port + if fv[0] == "SAI_PORT_ATTR_MTU": + assert fv[1] == "8910" + + # remove IP from interface + self.remove_ip_address("PortChannel002", "40.0.0.8/29") + + # remove l3 interface + self.remove_l3_intf("PortChannel002") + + # remove port channel members + self.remove_port_channel_members("PortChannel002", ["Ethernet0", "Ethernet4"]) + + # remove port channel + self.remove_port_channel("PortChannel002") + + def test_LagInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): + self.setup_db(dvs) + + # create vrf + vrf_oid = self.create_vrf("Vrf_0") + + # create port channel + self.create_port_channel("PortChannel001") + + # bring up interface + self.set_admin_status(dvs, "PortChannel001", "up") + + # create l3 interface + self.create_l3_intf("PortChannel001", "Vrf_0") + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("PortChannel001") + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == "Vrf_0" + vrf_found = True + break + assert vrf_found == True + + # assign IP to interface + self.add_ip_address("PortChannel001", "fc00::1/126") + time.sleep(2) # IPv6 netlink message needs longer time + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "fc00::1/126" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + subnet_found = True + assert route["vr"] == vrf_oid + if route["dest"] == "fc00::1/128": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("PortChannel001", "fc00::1/126") + + # remove interface + self.remove_l3_intf("PortChannel001") + + # remove vrf + self.remove_vrf("Vrf_0") + + # 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") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "PortChannel001" + + tbl = swsscommon.Table(self.pdb, "VRF") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::1/126": + assert False + if route["dest"] == "fc00::1/128": + assert False + + # remove port channel + self.remove_port_channel("PortChannel001") + + def test_LagInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): + self.setup_db(dvs) + + # create port channel + self.create_port_channel("PortChannel001") + + # create vrf + vrf_oid = self.create_vrf("Vrf_0") + + # create interface with vrf + self.create_l3_intf("PortChannel001", "Vrf_0") + + # bring up interface + self.set_admin_status(dvs, "PortChannel001", "up") + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("PortChannel001") + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == "Vrf_0" + vrf_found = True + break + assert vrf_found == True + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show PortChannel001 | grep Vrf"]) + assert "Vrf_0" in result + + # assign IP to interface + self.add_ip_address("PortChannel001", "30.0.0.4/31") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:PortChannel001") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "30.0.0.4/31" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "30.0.0.4/31": + subnet_found = True + assert route["vr"] == vrf_oid + if route["dest"] == "30.0.0.4/32": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("PortChannel001", "30.0.0.4/31") + + # remove l3 interface + self.remove_l3_intf("PortChannel001") + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show PortChannel001 | grep Vrf"]) + assert "Vrf_0" not in result + + # remove vrf + self.remove_vrf("Vrf_0") + + # 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") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "PortChannel001" + + tbl = swsscommon.Table(self.pdb, "VRF") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "30.0.0.4/31": + assert False + if route["dest"] == "30.0.0.4/32": + assert False + + # remove port channel + self.remove_port_channel("PortChannel001") + + def create_vlan(self, vlan_id): + tbl = swsscommon.Table(self.cdb, "VLAN") + fvs = swsscommon.FieldValuePairs([("vlanid", vlan_id)]) + tbl.set("Vlan" + vlan_id, fvs) + time.sleep(1) + + def remove_vlan(self, vlan_id): + tbl = swsscommon.Table(self.cdb, "VLAN") + tbl._del("Vlan" + vlan_id) + time.sleep(1) + + def create_vlan_member(self, vlan_id, interface): + tbl = swsscommon.Table(self.cdb, "VLAN_MEMBER") + fvs = swsscommon.FieldValuePairs([("tagging_mode", "untagged")]) + tbl.set("Vlan" + vlan_id + "|" + interface, fvs) + time.sleep(1) + + def remove_vlan_member(self, vlan_id, interface): + tbl = swsscommon.Table(self.cdb, "VLAN_MEMBER") + tbl._del("Vlan" + vlan_id + "|" + interface) + time.sleep(1) + + def test_VLanInterfaceAddRemoveIpv6Address(self, dvs, testlog): + self.setup_db(dvs) + + # create vlan + self.create_vlan("10") + + # add vlan member + self.create_vlan_member("10", "Ethernet0") + + # bring up interface + self.set_admin_status(dvs, "Ethernet0", "up") + self.set_admin_status(dvs, "Vlan10", "up") + + # create vlan interface + self.create_l3_intf("Vlan10", "") + + # assign IP to interface + self.add_ip_address("Vlan10", "fc00::1/126") + time.sleep(2) # IPv6 netlink message needs longer time + + # check asic database and get vlan_oid + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] + assert len(vlan_entries) == 1 + vlan_oid = vlan_entries[0] + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "fc00::1/126" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one vlan router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": + assert fv[1] == vlan_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + subnet_found = True + if route["dest"] == "fc00::1/128": + ip2me_found = True + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Vlan10", "fc00::1/126") + + # remove interface + self.remove_l3_intf("Vlan10") + + # remove vlan member + self.remove_vlan_member("10", "Ethernet0") + + # remove vlan + self.remove_vlan("10") + + # bring down interface + self.set_admin_status(dvs, "Ethernet0", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Vlan10" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + assert False + if route["dest"] == "fc00::1/128": + assert False + + def test_VLanInterfaceAddRemoveIpv4Address(self, dvs, testlog): + self.setup_db(dvs) + + # create vlan + self.create_vlan("10") + + # add vlan member + self.create_vlan_member("10", "Ethernet0") + + # bring up interface + self.set_admin_status(dvs, "Ethernet0", "up") + self.set_admin_status(dvs, "Vlan10", "up") + + #create vlan interface + self.create_l3_intf("Vlan10", "") + + # assign IP to interface + self.add_ip_address("Vlan10", "10.0.0.4/31") + + # check asic database and get vlan_oid + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] + assert len(vlan_entries) == 1 + vlan_oid = vlan_entries[0] + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "10.0.0.4/31" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one vlan router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": + assert fv[1] == vlan_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + subnet_found = True + if route["dest"] == "10.0.0.4/32": + ip2me_found = True + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Vlan10", "10.0.0.4/31") + + # remove vlan interface + self.remove_l3_intf("Vlan10") + + # remove vlan member + self.remove_vlan_member("10", "Ethernet0") + + # remove vlan + self.remove_vlan("10") + + # bring down interface + self.set_admin_status(dvs, "Ethernet0", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "VLAN_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Vlan10" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + assert False + if route["dest"] == "10.0.0.4/32": + assert False + + def test_VLanInterfaceAddRemoveIpv6AddressWithVrf(self, dvs, testlog): + self.setup_db(dvs) + + # create vlan + self.create_vlan("10") + + # add vlan member + self.create_vlan_member("10", "Ethernet0") + + # bring up interface + self.set_admin_status(dvs, "Ethernet0", "up") + self.set_admin_status(dvs, "Vlan10", "up") + + # create vrf + vrf_oid = self.create_vrf("Vrf_0") + + # create vlan interface + self.create_l3_intf("Vlan10", "Vrf_0") + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Vlan10 | grep Vrf"]) + assert "Vrf_0" in result + + # assign IP to interface + self.add_ip_address("Vlan10", "fc00::1/126") + time.sleep(2) # IPv6 netlink message needs longer time + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Vlan10") + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == "Vrf_0" + vrf_found = True + break + assert vrf_found == True + + # check asic database and get vlan_oid + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] + assert len(vlan_entries) == 1 + vlan_oid = vlan_entries[0] + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "fc00::1/126" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv6" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one vlan router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": + assert fv[1] == vlan_oid + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + subnet_found = True + assert route["vr"] == vrf_oid + if route["dest"] == "fc00::1/128": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Vlan10", "fc00::1/126") + + # remove vlan interface + self.remove_l3_intf("Vlan10") + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show Vlan10 | grep Vrf"]) + assert "Vrf_0" not in result + + # remove vlan member + self.remove_vlan_member("10", "Ethernet0") + + # remove vlan + self.remove_vlan("10") + + # bring down interface + self.set_admin_status(dvs, "Ethernet0", "down") + + # remove vrf + self.remove_vrf("Vrf_0") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Vlan10" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::/126": + assert False + if route["dest"] == "fc00::1/128": + assert False + + def test_VLanInterfaceAddRemoveIpv4AddressWithVrf(self, dvs, testlog): + self.setup_db(dvs) + + # create vlan + self.create_vlan("10") + + # add vlan member + self.create_vlan_member("10", "Ethernet0") + + # bring up interface + self.set_admin_status(dvs, "Ethernet0", "up") + self.set_admin_status(dvs, "Vlan10", "up") + + # create vrf + vrf_oid = self.create_vrf("Vrf_0") + + # create vlan interface + self.create_l3_intf("Vlan10", "Vrf_0") + + # assign IP to interface + self.add_ip_address("Vlan10", "10.0.0.4/31") + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Vlan10") + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == "Vrf_0" + vrf_found = True + break + assert vrf_found == True + + # check asic database and get vlan_oid + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] + assert len(vlan_entries) == 1 + vlan_oid = vlan_entries[0] + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "10.0.0.4/31" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one vlan router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": + assert fv[1] == vlan_oid + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + subnet_found = True + assert route["vr"] == vrf_oid + if route["dest"] == "10.0.0.4/32": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert subnet_found and ip2me_found + + # remove IP from interface + self.remove_ip_address("Vlan10", "10.0.0.4/31") + + # remove vlan interface + self.remove_l3_intf("Vlan10") + + # remove vlan member + self.remove_vlan_member("10", "Ethernet0") + + # remove vlan + self.remove_vlan("10") + + # bring down interface + self.set_admin_status(dvs, "Ethernet0", "down") + + # remove vrf + self.remove_vrf("Vrf_0") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "VLAN_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Vlan10" + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/31": + assert False + if route["dest"] == "10.0.0.4/32": + assert False + + def test_LoopbackInterfacesAddRemoveIpv4Address(self, dvs, testlog): + self.setup_db(dvs) + + # Create loopback interfaces + self.create_l3_intf("Loopback0", "") + self.create_l3_intf("Loopback1", "") + + # add ip address + self.add_ip_address("Loopback0", "10.1.0.1/32") + self.add_ip_address("Loopback1", "10.1.0.2/32") + + # Check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") + intf_entries = tbl.getKeys() + assert intf_entries[0] == "10.1.0.1/32" + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") + intf_entries = tbl.getKeys() + assert intf_entries[0] == "10.1.0.2/32" + + # Check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.1.0.1/32": + lo0_ip2me_found = True + if route["dest"] == "10.1.0.2/32": + lo1_ip2me_found = True + + assert lo0_ip2me_found and lo1_ip2me_found + + # Remove ip address + self.remove_ip_address("Loopback0", "10.1.0.1/32") + self.remove_ip_address("Loopback1", "10.1.0.2/32") + + # Remove interface + self.remove_l3_intf("Loopback0") + self.remove_l3_intf("Loopback1") + + # Check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # Check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.1.0.1/32": + assert False + if route["dest"] == "10.1.0.2/32": + assert False + + def test_LoopbackInterfacesAddRemoveIpv6Address(self, dvs, testlog): + self.setup_db(dvs) + + # Create loopback interfaces + self.create_l3_intf("Loopback0", "") + self.create_l3_intf("Loopback1", "") + + # add ip address + self.add_ip_address("Loopback0", "fc00::1/128") + self.add_ip_address("Loopback1", "fd00::1/128") + time.sleep(2) # IPv6 netlink message needs longer time + + # Check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") + intf_entries = tbl.getKeys() + assert intf_entries[0] == "fc00::1/128" + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") + intf_entries = tbl.getKeys() + assert intf_entries[0] == "fd00::1/128" + + # Check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::1/128": + lo0_ip2me_found = True + if route["dest"] == "fd00::1/128": + lo1_ip2me_found = True + + assert lo0_ip2me_found and lo1_ip2me_found + + # Remove ip address + self.remove_ip_address("Loopback0", "fc00::1/128") + self.remove_ip_address("Loopback1", "fd00::1/128") + + # Remove interface + self.remove_l3_intf("Loopback0") + self.remove_l3_intf("Loopback1") + + # Check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback0") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Loopback1") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # Check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "fc00::1/128": + assert False + if route["dest"] == "fd00::1/128": + assert False + + def test_LoopbackInterfaceIpv4AddressWithVrf(self, dvs, testlog): + self.setup_db(dvs) + + for i in [0, 1]: + # record ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + old_intf_entries = set(tbl.getKeys()) + + # record ASIC router entry database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + old_route_entries = set(tbl.getKeys()) + + intf_name = "Loopback" + str(i) + vrf_name = "Vrf_" + str(i) + + # create vrf + vrf_oid = self.create_vrf(vrf_name) + + # create interface with vrf + self.create_l3_intf(intf_name, vrf_name) + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show %s | grep Vrf" % intf_name]) + assert "%s" % vrf_name in result + + # check interface's vrf + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get(intf_name) + assert status == True + for fv in fvs: + if fv[0] == "vrf_name": + assert fv[1] == vrf_name + vrf_found = True + break + assert vrf_found == True + + # assign IP to interface + self.add_ip_address(intf_name, "10.0.0.4/32") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) + intf_entries = tbl.getKeys() + assert len(intf_entries) == 1 + assert intf_entries[0] == "10.0.0.4/32" + + (status, fvs) = tbl.get(tbl.getKeys()[0]) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "scope": + assert fv[1] == "global" + elif fv[0] == "family": + assert fv[1] == "IPv4" + else: + assert False + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + current_intf_entries = set(tbl.getKeys()) + intf_entries = list(current_intf_entries - old_intf_entries) + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID": + assert fv[1] == vrf_oid + + # check ASIC route database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + current_route_entries = set(tbl.getKeys()) + route_entries = list(current_route_entries - old_route_entries) + + for key in route_entries: + route = json.loads(key) + if route["dest"] == "10.0.0.4/32": + ip2me_found = True + assert route["vr"] == vrf_oid + + assert ip2me_found + + + for i in [0, 1]: + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + old_intf_entries = set(tbl.getKeys()) + + intf_name = "Loopback" + str(i) + vrf_name = "Vrf_" + str(i) + + # remove IP from interface + self.remove_ip_address(intf_name, "10.0.0.4/32") + + # remove interface + self.remove_l3_intf(intf_name) + + # remove vrf + self.remove_vrf(vrf_name) + + # check linux kernel + (exitcode, result) = dvs.runcmd(['sh', '-c', "ip link show %s | grep Vrf" % intf_name]) + assert "%s" % vrf_name not in result + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:" + intf_name) + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Loopback0" and entry[0] != "Loopback1" + + tbl = swsscommon.Table(self.pdb, "VRF") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + # check ASIC database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY") + for key in tbl.getKeys(): + route = json.loads(key) + if route["dest"] == "10.0.0.4/32": + assert False + + +# Add Dummy always-pass test at end as workaroud +# for issue when Flaky fail on final test it invokes module tear-down before retrying +def test_nonflaky_dummy(): + pass From a6ed4502092bca4174a93e4cf8c89522afab1e44 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Wed, 14 Apr 2021 02:00:15 -0700 Subject: [PATCH 06/31] Removed hasIp2MeAddr function. --- orchagent/intfsorch.cpp | 66 ++++------------------------------------- orchagent/intfsorch.h | 2 -- 2 files changed, 6 insertions(+), 62 deletions(-) diff --git a/orchagent/intfsorch.cpp b/orchagent/intfsorch.cpp index f396d2b166..b270a0c5e5 100644 --- a/orchagent/intfsorch.cpp +++ b/orchagent/intfsorch.cpp @@ -858,32 +858,14 @@ void IntfsOrch::doTask(Consumer &consumer) } else { - if (gPortsOrch->getPort(alias, port)) + if (!setIntf(alias, vrf_id, ip_prefix_in_key ? &ip_prefix : nullptr, adminUp, mtu)) { - if (ip_prefix_in_key) - { - string out_alias; - - if (hasIp2MeAddr(port.m_vr_id, ip_prefix, &out_alias)) - { - string vrfName = m_vrfOrch->getVRFname(port.m_vr_id); - - if (ip_prefix.getIp().getAddrScope() == IpAddress::LINK_SCOPE) - { - SWSS_LOG_INFO("Ignoring SET IP Address: %s in %s, Same IP configured in %s, vrf: %s ", - ip_prefix.to_string().c_str(), alias.c_str(), out_alias.c_str(), vrfName.empty()? "default": vrfName.c_str()); - } - else - { - SWSS_LOG_ERROR("Ignoring SET IP Address: %s in %s, Same IP configured in %s, vrf: %s ", - ip_prefix.to_string().c_str(), alias.c_str(), out_alias.c_str(), vrfName.empty()? "default": vrfName.c_str()); - } - - it = consumer.m_toSync.erase(it); - continue; - } - } + it++; + continue; + } + if (gPortsOrch->getPort(alias, port)) + { /* Set nat zone id */ if ((!nat_zone.empty()) and (port.m_nat_zone_id != nat_zone_id)) { @@ -909,12 +891,6 @@ void IntfsOrch::doTask(Consumer &consumer) gPortsOrch->setPort(alias, port); } } - - if (!setIntf(alias, vrf_id, ip_prefix_in_key ? &ip_prefix : nullptr, adminUp, mtu)) - { - it++; - continue; - } } if (mac) @@ -1240,36 +1216,6 @@ bool IntfsOrch::removeRouterIntfs(Port &port) return true; } -bool IntfsOrch::hasIp2MeAddr(sai_object_id_t in_vrf_id, const IpPrefix &in_ip_prefix, string *out_alias) -{ - sai_object_id_t vrf_id = gVirtualRouterId; - - for (auto it = m_syncdIntfses.begin(); it != m_syncdIntfses.end(); it++) - { - for (auto prefix : it->second.ip_addresses) - { - if (prefix.isAddressInSubnet(in_ip_prefix.getIp())) - { - vrf_id = m_syncdIntfses[it->first].vrf_id; - string vrfName = m_vrfOrch->getVRFname(vrf_id); - - if (vrf_id == in_vrf_id) - { - *out_alias = it->first; - - if (prefix == in_ip_prefix) - { - SWSS_LOG_NOTICE("IP2Me Matched Addr %s, Intf = %s vrf %s ", prefix.to_string().c_str(), it->first.c_str(), vrfName.c_str()); - return true; - } - } - } - } - } - - return false; -} - void IntfsOrch::addIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix) { sai_route_entry_t unicast_route_entry; diff --git a/orchagent/intfsorch.h b/orchagent/intfsorch.h index f1fe1a04b2..5605abf133 100644 --- a/orchagent/intfsorch.h +++ b/orchagent/intfsorch.h @@ -57,8 +57,6 @@ class IntfsOrch : public Orch bool setIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr, const bool adminUp = true, const uint32_t mtu = 0); bool removeIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr); - bool hasIp2MeAddr(sai_object_id_t in_vrf_id, const IpPrefix &in_ip_prefix, string *out_alias); - void addIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix); void removeIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix); From e85122ea61007e73dfc761f9157f7f5faf86b992 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Mon, 7 Jun 2021 05:01:07 -0700 Subject: [PATCH 07/31] Added vs testcase for interface. --- tests/test_interface.py | 83 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/tests/test_interface.py b/tests/test_interface.py index ac1446481a..979407a920 100644 --- a/tests/test_interface.py +++ b/tests/test_interface.py @@ -1964,6 +1964,89 @@ def test_LoopbackInterfaceIpv4AddressWithVrf(self, dvs, testlog): assert False + def create_ipv6_link_local(self, interface): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL_INTERFACE" + elif interface.startswith("Vlan"): + tbl_name = "VLAN_INTERFACE" + else: + tbl_name = "INTERFACE" + + fvs = swsscommon.FieldValuePairs([("ipv6_use_link_local_only", "enable")]) + tbl = swsscommon.Table(self.cdb, tbl_name) + tbl.set(interface, fvs) + time.sleep(1) + + def remove_ipv6_link_local(self, interface): + if interface.startswith("PortChannel"): + tbl_name = "PORTCHANNEL_INTERFACE" + elif interface.startswith("Vlan"): + tbl_name = "VLAN_INTERFACE" + else: + tbl_name = "INTERFACE" + tbl = swsscommon.Table(self.cdb, tbl_name) + tbl._del(interface) + time.sleep(1) + + def test_InterfaceIpv6LinkLocalOnly(self, dvs, testlog): + # Check enables ipv6-link-local mode is creates the routing interface + self.setup_db(dvs) + + # create ipv6 link local interface + self.create_ipv6_link_local("Ethernet8", "") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Ethernet8") + assert status == True + for fv in fvs: + assert fv[0] == "ipv6_use_link_local_only" + assert fv[1] == "enable" + + # bring up interface + self.set_admin_status(dvs, "Ethernet8", "up") + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) == 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + + # remove interface + self.remove_ipv6_link_local("Ethernet8") + + # bring down interface + self.set_admin_status(dvs, "Ethernet8", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Ethernet8") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Ethernet8" + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface + assert len(intf_entries) == 1 + + # Add Dummy always-pass test at end as workaroud # for issue when Flaky fail on final test it invokes module tear-down before retrying def test_nonflaky_dummy(): From 2642fa2d3193172fec919dc302669e982b77f032 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Mon, 7 Jun 2021 06:34:53 -0700 Subject: [PATCH 08/31] Fixed LGTM issue. --- tests/test_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_interface.py b/tests/test_interface.py index 979407a920..4f55e39db2 100644 --- a/tests/test_interface.py +++ b/tests/test_interface.py @@ -1993,7 +1993,7 @@ def test_InterfaceIpv6LinkLocalOnly(self, dvs, testlog): self.setup_db(dvs) # create ipv6 link local interface - self.create_ipv6_link_local("Ethernet8", "") + self.create_ipv6_link_local("Ethernet8") # check application database tbl = swsscommon.Table(self.pdb, "INTF_TABLE") From 37afab45a5b880223245b25f9db8406aca5bd257 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Mon, 7 Jun 2021 09:51:13 -0700 Subject: [PATCH 09/31] Added vs testcase for LAG and Vlan interfaces. --- tests/test_interface.py | 157 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 152 insertions(+), 5 deletions(-) diff --git a/tests/test_interface.py b/tests/test_interface.py index 4f55e39db2..a57970b1e5 100644 --- a/tests/test_interface.py +++ b/tests/test_interface.py @@ -1989,7 +1989,7 @@ def remove_ipv6_link_local(self, interface): time.sleep(1) def test_InterfaceIpv6LinkLocalOnly(self, dvs, testlog): - # Check enables ipv6-link-local mode is creates the routing interface + # Check enable/disable ipv6-link-local mode for physical interface self.setup_db(dvs) # create ipv6 link local interface @@ -2000,8 +2000,11 @@ def test_InterfaceIpv6LinkLocalOnly(self, dvs, testlog): (status, fvs) = tbl.get("Ethernet8") assert status == True for fv in fvs: - assert fv[0] == "ipv6_use_link_local_only" - assert fv[1] == "enable" + if fv[0] == "ipv6_use_link_local_only": + ipv6_link_local_found = True + assert fv[1] == "enable" + + assert ipv6_link_local_found # bring up interface self.set_admin_status(dvs, "Ethernet8", "up") @@ -2016,7 +2019,7 @@ def test_InterfaceIpv6LinkLocalOnly(self, dvs, testlog): (status, fvs) = tbl.get(key) assert status == True # a port based router interface has five field/value tuples - if len(fvs) == 5: + if len(fvs) >= 5: for fv in fvs: if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" @@ -2024,7 +2027,7 @@ def test_InterfaceIpv6LinkLocalOnly(self, dvs, testlog): if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": assert fv[1] == "9100" - # remove interface + # remove ipv6 link local interface self.remove_ipv6_link_local("Ethernet8") # bring down interface @@ -2046,6 +2049,150 @@ def test_InterfaceIpv6LinkLocalOnly(self, dvs, testlog): # one loopback router interface assert len(intf_entries) == 1 + def test_LagInterfaceIpv6LinkLocalOnly(self, dvs, testlog): + # Check enable/disable ipv6-link-local mode for lag interface + self.setup_db(dvs) + + # create port channel + self.create_port_channel("PortChannel001") + + # bring up interface + self.set_admin_status(dvs, "PortChannel001", "up") + + # create ipv6 link local interface + self.create_ipv6_link_local("PortChannel001") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("PortChannel001") + assert status == True + for fv in fvs: + if fv[0] == "ipv6_use_link_local_only": + ipv6_link_local_found = True + assert fv[1] == "enable" + + assert ipv6_link_local_found + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one port based router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + # a port based router interface has five field/value tuples + if len(fvs) >= 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_PORT" + # the default MTU without any configuration is 9100 + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_MTU": + assert fv[1] == "9100" + + # remove ipv6 link local interface + self.remove_ipv6_link_local("PortChannel001") + + # 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") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "PortChannel001" + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface + assert len(intf_entries) == 1 + + # remove port channel + self.remove_port_channel("PortChannel001") + + + def test_VLanInterfaceIpv6LinkLocalOnly(self, dvs, testlog): + # Check enable/disable ipv6-link-local mode for vlan interface + self.setup_db(dvs) + + # create vlan + self.create_vlan("10") + + # add vlan member + self.create_vlan_member("10", "Ethernet0") + + # bring up interface + self.set_admin_status(dvs, "Ethernet0", "up") + self.set_admin_status(dvs, "Vlan10", "up") + + # create ipv6 link local interface + self.create_ipv6_link_local("Vlan10") + + # check asic database and get vlan_oid + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_entries = [k for k in tbl.getKeys() if k != dvs.asicdb.default_vlan_id] + assert len(vlan_entries) == 1 + vlan_oid = vlan_entries[0] + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + (status, fvs) = tbl.get("Vlan10") + assert status == True + for fv in fvs: + if fv[0] == "ipv6_use_link_local_only": + ipv6_link_local_found = True + assert fv[1] == "enable" + + assert ipv6_link_local_found + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface one vlan router interface + assert len(intf_entries) == 2 + + for key in intf_entries: + (status, fvs) = tbl.get(key) + assert status == True + if len(fvs) >= 5: + for fv in fvs: + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_TYPE": + assert fv[1] == "SAI_ROUTER_INTERFACE_TYPE_VLAN" + if fv[0] == "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID": + assert fv[1] == vlan_oid + + + # remove ipv6 link local interface + self.remove_ipv6_link_local("Vlan10") + + # remove vlan member + self.remove_vlan_member("10", "Ethernet0") + + # remove vlan + self.remove_vlan("10") + + # bring down interface + self.set_admin_status(dvs, "Ethernet0", "down") + + # check application database + tbl = swsscommon.Table(self.pdb, "INTF_TABLE:Vlan10") + intf_entries = tbl.getKeys() + assert len(intf_entries) == 0 + + tbl = swsscommon.Table(self.pdb, "INTF_TABLE") + intf_entries = tbl.getKeys() + for entry in intf_entries: + assert entry[0] != "Vlan10" + + # check ASIC router interface database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE") + intf_entries = tbl.getKeys() + # one loopback router interface + assert len(intf_entries) == 1 + # Add Dummy always-pass test at end as workaroud # for issue when Flaky fail on final test it invokes module tear-down before retrying From a1670641aa9305314f4b38bab886ecb2ba92130e Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Fri, 25 Jun 2021 02:58:49 -0700 Subject: [PATCH 10/31] Addressed review comments --- fpmsyncd/routesync.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fpmsyncd/routesync.cpp b/fpmsyncd/routesync.cpp index 48a1a0df58..9910dca07e 100644 --- a/fpmsyncd/routesync.cpp +++ b/fpmsyncd/routesync.cpp @@ -916,11 +916,6 @@ string RouteSync::getNextHopGw(struct rtnl_route *route_obj) if (addr) { char gw_ip[MAX_ADDR_SIZE + 1] = {0}; - if (nl_addr_get_prefixlen(addr) > IPV4_MAX_BITLEN - && nl_addr_get_family(addr) == AF_INET) - { - nl_addr_set_family(addr, AF_INET6); - } nl_addr2str(addr, gw_ip, MAX_ADDR_SIZE); result += gw_ip; } From 2b7d62ce1bfb39cc83da0d446e37756db01c06b8 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Thu, 1 Jul 2021 02:02:12 -0700 Subject: [PATCH 11/31] Validation check added in remove_vlan() --- tests/test_evpn_l3_vxlan.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 6f541b20a6..2190aa20d6 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -194,10 +194,15 @@ def create_vlan(dvs, vlan_name, vlan_ids): def remove_vlan(dvs, vlan): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) + asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VLAN") tbl._del("Vlan" + vlan) time.sleep(1) + vlan_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + entries = set(vlan_tbl.getKeys()) + assert len(entries) == 0 + def create_vlan_member(dvs, vlan, interface, tagging_mode="untagged"): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VLAN_MEMBER") From 373cc3e6036c3bcc0b464fc7247589f9ecf4489c Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Thu, 1 Jul 2021 05:15:11 -0700 Subject: [PATCH 12/31] Added vlan verification using dvs_vlan --- tests/test_evpn_l3_vxlan.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 2190aa20d6..25c1e04a79 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -5,6 +5,7 @@ import pytest from pprint import pprint +@pytest.mark.usefixtures('dvs_vlan_manager') def create_entry(tbl, key, pairs): fvs = swsscommon.FieldValuePairs(pairs) @@ -194,15 +195,10 @@ def create_vlan(dvs, vlan_name, vlan_ids): def remove_vlan(dvs, vlan): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) - asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VLAN") tbl._del("Vlan" + vlan) time.sleep(1) - vlan_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - entries = set(vlan_tbl.getKeys()) - assert len(entries) == 0 - def create_vlan_member(dvs, vlan, interface, tagging_mode="untagged"): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VLAN_MEMBER") @@ -1085,7 +1081,8 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - remove_vlan(dvs, "100") + self.dvs_vlan.remove_vlan("100") + self.dvs_vlan.get_and_verify_vlan_ids(0) # Test 2 - Create and Delete DIP Tunnel on adding and removing prefix route From e2d14b07567a9217eb1857adeaa329c0c9da6696 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Thu, 1 Jul 2021 08:27:35 -0700 Subject: [PATCH 13/31] Corrected vlan verification --- tests/test_evpn_l3_vxlan.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 25c1e04a79..3cedc66164 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -5,7 +5,6 @@ import pytest from pprint import pprint -@pytest.mark.usefixtures('dvs_vlan_manager') def create_entry(tbl, key, pairs): fvs = swsscommon.FieldValuePairs(pairs) @@ -195,9 +194,13 @@ def create_vlan(dvs, vlan_name, vlan_ids): def remove_vlan(dvs, vlan): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) + asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VLAN") tbl._del("Vlan" + vlan) - time.sleep(1) + time.sleep(2) + vlan_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + entries = set(vlan_tbl.getKeys()) + assert len(entries) == 1 def create_vlan_member(dvs, vlan, interface, tagging_mode="untagged"): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) @@ -1081,8 +1084,7 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - self.dvs_vlan.remove_vlan("100") - self.dvs_vlan.get_and_verify_vlan_ids(0) + remove_vlan(dvs, "100") # Test 2 - Create and Delete DIP Tunnel on adding and removing prefix route From dda4999dd02059d690053afea2ee38364f21c83e Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Thu, 1 Jul 2021 13:36:25 -0700 Subject: [PATCH 14/31] Correction in Vlan create function --- tests/test_evpn_l3_vxlan.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 3cedc66164..db27e1bc38 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -165,12 +165,14 @@ def create_vrf_routes_ecmp(dvs, prefix, vrf_name, ecmp_nexthop_attributes): time.sleep(2) -def create_vlan(dvs, vlan_name, vlan_ids): +def create_vlan(dvs, vlan_name): asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) vlan_id = vlan_name[4:] - + tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_ids = set(tbl.getKeys()) + # create vlan create_entry_tbl( conf_db, @@ -1101,8 +1103,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): print ("\n\nTesting Create and Delete DIP Tunnel on adding and removing prefix route") print ("\tCreate SIP Tunnel") - vlan_ids = get_exist_entries(dvs, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - vlan_oid = create_vlan(dvs,"Vlan100", vlan_ids) + vlan_oid = create_vlan(dvs,"Vlan100") create_vxlan_tunnel(dvs, tunnel_name, '6.6.6.6') create_evpn_nvo(dvs, 'nvo1', tunnel_name) From 0e1cb0605c2d9cf5d2e666d1fd64fe0b6181ebd5 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Fri, 2 Jul 2021 02:14:56 -0700 Subject: [PATCH 15/31] Modified in Vlan create --- tests/test_evpn_l3_vxlan.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index db27e1bc38..e732b1bd6f 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -170,8 +170,7 @@ def create_vlan(dvs, vlan_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) vlan_id = vlan_name[4:] - tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - vlan_ids = set(tbl.getKeys()) + vlan_oid_found = False # create vlan create_entry_tbl( @@ -184,14 +183,23 @@ def create_vlan(dvs, vlan_name): time.sleep(1) - vlan_oid = get_created_entry(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN", vlan_ids) + tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_ids = set(tbl.getKeys()) - check_object(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN", vlan_oid, - { - "SAI_VLAN_ATTR_VLAN_ID": vlan_id, - } - ) + for vlan in vlan_ids: + status, fvs = tbl.get(vlan) + assert status, "Got an error when get a key" + + for name, value in fvs: + if name == SAI_VLAN_ATTR_VLAN_ID and value == vlan_id: + vlan_oid = vlan + vlan_oid_found = True + break + + if vlan_oid_found == True: + break + assert vlan_oid_found, "Vlan OID not found" return vlan_oid def remove_vlan(dvs, vlan): From 7574a3a62e06524fc261a5807da577733689f8cc Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Fri, 2 Jul 2021 05:42:32 -0700 Subject: [PATCH 16/31] Few more corrections --- tests/test_evpn_l3_vxlan.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index e732b1bd6f..e5bf55e3e4 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -186,15 +186,18 @@ def create_vlan(dvs, vlan_name): tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") vlan_ids = set(tbl.getKeys()) + expected_attributes = { "SAI_VLAN_ATTR_VLAN_ID": vlan_id } + for vlan in vlan_ids: status, fvs = tbl.get(vlan) assert status, "Got an error when get a key" for name, value in fvs: - if name == SAI_VLAN_ATTR_VLAN_ID and value == vlan_id: - vlan_oid = vlan - vlan_oid_found = True - break + if name in expected_attributes: + if expected_attributes[name] == value: + vlan_oid = vlan + vlan_oid_found = True + break if vlan_oid_found == True: break From bf6336a6ef1b812d51db3d2a9f8f106698d2f868 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Fri, 2 Jul 2021 08:49:47 -0700 Subject: [PATCH 17/31] Added validation checks in remove_vrf --- tests/test_evpn_l3_vxlan.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index e5bf55e3e4..95d3504078 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -970,9 +970,6 @@ def create_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) - tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - initial_entries = set(tbl.getKeys()) - attrs = [ ("vni", "0"), ] @@ -981,10 +978,6 @@ def create_vrf(self, dvs, vrf_name): tbl.set(vrf_name, fvs) time.sleep(2) - tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - current_entries = set(tbl.getKeys()) - assert len(current_entries - initial_entries) == 1 - new_vr_ids = get_created_entries(asic_db, self.ASIC_VRF_TABLE, self.vnet_vr_ids, 1) self.vnet_vr_ids.update(new_vr_ids) self.vr_map[vrf_name] = { 'ing':new_vr_ids[0], 'egr':new_vr_ids[0]} @@ -993,9 +986,13 @@ def create_vrf(self, dvs, vrf_name): def remove_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) + asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VRF") tbl._del(vrf_name) time.sleep(2) + vrf_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + entries = set(vrf_tbl.getKeys()) + assert len(entries) == 0 def is_vrf_attributes_correct(self, db, table, key, expected_attributes): From ae7a1698983b98e1dacc14fddf848d976f244ea8 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Fri, 2 Jul 2021 12:52:08 -0700 Subject: [PATCH 18/31] Added different VRs in the testcase --- tests/test_evpn_l3_vxlan.py | 203 +++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 98 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 95d3504078..1661c79477 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -970,6 +970,9 @@ def create_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) + tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + initial_entries = set(tbl.getKeys()) + attrs = [ ("vni", "0"), ] @@ -978,6 +981,10 @@ def create_vrf(self, dvs, vrf_name): tbl.set(vrf_name, fvs) time.sleep(2) + tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + current_entries = set(tbl.getKeys()) + assert len(current_entries - initial_entries) == 1 + new_vr_ids = get_created_entries(asic_db, self.ASIC_VRF_TABLE, self.vnet_vr_ids, 1) self.vnet_vr_ids.update(new_vr_ids) self.vr_map[vrf_name] = { 'ing':new_vr_ids[0], 'egr':new_vr_ids[0]} @@ -992,7 +999,7 @@ def remove_vrf(self, dvs, vrf_name): time.sleep(2) vrf_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") entries = set(vrf_tbl.getKeys()) - assert len(entries) == 0 + assert len(entries) == 1 def is_vrf_attributes_correct(self, db, table, key, expected_attributes): @@ -1033,7 +1040,7 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED' + vrf_map_name = 'evpn_map_1000_Vrf-RED1' vxlan_obj.fetch_exist_entries(dvs) @@ -1046,8 +1053,8 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): print ("\tCreate Vlan-VNI map and VRF-VNI map") create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') - vxlan_obj.create_vrf(dvs, "Vrf-RED") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED1") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED1', '1000') print ("\tTesting VRF-VNI map in APP DB") vlanlist = ['100'] @@ -1060,7 +1067,7 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): for an in range(len(exp_attrs)): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED1', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1079,12 +1086,12 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel VRF VNI Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED1', '1000') print ("\tTesting Tunnel VRF VNI Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') - vxlan_obj.remove_vrf(dvs, "Vrf-RED") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED1') + vxlan_obj.remove_vrf(dvs, "Vrf-RED1") + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED1', '1000') print ("\tTesting Tunnel Vlan VNI Map entry removal") remove_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') @@ -1106,7 +1113,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED' + vrf_map_name = 'evpn_map_1000_Vrf-RED2' vxlan_obj.fetch_exist_entries(dvs) print ("\n\nTesting Create and Delete DIP Tunnel on adding and removing prefix route") @@ -1119,8 +1126,8 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') print ("\tTesting VRF-VNI map in APP DB") - vxlan_obj.create_vrf(dvs, "Vrf-RED") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED2") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED2', '1000') vlanlist = ['100'] vnilist = ['1000'] @@ -1132,7 +1139,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): for an in range(len(exp_attrs)): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED2', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1151,31 +1158,31 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel Vrf Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED2', '1000') print ("\tTesting VLAN 100 interface creation") - create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED", "100.100.3.1/24") - vxlan_obj.check_router_interface(dvs, 'Vrf-RED', vlan_oid, 2) + create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED2", "100.100.3.1/24") + vxlan_obj.check_router_interface(dvs, 'Vrf-RED2', vlan_oid, 2) print ("\tTest VRF IPv4 Route with Tunnel Nexthop Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTesting DIP tunnel 7.7.7.7 creation") vxlan_obj.check_vxlan_dip_tunnel(dvs, tunnel_name, '6.6.6.6', '7.7.7.7') print ("\tTest VRF IPv4 Route with Tunnel Nexthop Delete") - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED2', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2') print ("\tTesting DIP tunnel 7.7.7.7 deletion") vxlan_obj.check_vxlan_dip_tunnel_delete(dvs, '7.7.7.7') print ("\tTesting Tunnel Vrf Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED2') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED2', '1000') print ("\tTesting Vlan 100 interface delete") delete_vlan_interface(dvs, "Vlan100", "100.100.3.1/24") @@ -1189,7 +1196,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - vxlan_obj.remove_vrf(dvs, "Vrf-RED") + vxlan_obj.remove_vrf(dvs, "Vrf-RED2") remove_vlan_member(dvs, "100", "Ethernet24") remove_vlan(dvs, "100") @@ -1203,7 +1210,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED' + vrf_map_name = 'evpn_map_1000_Vrf-RED3' vxlan_obj.fetch_exist_entries(dvs) print ("\n\nTesting IPv4 Route and Overlay Nexthop Add and Delete") @@ -1215,8 +1222,8 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): print ("\tCreate Vlan-VNI map and VRF-VNI map") create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') - vxlan_obj.create_vrf(dvs, "Vrf-RED") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED3") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED3', '1000') print ("\tTesting VRF-VNI map in APP DB") vlanlist = ['100'] @@ -1229,7 +1236,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): for an in range(len(exp_attrs)): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED3', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1248,7 +1255,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel Vrf Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED3', '1000') print ("\tTesting First DIP tunnel creation to 7.7.7.7") create_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7', '1000') @@ -1266,37 +1273,37 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): vxlan_obj.check_vlan_extension(dvs, '100', '7.7.7.7') print ("\tTesting VLAN 100 interface creation") - create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED", "100.100.3.1/24") - vxlan_obj.check_router_interface(dvs, 'Vrf-RED', vxlan_obj.vlan_id_map['100'], 2) + create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED3", "100.100.3.1/24") + vxlan_obj.check_router_interface(dvs, 'Vrf-RED3', vxlan_obj.vlan_id_map['100'], 2) print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Delete") - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') print ("\n\nTesting IPv4 Route and Overlay Nexthop Update") print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop change from 7.7.7.7 to 8.8.8.8") - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Previous Tunnel Nexthop 7.7.7.7 is removed") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv4 Route and Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') print ("\n\nTest VRF IPv4 Route with ECMP Tunnel Nexthop Add and Delete") vxlan_obj.fetch_exist_entries(dvs) @@ -1309,28 +1316,28 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): ] print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Add") - create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', tunnel_name, nh_count) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', tunnel_name, nh_count) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[0]) check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[1]) vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') print ("\n\nTest VRF IPv4 Route with Tunnel Nexthop update from non-ECMP to ECMP") print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') ecmp_nexthop_attr = [ ("nexthop", "7.7.7.7,8.8.8.8"), @@ -1340,36 +1347,36 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): ] print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Udpate") - create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', tunnel_name, nh_count, 1) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', tunnel_name, nh_count, 1) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\n\nTest VRF IPv4 Route with Tunnel Nexthop update from ECMP to non-ECMP") print ("\tTest VRF IPv4 Route with Tunnel Nexthop 8.8.8.8 Update") - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Tunnel Nexthop 7.7.7.7 is deleted") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop ECMP Group is deleted") vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) print ("\tTest VRF IPv4 Route with Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') print ("\n\nTest DIP and SIP Tunnel Deletion ") print ("\tTesting Tunnel Vrf VNI Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED3') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED3', '1000') print ("\tTesting LastVlan removal and DIP tunnel delete for 7.7.7.7") remove_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7') @@ -1393,7 +1400,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - vxlan_obj.remove_vrf(dvs, "Vrf-RED") + vxlan_obj.remove_vrf(dvs, "Vrf-RED3") remove_vlan_member(dvs, "100", "Ethernet24") remove_vlan(dvs, "100") @@ -1407,7 +1414,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED' + vrf_map_name = 'evpn_map_1000_Vrf-RED4' vxlan_obj.fetch_exist_entries(dvs) print ("\n\nTesting IPv6 Route and Overlay Nexthop Add and Delete") @@ -1420,8 +1427,8 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') print ("\tTesting VRF-VNI map in APP DB") - vxlan_obj.create_vrf(dvs, "Vrf-RED") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED4") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED4', '1000') vlanlist = ['100'] vnilist = ['1000'] @@ -1434,7 +1441,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] print ("\tCheck VRF Table in APP DB") - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED4', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1453,7 +1460,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel Vrf Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED4', '1000') print ("\tTesting First DIP tunnel creation to 7.7.7.7") create_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7', '1000') @@ -1472,37 +1479,37 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): vxlan_obj.fetch_exist_entries(dvs) print ("\tTesting VLAN 100 interface creation") - create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED", "2001::8/64") - vxlan_obj.check_router_interface(dvs, 'Vrf-RED', vxlan_obj.vlan_id_map['100'], 2) + create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED4", "2001::8/64") + vxlan_obj.check_router_interface(dvs, 'Vrf-RED4', vxlan_obj.vlan_id_map['100'], 2) print ("\tTest VRF IPv6 Route with Tunnel Nexthop Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv6 Route with Tunnel Nexthop Delete") - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') print ("\n\nTesting IPv6 Route and Overlay Nexthop Update") print ("\tTest VRF IPv6 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop change from 7.7.7.7 to 8.8.8.8") - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Previous Tunnel Nexthop 7.7.7.7 is removed") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv6 Route and Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') print ("\n\nTest VRF IPv6 Route with ECMP Tunnel Nexthop Add and delete") vxlan_obj.fetch_exist_entries(dvs) @@ -1515,28 +1522,28 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): ] print ("\tTest VRF IPv6 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Add") - create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', tunnel_name, nh_count) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', tunnel_name, nh_count) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\tTest VRF IPv6 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[0]) check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[1]) vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') print ("\n\nTest VRF IPv6 Route with Tunnel Nexthop update from non-ECMP to ECMP") print ("\tTest VRF IPv6 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Udpate") ecmp_nexthop_attr = [ @@ -1546,36 +1553,36 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): ("router_mac", "00:11:11:11:11:11,00:22:22:22:22:22"), ] - create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', tunnel_name, nh_count, 1) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', tunnel_name, nh_count, 1) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\n\nTest VRF IPv6 Route with Tunnel Nexthop update from ECMP to non-ECMP") print ("\tTest VRF IPv6 Route with Tunnel Nexthop 8.8.8.8 Update") - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Tunnel Nexthop 7.7.7.7 is deleted") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop ECMP Group is deleted") vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) print ("\tTest VRF IPv6 Route with Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') print ("\n\nTest DIP and SIP Tunnel Deletion ") print ("\tTesting Tunnel Vrf Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED4') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED4', '1000') print ("\tTesting LastVlan removal and DIP tunnel delete for 7.7.7.7") remove_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7') @@ -1599,7 +1606,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - vxlan_obj.remove_vrf(dvs, "Vrf-RED") + vxlan_obj.remove_vrf(dvs, "Vrf-RED4") remove_vlan_member(dvs, "100", "Ethernet24") remove_vlan(dvs, "100") From 1e035232691b5fa1ae5273cf0ff721250eddfac1 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Fri, 2 Jul 2021 23:51:16 -0700 Subject: [PATCH 19/31] Few correction in create_vrf --- tests/test_evpn_l3_vxlan.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 1661c79477..c1ae3d80c8 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -970,9 +970,6 @@ def create_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) - tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - initial_entries = set(tbl.getKeys()) - attrs = [ ("vni", "0"), ] @@ -981,10 +978,6 @@ def create_vrf(self, dvs, vrf_name): tbl.set(vrf_name, fvs) time.sleep(2) - tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - current_entries = set(tbl.getKeys()) - assert len(current_entries - initial_entries) == 1 - new_vr_ids = get_created_entries(asic_db, self.ASIC_VRF_TABLE, self.vnet_vr_ids, 1) self.vnet_vr_ids.update(new_vr_ids) self.vr_map[vrf_name] = { 'ing':new_vr_ids[0], 'egr':new_vr_ids[0]} From f99203ef1a547e48e67dee6a9bb37324be39f9f1 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Sat, 3 Jul 2021 02:54:40 -0700 Subject: [PATCH 20/31] Cleanup in remove_vrf --- tests/test_evpn_l3_vxlan.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index c1ae3d80c8..9029c58930 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -993,6 +993,7 @@ def remove_vrf(self, dvs, vrf_name): vrf_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") entries = set(vrf_tbl.getKeys()) assert len(entries) == 1 + self.vnet_vr_ids = entries def is_vrf_attributes_correct(self, db, table, key, expected_attributes): From c9fa5ea234bc0971f6fccbf0686730098bf86818 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Sat, 3 Jul 2021 07:51:47 -0700 Subject: [PATCH 21/31] Added few more cleanup --- tests/test_evpn_l3_vxlan.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 9029c58930..028976aece 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -1037,6 +1037,7 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): vrf_map_name = 'evpn_map_1000_Vrf-RED1' vxlan_obj.fetch_exist_entries(dvs) + vxlan_obj.remove_vrf(dvs, "Vrf-RED1") print ("\n\nTesting Create and Delete SIP Tunnel and VRF VNI Map entries") print ("\tCreate SIP Tunnel") @@ -1109,6 +1110,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): map_name = 'map_1000_100' vrf_map_name = 'evpn_map_1000_Vrf-RED2' vxlan_obj.fetch_exist_entries(dvs) + vxlan_obj.remove_vrf(dvs, "Vrf-RED2") print ("\n\nTesting Create and Delete DIP Tunnel on adding and removing prefix route") print ("\tCreate SIP Tunnel") @@ -1206,6 +1208,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): map_name = 'map_1000_100' vrf_map_name = 'evpn_map_1000_Vrf-RED3' vxlan_obj.fetch_exist_entries(dvs) + vxlan_obj.remove_vrf(dvs, "Vrf-RED3") print ("\n\nTesting IPv4 Route and Overlay Nexthop Add and Delete") print ("\tCreate SIP Tunnel") @@ -1410,6 +1413,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): map_name = 'map_1000_100' vrf_map_name = 'evpn_map_1000_Vrf-RED4' vxlan_obj.fetch_exist_entries(dvs) + vxlan_obj.remove_vrf(dvs, "Vrf-RED4") print ("\n\nTesting IPv6 Route and Overlay Nexthop Add and Delete") print ("\tCreate SIP Tunnel") From 5d36b601aa9f8e3c8bd3f89049ae5cfe23a8210a Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Sat, 3 Jul 2021 10:55:08 -0700 Subject: [PATCH 22/31] Added few more cleanup in create_vrf --- tests/test_evpn_l3_vxlan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 028976aece..25eabfdc23 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -982,7 +982,7 @@ def create_vrf(self, dvs, vrf_name): self.vnet_vr_ids.update(new_vr_ids) self.vr_map[vrf_name] = { 'ing':new_vr_ids[0], 'egr':new_vr_ids[0]} - return list(current_entries - initial_entries)[0] + return new_vr_ids def remove_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) From 122afaa28d2363bf08234624de7adc1dcd228804 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Sat, 3 Jul 2021 22:38:31 -0700 Subject: [PATCH 23/31] Reverted the changes tried for l3 vxlan test case --- tests/test_evpn_l3_vxlan.py | 250 +++++++++++++++++------------------- 1 file changed, 116 insertions(+), 134 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 25eabfdc23..6f541b20a6 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -165,13 +165,12 @@ def create_vrf_routes_ecmp(dvs, prefix, vrf_name, ecmp_nexthop_attributes): time.sleep(2) -def create_vlan(dvs, vlan_name): +def create_vlan(dvs, vlan_name, vlan_ids): asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) vlan_id = vlan_name[4:] - vlan_oid_found = False - + # create vlan create_entry_tbl( conf_db, @@ -183,37 +182,21 @@ def create_vlan(dvs, vlan_name): time.sleep(1) - tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - vlan_ids = set(tbl.getKeys()) - - expected_attributes = { "SAI_VLAN_ATTR_VLAN_ID": vlan_id } - - for vlan in vlan_ids: - status, fvs = tbl.get(vlan) - assert status, "Got an error when get a key" - - for name, value in fvs: - if name in expected_attributes: - if expected_attributes[name] == value: - vlan_oid = vlan - vlan_oid_found = True - break + vlan_oid = get_created_entry(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN", vlan_ids) - if vlan_oid_found == True: - break + check_object(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN", vlan_oid, + { + "SAI_VLAN_ATTR_VLAN_ID": vlan_id, + } + ) - assert vlan_oid_found, "Vlan OID not found" return vlan_oid def remove_vlan(dvs, vlan): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) - asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VLAN") tbl._del("Vlan" + vlan) - time.sleep(2) - vlan_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - entries = set(vlan_tbl.getKeys()) - assert len(entries) == 1 + time.sleep(1) def create_vlan_member(dvs, vlan, interface, tagging_mode="untagged"): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) @@ -970,6 +953,9 @@ def create_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) + tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + initial_entries = set(tbl.getKeys()) + attrs = [ ("vni", "0"), ] @@ -978,22 +964,21 @@ def create_vrf(self, dvs, vrf_name): tbl.set(vrf_name, fvs) time.sleep(2) + tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + current_entries = set(tbl.getKeys()) + assert len(current_entries - initial_entries) == 1 + new_vr_ids = get_created_entries(asic_db, self.ASIC_VRF_TABLE, self.vnet_vr_ids, 1) self.vnet_vr_ids.update(new_vr_ids) self.vr_map[vrf_name] = { 'ing':new_vr_ids[0], 'egr':new_vr_ids[0]} - return new_vr_ids + return list(current_entries - initial_entries)[0] def remove_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) - asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VRF") tbl._del(vrf_name) time.sleep(2) - vrf_tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - entries = set(vrf_tbl.getKeys()) - assert len(entries) == 1 - self.vnet_vr_ids = entries def is_vrf_attributes_correct(self, db, table, key, expected_attributes): @@ -1034,10 +1019,9 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED1' + vrf_map_name = 'evpn_map_1000_Vrf-RED' vxlan_obj.fetch_exist_entries(dvs) - vxlan_obj.remove_vrf(dvs, "Vrf-RED1") print ("\n\nTesting Create and Delete SIP Tunnel and VRF VNI Map entries") print ("\tCreate SIP Tunnel") @@ -1048,8 +1032,8 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): print ("\tCreate Vlan-VNI map and VRF-VNI map") create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') - vxlan_obj.create_vrf(dvs, "Vrf-RED1") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED1', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') print ("\tTesting VRF-VNI map in APP DB") vlanlist = ['100'] @@ -1062,7 +1046,7 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): for an in range(len(exp_attrs)): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED1', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1081,12 +1065,12 @@ def test_sip_tunnel_vrf_vni_map(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel VRF VNI Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED1', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting Tunnel VRF VNI Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED1') - vxlan_obj.remove_vrf(dvs, "Vrf-RED1") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED1', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') + vxlan_obj.remove_vrf(dvs, "Vrf-RED") + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting Tunnel Vlan VNI Map entry removal") remove_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') @@ -1108,13 +1092,13 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED2' + vrf_map_name = 'evpn_map_1000_Vrf-RED' vxlan_obj.fetch_exist_entries(dvs) - vxlan_obj.remove_vrf(dvs, "Vrf-RED2") print ("\n\nTesting Create and Delete DIP Tunnel on adding and removing prefix route") print ("\tCreate SIP Tunnel") - vlan_oid = create_vlan(dvs,"Vlan100") + vlan_ids = get_exist_entries(dvs, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_oid = create_vlan(dvs,"Vlan100", vlan_ids) create_vxlan_tunnel(dvs, tunnel_name, '6.6.6.6') create_evpn_nvo(dvs, 'nvo1', tunnel_name) @@ -1122,8 +1106,8 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') print ("\tTesting VRF-VNI map in APP DB") - vxlan_obj.create_vrf(dvs, "Vrf-RED2") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED2', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') vlanlist = ['100'] vnilist = ['1000'] @@ -1135,7 +1119,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): for an in range(len(exp_attrs)): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED2', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1154,31 +1138,31 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel Vrf Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED2', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting VLAN 100 interface creation") - create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED2", "100.100.3.1/24") - vxlan_obj.check_router_interface(dvs, 'Vrf-RED2', vlan_oid, 2) + create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED", "100.100.3.1/24") + vxlan_obj.check_router_interface(dvs, 'Vrf-RED', vlan_oid, 2) print ("\tTest VRF IPv4 Route with Tunnel Nexthop Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTesting DIP tunnel 7.7.7.7 creation") vxlan_obj.check_vxlan_dip_tunnel(dvs, tunnel_name, '6.6.6.6', '7.7.7.7') print ("\tTest VRF IPv4 Route with Tunnel Nexthop Delete") - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED2', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED2') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') print ("\tTesting DIP tunnel 7.7.7.7 deletion") vxlan_obj.check_vxlan_dip_tunnel_delete(dvs, '7.7.7.7') print ("\tTesting Tunnel Vrf Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED2') - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED2', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting Vlan 100 interface delete") delete_vlan_interface(dvs, "Vlan100", "100.100.3.1/24") @@ -1192,7 +1176,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - vxlan_obj.remove_vrf(dvs, "Vrf-RED2") + vxlan_obj.remove_vrf(dvs, "Vrf-RED") remove_vlan_member(dvs, "100", "Ethernet24") remove_vlan(dvs, "100") @@ -1206,9 +1190,8 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED3' + vrf_map_name = 'evpn_map_1000_Vrf-RED' vxlan_obj.fetch_exist_entries(dvs) - vxlan_obj.remove_vrf(dvs, "Vrf-RED3") print ("\n\nTesting IPv4 Route and Overlay Nexthop Add and Delete") print ("\tCreate SIP Tunnel") @@ -1219,8 +1202,8 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): print ("\tCreate Vlan-VNI map and VRF-VNI map") create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') - vxlan_obj.create_vrf(dvs, "Vrf-RED3") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED3', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') print ("\tTesting VRF-VNI map in APP DB") vlanlist = ['100'] @@ -1233,7 +1216,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): for an in range(len(exp_attrs)): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED3', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1252,7 +1235,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel Vrf Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED3', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting First DIP tunnel creation to 7.7.7.7") create_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7', '1000') @@ -1270,37 +1253,37 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): vxlan_obj.check_vlan_extension(dvs, '100', '7.7.7.7') print ("\tTesting VLAN 100 interface creation") - create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED3", "100.100.3.1/24") - vxlan_obj.check_router_interface(dvs, 'Vrf-RED3', vxlan_obj.vlan_id_map['100'], 2) + create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED", "100.100.3.1/24") + vxlan_obj.check_router_interface(dvs, 'Vrf-RED', vxlan_obj.vlan_id_map['100'], 2) print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Delete") - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') print ("\n\nTesting IPv4 Route and Overlay Nexthop Update") print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop change from 7.7.7.7 to 8.8.8.8") - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Previous Tunnel Nexthop 7.7.7.7 is removed") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv4 Route and Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') print ("\n\nTest VRF IPv4 Route with ECMP Tunnel Nexthop Add and Delete") vxlan_obj.fetch_exist_entries(dvs) @@ -1313,28 +1296,28 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): ] print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Add") - create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', tunnel_name, nh_count) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', tunnel_name, nh_count) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[0]) check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[1]) vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') print ("\n\nTest VRF IPv4 Route with Tunnel Nexthop update from non-ECMP to ECMP") print ("\tTest VRF IPv4 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') ecmp_nexthop_attr = [ ("nexthop", "7.7.7.7,8.8.8.8"), @@ -1344,36 +1327,36 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): ] print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Udpate") - create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED3', tunnel_name, nh_count, 1) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "80.80.1.0/24", 'Vrf-RED', tunnel_name, nh_count, 1) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\n\nTest VRF IPv4 Route with Tunnel Nexthop update from ECMP to non-ECMP") print ("\tTest VRF IPv4 Route with Tunnel Nexthop 8.8.8.8 Update") - create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Tunnel Nexthop 7.7.7.7 is deleted") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop ECMP Group is deleted") vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) print ("\tTest VRF IPv4 Route with Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + delete_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED3', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED3') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "80.80.1.0/24", 'Vrf-RED') print ("\n\nTest DIP and SIP Tunnel Deletion ") print ("\tTesting Tunnel Vrf VNI Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED3') - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED3', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting LastVlan removal and DIP tunnel delete for 7.7.7.7") remove_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7') @@ -1397,7 +1380,7 @@ def test_dip_tunnel_ipv4_routes(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - vxlan_obj.remove_vrf(dvs, "Vrf-RED3") + vxlan_obj.remove_vrf(dvs, "Vrf-RED") remove_vlan_member(dvs, "100", "Ethernet24") remove_vlan(dvs, "100") @@ -1411,9 +1394,8 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): self.setup_db(dvs) tunnel_name = 'tunnel_2' map_name = 'map_1000_100' - vrf_map_name = 'evpn_map_1000_Vrf-RED4' + vrf_map_name = 'evpn_map_1000_Vrf-RED' vxlan_obj.fetch_exist_entries(dvs) - vxlan_obj.remove_vrf(dvs, "Vrf-RED4") print ("\n\nTesting IPv6 Route and Overlay Nexthop Add and Delete") print ("\tCreate SIP Tunnel") @@ -1425,8 +1407,8 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') print ("\tTesting VRF-VNI map in APP DB") - vxlan_obj.create_vrf(dvs, "Vrf-RED4") - create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED4', '1000') + vxlan_obj.create_vrf(dvs, "Vrf-RED") + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') vlanlist = ['100'] vnilist = ['1000'] @@ -1439,7 +1421,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): exp_attr[exp_attrs[an][0]] = exp_attrs[an][1] print ("\tCheck VRF Table in APP DB") - check_object(self.pdb, "VRF_TABLE", 'Vrf-RED4', exp_attr) + check_object(self.pdb, "VRF_TABLE", 'Vrf-RED', exp_attr) exp_attrs1 = [ ("vni", "1000"), @@ -1458,7 +1440,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): vxlan_obj.check_vxlan_tunnel_vlan_map_entry(dvs, tunnel_name, vlanlist, vnilist) print ("\tTesting Tunnel Vrf Map Entry") - vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED4', '1000') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting First DIP tunnel creation to 7.7.7.7") create_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7', '1000') @@ -1477,37 +1459,37 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): vxlan_obj.fetch_exist_entries(dvs) print ("\tTesting VLAN 100 interface creation") - create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED4", "2001::8/64") - vxlan_obj.check_router_interface(dvs, 'Vrf-RED4', vxlan_obj.vlan_id_map['100'], 2) + create_vlan_interface(dvs, "Vlan100", "Ethernet24", "Vrf-RED", "2001::8/64") + vxlan_obj.check_router_interface(dvs, 'Vrf-RED', vxlan_obj.vlan_id_map['100'], 2) print ("\tTest VRF IPv6 Route with Tunnel Nexthop Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv6 Route with Tunnel Nexthop Delete") - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') print ("\n\nTesting IPv6 Route and Overlay Nexthop Update") print ("\tTest VRF IPv6 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop change from 7.7.7.7 to 8.8.8.8") - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Previous Tunnel Nexthop 7.7.7.7 is removed") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv6 Route and Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') print ("\n\nTest VRF IPv6 Route with ECMP Tunnel Nexthop Add and delete") vxlan_obj.fetch_exist_entries(dvs) @@ -1520,28 +1502,28 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): ] print ("\tTest VRF IPv6 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Add") - create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', tunnel_name, nh_count) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', tunnel_name, nh_count) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\tTest VRF IPv6 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[0]) check_deleted_object(self.adb, vxlan_obj.ASIC_NEXT_HOP, ecmp_nhid_list[1]) vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') print ("\n\nTest VRF IPv6 Route with Tunnel Nexthop update from non-ECMP to ECMP") print ("\tTest VRF IPv6 Route with Tunnel Nexthop 7.7.7.7 Add") vxlan_obj.fetch_exist_entries(dvs) - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', "Vlan100", "00:11:11:11:11:11", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest VRF IPv4 Route with ECMP Tunnel Nexthop [7.7.7.7 , 8.8.8.8] Udpate") ecmp_nexthop_attr = [ @@ -1551,36 +1533,36 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): ("router_mac", "00:11:11:11:11:11,00:22:22:22:22:22"), ] - create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', ecmp_nexthop_attr) + create_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', ecmp_nexthop_attr) nh_count = 2 - ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED4', tunnel_name, nh_count, 1) + ecmp_nhid_list = vxlan_obj.check_vrf_routes_ecmp(dvs, "2002::8/64", 'Vrf-RED', tunnel_name, nh_count, 1) assert nh_count == len(ecmp_nhid_list) vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[0], '7.7.7.7', tunnel_name, '00:11:11:11:11:11', '1000') vxlan_obj.check_add_tunnel_nexthop(dvs, ecmp_nhid_list[1], '8.8.8.8', tunnel_name, '00:22:22:22:22:22', '1000') print ("\n\nTest VRF IPv6 Route with Tunnel Nexthop update from ECMP to non-ECMP") print ("\tTest VRF IPv6 Route with Tunnel Nexthop 8.8.8.8 Update") - create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') - vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) + create_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', "Vlan100", "00:22:22:22:22:22", '1000') + vxlan_obj.check_vrf_routes(dvs, "2002::8/64", 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000', 1) print ("\tTest Tunnel Nexthop 7.7.7.7 is deleted") - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '7.7.7.7', tunnel_name, "00:11:11:11:11:11", '1000') print ("\tTest Tunnel Nexthop ECMP Group is deleted") vxlan_obj.check_vrf_routes_ecmp_nexthop_grp_del(dvs, 2) print ("\tTest VRF IPv6 Route with Tunnel Nexthop 8.8.8.8 Delete") vxlan_obj.fetch_exist_entries(dvs) - delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + delete_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') - vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED4', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') - vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED4') + vxlan_obj.check_del_tunnel_nexthop(dvs, 'Vrf-RED', '8.8.8.8', tunnel_name, "00:22:22:22:22:22", '1000') + vxlan_obj.check_del_vrf_routes(dvs, "2002::8/64", 'Vrf-RED') print ("\n\nTest DIP and SIP Tunnel Deletion ") print ("\tTesting Tunnel Vrf Map Entry removal") - remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED4') - vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED4', '1000') + remove_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED') + vxlan_obj.check_vxlan_tunnel_vrf_map_entry_remove(dvs, tunnel_name, 'Vrf-RED', '1000') print ("\tTesting LastVlan removal and DIP tunnel delete for 7.7.7.7") remove_evpn_remote_vni(dvs, 'Vlan100', '7.7.7.7') @@ -1604,7 +1586,7 @@ def test_dip_tunnel_ipv6_routes(self, dvs, testlog): remove_vxlan_tunnel(dvs, tunnel_name) remove_evpn_nvo(dvs, 'nvo1') vxlan_obj.check_vxlan_sip_tunnel_delete(dvs, tunnel_name) - vxlan_obj.remove_vrf(dvs, "Vrf-RED4") + vxlan_obj.remove_vrf(dvs, "Vrf-RED") remove_vlan_member(dvs, "100", "Ethernet24") remove_vlan(dvs, "100") From cb780edfd421e26dd5eea3877887316fc63f861d Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Tue, 6 Jul 2021 07:04:33 -0700 Subject: [PATCH 24/31] Added few prints to debug further --- tests/test_evpn_l3_vxlan.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 6f541b20a6..6c60cef4d4 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -956,6 +956,14 @@ def create_vrf(self, dvs, vrf_name): tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") initial_entries = set(tbl.getKeys()) + print ("ROUTER_Ids = {}".format(initial_entries)) + for entry in initial_entries: + status, fvs = tbl.get(entry) + print ("entry = {}, fvs = {}".format(entry, fvs)) + + initial_entries1 = dvs.runcmd("redis-cli -n 1 keys *ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER*") + print ("Router_IDs = {}".format(initial_entries1)) + attrs = [ ("vni", "0"), ] @@ -1098,6 +1106,15 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): print ("\n\nTesting Create and Delete DIP Tunnel on adding and removing prefix route") print ("\tCreate SIP Tunnel") vlan_ids = get_exist_entries(dvs, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + print ("vlan_ids = {}".format(vlan_ids)) + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + for vlan in vlan_ids: + status, fvs = tbl.get(vlan) + print ("vlan_id = {}, fvs = {}".format(vlan, fvs)) + + vlan_id1s = dvs.runcmd("redis-cli -n 1 keys *ASIC_STATE:SAI_OBJECT_TYPE_VLAN*") + print ("vlan_ids = {}".format(vlan_id1s)) + vlan_oid = create_vlan(dvs,"Vlan100", vlan_ids) create_vxlan_tunnel(dvs, tunnel_name, '6.6.6.6') create_evpn_nvo(dvs, 'nvo1', tunnel_name) From 2c62ef626346092ee994b4378c7fa3fdb7241ed2 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Tue, 6 Jul 2021 13:32:51 -0700 Subject: [PATCH 25/31] Added few more changes in test case --- tests/test_evpn_l3_vxlan.py | 66 +++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 6c60cef4d4..681fb5e7a8 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -956,14 +956,6 @@ def create_vrf(self, dvs, vrf_name): tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") initial_entries = set(tbl.getKeys()) - print ("ROUTER_Ids = {}".format(initial_entries)) - for entry in initial_entries: - status, fvs = tbl.get(entry) - print ("entry = {}, fvs = {}".format(entry, fvs)) - - initial_entries1 = dvs.runcmd("redis-cli -n 1 keys *ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER*") - print ("Router_IDs = {}".format(initial_entries1)) - attrs = [ ("vni", "0"), ] @@ -982,6 +974,17 @@ def create_vrf(self, dvs, vrf_name): return list(current_entries - initial_entries)[0] + def create_vrf1(self, dvs, vrf_name): + conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) + + attrs = [ + ("vni", "0"), + ] + tbl = swsscommon.Table(conf_db, "VRF") + fvs = swsscommon.FieldValuePairs(attrs) + tbl.set(vrf_name, fvs) + time.sleep(2) + def remove_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VRF") @@ -1105,17 +1108,26 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): print ("\n\nTesting Create and Delete DIP Tunnel on adding and removing prefix route") print ("\tCreate SIP Tunnel") - vlan_ids = get_exist_entries(dvs, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - print ("vlan_ids = {}".format(vlan_ids)) - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - for vlan in vlan_ids: - status, fvs = tbl.get(vlan) + + # Get existing asic_db Vlan Ids + vlan_asic_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + existing_vlan_ids = set(vlan_asic_tbl.getKeys()) + + # Print the existing entries + print ("Existing vlan_ids = {}".format(existing_vlan_ids)) + for vlan in existing_vlan_ids: + status, fvs = vlan_asic_tbl.get(vlan) print ("vlan_id = {}, fvs = {}".format(vlan, fvs)) - vlan_id1s = dvs.runcmd("redis-cli -n 1 keys *ASIC_STATE:SAI_OBJECT_TYPE_VLAN*") - print ("vlan_ids = {}".format(vlan_id1s)) + # Create Vlan 100 + create_vlan1(dvs,"Vlan100") + + # Get asic_db Vlan Ids entries + entries_vlan_ids = set(vlan_asic_tbl.getKeys()) + new_vlan_ids = list(entries_vlan_ids - existing_vlan_ids) + assert len(new_vlan_ids) == 1, "Wrong number of created entries." + vlan_oid = new_vlan_ids[0] - vlan_oid = create_vlan(dvs,"Vlan100", vlan_ids) create_vxlan_tunnel(dvs, tunnel_name, '6.6.6.6') create_evpn_nvo(dvs, 'nvo1', tunnel_name) @@ -1123,7 +1135,27 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') print ("\tTesting VRF-VNI map in APP DB") - vxlan_obj.create_vrf(dvs, "Vrf-RED") + + # Get the initial VRF ids + vrf_asic_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") + initial_entries = set(vrf_asic_tbl.getKeys()) + + # Print the Existing VRF Ids + print ("Existing Router_IDs = {}".format(initial_entries)) + for entry in initial_entries: + status, fvs = vrf_asic_tbl .get(entry) + print ("entry = {}, fvs = {}".format(entry, fvs)) + + # Create VRF "Vrf_Red" + vxlan_obj.create_vrf1(dvs, "Vrf-RED") + + # Get the current VRF ids + current_entries = set(vrf_asic_tbl.getKeys()) + new_entries = list(current_entries - initial_entries) + assert len(new_entries) == 1, "Wrong number of created entries." + new_entries.sort() + new_vr_ids = new_entries + create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') vlanlist = ['100'] From 47faa873c1fafb8e8172fba7055e8597e019eb4a Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Tue, 6 Jul 2021 13:43:30 -0700 Subject: [PATCH 26/31] Added few more changes in test case2 --- tests/test_evpn_l3_vxlan.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 681fb5e7a8..7e242ad48d 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -1155,6 +1155,8 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): assert len(new_entries) == 1, "Wrong number of created entries." new_entries.sort() new_vr_ids = new_entries + self.vnet_vr_ids.update(new_vr_ids) + self.vr_map[vrf_name] = { 'ing':new_vr_ids[0], 'egr':new_vr_ids[0]} create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') From adfb5d52171ce5904b95f629d1adf2941dae96fe Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Thu, 22 Jul 2021 00:10:10 -0700 Subject: [PATCH 27/31] Reverted/Removed few changes to verify the l3 vxlan test case --- orchagent/vrforch.cpp | 24 ++++++++-------- tests/test_evpn_l3_vxlan.py | 57 ++----------------------------------- 2 files changed, 15 insertions(+), 66 deletions(-) diff --git a/orchagent/vrforch.cpp b/orchagent/vrforch.cpp index a45b0038de..1cbd2f4f54 100644 --- a/orchagent/vrforch.cpp +++ b/orchagent/vrforch.cpp @@ -104,19 +104,19 @@ bool VRFOrch::addOperation(const Request& request) } /* Add link-local fe80::/10 CPU route for the VRF. */ - IpPrefix default_link_local_prefix("fe80::/10"); + //IpPrefix default_link_local_prefix("fe80::/10"); - gRouteOrch->addLinkLocalRouteToMe(router_id, default_link_local_prefix); - SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); + //gRouteOrch->addLinkLocalRouteToMe(router_id, default_link_local_prefix); + //SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); /* All the interfaces have the same MAC address and hence the same * auto-generated link-local ipv6 address with eui64 interface-id. * Hence add a single /128 route entry for the link-local interface * address pointing to the CPU port. */ - IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); - gRouteOrch->addLinkLocalRouteToMe(router_id, linklocal_prefix); - SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); + //IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); + //gRouteOrch->addLinkLocalRouteToMe(router_id, linklocal_prefix); + //SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); vrf_table_[vrf_name].vrf_id = router_id; vrf_table_[vrf_name].ref_count = 0; @@ -184,14 +184,14 @@ bool VRFOrch::delOperation(const Request& request) sai_object_id_t router_id = vrf_table_[vrf_name].vrf_id; /* Delete link-local ipv6 address with eui64 /128 CPU route for the VRF. */ - IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); - gRouteOrch->delLinkLocalRouteToMe(router_id, linklocal_prefix); - SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); + //IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); + //gRouteOrch->delLinkLocalRouteToMe(router_id, linklocal_prefix); + //SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); /* Delete link-local fe80::/10 CPU route for the VRF. */ - IpPrefix default_link_local_prefix("fe80::/10"); - gRouteOrch->delLinkLocalRouteToMe(router_id, default_link_local_prefix); - SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); + //IpPrefix default_link_local_prefix("fe80::/10"); + //gRouteOrch->delLinkLocalRouteToMe(router_id, default_link_local_prefix); + //SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); sai_status_t status = sai_virtual_router_api->remove_virtual_router(router_id); if (status != SAI_STATUS_SUCCESS) diff --git a/tests/test_evpn_l3_vxlan.py b/tests/test_evpn_l3_vxlan.py index 7e242ad48d..6f541b20a6 100644 --- a/tests/test_evpn_l3_vxlan.py +++ b/tests/test_evpn_l3_vxlan.py @@ -974,17 +974,6 @@ def create_vrf(self, dvs, vrf_name): return list(current_entries - initial_entries)[0] - def create_vrf1(self, dvs, vrf_name): - conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) - - attrs = [ - ("vni", "0"), - ] - tbl = swsscommon.Table(conf_db, "VRF") - fvs = swsscommon.FieldValuePairs(attrs) - tbl.set(vrf_name, fvs) - time.sleep(2) - def remove_vrf(self, dvs, vrf_name): conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) tbl = swsscommon.Table(conf_db, "VRF") @@ -1108,26 +1097,8 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): print ("\n\nTesting Create and Delete DIP Tunnel on adding and removing prefix route") print ("\tCreate SIP Tunnel") - - # Get existing asic_db Vlan Ids - vlan_asic_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - existing_vlan_ids = set(vlan_asic_tbl.getKeys()) - - # Print the existing entries - print ("Existing vlan_ids = {}".format(existing_vlan_ids)) - for vlan in existing_vlan_ids: - status, fvs = vlan_asic_tbl.get(vlan) - print ("vlan_id = {}, fvs = {}".format(vlan, fvs)) - - # Create Vlan 100 - create_vlan1(dvs,"Vlan100") - - # Get asic_db Vlan Ids entries - entries_vlan_ids = set(vlan_asic_tbl.getKeys()) - new_vlan_ids = list(entries_vlan_ids - existing_vlan_ids) - assert len(new_vlan_ids) == 1, "Wrong number of created entries." - vlan_oid = new_vlan_ids[0] - + vlan_ids = get_exist_entries(dvs, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + vlan_oid = create_vlan(dvs,"Vlan100", vlan_ids) create_vxlan_tunnel(dvs, tunnel_name, '6.6.6.6') create_evpn_nvo(dvs, 'nvo1', tunnel_name) @@ -1135,29 +1106,7 @@ def test_prefix_route_create_dip_tunnel(self, dvs, testlog): create_vxlan_tunnel_map(dvs, tunnel_name, map_name, '1000', 'Vlan100') print ("\tTesting VRF-VNI map in APP DB") - - # Get the initial VRF ids - vrf_asic_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER") - initial_entries = set(vrf_asic_tbl.getKeys()) - - # Print the Existing VRF Ids - print ("Existing Router_IDs = {}".format(initial_entries)) - for entry in initial_entries: - status, fvs = vrf_asic_tbl .get(entry) - print ("entry = {}, fvs = {}".format(entry, fvs)) - - # Create VRF "Vrf_Red" - vxlan_obj.create_vrf1(dvs, "Vrf-RED") - - # Get the current VRF ids - current_entries = set(vrf_asic_tbl.getKeys()) - new_entries = list(current_entries - initial_entries) - assert len(new_entries) == 1, "Wrong number of created entries." - new_entries.sort() - new_vr_ids = new_entries - self.vnet_vr_ids.update(new_vr_ids) - self.vr_map[vrf_name] = { 'ing':new_vr_ids[0], 'egr':new_vr_ids[0]} - + vxlan_obj.create_vrf(dvs, "Vrf-RED") create_vxlan_vrf_tunnel_map(dvs, 'Vrf-RED', '1000') vlanlist = ['100'] From e2448d6633efe6dcf59eb42cdfc35b384ab17795 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Sun, 25 Jul 2021 22:05:33 -0700 Subject: [PATCH 28/31] Removed the VRF changes --- orchagent/vrforch.cpp | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/orchagent/vrforch.cpp b/orchagent/vrforch.cpp index 1cbd2f4f54..ce302b1765 100644 --- a/orchagent/vrforch.cpp +++ b/orchagent/vrforch.cpp @@ -12,7 +12,6 @@ #include "vrforch.h" #include "vxlanorch.h" #include "directory.h" -#include "routeorch.h" using namespace std; using namespace swss; @@ -21,7 +20,6 @@ extern sai_virtual_router_api_t* sai_virtual_router_api; extern sai_object_id_t gSwitchId; extern Directory gDirectory; extern PortsOrch* gPortsOrch; -extern RouteOrch* gRouteOrch; bool VRFOrch::addOperation(const Request& request) { @@ -103,21 +101,6 @@ bool VRFOrch::addOperation(const Request& request) } } - /* Add link-local fe80::/10 CPU route for the VRF. */ - //IpPrefix default_link_local_prefix("fe80::/10"); - - //gRouteOrch->addLinkLocalRouteToMe(router_id, default_link_local_prefix); - //SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); - - /* All the interfaces have the same MAC address and hence the same - * auto-generated link-local ipv6 address with eui64 interface-id. - * Hence add a single /128 route entry for the link-local interface - * address pointing to the CPU port. - */ - //IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); - //gRouteOrch->addLinkLocalRouteToMe(router_id, linklocal_prefix); - //SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); - vrf_table_[vrf_name].vrf_id = router_id; vrf_table_[vrf_name].ref_count = 0; vrf_id_table_[router_id] = vrf_name; @@ -183,16 +166,6 @@ bool VRFOrch::delOperation(const Request& request) sai_object_id_t router_id = vrf_table_[vrf_name].vrf_id; - /* Delete link-local ipv6 address with eui64 /128 CPU route for the VRF. */ - //IpPrefix linklocal_prefix = gRouteOrch->getLinkLocalEui64Addr(); - //gRouteOrch->delLinkLocalRouteToMe(router_id, linklocal_prefix); - //SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", linklocal_prefix.to_string().c_str(), vrf_name.c_str()); - - /* Delete link-local fe80::/10 CPU route for the VRF. */ - //IpPrefix default_link_local_prefix("fe80::/10"); - //gRouteOrch->delLinkLocalRouteToMe(router_id, default_link_local_prefix); - //SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu in VRF %s", default_link_local_prefix.to_string().c_str(), vrf_name.c_str()); - sai_status_t status = sai_virtual_router_api->remove_virtual_router(router_id); if (status != SAI_STATUS_SUCCESS) { From 37ed2cf87b8210063aab80166a367b0013d78eae Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Mon, 26 Jul 2021 09:46:46 -0700 Subject: [PATCH 29/31] Removed the extra line in file --- orchagent/vrforch.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/orchagent/vrforch.cpp b/orchagent/vrforch.cpp index ce302b1765..19ca5c0fd8 100644 --- a/orchagent/vrforch.cpp +++ b/orchagent/vrforch.cpp @@ -165,7 +165,6 @@ bool VRFOrch::delOperation(const Request& request) return false; sai_object_id_t router_id = vrf_table_[vrf_name].vrf_id; - sai_status_t status = sai_virtual_router_api->remove_virtual_router(router_id); if (status != SAI_STATUS_SUCCESS) { From d774cea5d97c24e944bc756545dbf3c36faaf4a4 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Mon, 2 Aug 2021 05:35:57 -0700 Subject: [PATCH 30/31] Addressed minor comment --- cfgmgr/intfmgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cfgmgr/intfmgr.cpp b/cfgmgr/intfmgr.cpp index 8b2f12c7fc..3e0ed862be 100644 --- a/cfgmgr/intfmgr.cpp +++ b/cfgmgr/intfmgr.cpp @@ -744,7 +744,7 @@ bool IntfMgr::doIntfAddrTask(const vector& keys, FieldValueTuple f("family", ip_prefix.isV4() ? IPV4_NAME : IPV6_NAME); // Don't send ipv4 link local config to AppDB and Orchagent - if ((ip_prefix.isV4() == false) or (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)) + if ((ip_prefix.isV4() == false) || (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)) { FieldValueTuple s("scope", "global"); fvVector.push_back(s); @@ -758,7 +758,7 @@ bool IntfMgr::doIntfAddrTask(const vector& keys, setIntfIp(alias, "del", ip_prefix); // Don't send ipv4 link local config to AppDB and Orchagent - if ((ip_prefix.isV4() == false) or (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)) + if ((ip_prefix.isV4() == false) || (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)) { m_appIntfTableProducer.del(appKey); m_stateIntfTable.del(keys[0] + state_db_key_delimiter + keys[1]); From 3e615e20ac8d939dd147335efa1b9b882bf9d991 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni Date: Wed, 4 Aug 2021 01:43:11 -0700 Subject: [PATCH 31/31] Added changes to skip the link-local neighbors based on ipv6_link_local_mode config --- neighsyncd/neighsync.cpp | 67 +++++++++++++++++++++++++++++++++++++-- neighsyncd/neighsync.h | 5 ++- neighsyncd/neighsyncd.cpp | 3 +- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/neighsyncd/neighsync.cpp b/neighsyncd/neighsync.cpp index 8095dc6676..6b1abc235f 100644 --- a/neighsyncd/neighsync.cpp +++ b/neighsyncd/neighsync.cpp @@ -13,13 +13,17 @@ #include "neighsync.h" #include "warm_restart.h" +#include using namespace std; using namespace swss; -NeighSync::NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb) : +NeighSync::NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb, DBConnector *cfgDb) : m_neighTable(pipelineAppDB, APP_NEIGH_TABLE_NAME), - m_stateNeighRestoreTable(stateDb, STATE_NEIGH_RESTORE_TABLE_NAME) + m_stateNeighRestoreTable(stateDb, STATE_NEIGH_RESTORE_TABLE_NAME), + m_cfgInterfaceTable(cfgDb, CFG_INTF_TABLE_NAME), + m_cfgLagInterfaceTable(cfgDb, CFG_LAG_INTF_TABLE_NAME), + m_cfgVlanInterfaceTable(cfgDb, CFG_VLAN_INTF_TABLE_NAME) { m_AppRestartAssist = new AppRestartAssist(pipelineAppDB, "neighsyncd", "swss", DEFAULT_NEIGHSYNC_WARMSTART_TIMER); if (m_AppRestartAssist) @@ -57,6 +61,7 @@ void NeighSync::onMsg(int nlmsg_type, struct nl_object *obj) struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj; string key; string family; + string intfName; if ((nlmsg_type != RTM_NEWNEIGH) && (nlmsg_type != RTM_GETNEIGH) && (nlmsg_type != RTM_DELNEIGH)) @@ -70,9 +75,18 @@ void NeighSync::onMsg(int nlmsg_type, struct nl_object *obj) return; key+= LinkCache::getInstance().ifindexToName(rtnl_neigh_get_ifindex(neigh)); + intfName = key; key+= ":"; nl_addr2str(rtnl_neigh_get_dst(neigh), ipStr, MAX_ADDR_SIZE); + /* Ignore IPv6 link-local addresses as neighbors, if ipv6 link local mode is disabled */ + if (family == IPV6_NAME && IN6_IS_ADDR_LINKLOCAL(nl_addr_get_binary_addr(rtnl_neigh_get_dst(neigh)))) + { + if (isLinkLocalEnabled(intfName) == false) + { + return; + } + } /* Ignore IPv6 multicast link-local addresses as neighbors */ if (family == IPV6_NAME && IN6_IS_ADDR_MC_LINKLOCAL(nl_addr_get_binary_addr(rtnl_neigh_get_dst(neigh)))) return; @@ -121,3 +135,52 @@ void NeighSync::onMsg(int nlmsg_type, struct nl_object *obj) m_neighTable.set(key, fvVector); } } + +/* To check the ipv6 link local is enabled on a given port */ +bool NeighSync::isLinkLocalEnabled(const string &port) +{ + vector values; + + if (!port.compare(0, strlen("Vlan"), "Vlan")) + { + if (!m_cfgVlanInterfaceTable.get(port, values)) + { + SWSS_LOG_INFO("IPv6 Link local is not enabled on %s", port.c_str()); + return false; + } + } + else if (!port.compare(0, strlen("PortChannel"), "PortChannel")) + { + if (!m_cfgLagInterfaceTable.get(port, values)) + { + SWSS_LOG_INFO("IPv6 Link local is not enabled on %s", port.c_str()); + return false; + } + } + else if (!port.compare(0, strlen("Ethernet"), "Ethernet")) + { + if (!m_cfgInterfaceTable.get(port, values)) + { + SWSS_LOG_INFO("IPv6 Link local is not enabled on %s", port.c_str()); + return false; + } + } + else + { + SWSS_LOG_INFO("IPv6 Link local is not supported for %s ", port.c_str()); + return false; + } + + auto it = std::find_if(values.begin(), values.end(), [](const FieldValueTuple& t){ return t.first == "ipv6_use_link_local_only";}); + if (it != values.end()) + { + if (it->second == "enable") + { + SWSS_LOG_INFO("IPv6 Link local is enabled on %s", port.c_str()); + return true; + } + } + + SWSS_LOG_INFO("IPv6 Link local is not enabled on %s", port.c_str()); + return false; +} diff --git a/neighsyncd/neighsync.h b/neighsyncd/neighsync.h index 387c849f30..49a17ee6b6 100644 --- a/neighsyncd/neighsync.h +++ b/neighsyncd/neighsync.h @@ -23,7 +23,7 @@ class NeighSync : public NetMsg public: enum { MAX_ADDR_SIZE = 64 }; - NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb); + NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb, DBConnector *cfgDb); ~NeighSync(); virtual void onMsg(int nlmsg_type, struct nl_object *obj); @@ -39,6 +39,9 @@ class NeighSync : public NetMsg Table m_stateNeighRestoreTable; ProducerStateTable m_neighTable; AppRestartAssist *m_AppRestartAssist; + Table m_cfgVlanInterfaceTable, m_cfgLagInterfaceTable, m_cfgInterfaceTable; + + bool isLinkLocalEnabled(const std::string &port); }; } diff --git a/neighsyncd/neighsyncd.cpp b/neighsyncd/neighsyncd.cpp index 99e86b2ef9..a0882c28e2 100644 --- a/neighsyncd/neighsyncd.cpp +++ b/neighsyncd/neighsyncd.cpp @@ -18,8 +18,9 @@ int main(int argc, char **argv) DBConnector appDb("APPL_DB", 0); RedisPipeline pipelineAppDB(&appDb); DBConnector stateDb("STATE_DB", 0); + DBConnector cfgDb("CONFIG_DB", 0); - NeighSync sync(&pipelineAppDB, &stateDb); + NeighSync sync(&pipelineAppDB, &stateDb, &cfgDb); NetDispatcher::getInstance().registerMessageHandler(RTM_NEWNEIGH, &sync); NetDispatcher::getInstance().registerMessageHandler(RTM_DELNEIGH, &sync);