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

[proxy_arp] Implement proxy ARP feature #1302

Merged
merged 1 commit into from
May 29, 2020
Merged
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
48 changes: 48 additions & 0 deletions cfgmgr/intfmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,33 @@ void IntfMgr::removeSubIntfState(const string &alias)
}
}

bool IntfMgr::setIntfProxyArp(const string &alias, const string &proxy_arp)
{
stringstream cmd;
string res;
string proxy_arp_pvlan;

if (proxy_arp == "enabled")
{
proxy_arp_pvlan = "1";
}
else if (proxy_arp == "disabled")
{
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());
return true;
}

bool IntfMgr::isIntfStateOk(const string &alias)
{
vector<FieldValueTuple> temp;
Expand Down Expand Up @@ -418,6 +445,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);
Expand All @@ -432,6 +461,10 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
{
adminStatus = value;
}
else if (field == "proxy_arp")
{
proxy_arp = value;
}

if (field == "nat_zone")
{
Expand Down Expand Up @@ -479,6 +512,21 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
setIntfVrf(alias, vrf_name);
}

if (!proxy_arp.empty())
{
if (!setIntfProxyArp(alias, 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())
Expand Down
2 changes: 2 additions & 0 deletions cfgmgr/intfmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class IntfMgr : public Orch
void removeHostSubIntf(const std::string &subIntf);
void setSubIntfStateOk(const std::string &alias);
void removeSubIntfState(const std::string &alias);

bool setIntfProxyArp(const std::string &alias, const std::string &proxy_arp);
};

}
Expand Down
85 changes: 85 additions & 0 deletions orchagent/intfsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -226,6 +227,75 @@ bool IntfsOrch::setRouterIntfsAdminStatus(const Port &port)
return true;
}

bool IntfsOrch::setIntfVlanFloodType(const Port &port, sai_vlan_flood_control_type_t vlan_flood_type)
{
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 = 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 (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)
{
sai_vlan_flood_control_type_t vlan_flood_type;
if (proxy_arp == "enabled")
{
vlan_flood_type = SAI_VLAN_FLOOD_CONTROL_TYPE_NONE;
}
else
{
vlan_flood_type = SAI_VLAN_FLOOD_CONTROL_TYPE_ALL;
}

if (!setIntfVlanFloodType(port, vlan_flood_type))
{
return false;
}
}

m_syncdIntfses[alias].proxy_arp = (proxy_arp == "enabled") ? true : false;
return true;
}

set<IpPrefix> IntfsOrch:: getSubnetRoutes()
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -439,6 +509,7 @@ void IntfsOrch::doTask(Consumer &consumer)
uint32_t mtu;
bool adminUp;
uint32_t nat_zone_id = 0;
string proxy_arp = "";

for (auto idx : data)
{
Expand Down Expand Up @@ -502,6 +573,10 @@ void IntfsOrch::doTask(Consumer &consumer)
{
nat_zone = value;
}
else if (field == "proxy_arp")
{
proxy_arp = value;
}
}

if (alias == "eth0" || alias == "docker0")
Expand Down Expand Up @@ -624,6 +699,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)
Expand Down Expand Up @@ -682,6 +762,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*>();
Expand Down
4 changes: 4 additions & 0 deletions orchagent/intfsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct IntfsEntry
std::set<IpPrefix> ip_addresses;
int ref_count;
sai_object_id_t vrf_id;
bool proxy_arp;
};

typedef map<string, IntfsEntry> IntfsTable;
Expand Down Expand Up @@ -89,6 +90,9 @@ class IntfsOrch : public Orch

void addDirectedBroadcast(const Port &port, const IpPrefix &ip_prefix);
void removeDirectedBroadcast(const Port &port, const IpPrefix &ip_prefix);

bool setIntfVlanFloodType(const Port &port, sai_vlan_flood_control_type_t vlan_flood_type);
bool setIntfProxyArp(const string &alias, const string &proxy_arp);
};

#endif /* SWSS_INTFSORCH_H */
Loading