Skip to content

Commit d5f2b92

Browse files
[Multiasic]: Provide namespace support for ipNetToMediaPhysAddress (sonic-net#129)
* [Multiasic]: Provide namespace support for ipNetToMediaPhysAddress MIB in rfc1213. Signed-off-by: SuvarnaMeenakshi <[email protected]> * [Namespace][ArpUpdater]: Update ArpUpdater to support multiple namespaces. Add function to retrieve data from NEIGH_TABLE in APP_DB of each namespace. Signed-off-by: SuvarnaMeenakshi <[email protected]> * Updated as per review comments. Changes made so that for single asic platform, arp table information is retrieved from NEIGH_TABLE. Signed-off-by: SuvarnaMeenakshi <[email protected]>
1 parent 166c221 commit d5f2b92

File tree

9 files changed

+411
-50
lines changed

9 files changed

+411
-50
lines changed

src/sonic_ax_impl/mibs/__init__.py

+24
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@
4848

4949
redis_kwargs = {'unix_socket_path': '/var/run/redis/redis.sock'}
5050

51+
52+
def get_neigh_info(neigh_key):
53+
"""
54+
split neigh_key string of the format:
55+
NEIGH_TABLE:device:ipv4_address
56+
"""
57+
_, device, ip = neigh_key.split(':')
58+
return device, ip
59+
5160
def chassis_info_table(chassis_name):
5261
"""
5362
:param: chassis_name: chassis name
@@ -520,6 +529,21 @@ def dbs_keys(dbs, db_name, pattern='*'):
520529
result_keys.extend(keys)
521530
return result_keys
522531

532+
@staticmethod
533+
def dbs_keys_namespace(dbs, db_name, pattern='*'):
534+
"""
535+
dbs_keys_namespace function execute on global
536+
and all namespace DBs. Provides a map of keys
537+
and namespace(db index).
538+
"""
539+
result_keys = {}
540+
for db_index in range(len(dbs)):
541+
keys = dbs[db_index].keys(db_name, pattern)
542+
if keys is not None:
543+
keys_ns = dict.fromkeys(keys, db_index)
544+
result_keys.update(keys_ns)
545+
return result_keys
546+
523547
@staticmethod
524548
def dbs_get_all(dbs, db_name, _hash, *args, **kwargs):
525549
"""

src/sonic_ax_impl/mibs/ietf/rfc1213.py

+50-16
Original file line numberDiff line numberDiff line change
@@ -54,32 +54,66 @@ class IfTypes(int, Enum):
5454
class ArpUpdater(MIBUpdater):
5555
def __init__(self):
5656
super().__init__()
57+
self.db_conn = Namespace.init_namespace_dbs()
5758
self.arp_dest_map = {}
5859
self.arp_dest_list = []
5960
self.arp_dest_map = {}
6061
self.arp_dest_list = []
62+
self.neigh_key_list = {}
6163

62-
def update_data(self):
63-
self.arp_dest_map = {}
64-
self.arp_dest_list = []
64+
def reinit_data(self):
65+
Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB)
66+
self.neigh_key_list = Namespace.dbs_keys_namespace(self.db_conn, mibs.APPL_DB, "NEIGH_TABLE:*")
67+
68+
def _update_from_arptable(self):
6569
for entry in python_arptable.get_arp_table():
6670
dev = entry['Device']
6771
mac = entry['HW address']
6872
ip = entry['IP address']
73+
self._update_arp_info(dev, mac, ip)
74+
75+
def _update_from_db(self):
76+
for neigh_key in self.neigh_key_list:
77+
neigh_str = neigh_key.decode()
78+
db_index = self.neigh_key_list[neigh_key]
79+
neigh_info = self.db_conn[db_index].get_all(mibs.APPL_DB, neigh_key, blocking=False)
80+
if neigh_info is None:
81+
continue
82+
ip_family = neigh_info[b'family'].decode()
83+
if ip_family == "IPv4":
84+
dev, ip = mibs.get_neigh_info(neigh_str)
85+
mac = neigh_info[b'neigh'].decode()
86+
# eth0 interface in a namespace is not management interface
87+
# but is a part of docker0 bridge. Ignore this interface.
88+
if len(self.db_conn) > 1 and dev == "eth0":
89+
continue
90+
self._update_arp_info(dev, mac, ip)
91+
92+
def _update_arp_info(self, dev, mac, ip):
93+
if_index = mibs.get_index_from_str(dev)
94+
if if_index is None: return
95+
96+
mactuple = mac_decimals(mac)
97+
machex = ''.join(chr(b) for b in mactuple)
98+
# if MAC is all zero
99+
#if not any(mac): continue
100+
101+
iptuple = ip2tuple_v4(ip)
102+
103+
subid = (if_index,) + iptuple
104+
self.arp_dest_map[subid] = machex
105+
self.arp_dest_list.append(subid)
69106

