@@ -100,6 +100,73 @@ set<IpPrefix> IntfsOrch:: getSubnetRoutes()
100
100
return subnet_routes;
101
101
}
102
102
103
+ bool IntfsOrch::setIntf (const string& alias, sai_object_id_t vrf_id, const IpPrefix *ip_prefix)
104
+ {
105
+ SWSS_LOG_ENTER ();
106
+
107
+ Port port;
108
+ gPortsOrch ->getPort (alias, port);
109
+
110
+ auto it_intfs = m_syncdIntfses.find (alias);
111
+ if (it_intfs == m_syncdIntfses.end ())
112
+ {
113
+ if (addRouterIntfs (vrf_id, port))
114
+ {
115
+ IntfsEntry intfs_entry;
116
+ intfs_entry.ref_count = 0 ;
117
+ m_syncdIntfses[alias] = intfs_entry;
118
+ }
119
+ else
120
+ {
121
+ return false ;
122
+ }
123
+ }
124
+
125
+ if (!ip_prefix || m_syncdIntfses[alias].ip_addresses .count (*ip_prefix))
126
+ {
127
+ /* Request to create router interface, no prefix present or Duplicate entry */
128
+ return true ;
129
+ }
130
+
131
+ /* NOTE: Overlap checking is required to handle ifconfig weird behavior.
132
+ * When set IP address using ifconfig command it applies it in two stages.
133
+ * On stage one it sets IP address with netmask /8. On stage two it
134
+ * changes netmask to specified in command. As DB is async event to
135
+ * add IP address with original netmask may come before event to
136
+ * delete IP with netmask /8. To handle this we in case of overlap
137
+ * we should wait until entry with /8 netmask will be removed.
138
+ * Time frame between those event is quite small.*/
139
+ bool overlaps = false ;
140
+ for (const auto &prefixIt: m_syncdIntfses[alias].ip_addresses )
141
+ {
142
+ if (prefixIt.isAddressInSubnet (ip_prefix->getIp ()) ||
143
+ ip_prefix->isAddressInSubnet (prefixIt.getIp ()))
144
+ {
145
+ overlaps = true ;
146
+ SWSS_LOG_NOTICE (" Router interface %s IP %s overlaps with %s." , port.m_alias .c_str (),
147
+ prefixIt.to_string ().c_str (), ip_prefix->to_string ().c_str ());
148
+ break ;
149
+ }
150
+ }
151
+
152
+ if (overlaps)
153
+ {
154
+ /* Overlap of IP address network */
155
+ return false ;
156
+ }
157
+
158
+ addSubnetRoute (port, *ip_prefix);
159
+ addIp2MeRoute (vrf_id, *ip_prefix);
160
+
161
+ if (port.m_type == Port::VLAN && ip_prefix->isV4 ())
162
+ {
163
+ addDirectedBroadcast (port, ip_prefix->getBroadcastIp ());
164
+ }
165
+
166
+ m_syncdIntfses[alias].ip_addresses .insert (*ip_prefix);
167
+ return true ;
168
+ }
169
+
103
170
void IntfsOrch::doTask (Consumer &consumer)
104
171
{
105
172
SWSS_LOG_ENTER ();
@@ -149,17 +216,7 @@ void IntfsOrch::doTask(Consumer &consumer)
149
216
}
150
217
151
218
sai_object_id_t vrf_id = gVirtualRouterId ;
152
- if (!vnet_name.empty ())
153
- {
154
- VNetOrch* vnet_orch = gDirectory .get <VNetOrch*>();
155
- if (!vnet_orch->isVnetExists (vnet_name))
156
- {
157
- it++;
158
- continue ;
159
- }
160
- vrf_id = vnet_orch->getVRid (vnet_name);
161
- }
162
- else if (!vrf_name.empty ())
219
+ if (!vrf_name.empty ())
163
220
{
164
221
if (m_vrfOrch->isVRFexists (vrf_name))
165
222
{
@@ -225,67 +282,29 @@ void IntfsOrch::doTask(Consumer &consumer)
225
282
continue ;
226
283
}
227
284
228
- auto it_intfs = m_syncdIntfses.find (alias);
229
- if (it_intfs == m_syncdIntfses.end ())
285
+ if (!vnet_name.empty ())
230
286
{
231
- if (addRouterIntfs (vrf_id, port))
287
+ VNetOrch* vnet_orch = gDirectory .get <VNetOrch*>();
288
+ if (!vnet_orch->isVnetExists (vnet_name))
232
289
{
233
- IntfsEntry intfs_entry;
234
- intfs_entry.ref_count = 0 ;
235
- m_syncdIntfses[alias] = intfs_entry;
290
+ it++;
291
+ continue ;
236
292
}
237
- else
293
+ if (!vnet_orch-> setIntf (alias, vnet_name, ip_prefix_in_key ? &ip_prefix : nullptr ))
238
294
{
239
295
it++;
240
296
continue ;
241
297
}
242
298
}
243
-
244
- vrf_id = port.m_vr_id ;
245
- if (!ip_prefix_in_key || m_syncdIntfses[alias].ip_addresses .count (ip_prefix))
246
- {
247
- /* Request to create router interface, no prefix present or Duplicate entry */
248
- it = consumer.m_toSync .erase (it);
249
- continue ;
250
- }
251
-
252
- /* NOTE: Overlap checking is required to handle ifconfig weird behavior.
253
- * When set IP address using ifconfig command it applies it in two stages.
254
- * On stage one it sets IP address with netmask /8. On stage two it
255
- * changes netmask to specified in command. As DB is async event to
256
- * add IP address with original netmask may come before event to
257
- * delete IP with netmask /8. To handle this we in case of overlap
258
- * we should wait until entry with /8 netmask will be removed.
259
- * Time frame between those event is quite small.*/
260
- bool overlaps = false ;
261
- for (const auto &prefixIt: m_syncdIntfses[alias].ip_addresses )
299
+ else
262
300
{
263
- if (prefixIt.isAddressInSubnet (ip_prefix.getIp ()) ||
264
- ip_prefix.isAddressInSubnet (prefixIt.getIp ()))
301
+ if (!setIntf (alias, vrf_id, ip_prefix_in_key ? &ip_prefix : nullptr ))
265
302
{
266
- overlaps = true ;
267
- SWSS_LOG_NOTICE (" Router interface %s IP %s overlaps with %s." , port.m_alias .c_str (),
268
- prefixIt.to_string ().c_str (), ip_prefix.to_string ().c_str ());
269
- break ;
303
+ it++;
304
+ continue ;
270
305
}
271
306
}
272
307
273
- if (overlaps)
274
- {
275
- /* Overlap of IP address network */
276
- ++it;
277
- continue ;
278
- }
279
-
280
- addSubnetRoute (port, ip_prefix);
281
- addIp2MeRoute (vrf_id, ip_prefix);
282
-
283
- if (port.m_type == Port::VLAN && ip_prefix.isV4 ())
284
- {
285
- addDirectedBroadcast (port, ip_prefix.getBroadcastIp ());
286
- }
287
-
288
- m_syncdIntfses[alias].ip_addresses .insert (ip_prefix);
289
308
it = consumer.m_toSync .erase (it);
290
309
}
291
310
else if (op == DEL_COMMAND)
0 commit comments