@@ -13,6 +13,7 @@ using namespace swss;
13
13
14
14
#define VLAN_PREFIX " Vlan"
15
15
#define LAG_PREFIX " PortChannel"
16
+ #define VNET_PREFIX " Vnet"
16
17
17
18
IntfMgr::IntfMgr (DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames) :
18
19
Orch(cfgDb, tableNames),
@@ -21,12 +22,13 @@ IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
21
22
m_statePortTable(stateDb, STATE_PORT_TABLE_NAME),
22
23
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME),
23
24
m_stateVlanTable(stateDb, STATE_VLAN_TABLE_NAME),
25
+ m_stateVrfTable(stateDb, STATE_VRF_TABLE_NAME),
24
26
m_stateIntfTable(stateDb, STATE_INTERFACE_TABLE_NAME),
25
27
m_appIntfTableProducer(appDb, APP_INTF_TABLE_NAME)
26
28
{
27
29
}
28
30
29
- bool IntfMgr::setIntfIp (const string &alias, const string &opCmd,
31
+ void IntfMgr::setIntfIp (const string &alias, const string &opCmd,
30
32
const string &ipPrefixStr, const bool ipv4)
31
33
{
32
34
stringstream cmd;
@@ -41,7 +43,26 @@ bool IntfMgr::setIntfIp(const string &alias, const string &opCmd,
41
43
cmd << IP_CMD << " -6 address " << opCmd << " " << ipPrefixStr << " dev " << alias;
42
44
}
43
45
int ret = swss::exec (cmd.str (), res);
44
- return (ret == 0 );
46
+ if (ret)
47
+ {
48
+ SWSS_LOG_ERROR (" Command '%s' failed with rc %d" , cmd.str ().c_str (), ret);
49
+ }
50
+ }
51
+
52
+ void IntfMgr::setIntfVrf (const string &alias, const string vrfName)
53
+ {
54
+ stringstream cmd;
55
+ string res;
56
+
57
+ if (!vrfName.empty ())
58
+ {
59
+ cmd << IP_CMD << " link set " << alias << " master " << vrfName;
60
+ }
61
+ else
62
+ {
63
+ cmd << IP_CMD << " link set " << alias << " nomaster" ;
64
+ }
65
+ EXEC_WITH_ERROR_THROW (cmd.str (), res);
45
66
}
46
67
47
68
bool IntfMgr::isIntfStateOk (const string &alias)
@@ -64,6 +85,14 @@ bool IntfMgr::isIntfStateOk(const string &alias)
64
85
return true ;
65
86
}
66
87
}
88
+ else if (!alias.compare (0 , strlen (VNET_PREFIX), VNET_PREFIX))
89
+ {
90
+ if (m_stateVrfTable.get (alias, temp))
91
+ {
92
+ SWSS_LOG_DEBUG (" Vnet %s is ready" , alias.c_str ());
93
+ return true ;
94
+ }
95
+ }
67
96
else if (m_statePortTable.get (alias, temp))
68
97
{
69
98
SWSS_LOG_DEBUG (" Port %s is ready" , alias.c_str ());
@@ -72,55 +101,133 @@ bool IntfMgr::isIntfStateOk(const string &alias)
72
101
73
102
return false ;
74
103
}
75
- void IntfMgr::doTask (Consumer &consumer)
104
+
105
+ bool IntfMgr::doIntfGeneralTask (const vector<string>& keys,
106
+ const vector<FieldValueTuple>& data,
107
+ const string& op)
76
108
{
77
109
SWSS_LOG_ENTER ();
78
110
79
- auto it = consumer.m_toSync .begin ();
80
- while (it != consumer.m_toSync .end ())
111
+ string alias (keys[0 ]);
112
+ string vrf_name = " " ;
113
+
114
+ for (auto idx : data)
81
115
{
82
- KeyOpFieldsValuesTuple t = it->second ;
116
+ const auto &field = fvField (idx);
117
+ const auto &value = fvValue (idx);
118
+ if (field == " vnet_name" || field == " vrf_name" )
119
+ {
120
+ vrf_name = value;
121
+ }
122
+ }
83
123
84
- vector<string> keys = tokenize (kfvKey (t), config_db_key_delimiter);
124
+ if (op == SET_COMMAND)
125
+ {
126
+ if (!isIntfStateOk (alias))
127
+ {
128
+ SWSS_LOG_DEBUG (" Interface is not ready, skipping %s" , alias.c_str ());
129
+ return false ;
130
+ }
85
131
86
- if (keys. size () != 2 )
132
+ if (!vrf_name. empty () && ! isIntfStateOk (vrf_name) )
87
133
{
88
- SWSS_LOG_ERROR (" Invalid key %s" , kfvKey (t).c_str ());
89
- it = consumer.m_toSync .erase (it);
90
- continue ;
134
+ SWSS_LOG_DEBUG (" VRF is not ready, skipping %s" , vrf_name.c_str ());
135
+ return false ;
136
+ }
137
+
138
+ setIntfVrf (alias, vrf_name);
139
+ m_appIntfTableProducer.set (alias, data);
140
+ }
141
+ else if (op == DEL_COMMAND)
142
+ {
143
+ setIntfVrf (alias, " " );
144
+ m_appIntfTableProducer.del (alias);
145
+ }
146
+ else
147
+ {
148
+ SWSS_LOG_ERROR (" Unknown operation: %s" , op.c_str ());
149
+ }
150
+
151
+ return true ;
152
+ }
153
+
154
+ bool IntfMgr::doIntfAddrTask (const vector<string>& keys,
155
+ const vector<FieldValueTuple>& data,
156
+ const string& op)
157
+ {
158
+ SWSS_LOG_ENTER ();
159
+
160
+ string alias (keys[0 ]);
161
+ IpPrefix ip_prefix (keys[1 ]);
162
+ string appKey = keys[0 ] + " :" + keys[1 ];
163
+
164
+ if (op == SET_COMMAND)
165
+ {
166
+ /*
167
+ * Don't proceed if port/LAG/VLAN is not ready yet.
168
+ * The pending task will be checked periodically and retried.
169
+ */
170
+ if (!isIntfStateOk (alias))
171
+ {
172
+ SWSS_LOG_DEBUG (" Interface is not ready, skipping %s" , alias.c_str ());
173
+ return false ;
91
174
}
92
175
93
- string alias (keys[0 ]);
94
- IpPrefix ip_prefix (keys[1 ]);
176
+ setIntfIp (alias, " add" , ip_prefix.to_string (), ip_prefix.isV4 ());
177
+
178
+ std::vector<FieldValueTuple> fvVector;
179
+ FieldValueTuple f (" family" , ip_prefix.isV4 () ? IPV4_NAME : IPV6_NAME);
180
+ FieldValueTuple s (" scope" , " global" );
181
+ fvVector.push_back (s);
182
+ fvVector.push_back (f);
95
183
184
+ m_appIntfTableProducer.set (appKey, fvVector);
185
+ m_stateIntfTable.hset (keys[0 ] + state_db_key_delimiter + keys[1 ], " state" , " ok" );
186
+ }
187
+ else if (op == DEL_COMMAND)
188
+ {
189
+ setIntfIp (alias, " del" , ip_prefix.to_string (), ip_prefix.isV4 ());
190
+ m_appIntfTableProducer.del (appKey);
191
+ m_stateIntfTable.del (keys[0 ] + state_db_key_delimiter + keys[1 ]);
192
+ }
193
+ else
194
+ {
195
+ SWSS_LOG_ERROR (" Unknown operation: %s" , op.c_str ());
196
+ }
197
+
198
+ return true ;
199
+ }
200
+
201
+ void IntfMgr::doTask (Consumer &consumer)
202
+ {
203
+ SWSS_LOG_ENTER ();
204
+
205
+ auto it = consumer.m_toSync .begin ();
206
+ while (it != consumer.m_toSync .end ())
207
+ {
208
+ KeyOpFieldsValuesTuple t = it->second ;
209
+
210
+ vector<string> keys = tokenize (kfvKey (t), config_db_key_delimiter);
211
+ const vector<FieldValueTuple>& data = kfvFieldsValues (t);
96
212
string op = kfvOp (t);
97
- if (op == SET_COMMAND)
213
+
214
+ if (keys.size () == 1 )
98
215
{
99
- /*
100
- * Don't proceed if port/LAG/VLAN is not ready yet.
101
- * The pending task will be checked periodically and retried.
102
- * TODO: Subscribe to stateDB for port/lag/VLAN state and retry
103
- * pending tasks immediately upon state change.
104
- */
105
- if (!isIntfStateOk (alias))
216
+ if (!doIntfGeneralTask (keys, data, op))
106
217
{
107
- SWSS_LOG_DEBUG (" Interface is not ready, skipping %s" , kfvKey (t).c_str ());
108
- it++;
109
218
continue ;
110
219
}
111
- setIntfIp (alias, " add" , ip_prefix.to_string (), ip_prefix.isV4 ());
112
- m_stateIntfTable.hset (keys[0 ] + state_db_key_delimiter + keys[1 ], " state" , " ok" );
113
- SWSS_LOG_NOTICE (" Add %s to %s" , ip_prefix.to_string ().c_str (), alias.c_str ());
114
220
}
115
- else if (op == DEL_COMMAND )
221
+ else if (keys. size () == 2 )
116
222
{
117
- setIntfIp (alias, " del" , ip_prefix.to_string (), ip_prefix.isV4 ());
118
- m_stateIntfTable.del (keys[0 ] + state_db_key_delimiter + keys[1 ]);
119
- SWSS_LOG_NOTICE (" Remove %s from %s" , ip_prefix.to_string ().c_str (), alias.c_str ());
223
+ if (!doIntfAddrTask (keys, data, op))
224
+ {
225
+ continue ;
226
+ }
120
227
}
121
228
else
122
229
{
123
- SWSS_LOG_ERROR (" Unknown operation: %s" , op .c_str ());
230
+ SWSS_LOG_ERROR (" Invalid key %s" , kfvKey (t) .c_str ());
124
231
}
125
232
126
233
it = consumer.m_toSync .erase (it);
0 commit comments