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 28, 2024
1 parent 3da2e67 commit 3a63721
Show file tree
Hide file tree
Showing 6 changed files with 458 additions and 33 deletions.
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:%ld, 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

0 comments on commit 3a63721

Please sign in to comment.