-
Notifications
You must be signed in to change notification settings - Fork 694
Delete the IPv6 link-local Neighbor when ipv6 link-local mode is disabled #1897
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
Changes from all commits
3a63fff
08a4c8d
75ac751
1b88e1a
0ac9869
a77af5e
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 |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| import time | ||
| import json | ||
| import pytest | ||
|
|
||
| from swsscommon import swsscommon | ||
|
|
||
| class TestIPv6LinkLocal(object): | ||
| def setup_db(self, dvs): | ||
| self.pdb = dvs.get_app_db() | ||
| self.adb = dvs.get_asic_db() | ||
| self.cdb = dvs.get_config_db() | ||
|
|
||
| def set_admin_status(self, interface, status): | ||
| self.cdb.update_entry("PORT", interface, {"admin_status": status}) | ||
|
|
||
| def add_ip_address(self, interface, ip): | ||
| self.cdb.create_entry("INTERFACE", interface + "|" + ip, {"NULL": "NULL"}) | ||
| time.sleep(2) | ||
|
|
||
| def remove_ip_address(self, interface, ip): | ||
| self.cdb.delete_entry("INTERFACE", interface + "|" + ip) | ||
| time.sleep(2) | ||
|
|
||
| def create_ipv6_link_local_intf(self, interface): | ||
| self.cdb.create_entry("INTERFACE", interface, {"ipv6_use_link_local_only": "enable"}) | ||
| time.sleep(2) | ||
|
|
||
| def remove_ipv6_link_local_intf(self, interface): | ||
| self.cdb.delete_entry("INTERFACE", interface) | ||
| time.sleep(2) | ||
|
|
||
| def test_NeighborAddRemoveIpv6LinkLocal(self, dvs, testlog): | ||
| self.setup_db(dvs) | ||
|
|
||
| # create ipv6 link local intf | ||
| self.create_ipv6_link_local_intf("Ethernet0") | ||
| self.create_ipv6_link_local_intf("Ethernet4") | ||
|
|
||
| # bring up interface | ||
| self.set_admin_status("Ethernet0", "up") | ||
| self.set_admin_status("Ethernet4", "up") | ||
|
|
||
| # set ip address | ||
| self.add_ip_address("Ethernet0", "2000::1/64") | ||
| self.add_ip_address("Ethernet4", "2001::1/64") | ||
| dvs.runcmd("sysctl -w net.ipv6.conf.all.forwarding=1") | ||
| dvs.runcmd("sysctl -w net.ipv6.conf.default.forwarding=1") | ||
|
|
||
| # set ip address and default route | ||
| dvs.servers[0].runcmd("ip -6 address add 2000::2/64 dev eth0") | ||
| dvs.servers[0].runcmd("ip -6 route add default via 2000::1") | ||
|
|
||
| dvs.servers[1].runcmd("ip -6 address add 2001::2/64 dev eth0") | ||
| dvs.servers[1].runcmd("ip -6 route add default via 2001::1") | ||
| time.sleep(2) | ||
|
|
||
| # get neighbor entry | ||
| dvs.servers[0].runcmd("ping -6 -c 1 2001::2") | ||
| time.sleep(2) | ||
|
|
||
| # Neigh entries should contain Ipv6-link-local neighbors, should be 4 | ||
| neigh_entries = self.pdb.get_keys("NEIGH_TABLE") | ||
| assert (len(neigh_entries) == 4) | ||
|
|
||
| found_entry = False | ||
| for key in neigh_entries: | ||
| if (key.find("Ethernet4:2001::2") or key.find("Ethernet0:2000::2")): | ||
|
Collaborator
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. Why is this an 'or' check? Shouldn't it be mandatory that both entries exist?
Contributor
Author
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. Both entries should exist, but here moving ahead by checking 1 entry only. Anyways checking number of entries as 4 right. |
||
| found_entry = True | ||
|
|
||
| assert found_entry | ||
|
|
||
| # remove ip address | ||
| self.remove_ip_address("Ethernet0", "2000::1/64") | ||
| self.remove_ip_address("Ethernet4", "2001::1/64") | ||
|
|
||
| # remove ipv6 link local intf | ||
| self.remove_ipv6_link_local_intf("Ethernet0") | ||
| self.remove_ipv6_link_local_intf("Ethernet4") | ||
|
|
||
| # Neigh entries should not contain Ipv6-link-local neighbors, should be 2 | ||
|
Collaborator
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. Wouldn't removing the global IPv6 remove both IP link local as well as global neighbor entries? Can you please clarify?
Contributor
Author
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. Global ipv6 remove will not remove the link local neighbor entries because ipv6 link local is always enable in kernel. The ipv6 link local remove command will remove the neighbors from APPL_DB only.
Collaborator
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. If it removes the neighbors from APPL_DB and remove_ip_address remove the global neighbors shouldn't the number of entries be zero? My earlier question was why 2 entries are present since the interface now has no IPv6 address (global) or has link local enabled.
Collaborator
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. @AkhileshSamineni Can you please let me know if my understanding is correct?
Contributor
Author
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. @dgsudharsan Global neighbor entries gets deleted when interface is set to down. |
||
| neigh_after_entries = self.pdb.get_keys("NEIGH_TABLE") | ||
| print(neigh_after_entries) | ||
| assert (len(neigh_after_entries) == 2) | ||
|
|
||
| found_existing_entry = False | ||
| for key in neigh_entries: | ||
| if (key.find("Ethernet4:2001::2") or key.find("Ethernet0:2000::2")): | ||
| found_existing_entry = True | ||
|
|
||
| assert found_existing_entry | ||
|
|
||
| self.set_admin_status("Ethernet0", "down") | ||
| self.set_admin_status("Ethernet4", "down") | ||
|
|
||
| # remove ip address and default route | ||
| dvs.servers[0].runcmd("ip -6 route del default dev eth0") | ||
| dvs.servers[0].runcmd("ip -6 address del 2000::2/64 dev eth0") | ||
|
|
||
| dvs.servers[1].runcmd("ip -6 route del default dev eth0") | ||
| dvs.servers[1].runcmd("ip -6 address del 2001::2/64 dev eth0") | ||
|
|
||
| dvs.runcmd("sysctl -w net.ipv6.conf.all.forwarding=0") | ||
| dvs.runcmd("sysctl -w net.ipv6.conf.default.forwarding=0") | ||
|
|
||
| neigh_entries = self.pdb.get_keys("NEIGH_TABLE") | ||
| assert (len(neigh_entries) == 0) | ||
|
|
||
| # 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(): | ||
| pass | ||
|
|
||
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.
why don't we just do a flush of neigh on this interface? why to loop through each of the neighbors especially since this happens during a major config change
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.
When we do flushing on a interface, the global ipv6 address also gets deleted along with link-local. For 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.
agree.. but this operation is not done frequently, and flushing the interface, it can also relearn, right?
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.
Looks like this is deleting the link-local neighbor only, given that we will not have many link local neighbors, flushing per interface level may not be required.
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.
ok, i was thinking if we could avoid this Neighbor handling and scanning the APP_DB in this context. @AkhileshSamineni, please make sure if the delete operation fails (for some reason the linklocal is not present in kernel while attempting to delete) does not cause process exit
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.
@prsunny If the delete operation fails for some reason, it does not cause the process exit.
we see below INFO message only