Skip to content

Commit 58a6447

Browse files
[vxlan tunnel decap]: Add vxlan tunnel decapsulation support (sonic-net#457)
* Implementation of vxlanorch and a test for it
1 parent ddb9a5e commit 58a6447

11 files changed

+1276
-63
lines changed

doc/swss-schema.md

+19
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,25 @@ Equivalent RedisDB entry:
647647
; and push the delta to appDB
648648
; Valid value is 1-9999. 0 is invalid.
649649

650+
### VXLAN\_TUNNEL
651+
Stores vxlan tunnels configuration
652+
Status: ready
653+
654+
key = VXLAN_TUNNEL:name ; name is an arbitrary name of vxlan tunnel
655+
src_ip = ipv4_address ; tunnel source IP address. Mandatory
656+
dst_ip = ipv4_address ; tunnel destination IP address. Optional. When this attribute is omitted or equal to "0.0.0.0"
657+
; the created tunnel will be P2MP. Otherwise the created tunnel will be P2P
658+
659+
### VXLAN\_TUNNEL\_MAP
660+
Stores vxlan tunnel map configuration. Defines mapping between vxlan vni and vlan interface
661+
Status: ready
662+
663+
key = VXLAN_TUNNEL_MAP:tunnel_name:tunnel_map_name
664+
; tunnel_name is a reference to created vxlan tunnel
665+
; tunnel_map_name is an arbitrary name of the map
666+
vni = uint24 ; vni id, defined for tunnel map
667+
vlan = "Vlan"vlan_id ; name of the existing vlan interface
668+
650669

651670
## State DB schema
652671

orchagent/Makefile.am

+58-55
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,64 @@ DBGFLAGS = -g -DNDEBUG
1919
endif
2020

2121
orchagent_SOURCES = \
22-
main.cpp \
23-
orchdaemon.cpp \
24-
orch.cpp \
25-
notifications.cpp \
26-
routeorch.cpp \
27-
neighorch.cpp \
28-
intfsorch.cpp \
29-
portsorch.cpp \
30-
copporch.cpp \
31-
tunneldecaporch.cpp \
32-
qosorch.cpp \
33-
bufferorch.cpp \
34-
mirrororch.cpp \
35-
fdborch.cpp \
36-
aclorch.cpp \
37-
saihelper.cpp \
38-
switchorch.cpp \
39-
pfcwdorch.cpp \
40-
pfcactionhandler.cpp \
41-
crmorch.cpp \
42-
request_parser.cpp \
43-
vrforch.cpp \
44-
countercheckorch.cpp \
45-
dtelorch.cpp \
46-
flexcounterorch.cpp\
47-
acltable.h \
48-
aclorch.h \
49-
bufferorch.h \
50-
copporch.h \
51-
fdborch.h \
52-
intfsorch.h \
53-
mirrororch.h \
54-
neighorch.h \
55-
notifications.h \
56-
observer.h \
57-
orch.h \
58-
orchdaemon.h \
59-
pfcactionhandler.h \
60-
pfcwdorch.h \
61-
port.h \
62-
portsorch.h \
63-
qosorch.h \
64-
routeorch.h \
65-
saihelper.h \
66-
switchorch.h \
67-
swssnet.h \
68-
tunneldecaporch.h \
69-
crmorch.h \
70-
request_parser.h \
71-
vrforch.h \
72-
dtelorch.h \
73-
countercheckorch.h \
74-
flexcounterorch.h \
75-
$(top_srcdir)/warmrestart/warm_restart.cpp \
76-
$(top_srcdir)/warmrestart/warm_restart.h
22+
main.cpp \
23+
orchdaemon.cpp \
24+
orch.cpp \
25+
notifications.cpp \
26+
routeorch.cpp \
27+
neighorch.cpp \
28+
intfsorch.cpp \
29+
portsorch.cpp \
30+
copporch.cpp \
31+
tunneldecaporch.cpp \
32+
qosorch.cpp \
33+
bufferorch.cpp \
34+
mirrororch.cpp \
35+
fdborch.cpp \
36+
aclorch.cpp \
37+
saihelper.cpp \
38+
switchorch.cpp \
39+
pfcwdorch.cpp \
40+
pfcactionhandler.cpp \
41+
crmorch.cpp \
42+
request_parser.cpp \
43+
vrforch.cpp \
44+
countercheckorch.cpp \
45+
vxlanorch.cpp \
46+
dtelorch.cpp \
47+
flexcounterorch.cpp \
48+
acltable.h \
49+
aclorch.h \
50+
bufferorch.h \
51+
copporch.h \
52+
directory.h \
53+
fdborch.h \
54+
intfsorch.h \
55+
mirrororch.h \
56+
neighorch.h \
57+
notifications.h \
58+
observer.h \
59+
orch.h \
60+
orchdaemon.h \
61+
pfcactionhandler.h \
62+
pfcwdorch.h \
63+
port.h \
64+
portsorch.h \
65+
qosorch.h \
66+
routeorch.h \
67+
saihelper.h \
68+
switchorch.h \
69+
swssnet.h \
70+
tunneldecaporch.h \
71+
crmorch.h \
72+
request_parser.h \
73+
vrforch.h \
74+
dtelorch.h \
75+
countercheckorch.h \
76+
vxlanorch.h \
77+
flexcounterorch.h \
78+
$(top_srcdir)/warmrestart/warm_restart.cpp \
79+
$(top_srcdir)/warmrestart/warm_restart.h
7780

7881
orchagent_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
7982
orchagent_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)

