Skip to content

Commit 882ccc6

Browse files
marian-pritsaklguohan
authored andcommitted
[vnetorch] Change logic for adding VNet interface (sonic-net#761)
* [vnetorch] Change logic for adding VNet interface Signed-off-by: Marian Pritsak <marianp@mellanox.com> * Insert ipprefix only if exists Signed-off-by: Marian Pritsak <marianp@mellanox.com>
1 parent f637557 commit 882ccc6

File tree

4 files changed

+107
-84
lines changed

4 files changed

+107
-84
lines changed

orchagent/intfsorch.cpp

+78-59
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,73 @@ set<IpPrefix> IntfsOrch:: getSubnetRoutes()
100100
return subnet_routes;
101101
}
102102

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+
103170
void IntfsOrch::doTask(Consumer &consumer)
104171
{
105172
SWSS_LOG_ENTER();
@@ -149,17 +216,7 @@ void IntfsOrch::doTask(Consumer &consumer)
149216
}
150217

151218
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())
163220
{
164221
if (m_vrfOrch->isVRFexists(vrf_name))
165222
{
@@ -225,67 +282,29 @@ void IntfsOrch::doTask(Consumer &consumer)
225282
continue;
226283
}
227284

228-
auto it_intfs = m_syncdIntfses.find(alias);
229-
if (it_intfs == m_syncdIntfses.end())
285+
if (!vnet_name.empty())
230286
{
231-
if (addRouterIntfs(vrf_id, port))
287+
VNetOrch* vnet_orch = gDirectory.get<VNetOrch*>();
288+
if (!vnet_orch->isVnetExists(vnet_name))
232289
{
233-
IntfsEntry intfs_entry;
234-
intfs_entry.ref_count = 0;
235-
m_syncdIntfses[alias] = intfs_entry;
290+
it++;
291+
continue;
236292
}
237-
else
293+
if (!vnet_orch->setIntf(alias, vnet_name, ip_prefix_in_key ? &ip_prefix : nullptr))
238294
{
239295
it++;
240296
continue;
241297
}
242298
}
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
262300
{
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))
265302
{
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;
270305
}
271306
}
272307

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);
289308
it = consumer.m_toSync.erase(it);
290309
}
291310
else if (op == DEL_COMMAND)

orchagent/intfsorch.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class IntfsOrch : public Orch
3535

3636
bool setRouterIntfsMtu(Port &port);
3737
std::set<IpPrefix> getSubnetRoutes();
38+
bool setIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr);
3839
private:
3940
VRFOrch *m_vrfOrch;
4041
IntfsTable m_syncdIntfses;

orchagent/vnetorch.cpp

+24-1
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
#include "vxlanorch.h"
1515
#include "directory.h"
1616
#include "swssnet.h"
17+
#include "intfsorch.h"
1718

1819
extern sai_virtual_router_api_t* sai_virtual_router_api;
1920
extern sai_route_api_t* sai_route_api;
2021
extern sai_object_id_t gSwitchId;
2122
extern Directory<Orch*> gDirectory;
2223
extern PortsOrch *gPortsOrch;
24+
extern IntfsOrch *gIntfsOrch;
2325

