Skip to content

Commit 414d38a

Browse files
committed
ERSPAN support updates
Signed-off-by: Tom Flynn <tom.flynn@gmail.com> Change-Id: Ie7629a6eb681d55864ad85074355f7dbd937c8a5
1 parent 353fee2 commit 414d38a

File tree

5 files changed

+104
-160
lines changed

5 files changed

+104
-160
lines changed

agent-ovs/lib/include/opflexagent/SpanSessionState.h

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class SessionState {
112112

113113
/**
114114
* constructor that takes a URI that points to a Session object
115-
* @param uri_ URI to a Session object
115+
* @param uri_ URI of a Session object
116116
* @param name_ name of Session object
117117
*/
118118
SessionState(const URI& uri_, const string& name_) :
@@ -196,6 +196,75 @@ class SessionState {
196196
// mapping DstSummary to dst IP
197197
address destination;
198198
};
199+
200+
class ErspanParams {
201+
public:
202+
/**
203+
* Default constructor
204+
*/
205+
ErspanParams() : ver(0) {}
206+
207+
/**
208+
* Copy constructor
209+
*/
210+
ErspanParams(const ErspanParams& copy) : ver(copy.ver), remoteIp(copy.remoteIp), portName(copy.portName) {}
211+
212+
/**
213+
* Get the ERSPAN version
214+
*
215+
* @return 1 for Type II, 2 for Type III
216+
*/
217+
unsigned int getVersion() const {
218+
return ver;
219+
}
220+
221+
/**
222+
* Set the ERSPAN version
223+
*
224+
* @param version ERSPAN version
225+
*/
226+
void setVersion(int version) {
227+
ver = version;
228+
}
229+
230+
/**
231+
* Get the ERSPAN session dest IP
232+
* @return dest IP
233+
*/
234+
const string& getRemoteIp() const {
235+
return remoteIp;
236+
}
237+
238+
/**
239+
* Set the ERSPAN session dest IP
240+
* @param remoteIp_ ERSPAN session dest IP
241+
*/
242+
void setRemoteIp(const string& remoteIp_) {
243+
remoteIp = remoteIp_;
244+
}
245+
246+
/**
247+
* Get the ERSPAN port name
248+
* @return ERSPAN port name
249+
*/
250+
const string& getPortName() const {
251+
return portName;
252+
}
253+
254+
/**
255+
* Set the ERSPAN port name
256+
* @param portName_ ERSPAN port name
257+
*/
258+
void setPortName(const string& portName_) {
259+
portName = portName_;
260+
}
261+
262+
private:
263+
264+
unsigned int ver;
265+
string remoteIp;
266+
string portName;
267+
};
199268
}
200269

201270
#endif // SPANSESSIONSTATE_H

agent-ovs/ovs/JsonRpc.cpp

Lines changed: 12 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ bool JsonRpc::getOvsdbMirrorConfig(mirror& mir) {
307307
return true;
308308
}
309309