70-
if_index = mibs.get_index_from_str(dev)
71-
if if_index is None: continue
72-
73-
mactuple = mac_decimals(mac)
74-
machex = ''.join(chr(b) for b in mactuple)
75-
# if MAC is all zero
76-
#if not any(mac): continue
77-
78-
iptuple = ip2tuple_v4(ip)
79-
80-
subid = (if_index,) + iptuple
81-
self.arp_dest_map[subid] = machex
82-
self.arp_dest_list.append(subid)
107+
def update_data(self):
108+
self.arp_dest_map = {}
109+
self.arp_dest_list = []
110+
# Update arp table of host.
111+
# In case of multi-asic platform, get host arp table
112+
# from kernel and namespace arp table from NEIGH_TABLE in APP_DB
113+
# in each namespace.
114+
self._update_from_db()
115+
if len(self.db_conn) > 1:
116+
self._update_from_arptable()
83117
self.arp_dest_list.sort()
84118

85119
def arp_dest(self, sub_id):

tests/mock_tables/appl_db.json

+120
Original file line numberDiff line numberDiff line change
@@ -684,5 +684,125 @@
684684
"INTF_TABLE:lo:fc00:1::32/128": {
685685
"scope": "global",
686686
"family": "IPv6"
687+
},
688+
"NEIGH_TABLE:eth0:10.3.146.86": {
689+
"neigh": "00:a0:a5:75:35:8d",
690+
"family": "IPv4"
691+
},
692+
"NEIGH_TABLE:Ethernet68:10.0.0.35": {
693+
"neigh": "52:54:00:a5:70:47",
694+
"family": "IPv4"
695+
},
696+
"NEIGH_TABLE:Ethernet36:10.0.0.19": {
697+
"neigh": "52:54:00:04:52:5d",
698+
"family": "IPv4"
699+
},
700+
"NEIGH_TABLE:Ethernet112:10.0.0.57": {
701+
"neigh": "52:54:00:b4:59:59",
702+
"family": "IPv4"
703+
},
704+
"NEIGH_TABLE:eth0:10.3.146.1": {
705+
"neigh": "00:00:5e:00:01:64",
706+
"family": "IPv4"
707+
},
708+
"NEIGH_TABLE:eth0:10.3.146.244": {
709+
"neigh": "e4:d3:f1:51:3c:80",
710+
"family": "IPv4"
711+
},
712+
"NEIGH_TABLE:eth0:10.3.147.97": {
713+
"neigh": "3c:94:d5:69:b5:02",
714+
"family": "IPv4"
715+
},
716+
"NEIGH_TABLE:Ethernet48:10.0.0.25": {
717+
"neigh": "52:54:00:55:2d:fe",
718+
"family": "IPv4"
719+
},
720+
"NEIGH_TABLE:eth0:10.3.146.75": {
721+
"neigh": "00:a0:a5:76:17:70",
722+
"family": "IPv4"
723+
},
724+
"NEIGH_TABLE:eth0:10.3.146.131": {
725+
"neigh": "00:15:c7:21:f7:40",
726+
"family": "IPv4"
727+
},
728+
"NEIGH_TABLE:Ethernet40:10.0.0.21": {
729+
"neigh": "52:54:00:d0:a0:8c",
730+
"family": "IPv4"
731+
},
732+
"NEIGH_TABLE:Ethernet64:10.0.0.33": {
733+
"neigh": "7c:fe:90:5e:6b:a6",
734+
"family": "IPv4"
735+
},
736+
"NEIGH_TABLE:Ethernet88:10.0.0.45": {
737+
"neigh": "52:54:00:d0:23:2b",
738+
"family": "IPv4"
739+
},
740+
"NEIGH_TABLE:Ethernet116:10.0.0.59": {
741+
"neigh": "52:54:00:ae:c8:01",
742+
"family": "IPv4"
743+
},
744+
"NEIGH_TABLE:Ethernet8:10.0.0.5": {
745+
"neigh": "52:54:00:fc:50:3c",
746+
"family": "IPv4"
747+
},
748+
"NEIGH_TABLE:Ethernet108:10.0.0.55": {
749+
"neigh": "52:54:00:1b:d6:95",
750+
"family": "IPv4"
751+
},
752+
"NEIGH_TABLE:Ethernet20:10.0.0.11": {
753+
"neigh": "00:00:00:00:00:00",
754+
"family": "IPv4"
755+
},
756+
"NEIGH_TABLE:Ethernet120:10.0.0.61": {
757+
"neigh": "00:00:00:00:00:00",
758+
"family": "IPv4"
759+
},
760+
"NEIGH_TABLE:Ethernet4:10.0.0.3": {
761+
"neigh": "00:00:00:00:00:00",
762+
"family": "IPv4"
763+
},
764+
"NEIGH_TABLE:Ethernet56:10.0.0.29": {
765+
"neigh": "00:00:00:00:00:00",
766+
"family": "IPv4"
767+
},
768+
"NEIGH_TABLE:Ethernet60:10.0.0.31": {
769+
"neigh": "00:00:00:00:00:00",
770+
"family": "IPv4"
771+
},
772+
"NEIGH_TABLE:Ethernet104:10.0.0.53": {
773+
"neigh": "52:54:00:c3:a1:2d",
774+
"family": "IPv4"
775+
},
776+
"NEIGH_TABLE:Ethernet80:10.0.0.41": {
777+
"neigh": "52:54:00:08:de:c3",
778+
"family": "IPv4"
779+
},
780+
"NEIGH_TABLE:Ethernet28:10.0.0.15": {
781+
"neigh": "52:54:00:c6:31:42",
782+
"family": "IPv4"
783+
},
784+
"NEIGH_TABLE:Ethernet84:10.0.0.43": {
785+
"neigh": "52:54:00:44:73:a4",
786+
"family": "IPv4"
787+
},
788+
"NEIGH_TABLE:Ethernet96:10.0.0.49": {
789+
"neigh": "52:54:00:74:c5:38",
790+
"family": "IPv4"
791+
},
792+
"NEIGH_TABLE:Ethernet124:10.0.0.63": {
793+
"neigh": "00:00:00:00:00:00",
794+
"family": "IPv4"
795+
},
796+
"NEIGH_TABLE:Ethernet52:10.0.0.27": {
797+
"neigh": "52:54:00:1c:90:c4",
798+
"family": "IPv4"
799+
},
800+
"NEIGH_TABLE:Ethernet16:10.0.0.9": {
801+
"neigh": "52:54:00:71:ae:0e",
802+
"family": "IPv4"
803+
},
804+
"NEIGH_TABLE:Ethernet12:fec0::ffff:afa:10": {
805+
"neigh": "52:54:00:d0:72:b7",
806+
"family": "IPv6"
687807
}
688808
}

