-
Notifications
You must be signed in to change notification settings - Fork 547
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
Changes from all commits
3a63721
a81dbf0
03c7041
8ce30c8
fbb2885
4c60841
fd73fa3
20c5dd7
de48b3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
#include "timer.h" | ||
#include "crmorch.h" | ||
#include "sai_serialize.h" | ||
#include "directory.h" | ||
|
||
using namespace std; | ||
using namespace swss; | ||
|
@@ -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 | ||
|
@@ -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; | ||
|
@@ -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; | ||
} | ||
|
||
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like logic is changed. Previously it returned NULL OBJECT if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This field can take many variants, it can be Port, Lag, NH IP, NHG and now Tunnel NH. Previous logic is incorrect as if get NH fails, it should try to check if it is one of other variants instead of returning SAI_NULL_OBJECT_ID |
||
} | ||
|
||
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 | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add this schema in the PR description and how it would look like with an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated