Skip to content

Commit

Permalink
Addressed review comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
rupesh-k committed Jun 29, 2020
1 parent ea9a7bf commit b92c3d4
Show file tree
Hide file tree
Showing 8 changed files with 939 additions and 1,384 deletions.
129 changes: 100 additions & 29 deletions orchagent/mirrororch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,76 @@ bool MirrorOrch::decreaseRefCount(const string& name)
return true;
}

bool MirrorOrch::validateDstPort(const string& dstPort)
{
Port port;
if (!m_portsOrch->getPort(dstPort, port) && port.m_type != Port::PHY)
{
SWSS_LOG_ERROR("Failed to locate port %s", dstPort.c_str());
return false;
}
return true;
}

bool MirrorOrch::checkPortExistsInSrcPortList(const string& port, const string& srcPort)
{
auto ports = tokenize(srcPort, ',');
if (ports.size() != 0)
{
for (auto alias : ports)
{
if(port == alias)
{
return true;
}
}
}

return false;
}

bool MirrorOrch::validateSrcPort(const string& srcPort)
{
auto ports = tokenize(srcPort, ',');

if (ports.size() != 0)
{
for (auto alias : ports)
{
Port port;
if (!gPortsOrch->getPort(alias, port))
{
SWSS_LOG_ERROR("Failed to locate Port/LAG %s", alias.c_str());
return false;
}

if(!(port.m_type == Port::PHY || port.m_type == Port::LAG))
{
SWSS_LOG_ERROR("Not supported port %s", alias.c_str());
return false;
}

// Check if the ports in LAG are part of source port list
if (port.m_type == Port::LAG)
{
vector<Port> portv;
m_portsOrch->getLagMember(port, portv);
for (const auto p : portv)
{
if (checkPortExistsInSrcPortList(p.m_alias, srcPort))
{
SWSS_LOG_ERROR("Port %s in LAG %s is also part of src_port config %s",
p.m_alias.c_str(), port.m_alias.c_str(), srcPort.c_str());
return false;
}
}
}
}
}

return true;
}

void MirrorOrch::createEntry(const string& key, const vector<FieldValueTuple>& data)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -331,36 +401,26 @@ void MirrorOrch::createEntry(const string& key, const vector<FieldValueTuple>& d
}
else if (fvField(i) == MIRROR_SESSION_SRC_PORT)
{
auto ports = tokenize(fvValue(i), ',');
if (ports.size() != 0)
if (!validateSrcPort(fvValue(i)))
{
for (auto alias : ports)
{
Port port;
if (!gPortsOrch->getPort(alias, port))
{
SWSS_LOG_ERROR("Failed to locate port/LAG %s", alias.c_str());
return;
}
}
SWSS_LOG_ERROR("Failed to get valid source port list %s", fvValue(i).c_str());
return;
}
entry.src_port = fvValue(i);
}
else if (fvField(i) == MIRROR_SESSION_DST_PORT)
{
Port dst_port;
if (!m_portsOrch->getPort(fvValue(i), dst_port))
if (!validateDstPort(fvValue(i)))
{
SWSS_LOG_ERROR("Failed to locate port %s", fvValue(i).c_str());
SWSS_LOG_ERROR("Failed to get valid destination port %s", fvValue(i).c_str());
return;
}
entry.dst_port = fvValue(i);

}
else if (fvField(i) == MIRROR_SESSION_DIRECTION)
{
if (!(fvValue(i) == mirror_rx_direction || fvValue(i) == mirror_tx_direction
|| fvValue(i) == mirror_both_direction))
if (!(fvValue(i) == MIRROR_RX_DIRECTION || fvValue(i) == MIRROR_TX_DIRECTION
|| fvValue(i) == MIRROR_BOTH_DIRECTION))
{
SWSS_LOG_ERROR("Failed to get valid direction %s", fvValue(i).c_str());
return;
Expand Down Expand Up @@ -395,7 +455,7 @@ void MirrorOrch::createEntry(const string& key, const vector<FieldValueTuple>& d

setSessionState(key, entry);

if (entry.type == mirror_session_span && !entry.dst_port.empty())
if (entry.type == MIRROR_SESSION_SPAN && !entry.dst_port.empty())
{
auto &session1 = m_syncdMirrors.find(key)->second;
activateSession(key, session1);
Expand Down Expand Up @@ -430,7 +490,7 @@ task_process_status MirrorOrch::deleteEntry(const string& name)

if (session.status)
{
if (session.type != mirror_session_span)
if (session.type != MIRROR_SESSION_SPAN)
{
m_routeOrch->detach(this, session.dstIp);
}
Expand Down Expand Up @@ -700,8 +760,9 @@ bool MirrorOrch::setUnsetPortMirror(Port port,
status = sai_port_api->set_port_attribute(p.m_port_id, &port_attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to configure mirror session port %s: %s, status %d, sessionId %x\n",
port.m_alias.c_str(), p.m_alias.c_str(), status, sessionId);
SWSS_LOG_ERROR("Failed to configure %s session on port %s: %s, status %d, sessionId %x\n",
ingress ? "RX" : "TX", port.m_alias.c_str(),
p.m_alias.c_str(), status, sessionId);
return false;
}
}
Expand All @@ -711,8 +772,8 @@ bool MirrorOrch::setUnsetPortMirror(Port port,
status = sai_port_api->set_port_attribute(port.m_port_id, &port_attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to configure mirror session to port %s, status %d, sessionId %x\n",
port.m_alias.c_str(), status, sessionId);
SWSS_LOG_ERROR("Failed to configure %s session on port %s, status %d, sessionId %x\n",
ingress ? "RX" : "TX", port.m_alias.c_str(), status, sessionId);
return false;
}
}
Expand All @@ -732,15 +793,23 @@ bool MirrorOrch::configurePortMirrorSession(const string& name, MirrorEntry& ses
SWSS_LOG_ERROR("Failed to locate port/LAG %s", alias.c_str());
return false;
}
if (session.direction == mirror_rx_direction || session.direction == mirror_both_direction)
if (session.direction == MIRROR_RX_DIRECTION || session.direction == MIRROR_BOTH_DIRECTION)
{
if (!setUnsetPortMirror(port, true, set, session.sessionId))
{
SWSS_LOG_ERROR("Failed to configure mirror session %s port %s\n",
name.c_str(), port.m_alias.c_str());
return false;
}
}
if (session.direction == mirror_tx_direction || session.direction == mirror_both_direction)
if (session.direction == MIRROR_TX_DIRECTION || session.direction == MIRROR_BOTH_DIRECTION)
{
if (!setUnsetPortMirror(port, false, set, session.sessionId))
{
SWSS_LOG_ERROR("Failed to configure mirror session %s port %s \n",
name.c_str(), port.m_alias.c_str());
return false;
}
}
}
}
Expand All @@ -767,7 +836,7 @@ bool MirrorOrch::activateSession(const string& name, MirrorEntry& session)
attrs.push_back(attr);
}

