Skip to content

Commit c9ed2c4

Browse files
author
Shuotian Cheng
authored
[intfmgr]: Support configuring IPs for all regular interfaces (sonic-net#544)
Enable configuring IPv4 and IPv6 addresses on regular ports Add tests to test IPv4 add/remove to regular ports Signed-off-by: Shu0T1an ChenG <shuche@microsoft.com>
1 parent fa7008f commit c9ed2c4

File tree

3 files changed

+90
-28
lines changed

3 files changed

+90
-28
lines changed

cfgmgr/intfmgr.cpp

+23-26
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,20 @@ IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
2525
{
2626
}
2727

28-
bool IntfMgr::setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr)
28+
bool IntfMgr::setIntfIp(const string &alias, const string &opCmd,
29+
const string &ipPrefixStr, const bool ipv4)
2930
{
3031
stringstream cmd;
3132
string res;
3233

33-
cmd << IP_CMD << " address " << opCmd << " " << ipPrefixStr << " dev " << alias;;
34+
if (ipv4)
35+
{
36+
cmd << IP_CMD << " address " << opCmd << " " << ipPrefixStr << " dev " << alias;
37+
}
38+
else
39+
{
40+
cmd << IP_CMD << " -6 address " << opCmd << " " << ipPrefixStr << " dev " << alias;
41+
}
3442
int ret = swss::exec(cmd.str(), res);
3543
return (ret == 0);
3644
}
@@ -72,34 +80,24 @@ void IntfMgr::doTask(Consumer &consumer)
7280
{
7381
KeyOpFieldsValuesTuple t = it->second;
7482

75-
string keySeparator = CONFIGDB_KEY_SEPARATOR;
76-
vector<string> keys = tokenize(kfvKey(t), keySeparator[0]);
77-
string alias(keys[0]);
83+
vector<string> keys = tokenize(kfvKey(t), config_db_key_delimiter);
7884

79-
if (alias.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX))
85+
if (keys.size() != 2)
8086
{
81-
/* handle IP over vlan Only for now, skip the rest */
87+
SWSS_LOG_ERROR("Invalid key %s", kfvKey(t).c_str());
8288
it = consumer.m_toSync.erase(it);
8389
continue;
8490
}
8591

86-
size_t pos = kfvKey(t).find(CONFIGDB_KEY_SEPARATOR);
87-
if (pos == string::npos)
88-
{
89-
SWSS_LOG_DEBUG("Invalid key %s", kfvKey(t).c_str());
90-
it = consumer.m_toSync.erase(it);
91-
continue;
92-
}
93-
IpPrefix ip_prefix(kfvKey(t).substr(pos+1));
94-
95-
SWSS_LOG_DEBUG("intfs doTask: %s", (dumpTuple(consumer, t)).c_str());
92+
string alias(keys[0]);
93+
IpPrefix ip_prefix(keys[1]);
9694

9795
string op = kfvOp(t);
9896
if (op == SET_COMMAND)
9997
{
10098
/*
101-
* Don't proceed if port/lag/VLAN is not ready yet.
102-
* The pending task will be checked periodially and retried.
99+
* Don't proceed if port/LAG/VLAN is not ready yet.
100+
* The pending task will be checked periodically and retried.
103101
* TODO: Subscribe to stateDB for port/lag/VLAN state and retry
104102
* pending tasks immediately upon state change.
105103
*/
@@ -109,18 +107,17 @@ void IntfMgr::doTask(Consumer &consumer)
109107
it++;
110108
continue;
111109
}
112-
string opCmd("add");
113-
string ipPrefixStr = ip_prefix.to_string();
114-
setIntfIp(alias, opCmd, ipPrefixStr);
110+
setIntfIp(alias, "add", ip_prefix.to_string(), ip_prefix.isV4());
115111
}
116112
else if (op == DEL_COMMAND)
117113
{
118-
string opCmd("del");
119-
string ipPrefixStr = ip_prefix.to_string();
120-
setIntfIp(alias, opCmd, ipPrefixStr);
114+
setIntfIp(alias, "del", ip_prefix.to_string(), ip_prefix.isV4());
115+
}
116+
else
117+
{
118+
SWSS_LOG_ERROR("Unknown operation: %s", op.c_str());
121119
}
122120

123121
it = consumer.m_toSync.erase(it);
124-
continue;
125122
}
126123
}

cfgmgr/intfmgr.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class IntfMgr : public Orch
2121
Table m_cfgIntfTable, m_cfgVlanIntfTable;
2222
Table m_statePortTable, m_stateLagTable, m_stateVlanTable;
2323

24-
bool setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr);
24+
bool setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr, const bool ipv4 = true);
2525
void doTask(Consumer &consumer);
2626
bool isIntfStateOk(const string &alias);
2727
};

tests/test_interface.py

+66-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,73 @@
11
from swsscommon import swsscommon
2+
23
import time
3-
import re
44
import json
55

6+
class TestInterfaceIpv4Addresses(object):
7+
def test_InterfaceAddIpv4Address(self, dvs):
8+
pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0)
9+
adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)
10+
cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0)
11+
12+
# assign IP to interface
13+
tbl = swsscommon.Table(cdb, "INTERFACE")
14+
fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
15+
tbl.set("Ethernet8|10.0.0.4/31", fvs)
16+
time.sleep(1)
17+
18+
# check application database
19+
tbl = swsscommon.Table(pdb, "INTF_TABLE:Ethernet8")
20+
intf_entries = tbl.getKeys()
21+
assert len(intf_entries) == 1
22+
assert intf_entries[0] == "10.0.0.4/31"
23+
24+
(status, fvs) = tbl.get(tbl.getKeys()[0])
25+
assert status == True
26+
assert len(fvs) == 2
27+
for fv in fvs:
28+
if fv[0] == "scope":
29+
assert fv[1] == "global"
30+
elif fv[0] == "family":
31+
assert fv[1] == "IPv4"
32+
else:
33+
assert False
34+
35+
# check asic database
36+
tbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
37+
for key in tbl.getKeys():
38+
route = json.loads(key)
39+
if route["dest"] == "10.0.0.4/31":
40+
subnet_found = True
41+
if route["dest"] == "10.0.0.4/32":
42+
ip2me_found = True
43+
44+
assert subnet_found and ip2me_found
45+
46+
def test_InterfaceRemoveIpv4Address(self, dvs):
47+
pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0)
48+
adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)
49+
cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0)
50+
51+
# assign IP to interface
52+
tbl = swsscommon.Table(cdb, "INTERFACE")
53+
tbl._del("Ethernet8|10.0.0.4/31")
54+
time.sleep(1)
55+
56+
# check application database
57+
tbl = swsscommon.Table(pdb, "INTF_TABLE:Ethernet8")
58+
intf_entries = tbl.getKeys()
59+
assert len(intf_entries) == 0
60+
61+
# check asic database
62+
tbl = swsscommon.Table(adb, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")
63+
for key in tbl.getKeys():
64+
route = json.loads(key)
65+
if route["dest"] == "10.0.0.4/31":
66+
assert False
67+
if route["dest"] == "10.0.0.4/32":
68+
assert False
69+
70+
671
def test_InterfaceIpChange(dvs):
772

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

0 commit comments

Comments
 (0)