310-
bool JsonRpc::getCurrentErspanParams(const string& portName, erspan_ifc& params) {
310+
bool JsonRpc::getCurrentErspanParams(const string& portName, ErspanParams& params) {
311311
// for ERSPAN port get IP address
312312
JsonRpcTransactMessage msg1(OvsdbOperation::SELECT, OvsdbTable::INTERFACE);
313313
tuple<string, string, string> cond1("name", "==", portName);
@@ -395,7 +395,7 @@ bool JsonRpc::getPortList(const uint64_t reqId, const Document& payload, unorder
395395
}
396396
}
397397

398-
bool JsonRpc::getErspanOptions(const uint64_t reqId, const Document& payload, erspan_ifc& pIfc) {
398+
bool JsonRpc::getErspanOptions(const uint64_t reqId, const Document& payload, ErspanParams& params) {
399399
if (!payload.IsArray()) {
400400
LOG(DEBUG) << "payload is not an array";
401401
return false;
@@ -407,45 +407,16 @@ bool JsonRpc::getErspanOptions(const uint64_t reqId, const Document& payload, er
407407
LOG(DEBUG) << "expected array";
408408
return false;
409409
}
410-
map<string, string> options;
411410
for (Value::ConstValueIterator itr1 = arr.Begin(); itr1 != arr.End(); itr1++) {
412-
LOG(DEBUG) << (*itr1)[0].GetString() << ":"
413-
<< (*itr1)[1].GetString();
414411
string val((*itr1)[1].GetString());
415412
string index((*itr1)[0].GetString());
416-
options.emplace(index, val);
417-
}
418-
auto ver = options.find("erspan_ver");
419-
if (ver != options.end()) {
420-
if (ver->second == "1") {
421-
erspan_ifc_v1 params = erspan_ifc_v1();
422-
if (options.find("erspan_idx") != options.end()) {
423-
params.erspan_idx = stoi(options["erspan_idx"]);
424-
}
425-
pIfc = params;
426-
} else if (ver->second == "2") {
427-
erspan_ifc_v2 params = erspan_ifc_v2();
428-
if (options.find("erspan_hwid") != options.end()) {
429-
params.erspan_hw_id = stoi(options["erspan_hwid"]);
430-
}
431-
if (options.find("erspan_dir") != options.end()) {
432-
params.erspan_dir = stoi(options["erspan_dir"]);
433-
}
434-
pIfc = params;
435-
} else {
436-
return false;
437-
}
438-
if (options.find("key") != options.end()) {
439-
pIfc.key = stoi(options["key"]);
413+
if (index == "erspan_ver") {
414+
params.setVersion(stoi(val));
415+
} else if (index == "remote_ip") {
416+
params.setRemoteIp(val);
440417
}
441-
pIfc.erspan_ver = stoi(ver->second);
442-
if (options.find("remote_ip") != options.end()) {
443-
pIfc.remote_ip = options["remote_ip"];
444-
}
445-
return true;
446-
} else {
447-
return false;
448418
}
419+
return (params.getVersion() != 0);
449420
}
450421

451422
void JsonRpc::getPortUuid(const string& name, string& uuid) {
@@ -578,10 +549,10 @@ bool JsonRpc::createMirror(const string& brUuid, const string& name, const set<s
578549
return handleCreateMirrorResp(pResp->reqId, pResp->payload);
579550
}
580551

581-
bool JsonRpc::addErspanPort(const string& bridge, erspan_ifc& port) {
552+
bool JsonRpc::addErspanPort(const string& bridge, ErspanParams& params) {
582553
JsonRpcTransactMessage msg1(OvsdbOperation::INSERT, OvsdbTable::PORT);
583554
vector<TupleData> tuples;
584-
tuples.emplace_back("", port.name);
555+
tuples.emplace_back("", params.getPortName());
585556
TupleDataSet tdSet(tuples);
586557
msg1.rowData.emplace("name", tdSet);
587558

@@ -603,7 +574,7 @@ bool JsonRpc::addErspanPort(const string& bridge, erspan_ifc& port) {
603574
// row entries
604575
// name
605576
tuples.clear();
606-
tuples.emplace_back("", port.name);
577+
tuples.emplace_back("", params.getPortName());
607578
tdSet = TupleDataSet(tuples);
608579
msg2.rowData.emplace("name", tdSet);
609580

@@ -616,18 +587,8 @@ bool JsonRpc::addErspanPort(const string& bridge, erspan_ifc& port) {
616587

617588
// options depend upon version
618589
tuples.clear();
619-
tuples.emplace_back("erspan_ver", std::to_string(port.erspan_ver));
620-
tuples.emplace_back("key", std::to_string(port.key));
621-
tuples.emplace_back("remote_ip", port.remote_ip);
622-
if (port.erspan_ver == 1) {
623-
tuples.emplace_back("erspan_idx",
624-
std::to_string(static_cast<erspan_ifc_v1&>(port).erspan_idx));
625-
} else if (port.erspan_ver == 2) {
626-
tuples.emplace_back("erspan_hwid",
627-
std::to_string(static_cast<erspan_ifc_v2&>(port).erspan_hw_id));
628-
tuples.emplace_back("erspan_dir",
629-
std::to_string(static_cast<erspan_ifc_v2&>(port).erspan_dir));
630-
}
590+
tuples.emplace_back("erspan_ver", std::to_string(params.getVersion()));
591+
tuples.emplace_back("remote_ip", params.getRemoteIp());
631592
tdSet = TupleDataSet(tuples, "map");
632593
msg2.rowData.emplace("options", tdSet);
633594

agent-ovs/ovs/SpanRenderer.cpp

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ namespace opflexagent {
183183
}
184184

185185
// get ERSPAN interface params if configured
186-
JsonRpc::erspan_ifc params;
186+
ErspanParams params;
187187
if (!jRpc->getCurrentErspanParams(ERSPAN_PORT_PREFIX + seSt.get()->getName(), params)) {
188188
LOG(DEBUG) << "Unable to get ERSPAN parameters";
189189
return;
190190
}
191191
// check for change in config, push it if there is a change.
192-
if (params.remote_ip != seSt.get()->getDestination().to_string() ||
193-
params.erspan_ver != seSt.get()->getVersion()) {
194-
LOG(INFO) << "Mirror config has changed";
192+
if (params.getRemoteIp() != seSt.get()->getDestination().to_string() ||
193+
params.getVersion() != seSt.get()->getVersion()) {
194+
LOG(INFO) << "Mirror config has changed for " << seSt.get()->getName();
195195
updateMirrorConfig(seSt.get());
196196
return;
197197
}
@@ -232,30 +232,11 @@ namespace opflexagent {
232232

233233
bool SpanRenderer::addErspanPort(const string& portName, const string &ipAddr, const uint8_t version) {
234234
LOG(DEBUG) << "adding erspan port " << portName << " IP " << ipAddr << " and version " << std::to_string(version);
235-
JsonRpc::erspan_ifc ep;
236-
if (version == 1) {
237-
JsonRpc::erspan_ifc_v1 params = JsonRpc::erspan_ifc_v1();
238-
// current OVS implementation supports only one ERSPAN port.
239-
// use 1 as ersan_idx
240-
params.erspan_idx = 1;
241-
ep = params;
242-
} else if (version == 2) {
243-
JsonRpc::erspan_ifc_v2 params = JsonRpc::erspan_ifc_v2();
244-
// current OVS implementation supports one ERSPAN port and mirror
245-
// choose 1 for hw_id.
246-
// dir can be set to 0 as it does not have an affect on the mirror traffic.
247-
params.erspan_hw_id = 1;
248-
params.erspan_dir = 0;
249-
ep = params;
250-
} else {
251-
return false;
252-
}
253-
ep.name = portName;
254-
ep.remote_ip = ipAddr;
255-
// current OVS implementation supports only one ERPSAN port and mirror.
256-
// choose 1 as the key.
257-
ep.key = 1;
258-
if (!jRpc->addErspanPort(switchName, ep)) {
235+
ErspanParams params;
236+
params.setVersion(version);
237+
params.setPortName(portName);
238+
params.setRemoteIp(ipAddr);
239+
if (!jRpc->addErspanPort(switchName, params)) {
259240
LOG(DEBUG) << "add erspan port failed";
260241
return false;
261242
}

agent-ovs/ovs/include/JsonRpc.h

Lines changed: 6 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <thread>
2626
#include <rapidjson/document.h>
2727
#include "OvsdbConnection.h"
28+
#include <opflexagent/SpanSessionState.h>
2829
#include <opflexagent/logging.h>
2930

3031
#include <boost/optional.hpp>
@@ -54,73 +55,7 @@ void getValue(const Document& val, const list<string>& idx, Value& result);
5455
*/
5556
class JsonRpc : public Transaction {
5657
public:
57-
/**
58-
* base struct for ERSPAN interface parameters
59-
*/
60-
typedef struct erspan_ifc_ {
61-
/**
62-
* ERSPAN version
63-
*/
64-
int erspan_ver;
65-
/**
66-
* name of ERSPAN port
67-
*/
68-
string name;
69-
/**
70-
* ERSPAN key
71-
* maps to ERSPAN session ID/Span ID
72-
*/
73-
int key;
74-
/**
75-
* destination IP address
76-
*/
77-
string remote_ip;
78-
} erspan_ifc;
7958

80-
/**
81-
* ERSPAN type II struct
82-
*/
83-
typedef struct erspan_ifc_v1_ : erspan_ifc {
84-
/**
85-
* constructor
86-
* ERSPAN version 1 maps to ERSPAN type 2
87-
*/
88-
erspan_ifc_v1_() {
89-
erspan_ver = 1;
90-
erspan_idx = 0;
91-
}
92-
/**
93-
* ERSPAN index
94-
* This field is a 20-bit index/port number associated with the ERSPAN traffic's
95-
* source port and direction (ingress/egress). This field is platform dependent.
96-
*/
97-
int erspan_idx;
98-
} erspan_ifc_v1;
99-
100-
/**
101-
* ERSPAN type III struct
102-
*/
103-
typedef struct erspan_ifc_v2_ : erspan_ifc {
104-
/**
105-
* constructor
106-
* ERSPAN version 2 maps to ERSPAN type 3.
107-
*/
108-
erspan_ifc_v2_() {
109-
erspan_ver = 2;
110-
erspan_hw_id = 0;
111-
erspan_dir = 0;
112-
}
113-
/**
114-
* ERSPAN hardware ID
115-
* A 6-bit unique identifier of an ERSPAN v2 engine within a system.
116-
*/
117-
int erspan_hw_id;
118-
/**
119-
* ERSPAN direction
120-
* the mirrored traffic's direction: 0 for ingress traffic, 1 for egress traffic.
121-
*/
122-
int erspan_dir;
123-
} erspan_ifc_v2;
12459

12560
/**
12661
* struct for managing mirror data
@@ -250,10 +185,10 @@ class JsonRpc : public Transaction {
250185
/**
251186
* add an erspan port to the bridge
252187
* @param[in] bridgeName name of bridge to add the port to
253-
* @param[in] port erspan_ifc struct
188+
* @param[in] params ERSPAN params
254189
* @return true if success, false otherwise
255190
*/
256-
bool addErspanPort(const string& bridgeName, erspan_ifc& port);
191+
bool addErspanPort(const string& bridgeName, ErspanParams& params);
257192

258193
/**
259194
* createNetFlow
@@ -347,7 +282,7 @@ class JsonRpc : public Transaction {
347282
* @param[out] params erspan interface struct
348283
* @return true if success, false otherwise
349284
*/
350-
bool getCurrentErspanParams(const string& portName, erspan_ifc& params);
285+
bool getCurrentErspanParams(const string& portName, ErspanParams& params);
351286

352287
/**
353288
* check if connection has been established
@@ -384,10 +319,10 @@ class JsonRpc : public Transaction {
384319
* get ERSPAN interface options from Value struct
385320
* @param[in] reqId request ID
386321
* @param[in] payload response Value struct
387-
* @param[out] pIfc empty shared pointer to ERSPAN
322+
* @param[out] pararms ERSPAN session params
388323
* interface struct
389324
*/
390-
static bool getErspanOptions(const uint64_t reqId, const Document& payload, erspan_ifc& pIfc);
325+
static bool getErspanOptions(const uint64_t reqId, const Document& payload, ErspanParams& params);
391326

392327
template <typename T>
393328
inline bool sendRequestAndAwaitResponse(const list<T> &tl) {

0 commit comments

Comments
 (0)