Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ACL] Add Tunnel Next Hop redirect support #3399

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 66 additions & 8 deletions orchagent/aclorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "timer.h"
#include "crmorch.h"
#include "sai_serialize.h"
#include "directory.h"

using namespace std;
using namespace swss;
Expand All @@ -30,6 +31,7 @@ extern PortsOrch* gPortsOrch;
extern CrmOrch *gCrmOrch;
extern SwitchOrch *gSwitchOrch;
extern string gMySwitchType;
extern Directory<Orch*> gDirectory;

#define MIN_VLAN_ID 1 // 0 is a reserved VLAN ID
#define MAX_VLAN_ID 4095 // 4096 is a reserved VLAN ID
Expand Down Expand Up @@ -617,6 +619,35 @@ bool AclTableRangeMatch::validateAclRuleMatch(const AclRule& rule) const
return true;
}

void AclRule::TunnelNH::load(const std::string& target)
{
parse(target);

VxlanTunnelOrch* vxlan_orch = gDirectory.get<VxlanTunnelOrch*>();
/* Only the first call creates the SAI object, further calls just increment the ref count */
oid = vxlan_orch->createNextHopTunnel(tunnel_name, endpoint_ip, mac, vni);
}

void AclRule::TunnelNH::parse(const std::string& target)
{
/* Supported Format: endpoint_ip@tunnel_name */
auto at_pos = target.find('@');
if (at_pos == std::string::npos)
{
throw std::logic_error("Invalid format for Tunnel Next Hop");
}

endpoint_ip = swss::IpAddress(target.substr(0, at_pos));
tunnel_name = target.substr(at_pos + 1);
}

void AclRule::TunnelNH::clear()
{
oid = SAI_NULL_OBJECT_ID;
VxlanTunnelOrch* vxlan_orch = gDirectory.get<VxlanTunnelOrch*>();
vxlan_orch->removeNextHopTunnel(tunnel_name, endpoint_ip, mac, vni);
}

string AclTableType::getName() const
{
return m_name;
Expand Down Expand Up @@ -1308,7 +1339,17 @@ void AclRule::decreaseNextHopRefCount()
}
m_redirect_target_next_hop_group.clear();
}

if (m_redirect_target_tun_nh.oid != SAI_NULL_OBJECT_ID)
{
try
{
m_redirect_target_tun_nh.clear();
}
catch (const std::runtime_error& e)
{
SWSS_LOG_ERROR("Failed to remove tunnel nh reference %s, ACL Rule: %s", e.what(), m_id.c_str());
}
}
return;
}

Expand Down Expand Up @@ -2001,21 +2042,38 @@ sai_object_id_t AclRulePacket::getRedirectObjectId(const string& redirect_value)
try
{
NextHopKey nh(target);
if (!m_pAclOrch->m_neighOrch->hasNextHop(nh))
if (m_pAclOrch->m_neighOrch->hasNextHop(nh))
{
SWSS_LOG_ERROR("ACL Redirect action target next hop ip: '%s' doesn't exist on the switch", nh.to_string().c_str());
return SAI_NULL_OBJECT_ID;
m_redirect_target_next_hop = target;
m_pAclOrch->m_neighOrch->increaseNextHopRefCount(nh);
return m_pAclOrch->m_neighOrch->getNextHopId(nh);
}

m_redirect_target_next_hop = target;
m_pAclOrch->m_neighOrch->increaseNextHopRefCount(nh);
return m_pAclOrch->m_neighOrch->getNextHopId(nh);
}
catch (...)
{
// no error, just try next variant
}

// Try to parse if this is a tunnel nexthop.
try
{
m_redirect_target_tun_nh.load(target);
if (SAI_NULL_OBJECT_ID != m_redirect_target_tun_nh.oid)
{
SWSS_LOG_INFO("Tunnel Next Hop Found: oid:0x%" PRIx64 ", target: %s", m_redirect_target_tun_nh.oid, target.c_str());
return m_redirect_target_tun_nh.oid;
}
}
catch (std::logic_error& e)
{
// no error, just try next variant
}
catch (const std::runtime_error& e)
{
SWSS_LOG_ERROR("Failed to create/fetch tunnel next hop, %s, err: %s", target.c_str(), e.what());
return SAI_NULL_OBJECT_ID;
}

// try to parse nh group the set of <ip address, interface name>
try
{
Expand Down
18 changes: 18 additions & 0 deletions orchagent/aclorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "mirrororch.h"
#include "dtelorch.h"
#include "observer.h"
#include "vxlanorch.h"
#include "flex_counter_manager.h"

#include "acltable.h"
Expand Down Expand Up @@ -286,6 +287,22 @@ class AclTable;
class AclRule
{
public:
struct TunnelNH
{
TunnelNH() = default;
~TunnelNH() = default;

void load(const std::string& target);
void parse(const std::string& target);
void clear();

std::string tunnel_name;
swss::IpAddress endpoint_ip;
swss::MacAddress mac;
uint32_t vni = 0;
sai_object_id_t oid = SAI_NULL_OBJECT_ID;
};

AclRule(AclOrch *pAclOrch, string rule, string table, bool createCounter = true);
virtual bool validateAddPriority(string attr_name, string attr_value);
virtual bool validateAddMatch(string attr_name, string attr_value);
Expand Down Expand Up @@ -359,6 +376,7 @@ class AclRule
map <sai_acl_entry_attr_t, SaiAttrWrapper> m_matches;
string m_redirect_target_next_hop;
string m_redirect_target_next_hop_group;
AclRule::TunnelNH m_redirect_target_tun_nh;

vector<AclRangeConfig> m_rangeConfig;
vector<AclRange*> m_ranges;
Expand Down
8 changes: 4 additions & 4 deletions orchagent/vxlanorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1329,10 +1329,6 @@ VxlanTunnelOrch::createNextHopTunnel(string tunnelName, IpAddress& ipAddr,
return SAI_NULL_OBJECT_ID;
}

SWSS_LOG_NOTICE("NH tunnel create for %s, ip %s, mac %s, vni %d",
tunnelName.c_str(), ipAddr.to_string().c_str(),
macAddress.to_string().c_str(), vni);

auto tunnel_obj = getVxlanTunnel(tunnelName);
sai_object_id_t nh_id, tunnel_id = tunnel_obj->getTunnelId();

Expand All @@ -1342,6 +1338,10 @@ VxlanTunnelOrch::createNextHopTunnel(string tunnelName, IpAddress& ipAddr,
return nh_id;
}

SWSS_LOG_NOTICE("NH tunnel create for %s, ip %s, mac %s, vni %d",
tunnelName.c_str(), ipAddr.to_string().c_str(),
macAddress.to_string().c_str(), vni);

sai_ip_address_t host_ip;
swss::copy(host_ip, ipAddr);

Expand Down
1 change: 1 addition & 0 deletions tests/mock_tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ LDADD_GTEST = -L/usr/src/gtest
tests_INCLUDES = -I $(FLEX_CTR_DIR) -I $(DEBUG_CTR_DIR) -I $(top_srcdir)/lib -I$(top_srcdir)/cfgmgr -I$(top_srcdir)/orchagent -I$(P4_ORCH_DIR)/tests -I$(DASH_ORCH_DIR) -I$(top_srcdir)/warmrestart

tests_SOURCES = aclorch_ut.cpp \
aclorch_rule_ut.cpp \
portsorch_ut.cpp \
routeorch_ut.cpp \
qosorch_ut.cpp \
Expand Down
Loading
Loading