Skip to content

Commit e81ed20

Browse files
[intfmgr]: Enable accept_untracked_na kernel param (sonic-net#2436)
* [intfmgr]: Enable `accept_untracked_na` kernel param * When enabling gratuitous ARP, also enable acceptance of untracked neighbor advertisements
1 parent 24d29f1 commit e81ed20

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

cfgmgr/intfmgr.cpp

+18-2
Original file line numberDiff line numberDiff line change
@@ -535,11 +535,12 @@ void IntfMgr::removeSubIntfState(const string &alias)
535535
bool IntfMgr::setIntfGratArp(const string &alias, const string &grat_arp)
536536
{
537537
/*
538-
* Enable gratuitous ARP by accepting unsolicited ARP replies
538+
* Enable gratuitous ARP by accepting unsolicited ARP replies and untracked neighbor advertisements
539539
*/
540540
stringstream cmd;
541541
string res;
542542
string garp_enabled;
543+
int rc;
543544

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

558559
cmd << ECHO_CMD << " " << garp_enabled << " > /proc/sys/net/ipv4/conf/" << alias << "/arp_accept";
559560
EXEC_WITH_ERROR_THROW(cmd.str(), res);
560-
561561
SWSS_LOG_INFO("ARP accept set to \"%s\" on interface \"%s\"", grat_arp.c_str(), alias.c_str());
562+
563+
cmd.clear();
564+
cmd.str(std::string());
565+
566+
// `accept_untracked_na` is not available in all kernels, so check for it before trying to set it
567+
cmd << "test -f /proc/sys/net/ipv6/conf/" << alias << "/accept_untracked_na";
568+
rc = swss::exec(cmd.str(), res);
569+
570+
if (rc == 0) {
571+
cmd.clear();
572+
cmd.str(std::string());
573+
cmd << ECHO_CMD << " " << garp_enabled << " > /proc/sys/net/ipv6/conf/" << alias << "/accept_untracked_na";
574+
EXEC_WITH_ERROR_THROW(cmd.str(), res);
575+
SWSS_LOG_INFO("`accept_untracked_na` set to \"%s\" on interface \"%s\"", grat_arp.c_str(), alias.c_str());
576+
}
577+
562578
return true;
563579
}
564580

tests/dvslib/dvs_vlan.py

+11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ def create_vlan(self, vlanID):
1313
vlan_entry = {"vlanid": vlanID}
1414
self.config_db.create_entry("VLAN", vlan, vlan_entry)
1515

16+
def create_vlan_interface(self, vlanID):
17+
vlan = "Vlan{}".format(vlanID)
18+
vlan_intf_entry = {}
19+
self.config_db.create_entry("VLAN_INTERFACE", vlan, vlan_intf_entry)
20+
21+
def set_vlan_intf_property(self, vlanID, property, value):
22+
vlan_key = "Vlan{}".format(vlanID)
23+
vlan_entry = self.config_db.get_entry("VLAN_INTERFACE", vlan_key)
24+
vlan_entry[property] = value
25+
self.config_db.update_entry("VLAN_INTERFACE", vlan_key, vlan_entry)
26+
1627
def create_vlan_hostif(self, vlan, hostif_name):
1728
vlan = "Vlan{}".format(vlan)
1829
vlan_entry = {"vlanid": vlan, "host_ifname": hostif_name}

tests/test_vlan.py

+53-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import pytest
33

44
from distutils.version import StrictVersion
5-
from dvslib.dvs_common import PollingConfig
5+
from dvslib.dvs_common import PollingConfig, wait_for_result
66

77
@pytest.mark.usefixtures("testlog")
88
@pytest.mark.usefixtures('dvs_vlan_manager')
@@ -436,6 +436,58 @@ def test_VlanHostIf(self, dvs):
436436
self.dvs_vlan.get_and_verify_vlan_ids(0)
437437
self.dvs_vlan.get_and_verify_vlan_hostif_ids(len(dvs.asic_db.hostif_name_map) - 1)
438438

439+
def test_VlanGratArp(self, dvs):
440+
def arp_accept_enabled():
441+
rc, res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/arp_accept".format(vlan))
442+
return (res.strip("\n") == "1", res)
443+
444+
def arp_accept_disabled():
445+
rc, res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/arp_accept".format(vlan))
446+
return (res.strip("\n") == "0", res)
447+
448+
vlan = "2"
449+
self.dvs_vlan.create_vlan(vlan)
450+
self.dvs_vlan.create_vlan_interface(vlan)
451+
self.dvs_vlan.set_vlan_intf_property(vlan, "grat_arp", "enabled")
452+
453+
wait_for_result(arp_accept_enabled, PollingConfig(), "IPv4 arp_accept not enabled")
454+
455+
# Not currently possible to test `accept_untracked_na` as it doesn't exist in the kernel for
456+
# our test VMs (only present in kernels 5.19 and above)
457+
458+
self.dvs_vlan.set_vlan_intf_property(vlan, "grat_arp", "disabled")
459+
460+
wait_for_result(arp_accept_disabled, PollingConfig(), "IPv4 arp_accept not disabled")
461+
462+
self.dvs_vlan.remove_vlan(vlan)
463+
464+
def test_VlanProxyArp(self, dvs):
465+
466+
def proxy_arp_enabled():
467+
rc, proxy_arp_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp".format(vlan))
468+
rc, pvlan_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp_pvlan".format(vlan))
469+
470+
return (proxy_arp_res.strip("\n") == "1" and pvlan_res.strip("\n") == "1", (proxy_arp_res, pvlan_res))
471+
472+
def proxy_arp_disabled():
473+
rc, proxy_arp_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp".format(vlan))
474+
rc, pvlan_res = dvs.runcmd("cat /proc/sys/net/ipv4/conf/Vlan{}/proxy_arp_pvlan".format(vlan))
475+
476+
return (proxy_arp_res.strip("\n") == "0" and pvlan_res.strip("\n") == "0", (proxy_arp_res, pvlan_res))
477+
478+
vlan = "2"
479+
self.dvs_vlan.create_vlan(vlan)
480+
self.dvs_vlan.create_vlan_interface(vlan)
481+
self.dvs_vlan.set_vlan_intf_property(vlan, "proxy_arp", "enabled")
482+
483+
wait_for_result(proxy_arp_enabled, PollingConfig(), 'IPv4 proxy_arp or proxy_arp_pvlan not enabled')
484+
485+
self.dvs_vlan.set_vlan_intf_property(vlan, "proxy_arp", "disabled")
486+
487+
wait_for_result(proxy_arp_disabled, PollingConfig(), 'IPv4 proxy_arp or proxy_arp_pvlan not disabled')
488+
489+
self.dvs_vlan.remove_vlan(vlan)
490+
439491
# Add Dummy always-pass test at end as workaroud
440492
# for issue when Flaky fail on final test it invokes module tear-down before retrying
441493
def test_nonflaky_dummy():

0 commit comments

Comments
 (0)