From 3460f8be94cfe560108d2248aa1ec2698991dd4d Mon Sep 17 00:00:00 2001 From: Pier Carlo Chiodi Date: Wed, 20 Sep 2017 18:14:07 +0200 Subject: [PATCH 1/3] add get_ipv6_neighbors_table() --- napalm_ios/ios.py | 68 +++++++++++++++++++ .../normal/expected_result.json | 19 ++++++ .../normal/show_ipv6_neighbors.txt | 4 ++ 3 files changed, 91 insertions(+) create mode 100644 test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json create mode 100644 test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt diff --git a/napalm_ios/ios.py b/napalm_ios/ios.py index 2447e73..ad28f20 100644 --- a/napalm_ios/ios.py +++ b/napalm_ios/ios.py @@ -2191,3 +2191,71 @@ def dest_file_system(self): if self.device and self._dest_file_system is None: self._dest_file_system = self._discover_file_system() return self._dest_file_system + + def get_ipv6_neighbors_table(self): + """ + Get IPv6 neighbors table information. + + Return a list of dictionaries having the following set of keys: + * interface (string) + * mac (string) + * ip (string) + * age (float) + * state (string) + + For example:: + [ + { + 'interface' : 'MgmtEth0/RSP0/CPU0/0', + 'mac' : '5c:5e:ab:da:3c:f0', + 'ip' : '2001:db8:1:1::1', + 'age' : 1454496274.84, + 'state' : 'REACH' + }, + { + 'interface': 'MgmtEth0/RSP0/CPU0/0', + 'mac' : '66:0e:94:96:e0:ff', + 'ip' : '2001:db8:1:1::2', + 'age' : 1435641582.49, + 'state' : 'STALE' + } + ] + """ + ipv6_neighbors_table = [] + + command = 'show ipv6 neighbors' + output = self._send_command(command) + + # Skip the first line which is a header + output = output.split('\n') + output = output[1:] + + for line in output: + if len(line) == 0: + return {} + if len(line.split()) == 5: + address, age, mac, state, interface = line.split() + else: + raise ValueError("Unexpected output from: {}".format(line.split())) + + try: + if age == '-': + age = 0 + age = float(age) + except ValueError: + raise ValueError("Unable to convert age value to float: {}".format(age)) + + # Validate we matched correctly + if not re.search(IPV6_ADDR_REGEX, address): + raise ValueError("Invalid IPv6 Address detected: {}".format(address)) + if not re.search(RE_MAC, mac): + raise ValueError("Invalid MAC Address detected: {}".format(mac)) + entry = { + 'interface': interface, + 'mac': napalm_base.helpers.mac(mac), + 'ip': address, + 'age': age, + 'state': state + } + ipv6_neighbors_table.append(entry) + return ipv6_neighbors_table diff --git a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json new file mode 100644 index 0000000..a384925 --- /dev/null +++ b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json @@ -0,0 +1,19 @@ +[{ + "interface": "Ethernet2", + "ip": "2000:0:0:4::2", + "mac": "00:03:A0:D6:14:1E", + "age": 0, + "state": "REACH" +}, { + "interface": "Ethernet2", + "ip": "FE80::203:A0FF:FED6:141E", + "mac": "00:03:A0:D6:14:1E", + "age": 0, + "state": "REACH" +}, { + "interface": "Ethernet2", + "ip": "3001:1::45a", + "mac": "00:02:7D:1A:94:72", + "age": 0, + "state": "REACH" +}] diff --git a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt new file mode 100644 index 0000000..53524a0 --- /dev/null +++ b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt @@ -0,0 +1,4 @@ +IPv6 Address Age Link-layer Addr State Interface +2000:0:0:4::2 0 0003.a0d6.141e REACH Ethernet2 +FE80::203:A0FF:FED6:141E 0 0003.a0d6.141e REACH Ethernet2 +3001:1::45a - 0002.7d1a.9472 REACH Ethernet2 From 270fff9cecae96256149cba3797e37f2129e9959 Mon Sep 17 00:00:00 2001 From: Pier Carlo Chiodi Date: Thu, 21 Sep 2017 17:32:17 +0200 Subject: [PATCH 2/3] ignore INCMP entries Example: 2001:DB8:1:2::3:4 0 - INCMP Gi0/0/2 --- napalm_ios/ios.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/napalm_ios/ios.py b/napalm_ios/ios.py index ad28f20..e8ebf47 100644 --- a/napalm_ios/ios.py +++ b/napalm_ios/ios.py @@ -2238,6 +2238,10 @@ def get_ipv6_neighbors_table(self): else: raise ValueError("Unexpected output from: {}".format(line.split())) + # 2001:DB8:1:2::3:4 0 - INCMP Gi0/0/2 + if mac == '-' and state == 'INCMP': + continue + try: if age == '-': age = 0 From 8eab70cbddea5e97ed46c30139a36d4e877c11f2 Mon Sep 17 00:00:00 2001 From: Pier Carlo Chiodi Date: Sat, 30 Sep 2017 08:32:17 +0200 Subject: [PATCH 3/3] age is in seconds but Cisco output in minutes Time (in minutes) since the address was confirmed to be reachable. https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipv6/command/ipv6-cr-book/ipv6-s4.html#wp1680937550 --- napalm_ios/ios.py | 2 +- .../test_get_ipv6_neighbors_table/normal/expected_result.json | 2 +- .../normal/show_ipv6_neighbors.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/napalm_ios/ios.py b/napalm_ios/ios.py index e8ebf47..7d4e9c9 100644 --- a/napalm_ios/ios.py +++ b/napalm_ios/ios.py @@ -2245,7 +2245,7 @@ def get_ipv6_neighbors_table(self): try: if age == '-': age = 0 - age = float(age) + age = float(age) * 60 except ValueError: raise ValueError("Unable to convert age value to float: {}".format(age)) diff --git a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json index a384925..2b49284 100644 --- a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json +++ b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/expected_result.json @@ -2,7 +2,7 @@ "interface": "Ethernet2", "ip": "2000:0:0:4::2", "mac": "00:03:A0:D6:14:1E", - "age": 0, + "age": 60, "state": "REACH" }, { "interface": "Ethernet2", diff --git a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt index 53524a0..2827817 100644 --- a/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt +++ b/test/unit/mocked_data/test_get_ipv6_neighbors_table/normal/show_ipv6_neighbors.txt @@ -1,4 +1,4 @@ IPv6 Address Age Link-layer Addr State Interface -2000:0:0:4::2 0 0003.a0d6.141e REACH Ethernet2 +2000:0:0:4::2 1 0003.a0d6.141e REACH Ethernet2 FE80::203:A0FF:FED6:141E 0 0003.a0d6.141e REACH Ethernet2 3001:1::45a - 0002.7d1a.9472 REACH Ethernet2