Skip to content

Commit df5282e

Browse files
committed
To be backward compatible with VLAN configuration via Minigraph
1 parent 505867e commit df5282e

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

portsyncd/linksync.cpp

+78-2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ const string LAG_PREFIX = "PortChannel";
2929
extern set<string> g_portSet;
3030
extern map<string, set<string>> g_vlanMap;
3131
extern bool g_init;
32+
extern bool g_minigraphVlan;
3233

3334
LinkSync::LinkSync(DBConnector *db) :
3435
m_portTableProducer(db, APP_PORT_TABLE_NAME),
36+
m_vlanTableProducer(db, APP_VLAN_TABLE_NAME),
37+
m_vlanMemberTableProducer(db, APP_VLAN_MEMBER_TABLE_NAME),
3538
m_lagTableProducer(db, APP_LAG_TABLE_NAME),
3639
m_portTableConsumer(db, APP_PORT_TABLE_NAME),
40+
m_vlanMemberTableConsumer(db, APP_VLAN_MEMBER_TABLE_NAME),
3741
m_lagTableConsumer(db, APP_LAG_TABLE_NAME)
3842
{
3943
/* See the comments for g_portSet in portsyncd.cpp */
@@ -52,6 +56,22 @@ LinkSync::LinkSync(DBConnector *db) :
5256
}
5357
}
5458
}
59+
60+
vector<KeyOpFieldsValuesTuple> tuples;
61+
m_vlanMemberTableConsumer.getTableContent(tuples);
62+
63+
for (auto tuple : tuples)
64+
{
65+
vector<string> keys = tokenize(kfvKey(tuple), ':');
66+
string vlan = keys[0];
67+
string member = keys[1];
68+
69+
if (g_vlanMap.find(vlan) == g_vlanMap.end())
70+
{
71+
g_vlanMap[vlan] = set<string>();
72+
}
73+
g_vlanMap[vlan].insert(member);
74+
}
5575
}
5676

5777
void LinkSync::onMsg(int nlmsg_type, struct nl_object *obj)
@@ -65,14 +85,17 @@ void LinkSync::onMsg(int nlmsg_type, struct nl_object *obj)
6585
string key = rtnl_link_get_name(link);
6686

6787
if (key.compare(0, INTFS_PREFIX.length(), INTFS_PREFIX) &&
88+
key.compare(0, VLAN_PREFIX.length(), VLAN_PREFIX) &&
6889
key.compare(0, LAG_PREFIX.length(), LAG_PREFIX))
6990
{
7091
return;
7192
}
7293

73-
if (key.compare(0, VLAN_PREFIX.length(), VLAN_PREFIX) == 0)
94+
if (!g_minigraphVlan && key.compare(0, VLAN_PREFIX.length(), VLAN_PREFIX) == 0)
7495
{
75-
/* VLAN APP config doesn't rely on netlink */
96+
/*
97+
* VLAN APP config doesn't rely on netlink when VLAN not configured from minigraph
98+
*/
7699
return;
77100
}
78101

@@ -108,12 +131,65 @@ void LinkSync::onMsg(int nlmsg_type, struct nl_object *obj)
108131
return;
109132
}
110133

