-
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
[proxy_arp] Implement proxy ARP feature #1285
Changes from 4 commits
931c8e7
33a8ef0
05f28d7
2d6354f
f649457
3c47041
e0ac724
dfcdabd
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 |
---|---|---|
|
@@ -272,6 +272,34 @@ void IntfMgr::removeSubIntfState(const string &alias) | |
} | ||
} | ||
|
||
bool IntfMgr::setIntfProxyArp(const string &alias, const string &vrf_name, const string &proxy_arp) | ||
{ | ||
stringstream cmd; | ||
string res; | ||
string proxy_arp_pvlan; | ||
|
||
if (proxy_arp == "enabled" || !vrf_name.compare(0, strlen(VNET_PREFIX), VNET_PREFIX)) | ||
{ | ||
proxy_arp_pvlan = "1"; | ||
} | ||
else if (proxy_arp == "disabled" && vrf_name.compare(0, strlen(VNET_PREFIX), VNET_PREFIX)) | ||
{ | ||
proxy_arp_pvlan = "0"; | ||
} | ||
else | ||
{ | ||
SWSS_LOG_ERROR("Proxy ARP state is invalid: \"%s\"", proxy_arp.c_str()); | ||
return false; | ||
} | ||
|
||
cmd << ECHO_CMD << " " << proxy_arp_pvlan << " > /proc/sys/net/ipv4/conf/" << alias << "/proxy_arp_pvlan"; | ||
EXEC_WITH_ERROR_THROW(cmd.str(), res); | ||
|
||
SWSS_LOG_INFO("Proxy ARP set to \"%s\" on interface \"%s\"", proxy_arp.c_str(), alias.c_str()); | ||
|
||
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. Suggest to remove extra line to avoid file getting bigger |
||
return true; | ||
} | ||
|
||
bool IntfMgr::isIntfStateOk(const string &alias) | ||
{ | ||
vector<FieldValueTuple> temp; | ||
|
@@ -346,6 +374,8 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys, | |
string mtu = ""; | ||
string adminStatus = ""; | ||
string nat_zone = ""; | ||
string proxy_arp = ""; | ||
|
||
for (auto idx : data) | ||
{ | ||
const auto &field = fvField(idx); | ||
|
@@ -363,6 +393,10 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys, | |
{ | ||
adminStatus = value; | ||
} | ||
else if (field == "proxy_arp") | ||
{ | ||
proxy_arp = value; | ||
} | ||
|
||
if (field == "nat_zone") | ||
{ | ||
|
@@ -420,7 +454,22 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys, | |
FieldValueTuple fvTuple("mac_addr", MacAddress().to_string()); | ||
data.push_back(fvTuple); | ||
} | ||
|
||
|
||
if (!proxy_arp.empty() || !vrf_name.compare(0, strlen(VNET_PREFIX), VNET_PREFIX)) | ||
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. A small request for change : After some internal discussion, we don't want to have proxy_arp enabled explicitly for Vnets. Let that also be triggered by config_db entry. I'll make necessary modifications to requirement doc. Please remove this check on Vnets |
||
{ | ||
if (!setIntfProxyArp(alias, vrf_name, proxy_arp)) | ||
{ | ||
SWSS_LOG_ERROR("Failed to set proxy ARP to \"%s\" state for the \"%s\" interface", proxy_arp.c_str(), alias.c_str()); | ||
return false; | ||
} | ||
|
||
if (!alias.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX)) | ||
{ | ||
FieldValueTuple fvTuple("proxy_arp", proxy_arp); | ||
data.push_back(fvTuple); | ||
} | ||
} | ||
|
||
if (!subIntfAlias.empty()) | ||
{ | ||
if (m_subIntfList.find(subIntfAlias) == m_subIntfList.end()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ extern sai_router_interface_api_t* sai_router_intfs_api; | |
extern sai_route_api_t* sai_route_api; | ||
extern sai_neighbor_api_t* sai_neighbor_api; | ||
extern sai_switch_api_t* sai_switch_api; | ||
extern sai_vlan_api_t* sai_vlan_api; | ||
|
||
extern sai_object_id_t gSwitchId; | ||
extern PortsOrch *gPortsOrch; | ||
|
@@ -226,6 +227,81 @@ bool IntfsOrch::setRouterIntfsAdminStatus(const Port &port) | |
return true; | ||
} | ||
|
||
bool IntfsOrch::setIntfVlanFloodType(const Port &port) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
if (port.m_type != Port::VLAN) | ||
{ | ||
SWSS_LOG_ERROR("VLAN flood type cannot be set for non VLAN interface \"%s\"", port.m_alias.c_str()); | ||
return false; | ||
} | ||
|
||
sai_attribute_t attr; | ||
attr.id = SAI_VLAN_ATTR_BROADCAST_FLOOD_CONTROL_TYPE; | ||
attr.value.s32 = port.m_vlan_info.vlan_flood_type; | ||
|
||
sai_status_t status = sai_vlan_api->set_vlan_attribute(port.m_vlan_info.vlan_oid, &attr); | ||
if (status != SAI_STATUS_SUCCESS) | ||
{ | ||
SWSS_LOG_ERROR("Failed to set flood type for VLAN %u, rv:%d", port.m_vlan_info.vlan_id, status); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool IntfsOrch::setIntfProxyArp(const string &alias, const string &proxy_arp) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
if (proxy_arp != "enabled" || proxy_arp != "disabled") | ||
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. I don't think we need this check. It wouldn't be added by IntfMgr if value is different |
||
{ | ||
SWSS_LOG_ERROR("Proxy ARP state is invalid: \"%s\"", proxy_arp.c_str()); | ||
return false; | ||
} | ||
|
||
if (m_syncdIntfses.find(alias) == m_syncdIntfses.end()) | ||
{ | ||
SWSS_LOG_ERROR("Interface \"%s\" doesn't exist", alias.c_str()); | ||
return false; | ||
} | ||
|
||
if (m_syncdIntfses[alias].proxy_arp == (proxy_arp == "enabled" ? true : false)) | ||
{ | ||
SWSS_LOG_INFO("Proxy ARP is already set to \"%s\" on interface \"%s\"", proxy_arp.c_str(), alias.c_str()); | ||
return true; | ||
} | ||
|
||
Port port; | ||
if (!gPortsOrch->getPort(alias, port)) | ||
{ | ||
SWSS_LOG_ERROR("Failed to get port info for the interface \"%s\"", alias.c_str()); | ||
return false; | ||
} | ||
|
||
if (port.m_type == Port::VLAN) | ||
{ | ||
if (proxy_arp == "enabled") | ||
{ | ||
port.m_vlan_info.vlan_flood_type = SAI_VLAN_FLOOD_CONTROL_TYPE_NONE; | ||
} | ||
else | ||
{ | ||
port.m_vlan_info.vlan_flood_type = SAI_VLAN_FLOOD_CONTROL_TYPE_ALL; | ||
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. I don't see this updated back to port map. Please refer this after updating a field of port. In this case, i dont think you need to store this value. Just pass the 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. Hi @volodymyrsamotiy @prsunny, is it alright to influence the flooding behavior of all BUM packets when proxy_arp enabled? This flood_type attr seems not only applied to ARP packets.
|
||
} | ||
|
||
if (!setIntfVlanFloodType(port)) | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
m_syncdIntfses[alias].proxy_arp = (proxy_arp == "enabled") ? true : false; | ||
|
||
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. Pls remove this extra line. Just a suggestion |
||
return true; | ||
} | ||
|
||
set<IpPrefix> IntfsOrch:: getSubnetRoutes() | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
@@ -440,6 +516,7 @@ void IntfsOrch::doTask(Consumer &consumer) | |
uint32_t mtu; | ||
bool adminUp; | ||
uint32_t nat_zone_id = 0; | ||
string proxy_arp = ""; | ||
|
||
for (auto idx : data) | ||
{ | ||
|
@@ -515,6 +592,10 @@ void IntfsOrch::doTask(Consumer &consumer) | |
{ | ||
nat_zone = value; | ||
} | ||
else if (field == "proxy_arp") | ||
{ | ||
proxy_arp = value; | ||
} | ||
} | ||
|
||
if (alias == "eth0" || alias == "docker0") | ||
|
@@ -666,6 +747,11 @@ void IntfsOrch::doTask(Consumer &consumer) | |
} | ||
} | ||
|
||
if (!proxy_arp.empty()) | ||
{ | ||
setIntfProxyArp(alias, proxy_arp); | ||
} | ||
|
||
it = consumer.m_toSync.erase(it); | ||
} | ||
else if (op == DEL_COMMAND) | ||
|
@@ -724,6 +810,11 @@ void IntfsOrch::doTask(Consumer &consumer) | |
vnet_name = m_vnetInfses.at(alias); | ||
} | ||
|
||
if (m_syncdIntfses[alias].proxy_arp) | ||
{ | ||
setIntfProxyArp(alias, "disabled"); | ||
} | ||
|
||
if (!vnet_name.empty()) | ||
{ | ||
VNetOrch* vnet_orch = gDirectory.get<VNetOrch*>(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,8 +32,9 @@ typedef std::map<sai_vlan_id_t, VlanMemberEntry> vlan_members_t; | |
|
||
struct VlanInfo | ||
{ | ||
sai_object_id_t vlan_oid = 0; | ||
sai_vlan_id_t vlan_id = 0; | ||
sai_object_id_t vlan_oid = 0; | ||
sai_vlan_id_t vlan_id = 0; | ||
sai_vlan_flood_control_type_t vlan_flood_type = SAI_VLAN_FLOOD_CONTROL_TYPE_ALL; | ||
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. I suggest to remove this attribute as it is a function handled in intforch and portorch doesn't necessarily be aware of this |
||
}; | ||
|
||
class Port | ||
|
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.
Could you please remove this parameter as it is not used?