Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[202012] Update default route status to state DB (#2009) #2067

Merged
merged 2 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions orchagent/routeorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ RouteOrch::RouteOrch(DBConnector *db, string tableName, SwitchOrch *switchOrch,

SWSS_LOG_NOTICE("Maximum number of ECMP groups supported is %d", m_maxNextHopGroupCount);

m_stateDb = shared_ptr<DBConnector>(new DBConnector("STATE_DB", 0));
m_stateDefaultRouteTb = unique_ptr<swss::Table>(new Table(m_stateDb.get(), STATE_ROUTE_TABLE_NAME));

IpPrefix default_ip_prefix("0.0.0.0/0");
updateDefRouteState("0.0.0.0/0");

sai_route_entry_t unicast_route_entry;
unicast_route_entry.vr_id = gVirtualRouterId;
Expand All @@ -101,6 +105,7 @@ RouteOrch::RouteOrch(DBConnector *db, string tableName, SwitchOrch *switchOrch,
SWSS_LOG_NOTICE("Create IPv4 default route with packet action drop");

IpPrefix v6_default_ip_prefix("::/0");
updateDefRouteState("::/0");

copy(unicast_route_entry.destination, v6_default_ip_prefix);
subnet(unicast_route_entry.destination, unicast_route_entry.destination);
Expand Down Expand Up @@ -205,6 +210,16 @@ 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::updateDefRouteState(string ip, bool add)
{
vector<FieldValueTuple> tuples;
string state = add?"ok":"na";
FieldValueTuple tuple("state", state);
tuples.push_back(tuple);

m_stateDefaultRouteTb->set(ip, tuples);
}

bool RouteOrch::hasNextHopGroup(const NextHopGroupKey& nexthops) const
{
return m_syncdNextHopGroups.find(nexthops) != m_syncdNextHopGroups.end();
Expand Down Expand Up @@ -1898,6 +1913,11 @@ bool RouteOrch::addRoutePost(const RouteBulkContext& ctx, const NextHopGroupKey
}
}

if (ipPrefix.isDefaultRoute())
{
updateDefRouteState(ipPrefix.to_string(), true);
}

m_syncdRoutes[vrf_id][ipPrefix] = nextHops;
shi-su marked this conversation as resolved.
Show resolved Hide resolved

notifyNextHopChangeObservers(vrf_id, ipPrefix, nextHops, true);
Expand Down Expand Up @@ -2007,6 +2027,8 @@ bool RouteOrch::removeRoutePost(const RouteBulkContext& ctx)
}
}

updateDefRouteState(ipPrefix.to_string());

SWSS_LOG_INFO("Set route %s next hop ID to NULL", ipPrefix.to_string().c_str());
}
else
Expand Down
5 changes: 5 additions & 0 deletions orchagent/routeorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ class RouteOrch : public Orch, public Subject
int m_maxNextHopGroupCount;
bool m_resync;

shared_ptr<DBConnector> m_stateDb;
unique_ptr<swss::Table> m_stateDefaultRouteTb;

RouteTables m_syncdRoutes;
NextHopGroupTable m_syncdNextHopGroups;
NextHopRouteTable m_nextHops;
Expand All @@ -168,6 +171,8 @@ class RouteOrch : public Orch, public Subject
std::string getLinkLocalEui64Addr(void);
void addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix);

void updateDefRouteState(string ip, bool add=false);

void doTask(Consumer& consumer);
};

Expand Down
50 changes: 50 additions & 0 deletions tests/test_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def setup_db(self, dvs):
self.pdb = dvs.get_app_db()
self.adb = dvs.get_asic_db()
self.cdb = dvs.get_config_db()
self.sdb = dvs.get_state_db()

def set_admin_status(self, interface, status):
self.cdb.update_entry("PORT", interface, {"admin_status": status})
Expand Down Expand Up @@ -62,6 +63,23 @@ def _access_function():

wait_for_result(_access_function)

def check_route_state(self, prefix, value):
found = False

route_entries = self.sdb.get_keys("ROUTE_TABLE")
for key in route_entries:
if key != prefix:
continue
found = True
fvs = self.sdb.get_entry("ROUTE_TABLE", key)

assert fvs != {}

for f,v in fvs.items():
if f == "state":
assert v == value
assert found

def get_asic_db_key(self, destination):
route_entries = self.adb.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
for route_entry in route_entries:
Expand Down Expand Up @@ -123,6 +141,9 @@ def test_RouteAddRemoveIpv4Route(self, dvs, testlog):
self.create_l3_intf("Ethernet0", "")
self.create_l3_intf("Ethernet4", "")

# check STATE route database, initial state shall be "na"
self.check_route_state("0.0.0.0/0", "na")

# set ip address
self.add_ip_address("Ethernet0", "10.0.0.0/31")
self.add_ip_address("Ethernet4", "10.0.0.2/31")
Expand All @@ -144,15 +165,25 @@ def test_RouteAddRemoveIpv4Route(self, dvs, testlog):
# add route entry
dvs.runcmd("vtysh -c \"configure terminal\" -c \"ip route 2.2.2.0/24 10.0.0.1\"")

# add default route entry
fieldValues = {"nexthop": "10.0.0.1", "ifname": "Ethernet0"}
self.create_route_entry("0.0.0.0/0", fieldValues)

# check application database
self.pdb.wait_for_entry("ROUTE_TABLE", "2.2.2.0/24")

# check ASIC route database
self.check_route_entries(["2.2.2.0/24"])

# check STATE route database
self.check_route_state("0.0.0.0/0", "ok")

# remove route entry
dvs.runcmd("vtysh -c \"configure terminal\" -c \"no ip route 2.2.2.0/24 10.0.0.1\"")

# remove default route entry
self.remove_route_entry("0.0.0.0/0")

# check application database
self.pdb.wait_for_deleted_entry("ROUTE_TABLE", "2.2.2.0/24")

Expand All @@ -170,6 +201,9 @@ def test_RouteAddRemoveIpv4Route(self, dvs, testlog):
self.set_admin_status("Ethernet0", "down")
self.set_admin_status("Ethernet4", "down")

# check STATE route database, state set to "na" after deleting the default route
self.check_route_state("0.0.0.0/0", "na")

# remove ip address and default route
dvs.servers[0].runcmd("ip route del default dev eth0")
dvs.servers[0].runcmd("ip address del 10.0.0.1/31 dev eth0")
Expand All @@ -184,6 +218,9 @@ def test_RouteAddRemoveIpv6Route(self, dvs, testlog):
self.create_l3_intf("Ethernet0", "")
self.create_l3_intf("Ethernet4", "")

# check STATE route database, initial state shall be "na"
self.check_route_state("::/0", "na")

# bring up interface
self.set_admin_status("Ethernet0", "up")
self.set_admin_status("Ethernet4", "up")
Expand All @@ -207,15 +244,25 @@ def test_RouteAddRemoveIpv6Route(self, dvs, testlog):
# add route entry
dvs.runcmd("vtysh -c \"configure terminal\" -c \"ipv6 route 3000::0/64 2000::2\"")

# add default route entry
fieldValues = {"nexthop": "2000::2", "ifname": "Ethernet0"}
self.create_route_entry("::/0", fieldValues)

# check application database
self.pdb.wait_for_entry("ROUTE_TABLE", "3000::/64")

# check ASIC route database
self.check_route_entries(["3000::/64"])

# check STATE route database
self.check_route_state("::/0", "ok")

# remove route entry
dvs.runcmd("vtysh -c \"configure terminal\" -c \"no ipv6 route 3000::0/64 2000::2\"")

# remove default route entry
self.remove_route_entry("::/0")

# check application database
self.pdb.wait_for_deleted_entry("ROUTE_TABLE", "3000::/64")

Expand All @@ -233,6 +280,9 @@ def test_RouteAddRemoveIpv6Route(self, dvs, testlog):
self.set_admin_status("Ethernet0", "down")
self.set_admin_status("Ethernet4", "down")

# check STATE route database, state set to "na" after deleting the default route
self.check_route_state("::/0", "na")

# remove ip address and default route
dvs.servers[0].runcmd("ip -6 route del default dev eth0")
dvs.servers[0].runcmd("ip -6 address del 2000::2/64 dev eth0")
Expand Down