Skip to content

Commit

Permalink
[intfmgr]: Enable accept_untracked_na kernel param (sonic-net#2436)
Browse files Browse the repository at this point in the history
* [intfmgr]: Enable `accept_untracked_na` kernel param
* When enabling gratuitous ARP, also enable acceptance of untracked neighbor advertisements
  • Loading branch information
theasianpianist authored Oct 4, 2022
1 parent 24d29f1 commit e81ed20
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
20 changes: 18 additions & 2 deletions cfgmgr/intfmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,12 @@ void IntfMgr::removeSubIntfState(const string &alias)
bool IntfMgr::setIntfGratArp(const string &alias, const string &grat_arp)
{
/*
* Enable gratuitous ARP by accepting unsolicited ARP replies
* Enable gratuitous ARP by accepting unsolicited ARP replies and untracked neighbor advertisements
*/
stringstream cmd;
string res;
string garp_enabled;
int rc;

if (grat_arp == "enabled")
{
Expand All @@ -557,8 +558,23 @@ bool IntfMgr::setIntfGratArp(const string &alias, const string &grat_arp)

cmd << ECHO_CMD << " " << garp_enabled << " > /proc/sys/net/ipv4/conf/" << alias << "/arp_accept";
EXEC_WITH_ERROR_THROW(cmd.str(), res);

SWSS_LOG_INFO("ARP accept set to \"%s\" on interface \"%s\"", grat_arp.c_str(), alias.c_str());

cmd.clear();
cmd.str(std::string());

// `accept_untracked_na` is not available in all kernels, so check for it before trying to set it
cmd << "test -f /proc/sys/net/ipv6/conf/" << alias << "/accept_untracked_na";
rc = swss::exec(cmd.str(), res);

if (rc == 0) {
cmd.clear();
cmd.str(std::string());
cmd << ECHO_CMD << " " << garp_enabled << " > /proc/sys/net/ipv6/conf/" << alias << "/accept_untracked_na";
EXEC_WITH_ERROR_THROW(cmd.str(), res);
SWSS_LOG_INFO("`accept_untracked_na` set to \"%s\" on interface \"%s\"", grat_arp.c_str(), alias.c_str());
}

return true;
}

Expand Down
11 changes: 11 additions & 0 deletions tests/dvslib/dvs_vlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ def create_vlan(self, vlanID):
vlan_entry = {"vlanid": vlanID}
self.config_db.create_entry("VLAN", vlan, vlan_entry)

def create_vlan_interface(self, vlanID):
vlan = "Vlan{}".format(vlanID)
vlan_intf_entry = {}
self.config_db.create_entry("VLAN_INTERFACE", vlan, vlan_intf_entry)

def set_vlan_intf_property(self, vlanID, property, value):
vlan_key = "Vlan{}".format(vlanID)
vlan_entry = self.config_db.get_entry("VLAN_INTERFACE", vlan_key)
vlan_entry[property] = value
self.config_db.update_entry("VLAN_INTERFACE", vlan_key, vlan_entry)

def create_vlan_hostif(self, vlan, hostif_name):
vlan = "Vlan{}".format(vlan)
vlan_entry = {"vlanid": vlan, "host_ifname": hostif_name}
Expand Down
54 changes: 53 additions & 1 deletion tests/test_vlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import pytest

from distutils.version import StrictVersion
from dvslib.dvs_common import PollingConfig
from dvslib.dvs_common import PollingConfig, wait_for_result

@pytest.mark.usefixtures("testlog")
@pytest.mark.usefixtures('dvs_vlan_manager')
Expand Down Expand Up @@ -436,6 +436,58 @@ def test_VlanHostIf(self, dvs):
self.dvs_vlan.get_and_verify_vlan_ids(0)
self.dvs_vlan.get_and_verify_vlan_hostif_ids(len(dvs.asic_db.hostif_name_map) - 1)

def test_VlanGratArp(self, dvs):
def arp_accept_enabled():
rc, res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/arp_accept".format(vlan))
return (res.strip("\n") == "1", res)

def arp_accept_disabled():
rc, res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/arp_accept".format(vlan))
return (res.strip("\n") == "0", res)

vlan = "2"
self.dvs_vlan.create_vlan(vlan)
self.dvs_vlan.create_vlan_interface(vlan)
self.dvs_vlan.set_vlan_intf_property(vlan, "grat_arp", "enabled")

wait_for_result(arp_accept_enabled, PollingConfig(), "IPv4 arp_accept not enabled")

# Not currently possible to test `accept_untracked_na` as it doesn't exist in the kernel for
# our test VMs (only present in kernels 5.19 and above)

self.dvs_vlan.set_vlan_intf_property(vlan, "grat_arp", "disabled")

wait_for_result(arp_accept_disabled, PollingConfig(), "IPv4 arp_accept not disabled")

self.dvs_vlan.remove_vlan(vlan)

def test_VlanProxyArp(self, dvs):

def proxy_arp_enabled():
rc, proxy_arp_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp".format(vlan))
rc, pvlan_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp_pvlan".format(vlan))

return (proxy_arp_res.strip("\n") == "1" and pvlan_res.strip("\n") == "1", (proxy_arp_res, pvlan_res))

def proxy_arp_disabled():
rc, proxy_arp_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp".format(vlan))
rc, pvlan_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp_pvlan".format(vlan))

return (proxy_arp_res.strip("\n") == "0" and pvlan_res.strip("\n") == "0", (proxy_arp_res, pvlan_res))

vlan = "2"
self.dvs_vlan.create_vlan(vlan)
self.dvs_vlan.create_vlan_interface(vlan)
self.dvs_vlan.set_vlan_intf_property(vlan, "proxy_arp", "enabled")

wait_for_result(proxy_arp_enabled, PollingConfig(), 'IPv4 proxy_arp or proxy_arp_pvlan not enabled')

self.dvs_vlan.set_vlan_intf_property(vlan, "proxy_arp", "disabled")

wait_for_result(proxy_arp_disabled, PollingConfig(), 'IPv4 proxy_arp or proxy_arp_pvlan not disabled')

self.dvs_vlan.remove_vlan(vlan)

# Add Dummy always-pass test at end as workaroud
# for issue when Flaky fail on final test it invokes module tear-down before retrying
def test_nonflaky_dummy():
Expand Down

0 comments on commit e81ed20

Please sign in to comment.