if (session.type == mirror_session_span)
if (session.type == MIRROR_SESSION_SPAN)
{
Port dst_port;
if (!m_portsOrch->getPort(session.dst_port, dst_port))
Expand Down Expand Up @@ -1225,16 +1294,18 @@ void MirrorOrch::updateLagMember(const LagMemberUpdate& update)
// Check the following conditions:
// 1) Session is active
// 2) LAG is part of mirror session source ports.
// 3) Member port is not part of session source ports.
// if the above condition matches then set/unset mirror configuration to new member port.
if (session.status &&
!session.src_port.empty() &&
session.src_port.find(update.lag.m_alias.c_str()) != std::string::npos)
session.src_port.find(update.lag.m_alias.c_str()) != std::string::npos &&
!checkPortExistsInSrcPortList(update.member.m_alias, session.src_port))
{
if (session.direction == mirror_rx_direction || session.direction == mirror_both_direction)
if (session.direction == MIRROR_RX_DIRECTION || session.direction == MIRROR_BOTH_DIRECTION)
{
setUnsetPortMirror(update.member, true, update.add, session.sessionId);
}
if (session.direction == mirror_tx_direction || session.direction == mirror_both_direction)
if (session.direction == MIRROR_TX_DIRECTION || session.direction == MIRROR_BOTH_DIRECTION)
{
setUnsetPortMirror(update.member, false, update.add, session.sessionId);
}
Expand Down
13 changes: 8 additions & 5 deletions orchagent/mirrororch.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
#include <map>
#include <inttypes.h>

const string mirror_rx_direction = "RX";
const string mirror_tx_direction = "TX";
const string mirror_both_direction = "BOTH";
const string mirror_session_span = "SPAN";
const string mirror_session_erspan = "ERSPAN";
#define MIRROR_RX_DIRECTION "RX"
#define MIRROR_TX_DIRECTION "TX"
#define MIRROR_BOTH_DIRECTION "BOTH"
#define MIRROR_SESSION_SPAN "SPAN"
#define MIRROR_SESSION_ERSPAN "ERSPAN"

/*
* Contains session data specified by user in config file
Expand Down Expand Up @@ -128,6 +128,9 @@ class MirrorOrch : public Orch, public Observer, public Subject
void updateLagMember(const LagMemberUpdate&);
void updateVlanMember(const VlanMemberUpdate&);

bool checkPortExistsInSrcPortList(const string& port, const string& srcPort);
bool validateSrcPort(const string& srcPort);
bool validateDstPort(const string& dstPort);
bool setUnsetPortMirror(Port port, bool ingress, bool set,
sai_object_id_t sessionId);
bool configurePortMirrorSession(const string&, MirrorEntry&, bool enable);
Expand Down
33 changes: 33 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
from dvslib import dvs_acl
from dvslib import dvs_vlan
from dvslib import dvs_lag
from dvslib import dvs_mirror
from dvslib import dvs_policer

def ensure_system(cmd):
(rc, output) = commands.getstatusoutput(cmd)
Expand Down Expand Up @@ -816,6 +818,26 @@ def remove_neighbor(self, interface, ip):
tbl._del(interface + ":" + ip)
time.sleep(1)

def add_route(self, prefix, nexthop):
self.runcmd("ip route add " + prefix + " via " + nexthop)
time.sleep(1)

def remove_route(self, prefix):
self.runcmd("ip route del " + prefix)
time.sleep(1)

def create_fdb(self, vlan, mac, interface):
tbl = swsscommon.ProducerStateTable(self.pdb, "FDB_TABLE")
fvs = swsscommon.FieldValuePairs([("port", interface),
("type", "dynamic")])
tbl.set("Vlan" + vlan + ":" + mac, fvs)
time.sleep(1)

def remove_fdb(self, vlan, mac):
tbl = swsscommon.ProducerStateTable(self.pdb, "FDB_TABLE")
tbl._del("Vlan" + vlan + ":" + mac)
time.sleep(1)

def setup_db(self):
self.pdb = swsscommon.DBConnector(0, self.redis_sock, 0)
self.adb = swsscommon.DBConnector(1, self.redis_sock, 0)
Expand Down Expand Up @@ -1023,6 +1045,17 @@ def dvs_vlan_manager(request, dvs):
dvs.get_state_db(),
dvs.get_counters_db(),
dvs.get_app_db())
@pytest.yield_fixture(scope="class")
def dvs_mirror_manager(request, dvs):
request.cls.dvs_mirror = dvs_mirror.DVSMirror(dvs.get_asic_db(),
dvs.get_config_db(),
dvs.get_state_db(),
dvs.get_counters_db(),
dvs.get_app_db())
@pytest.yield_fixture(scope="class")
def dvs_policer_manager(request, dvs):
request.cls.dvs_policer = dvs_policer.DVSPolicer(dvs.get_asic_db(),
dvs.get_config_db())
##################### DPB fixtures ###########################################
def create_dpb_config_file(dvs):
cmd = "sonic-cfggen -j /etc/sonic/init_cfg.json -j /tmp/ports.json --print-data > /tmp/dpb_config_db.json"
Expand Down
10 changes: 10 additions & 0 deletions tests/dvslib/dvs_acl.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ def create_acl_rule(self, table_name, rule_name, qualifiers, action="FORWARD", p

self.config_db.create_entry("ACL_RULE", "{}|{}".format(table_name, rule_name), fvs)

def create_mirror_acl_rule(self, table_name, rule_name, qualifiers, priority="2020"):
fvs = {
"priority": priority
}

for k, v in qualifiers.items():
fvs[k] = v

self.config_db.create_entry("ACL_RULE", "{}|{}".format(table_name, rule_name), fvs)

def remove_acl_rule(self, table_name, rule_name):
self.config_db.delete_entry("ACL_RULE", "{}|{}".format(table_name, rule_name))

Expand Down
Loading

0 comments on commit b92c3d4

Please sign in to comment.