134+
/* VLAN member: A separate entry in VLAN_TABLE will be inserted */
135+
if (master)
136+
{
137+
string master_key = m_ifindexNameMap[master];
138+
/* Verify the master interface starts with "Vlan" to exclude "PortChannel" interfaces */
139+
if (!master_key.compare(0, VLAN_PREFIX.length(), VLAN_PREFIX))
140+
{
141+
string member_key = master_key + ":" + key;
142+
143+
if (nlmsg_type == RTM_DELLINK) /* Will it happen? */
144+
{
145+
m_vlanMemberTableProducer.del(member_key);
146+
}
147+
else /* RTM_NEWLINK */
148+
{
149+
vector<FieldValueTuple> fvVector;
150+
FieldValueTuple t("tagging_mode", "untagged");
151+
fvVector.push_back(t);
152+
153+
m_vlanMemberTableProducer.set(member_key, fvVector);
154+
}
155+
}
156+
}
157+
/* No longer a VLAN member: Check if it was a member before and remove it */
158+
else
159+
{
160+
for (auto i = g_vlanMap.begin(); i != g_vlanMap.end(); i++)
161+
{
162+
set<string> member_set = (*i).second;
163+
if (member_set.find(key) != member_set.end())
164+
{
165+
string member_key = (*i).first + ":" + key;
166+
m_vlanMemberTableProducer.del(member_key);
167+
}
168+
}
169+
}
170+
111171
vector<FieldValueTuple> fvVector;
112172
FieldValueTuple a("admin_status", admin ? "up" : "down");
113173
FieldValueTuple m("mtu", to_string(mtu));
114174
fvVector.push_back(a);
115175
fvVector.push_back(m);
116176

177+
/* VLAN interfaces: Check if the type is bridge */
178+
if (type && !strcmp(type, VLAN_DRV_NAME))
179+
{
180+
if (nlmsg_type == RTM_DELLINK)
181+
{
182+
m_vlanTableProducer.del(key);
183+
}
184+
else
185+
{
186+
FieldValueTuple o("oper_status", oper ? "up" : "down");
187+
fvVector.push_back(o);
188+
m_vlanTableProducer.set(key, fvVector);
189+
}
190+
return;
191+
}
192+
117193
/* front panel interfaces: Check if the port is in the PORT_TABLE
118194
* non-front panel interfaces such as eth0, lo which are not in the
119195
* PORT_TABLE are ignored. */

portsyncd/linksync.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ class LinkSync : public NetMsg
1919
virtual void onMsg(int nlmsg_type, struct nl_object *obj);
2020

2121
private:
22-
ProducerStateTable m_portTableProducer, m_lagTableProducer;
23-
Table m_portTableConsumer, m_lagTableConsumer;
22+
ProducerStateTable m_portTableProducer, m_vlanTableProducer, m_vlanMemberTableProducer, m_lagTableProducer;
23+
Table m_portTableConsumer, m_vlanMemberTableConsumer, m_lagTableConsumer;
2424

2525
std::map<unsigned int, std::string> m_ifindexNameMap;
2626
};

portsyncd/portsyncd.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <vector>
66
#include <set>
77
#include <map>
8+
#include "exec.h"
89
#include "dbconnector.h"
910
#include "select.h"
1011
#include "netdispatcher.h"
@@ -30,7 +31,7 @@ using namespace swss;
3031
set<string> g_portSet;
3132
map<string, set<string>> g_vlanMap;
3233
bool g_init = false;
33-
34+
bool g_minigraphVlan = false;
3435
void usage()
3536
{
3637
cout << "Usage: portsyncd [-p port_config.ini]" << endl;
@@ -40,6 +41,7 @@ void usage()
4041

4142
void handlePortConfigFile(ProducerStateTable &p, string file);
4243
void handleVlanIntfFile(string file);
44+
void minigraphVlan();
4345

4446
int main(int argc, char **argv)
4547
{
@@ -63,6 +65,7 @@ int main(int argc, char **argv)
6365
}
6466
}
6567

68+
minigraphVlan();
6669
DBConnector db(0, DBConnector::DEFAULT_UNIXSOCKET, 0);
6770
ProducerStateTable p(&db, APP_PORT_TABLE_NAME);
6871

@@ -165,3 +168,15 @@ void handlePortConfigFile(ProducerStateTable &p, string file)
165168

166169
infile.close();
167170
}
171+
172+
void minigraphVlan()
173+
{
174+
string vlan;
175+
176+
vlan = swss::exec("sonic-cfggen -m /etc/sonic/minigraph.xml -v 'minigraph_vlans.keys()'");
177+
if(vlan.compare(0, 2, "[]"))
178+
{
179+
g_minigraphVlan = true;
180+
cout << "VLAN configured from minigraph" << endl;
181+
}
182+
}

0 commit comments

Comments
 (0)