tests/mock_tables/asic0/appl_db.json

+20
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,25 @@
8686
"INTF_TABLE:PortChannel01:10.10.0.1/31": {
8787
"scope": "global",
8888
"family": "IPv4"
89+
},
90+
"NEIGH_TABLE:Ethernet0:10.0.0.0": {
91+
"neigh": "52:54:00:a5:70:47",
92+
"family": "IPv4"
93+
},
94+
"NEIGH_TABLE:Ethernet4:10.0.0.2": {
95+
"neigh": "52:54:00:04:52:5d",
96+
"family": "IPv4"
97+
},
98+
"NEIGH_TABLE:Ethernet4:fec0::ffff:afa:07": {
99+
"neigh": "52:54:00:04:52:5d",
100+
"family": "IPv6"
101+
},
102+
"NEIGH_TABLE:PortChannel01:10.10.0.0": {
103+
"neigh": "f2:54:00:a5:70:02",
104+
"family": "IPv4"
105+
},
106+
"NEIGH_TABLE:eth0:240.127.1.1": {
107+
"neigh": "00:a0:a5:7a:39:ea",
108+
"family": "IPv4"
89109
}
90110
}

tests/mock_tables/asic1/appl_db.json

+12
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,17 @@
8787
"INTF_TABLE:PortChannel02:10.10.0.5/31": {
8888
"scope": "global",
8989
"family": "IPv4"
90+
},
91+
"NEIGH_TABLE:Ethernet8:10.0.0.6": {
92+
"neigh": "52:54:00:b4:59:59",
93+
"family": "IPv4"
94+
},
95+
"NEIGH_TABLE:Ethernet12:10.0.0.8": {
96+
"neigh": "52:54:00:55:2d:fe",
97+
"family": "IPv4"
98+
},
99+
"NEIGH_TABLE:eth0:240.127.1.1": {
100+
"neigh": "00:a0:a5:7a:39:ea",
101+
"family": "IPv4"
90102
}
91103
}