orchagent/directory.h

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#pragma once
2+
3+
// The Directory class below allows us to store objects inside.
4+
// The objects are supposed to be derived from a common base class B.
5+
// All set/get operations are addressed by the type of the storing/stored object.
6+
7+
#include <typeinfo>
8+
#include <string>
9+
#include <unordered_map>
10+
#include <algorithm>
11+
12+
template <typename B>
13+
class Directory
14+
{
15+
public:
16+
17+
template <typename U>
18+
void set(const U& value)
19+
{
20+
std::string type_name { typeid(U).name() };
21+
22+
if (m_values.find(type_name) != m_values.end())
23+
{
24+
throw std::logic_error(std::string("Type ") + type_name + " already registered");
25+
}
26+
27+
m_values[type_name] = value;
28+
}
29+
30+
template <typename U>
31+
const U get() const
32+
{
33+
std::string type_name { typeid(U).name() };
34+
35+
if (m_values.find(type_name) == m_values.end())
36+
{
37+
return nullptr;
38+
}
39+
40+
return static_cast<U>(m_values.at(type_name));
41+
}
42+
43+
class iterator : public std::iterator<std::input_iterator_tag, B>
44+
{
45+
public:
46+
explicit iterator(const typename std::unordered_map<std::string, B>::iterator& it) : it(it) {}
47+
48+
B& operator*() const
49+
{
50+
return it->second;
51+
}
52+
53+
bool operator!=(iterator other) const
54+
{
55+
return it != other.it;
56+
}
57+
58+
iterator& operator++()
59+
{
60+
++it;
61+
return *this;
62+
}
63+
64+
private:
65+
typename std::unordered_map<std::string, B>::iterator it;
66+
};
67+
68+
iterator begin()
69+
{
70+
return iterator(m_values.begin());
71+
}
72+
73+
iterator end()
74+
{
75+
return iterator(m_values.end());
76+
}
77+
78+
private:
79+
std::unordered_map<std::string, B> m_values;
80+
};

orchagent/orchdaemon.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ AclOrch *gAclOrch;
2929
CrmOrch *gCrmOrch;
3030
BufferOrch *gBufferOrch;
3131
SwitchOrch *gSwitchOrch;
32+
Directory<Orch*> gDirectory;
3233

3334
OrchDaemon::OrchDaemon(DBConnector *applDb, DBConnector *configDb, DBConnector *stateDb) :
3435
m_applDb(applDb),
@@ -72,6 +73,11 @@ bool OrchDaemon::init()
7273
CoppOrch *copp_orch = new CoppOrch(m_applDb, APP_COPP_TABLE_NAME);
7374
TunnelDecapOrch *tunnel_decap_orch = new TunnelDecapOrch(m_applDb, APP_TUNNEL_DECAP_TABLE_NAME);
7475