2426
/*
2527
* VRF Modeling and VNetVrf class definitions
@@ -163,6 +165,26 @@ VNetOrch::VNetOrch(DBConnector *db, const std::string& tableName, VNET_EXEC op)
163165
}
164166
}
165167

168+
bool VNetOrch::setIntf(const string& alias, const string vnet_name, const IpPrefix *prefix)
169+
{
170+
SWSS_LOG_ENTER();
171+
172+
if (isVnetExecVrf())
173+
{
174+
if (!isVnetExists(vnet_name))
175+
{
176+
SWSS_LOG_WARN("VNET %s doesn't exist", vnet_name.c_str());
177+
return false;
178+
}
179+
180+
auto *vnet_obj = getTypePtr<VNetVrfObject>(vnet_name);
181+
sai_object_id_t vrf_id = vnet_obj->getVRidIngress();
182+
183+
return gIntfsOrch->setIntf(alias, vrf_id, prefix);
184+
}
185+
186+
return false;
187+
}
166188
bool VNetOrch::addOperation(const Request& request)
167189
{
168190
SWSS_LOG_ENTER();
@@ -226,8 +248,9 @@ bool VNetOrch::addOperation(const Request& request)
226248
create = true;
227249
}
228250

251+
VNetVrfObject *vrfObj = dynamic_cast<VNetVrfObject*>(obj.get());
229252
if (!vxlan_orch->createVxlanTunnelMap(tunnel, TUNNEL_MAP_T_VIRTUAL_ROUTER, vni,
230-
obj->getEncapMapId(), obj->getDecapMapId()))
253+
vrfObj->getEncapMapId(), vrfObj->getDecapMapId()))
231254
{
232255
SWSS_LOG_ERROR("VNET '%s', tunnel '%s', map create failed",
233256
vnet_name.c_str(), tunnel.c_str());

orchagent/vnetorch.h

+4-24
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,13 @@ class VNetObject
4949
public:
5050
VNetObject(string& tunName, set<string>& peer) : tunnel_(tunName), peer_list_(peer) { }
5151

52-
virtual sai_object_id_t getEncapMapId() const = 0;
53-
54-
virtual sai_object_id_t getDecapMapId() const = 0;
55-
5652
virtual bool updateObj(vector<sai_attribute_t>&) = 0;
5753

5854
void setPeerList(set<string>& p_list)
5955
{
6056
peer_list_ = p_list;
6157
}
6258

63-
virtual sai_object_id_t getVRid() const = 0;
64-
6559
const set<string>& getPeerList() const
6660
{
6761
return peer_list_;
@@ -90,17 +84,17 @@ class VNetVrfObject : public VNetObject
9084

9185
set<sai_object_id_t> getVRids() const;
9286

93-
virtual sai_object_id_t getEncapMapId() const
87+
sai_object_id_t getEncapMapId() const
9488
{
9589
return getVRidIngress();
9690
}
9791

98-
virtual sai_object_id_t getDecapMapId() const
92+
sai_object_id_t getDecapMapId() const
9993
{
10094
return getVRidEgress();
10195
}
10296

103-
virtual sai_object_id_t getVRid() const
97+
sai_object_id_t getVRid() const
10498
{
10599
return getVRidIngress();
106100
}
@@ -123,6 +117,7 @@ class VNetOrch : public Orch2
123117
{
124118
public:
125119
VNetOrch(DBConnector *db, const std::string&, VNET_EXEC op = VNET_EXEC::VNET_EXEC_VRF);
120+
bool setIntf(const string& alias, const string vnet_name, const IpPrefix *prefix = nullptr);
126121

127122
bool isVnetExists(const std::string& name) const
128123
{
@@ -135,26 +130,11 @@ class VNetOrch : public Orch2
135130
return static_cast<T *>(vnet_table_.at(name).get());
136131
}
137132

138-
sai_object_id_t getEncapMapId(const std::string& name) const
139-
{
140-
return vnet_table_.at(name)->getEncapMapId();
141-
}
142-
143-
sai_object_id_t getDecapMapId(const std::string& name) const
144-
{
145-
return vnet_table_.at(name)->getDecapMapId();
146-
}
147-
148133
const set<string>& getPeerList(const std::string& name) const
149134
{
150135
return vnet_table_.at(name)->getPeerList();
151136
}
152137

153-
sai_object_id_t getVRid(const std::string& name) const
154-
{
155-
return vnet_table_.at(name)->getVRid();
156-
}
157-
158138
string getTunnelName(const std::string& name) const
159139
{
160140
return vnet_table_.at(name)->getTunnelName();

0 commit comments

Comments
 (0)