tests/mock_tables/asic2/appl_db.json

+4
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,9 @@
7878
"INTF_TABLE:PortChannel04:10.10.0.5/31": {
7979
"scope": "global",
8080
"family": "IPv4"
81+
},
82+
"NEIGH_TABLE:eth0:240.127.1.1": {
83+
"neigh": "00:a0:a5:7a:39:ea",
84+
"family": "IPv4"
8185
}
8286
}
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,46 @@
11
IP address HW type Flags HW address Mask Device
22
10.3.146.86 0x1 0x2 00:a0:a5:75:35:8d * eth0
3-
10.0.0.35 0x1 0x2 52:54:00:a5:70:47 * Ethernet68
4-
10.0.0.19 0x1 0x2 52:54:00:04:52:5d * Ethernet36
5-
10.0.0.57 0x1 0x2 52:54:00:b4:59:59 * Ethernet112
6-
10.3.146.1 0x1 0x2 00:00:5e:00:01:64 * eth0
3+
10.3.146.1 0x1 0x2 00:00:5e:00:01:54 * eth0
74
10.3.146.244 0x1 0x2 e4:d3:f1:51:3c:80 * eth0
85
10.3.147.97 0x1 0x2 3c:94:d5:69:b5:02 * eth0
9-
10.0.0.25 0x1 0x2 52:54:00:55:2d:fe * Ethernet48
106
10.3.146.75 0x1 0x2 00:a0:a5:76:17:70 * eth0
117
10.3.146.131 0x1 0x2 00:15:c7:21:f7:40 * eth0
12-
10.0.0.21 0x1 0x2 52:54:00:d0:a0:8c * Ethernet40
138
10.3.147.223 0x1 0x2 00:17:0f:ac:c4:40 * eth0
149
10.3.146.78 0x1 0x2 3c:94:d5:68:9d:82 * eth0
1510
10.3.146.184 0x1 0x2 e4:d3:f1:51:38:60 * eth0
1611
10.3.146.170 0x1 0x2 30:e4:db:a4:c9:3f * eth0
17-
10.0.0.33 0x1 0x2 7c:fe:90:5e:6b:a6 * Ethernet64
1812
10.3.146.134 0x1 0x2 00:23:04:18:8e:c0 * eth0
1913
10.3.146.15 0x1 0x2 00:1e:f7:f7:0a:80 * eth0
2014
10.3.146.85 0x1 0x2 00:a0:a5:80:38:22 * eth0
21-
10.0.0.45 0x1 0x2 52:54:00:d0:23:2b * Ethernet88
2215
10.3.147.40 0x1 0x2 3c:94:d5:68:4a:82 * eth0
23-
10.0.0.59 0x1 0x2 52:54:00:ae:c8:01 * Ethernet116
2416
10.3.146.74 0x1 0x2 00:a0:a5:7a:39:ea * eth0
25-
10.0.0.5 0x1 0x2 52:54:00:fc:50:3c * Ethernet8
2617
10.3.146.130 0x1 0x2 00:15:c7:21:dd:00 * eth0
2718
10.3.146.81 0x1 0x2 5c:5e:ab:de:70:ff * eth0
28-
10.0.0.55 0x1 0x2 52:54:00:1b:d6:95 * Ethernet108
29-
10.0.0.11 0x1 0x0 00:00:00:00:00:00 * Ethernet20
3019
10.3.146.14 0x1 0x2 00:1e:f7:f7:14:40 * eth0
31-
10.0.0.61 0x1 0x0 00:00:00:00:00:00 * Ethernet120
32-
10.0.0.3 0x1 0x0 00:00:00:00:00:00 * Ethernet4
3320
10.3.146.70 0x1 0x2 00:a0:a5:77:ef:f1 * eth0
3421
10.3.146.162 0x1 0x2 58:8d:09:8c:3c:bf * eth0
3522
10.3.146.172 0x1 0x2 a4:93:4c:da:f7:bf * eth0
36-
10.0.0.29 0x1 0x0 00:00:00:00:00:00 * Ethernet56
3723
10.3.146.95 0x1 0x2 00:a0:a5:85:f8:98 * eth0
3824
10.3.146.187 0x1 0x2 6c:20:56:cb:20:40 * eth0
39-
10.0.0.31 0x1 0x0 00:00:00:00:00:00 * Ethernet60
4025
10.3.146.10 0x1 0x2 4c:76:25:eb:52:42 * eth0
4126
10.3.147.225 0x1 0x2 00:22:91:86:10:00 * eth0
42-
10.0.0.53 0x1 0x2 52:54:00:c3:a1:2d * Ethernet104
43-
10.0.0.41 0x1 0x2 52:54:00:08:de:c3 * Ethernet80
4427
10.3.146.190 0x1 0x2 e4:d3:f1:51:33:20 * eth0
45-
10.0.0.15 0x1 0x2 52:54:00:c6:31:42 * Ethernet28
46-
10.0.0.43 0x1 0x2 52:54:00:44:73:a4 * Ethernet84
4728
10.3.146.3 0x1 0x2 f4:b5:2f:72:bf:f0 * eth0
4829
10.3.147.250 0x1 0x2 4c:76:25:f4:c6:02 * eth0
49-
10.0.0.49 0x1 0x2 52:54:00:74:c5:38 * Ethernet96
5030
10.3.146.91 0x1 0x2 54:e0:32:cf:6f:ff * eth0
51-
10.0.0.63 0x1 0x0 00:00:00:00:00:00 * Ethernet124
52-
10.0.0.27 0x1 0x2 52:54:00:1c:90:c4 * Ethernet52
53-
10.0.0.9 0x1 0x2 52:54:00:71:ae:0e * Ethernet16
5431
10.3.146.157 0x1 0x2 00:1e:be:38:44:ff * eth0
5532
10.3.147.239 0x1 0x2 ec:f4:bb:fe:80:a1 * eth0
56-
10.0.0.7 0x1 0x2 52:54:00:d1:75:b4 * Ethernet12
5733
10.3.146.72 0x1 0x2 00:a0:a5:80:26:07 * eth0
5834
10.3.146.164 0x1 0x2 00:15:c6:df:03:7f * eth0
5935
10.3.146.150 0x1 0x2 00:05:9b:7e:61:00 * eth0
6036
10.3.147.224 0x1 0x2 00:22:91:85:88:00 * eth0
6137
10.3.146.87 0x1 0x2 00:a0:a5:80:2c:7a * eth0
62-
10.0.0.37 0x1 0x2 52:54:00:30:a7:95 * Ethernet72
6338
10.3.146.16 0x1 0x2 ec:bd:1d:f2:a6:00 * eth0
64-
10.0.0.51 0x1 0x2 52:54:00:36:5b:05 * Ethernet100
6539
10.3.146.2 0x1 0x2 f4:b5:2f:79:b3:f0 * eth0
66-
10.0.0.1 0x1 0x2 7c:fe:90:5e:6b:a6 * Ethernet0
67-
10.0.0.13 0x1 0x2 52:54:00:88:3c:5e * Ethernet24
6840
10.3.146.90 0x1 0x2 54:e0:32:cf:76:ff * eth0
6941
10.3.146.182 0x1 0x2 6c:20:56:ee:c0:80 * eth0
70-
10.0.0.47 0x1 0x2 52:54:00:77:e3:91 * Ethernet92
7142
10.3.146.156 0x1 0x2 00:18:73:b1:7d:bf * eth0
72-
10.0.0.23 0x1 0x2 52:54:00:df:ec:bf * Ethernet44
7343
10.3.146.83 0x1 0x2 00:a0:a5:87:1d:28 * eth0
7444
10.3.146.93 0x1 0x2 54:e0:32:cf:77:ff * eth0
7545
10.3.146.79 0x1 0x2 3c:94:d5:60:40:c2 * eth0
7646
10.3.146.171 0x1 0x2 c8:9c:1d:ee:7f:7f * eth0
77-
10.0.0.39 0x1 0x2 52:54:00:66:a7:29 * Ethernet76
78-
10.0.0.17 0x1 0x2 52:54:00:e7:53:c2 * Ethernet32

tests/mock_tables/python_arptable.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@
1010

1111
# Backup original function
1212
_get_arp_table = getattr(python_arptable, 'get_arp_table')
13+
# Mock arp table for host arp information on mulit-asic plaform.
14+
# In multi-asic platform, the namespace ARP inforamtion is retrieved
15+
# from NEIGH_TABLE from namespace APP_DBs. Host arp information is
16+
# retrieved from kernel.
17+
arp_filename = '/host_arp.txt'
1318

1419
# Monkey patch
1520
def get_arp_table():
16-
with open(INPUT_DIR + '/arp.txt') as farp:
21+
with open(INPUT_DIR + arp_filename) as farp:
1722
file_content = mock_open(read_data = farp.read())
1823
file_content.return_value.__iter__ = lambda self : iter(self.readline, '')
1924
# file_content = MagicMock(name = 'open', spec = open)

0 commit comments

Comments
 (0)