Skip to content

Commit

Permalink
[ACL] Add Tunnel Next Hop redirect support
Browse files Browse the repository at this point in the history
Signed-off-by: Vivek Reddy <[email protected]>
  • Loading branch information
vivekrnv committed Nov 27, 2024
1 parent 3da2e67 commit 0052e09
Show file tree
Hide file tree
Showing 6 changed files with 489 additions and 31 deletions.
87 changes: 80 additions & 7 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,58 @@ 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*>();
if (!vxlan_orch)
{
throw std::logic_error("VxlanTunnelOrch couldn't be retrieved");
}

tunn_ = vxlan_orch->getVxlanTunnel(tunnel_name);
if (!tunn_)
{
throw std::logic_error("Invalid Tunnel object");
}

nh = tunn_->getNextHop(endpoint_ip, mac, 0);
}

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::incRefCount()
{
if (tunn_ && nh != SAI_NULL_OBJECT_ID)
{
tunn_->incNextHopRefCount(endpoint_ip, mac, vni);
}
}
void AclRule::TunnelNH::decRefCount()
{
if (tunn_ && nh != SAI_NULL_OBJECT_ID)
{
tunn_->decNextHopRefCount(endpoint_ip, mac, vni);
}
}

void AclRule::TunnelNH::clear()
{
nh = SAI_NULL_OBJECT_ID;
}

string AclTableType::getName() const
{
return m_name;
Expand Down Expand Up @@ -1308,6 +1362,11 @@ void AclRule::decreaseNextHopRefCount()
}
m_redirect_target_next_hop_group.clear();
}
if (m_redirect_target_tun_nh.get_nh_oid() != SAI_NULL_OBJECT_ID)
{
m_redirect_target_tun_nh.decRefCount();
m_redirect_target_tun_nh.clear();
}

return;
}
Expand Down Expand Up @@ -2001,21 +2060,35 @@ 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);
auto tunn_nh_oid = m_redirect_target_tun_nh.get_nh_oid();
if (SAI_NULL_OBJECT_ID != tunn_nh_oid)
{
SWSS_LOG_INFO("Tunnel Next Hop Found: oid:%ld, target: %s", tunn_nh_oid, target.c_str());
m_redirect_target_tun_nh.incRefCount();
return tunn_nh_oid;
}
}
catch (std::logic_error& e)
{
// no error, just try next variant
}

// try to parse nh group the set of <ip address, interface name>
try
{
Expand Down
24 changes: 24 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,28 @@ class AclTable;
class AclRule
{
public:
struct TunnelNH
{
TunnelNH() = default;
~TunnelNH() = default;

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

sai_object_id_t get_nh_oid() { return nh; }

void clear();
void incRefCount();
void decRefCount();

std::string tunnel_name;
swss::IpAddress endpoint_ip;
swss::MacAddress mac;
uint32_t vni = 0;
VxlanTunnel* tunn_ = nullptr;
sai_object_id_t nh = 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 +382,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
6 changes: 3 additions & 3 deletions orchagent/vxlanorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,10 +596,10 @@ bool VxlanTunnel::removeNextHop(IpAddress& ipAddr, MacAddress macAddress, uint32
ipAddr.to_string().c_str(), macAddress.to_string().c_str(), vni,
nh_tunnels_[key].ref_count);

//Decrement ref count if already exists
nh_tunnels_[key].ref_count --;

if (!nh_tunnels_[key].ref_count)
int curr_ref = nh_tunnels_[key].ref_count;

if (!--curr_ref)
{
if (sai_next_hop_api->remove_next_hop(nh_tunnels_[key].nh_id) != SAI_STATUS_SUCCESS)
{
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

0 comments on commit 0052e09

Please sign in to comment.