76+
VxlanTunnelOrch *vxlan_tunnel_orch = new VxlanTunnelOrch(m_configDb, CFG_VXLAN_TUNNEL_TABLE_NAME);
77+
gDirectory.set(vxlan_tunnel_orch);
78+
VxlanTunnelMapOrch *vxlan_tunnel_map_orch = new VxlanTunnelMapOrch(m_configDb, CFG_VXLAN_TUNNEL_MAP_TABLE_NAME);
79+
gDirectory.set(vxlan_tunnel_map_orch);
80+
7581
vector<string> qos_tables = {
7682
CFG_TC_TO_QUEUE_MAP_TABLE_NAME,
7783
CFG_SCHEDULER_TABLE_NAME,
@@ -166,6 +172,8 @@ bool OrchDaemon::init()
166172
m_orchList.push_back(mirror_orch);
167173
m_orchList.push_back(gAclOrch);
168174
m_orchList.push_back(vrf_orch);
175+
m_orchList.push_back(vxlan_tunnel_orch);
176+
m_orchList.push_back(vxlan_tunnel_map_orch);
169177

170178
m_select = new Select();
171179

orchagent/orchdaemon.h

+2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
#include "switchorch.h"
2222
#include "crmorch.h"
2323
#include "vrforch.h"
24+
#include "vxlanorch.h"
2425
#include "countercheckorch.h"
2526
#include "flexcounterorch.h"
27+
#include "directory.h"
2628

2729
using namespace swss;
2830

orchagent/request_parser.cpp

+79
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "sai.h"
1111
#include "macaddress.h"
12+
#include "ipaddress.h"
1213
#include "orch.h"
1314
#include "request_parser.h"
1415

@@ -87,6 +88,12 @@ void Request::parseKey(const KeyOpFieldsValuesTuple& request)
8788
case REQ_T_MAC_ADDRESS:
8889
key_item_mac_addresses_[i] = parseMacAddress(key_items[i]);
8990
break;
91+
case REQ_T_IP:
92+
key_item_ip_addresses_[i] = parseIpAddress(key_items[i]);
93+
break;
94+
case REQ_T_UINT:
95+
key_item_uint_[i] = parseUint(key_items[i]);
96+
break;
9097
default:
9198
throw std::logic_error(std::string("Not implemented key type parser. Key '")
9299
+ full_key_
@@ -129,6 +136,15 @@ void Request::parseAttrs(const KeyOpFieldsValuesTuple& request)
129136
case REQ_T_PACKET_ACTION:
130137
attr_item_packet_actions_[fvField(*i)] = parsePacketAction(fvValue(*i));
131138
break;
139+
case REQ_T_VLAN:
140+
attr_item_vlan_[fvField(*i)] = parseVlan(fvValue(*i));
141+
break;
142+
case REQ_T_IP:
143+
attr_item_ip_[fvField(*i)] = parseIpAddress(fvValue(*i));
144+
break;
145+
case REQ_T_UINT:
146+
attr_item_uint_[fvField(*i)] = parseUint(fvValue(*i));
147+
break;
132148
default:
133149
throw std::logic_error(std::string("Not implemented attribute type parser for attribute:") + fvField(*i));
134150
}
@@ -178,6 +194,69 @@ MacAddress Request::parseMacAddress(const std::string& str)
178194
return MacAddress(mac);
179195
}
180196

197+
IpAddress Request::parseIpAddress(const std::string& str)
198+
{
199+
try
200+
{
201+
IpAddress addr(str);
202+
return addr;
203+
}
204+
catch (std::invalid_argument& _)
205+
{
206+
throw std::invalid_argument(std::string("Invalid ip address: ") + str);
207+
}
208+
}
209+
210+
uint64_t Request::parseUint(const std::string& str)
211+
{
212+
try
213+
{
214+
uint64_t ret = std::stoul(str);
215+
return ret;
216+
}
217+
catch(std::invalid_argument& _)
218+
{
219+
throw std::invalid_argument(std::string("Invalid unsigned integer: ") + str);
220+
}
221+
catch(std::out_of_range& _)
222+
{
223+
throw std::invalid_argument(std::string("Out of range unsigned integer: ") + str);
224+
}
225+
}
226+
227+
uint16_t Request::parseVlan(const std::string& str)
228+
{
229+
uint16_t ret = 0;
230+
231+
const auto vlan_prefix = std::string("Vlan");
232+
const auto prefix_len = vlan_prefix.length();
233+
234+
if (str.substr(0, prefix_len) != vlan_prefix)
235+
{
236+
throw std::invalid_argument(std::string("Invalid vlan interface: ") + str);
237+
}
238+
239+
try
240+
{
241+
ret = static_cast<uint16_t>(std::stoul(str.substr(prefix_len)));
242+
}
243+
catch(std::invalid_argument& _)
244+
{
245+
throw std::invalid_argument(std::string("Invalid vlan id: ") + str);
246+
}
247+
catch(std::out_of_range& _)
248+
{
249+
throw std::invalid_argument(std::string("Out of range vlan id: ") + str);
250+
}
251+
252+
if (ret == 0 || ret > 4094)
253+
{
254+
throw std::invalid_argument(std::string("Out of range vlan id: ") + str);
255+
}
256+
257+
return ret;
258+
}
259+
181260
sai_packet_action_t Request::parsePacketAction(const std::string& str)
182261
{
183262
std::unordered_map<std::string, sai_packet_action_t> m = {

0 commit comments

Comments
 (0)