Skip to content

Commit

Permalink
[Multiasic]: Provide namespace support for ipNetToMediaPhysAddress (#129
Browse files Browse the repository at this point in the history
)

* [Multiasic]: Provide namespace support for ipNetToMediaPhysAddress
MIB in rfc1213.

Signed-off-by: SuvarnaMeenakshi <sumeenak@microsoft.com>

* [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 <sumeenak@microsoft.com>

* 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 <sumeenak@microsoft.com>
  • Loading branch information
SuvarnaMeenakshi authored and Ubuntu committed Sep 2, 2020
1 parent 61a8b68 commit 4186b74
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 50 deletions.
24 changes: 24 additions & 0 deletions src/sonic_ax_impl/mibs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@

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


def get_neigh_info(neigh_key):
"""
split neigh_key string of the format:
NEIGH_TABLE:device:ipv4_address
"""
_, device, ip = neigh_key.split(':')
return device, ip

def chassis_info_table(chassis_name):
"""
:param: chassis_name: chassis name
Expand Down Expand Up @@ -519,6 +528,21 @@ def dbs_keys(dbs, db_name, pattern='*'):
result_keys.extend(keys)
return result_keys

@staticmethod
def dbs_keys_namespace(dbs, db_name, pattern='*'):
"""
dbs_keys_namespace function execute on global
and all namespace DBs. Provides a map of keys
and namespace(db index).
"""
result_keys = {}
for db_index in range(len(dbs)):
keys = dbs[db_index].keys(db_name, pattern)
if keys is not None:
keys_ns = dict.fromkeys(keys, db_index)
result_keys.update(keys_ns)
return result_keys

@staticmethod
def dbs_get_all(dbs, db_name, _hash, *args, **kwargs):
"""
Expand Down
66 changes: 50 additions & 16 deletions src/sonic_ax_impl/mibs/ietf/rfc1213.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,66 @@ class IfTypes(int, Enum):
class ArpUpdater(MIBUpdater):
def __init__(self):
super().__init__()
self.db_conn = Namespace.init_namespace_dbs()
self.arp_dest_map = {}
self.arp_dest_list = []
self.arp_dest_map = {}
self.arp_dest_list = []
self.neigh_key_list = {}

def update_data(self):
self.arp_dest_map = {}
self.arp_dest_list = []
def reinit_data(self):
Namespace.connect_all_dbs(self.db_conn, mibs.APPL_DB)
self.neigh_key_list = Namespace.dbs_keys_namespace(self.db_conn, mibs.APPL_DB, "NEIGH_TABLE:*")

def _update_from_arptable(self):
for entry in python_arptable.get_arp_table():
dev = entry['Device']
mac = entry['HW address']
ip = entry['IP address']
self._update_arp_info(dev, mac, ip)

def _update_from_db(self):
for neigh_key in self.neigh_key_list:
neigh_str = neigh_key.decode()
db_index = self.neigh_key_list[neigh_key]
neigh_info = self.db_conn[db_index].get_all(mibs.APPL_DB, neigh_key, blocking=False)
if neigh_info is None:
continue
ip_family = neigh_info[b'family'].decode()
if ip_family == "IPv4":
dev, ip = mibs.get_neigh_info(neigh_str)
mac = neigh_info[b'neigh'].decode()
# eth0 interface in a namespace is not management interface
# but is a part of docker0 bridge. Ignore this interface.
if len(self.db_conn) > 1 and dev == "eth0":
continue
self._update_arp_info(dev, mac, ip)

def _update_arp_info(self, dev, mac, ip):
if_index = mibs.get_index_from_str(dev)
if if_index is None: return

mactuple = mac_decimals(mac)
machex = ''.join(chr(b) for b in mactuple)
# if MAC is all zero
#if not any(mac): continue

iptuple = ip2tuple_v4(ip)

subid = (if_index,) + iptuple
self.arp_dest_map[subid] = machex
self.arp_dest_list.append(subid)

if_index = mibs.get_index_from_str(dev)
if if_index is None: continue

mactuple = mac_decimals(mac)
machex = ''.join(chr(b) for b in mactuple)
# if MAC is all zero
#if not any(mac): continue

iptuple = ip2tuple_v4(ip)

subid = (if_index,) + iptuple
self.arp_dest_map[subid] = machex
self.arp_dest_list.append(subid)
def update_data(self):
self.arp_dest_map = {}
self.arp_dest_list = []
# Update arp table of host.
# In case of multi-asic platform, get host arp table
# from kernel and namespace arp table from NEIGH_TABLE in APP_DB
# in each namespace.
self._update_from_db()
if len(self.db_conn) > 1:
self._update_from_arptable()
self.arp_dest_list.sort()

def arp_dest(self, sub_id):
Expand Down
120 changes: 120 additions & 0 deletions tests/mock_tables/appl_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -684,5 +684,125 @@
"INTF_TABLE:lo:fc00:1::32/128": {
"scope": "global",
"family": "IPv6"
},
"NEIGH_TABLE:eth0:10.3.146.86": {
"neigh": "00:a0:a5:75:35:8d",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet68:10.0.0.35": {
"neigh": "52:54:00:a5:70:47",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet36:10.0.0.19": {
"neigh": "52:54:00:04:52:5d",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet112:10.0.0.57": {
"neigh": "52:54:00:b4:59:59",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:10.3.146.1": {
"neigh": "00:00:5e:00:01:64",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:10.3.146.244": {
"neigh": "e4:d3:f1:51:3c:80",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:10.3.147.97": {
"neigh": "3c:94:d5:69:b5:02",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet48:10.0.0.25": {
"neigh": "52:54:00:55:2d:fe",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:10.3.146.75": {
"neigh": "00:a0:a5:76:17:70",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:10.3.146.131": {
"neigh": "00:15:c7:21:f7:40",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet40:10.0.0.21": {
"neigh": "52:54:00:d0:a0:8c",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet64:10.0.0.33": {
"neigh": "7c:fe:90:5e:6b:a6",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet88:10.0.0.45": {
"neigh": "52:54:00:d0:23:2b",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet116:10.0.0.59": {
"neigh": "52:54:00:ae:c8:01",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet8:10.0.0.5": {
"neigh": "52:54:00:fc:50:3c",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet108:10.0.0.55": {
"neigh": "52:54:00:1b:d6:95",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet20:10.0.0.11": {
"neigh": "00:00:00:00:00:00",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet120:10.0.0.61": {
"neigh": "00:00:00:00:00:00",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet4:10.0.0.3": {
"neigh": "00:00:00:00:00:00",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet56:10.0.0.29": {
"neigh": "00:00:00:00:00:00",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet60:10.0.0.31": {
"neigh": "00:00:00:00:00:00",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet104:10.0.0.53": {
"neigh": "52:54:00:c3:a1:2d",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet80:10.0.0.41": {
"neigh": "52:54:00:08:de:c3",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet28:10.0.0.15": {
"neigh": "52:54:00:c6:31:42",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet84:10.0.0.43": {
"neigh": "52:54:00:44:73:a4",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet96:10.0.0.49": {
"neigh": "52:54:00:74:c5:38",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet124:10.0.0.63": {
"neigh": "00:00:00:00:00:00",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet52:10.0.0.27": {
"neigh": "52:54:00:1c:90:c4",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet16:10.0.0.9": {
"neigh": "52:54:00:71:ae:0e",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet12:fec0::ffff:afa:10": {
"neigh": "52:54:00:d0:72:b7",
"family": "IPv6"
}
}
20 changes: 20 additions & 0 deletions tests/mock_tables/asic0/appl_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,25 @@
"INTF_TABLE:PortChannel01:10.10.0.1/31": {
"scope": "global",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet0:10.0.0.0": {
"neigh": "52:54:00:a5:70:47",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet4:10.0.0.2": {
"neigh": "52:54:00:04:52:5d",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet4:fec0::ffff:afa:07": {
"neigh": "52:54:00:04:52:5d",
"family": "IPv6"
},
"NEIGH_TABLE:PortChannel01:10.10.0.0": {
"neigh": "f2:54:00:a5:70:02",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:240.127.1.1": {
"neigh": "00:a0:a5:7a:39:ea",
"family": "IPv4"
}
}
12 changes: 12 additions & 0 deletions tests/mock_tables/asic1/appl_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,17 @@
"INTF_TABLE:PortChannel02:10.10.0.5/31": {
"scope": "global",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet8:10.0.0.6": {
"neigh": "52:54:00:b4:59:59",
"family": "IPv4"
},
"NEIGH_TABLE:Ethernet12:10.0.0.8": {
"neigh": "52:54:00:55:2d:fe",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:240.127.1.1": {
"neigh": "00:a0:a5:7a:39:ea",
"family": "IPv4"
}
}
4 changes: 4 additions & 0 deletions tests/mock_tables/asic2/appl_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,9 @@
"INTF_TABLE:PortChannel04:10.10.0.5/31": {
"scope": "global",
"family": "IPv4"
},
"NEIGH_TABLE:eth0:240.127.1.1": {
"neigh": "00:a0:a5:7a:39:ea",
"family": "IPv4"
}
}
34 changes: 1 addition & 33 deletions tests/mock_tables/arp.txt → tests/mock_tables/host_arp.txt
Original file line number Diff line number Diff line change
@@ -1,78 +1,46 @@
IP address HW type Flags HW address Mask Device
10.3.146.86 0x1 0x2 00:a0:a5:75:35:8d * eth0
10.0.0.35 0x1 0x2 52:54:00:a5:70:47 * Ethernet68
10.0.0.19 0x1 0x2 52:54:00:04:52:5d * Ethernet36
10.0.0.57 0x1 0x2 52:54:00:b4:59:59 * Ethernet112
10.3.146.1 0x1 0x2 00:00:5e:00:01:64 * eth0
10.3.146.1 0x1 0x2 00:00:5e:00:01:54 * eth0
10.3.146.244 0x1 0x2 e4:d3:f1:51:3c:80 * eth0
10.3.147.97 0x1 0x2 3c:94:d5:69:b5:02 * eth0
10.0.0.25 0x1 0x2 52:54:00:55:2d:fe * Ethernet48
10.3.146.75 0x1 0x2 00:a0:a5:76:17:70 * eth0
10.3.146.131 0x1 0x2 00:15:c7:21:f7:40 * eth0
10.0.0.21 0x1 0x2 52:54:00:d0:a0:8c * Ethernet40
10.3.147.223 0x1 0x2 00:17:0f:ac:c4:40 * eth0
10.3.146.78 0x1 0x2 3c:94:d5:68:9d:82 * eth0
10.3.146.184 0x1 0x2 e4:d3:f1:51:38:60 * eth0
10.3.146.170 0x1 0x2 30:e4:db:a4:c9:3f * eth0
10.0.0.33 0x1 0x2 7c:fe:90:5e:6b:a6 * Ethernet64
10.3.146.134 0x1 0x2 00:23:04:18:8e:c0 * eth0
10.3.146.15 0x1 0x2 00:1e:f7:f7:0a:80 * eth0
10.3.146.85 0x1 0x2 00:a0:a5:80:38:22 * eth0
10.0.0.45 0x1 0x2 52:54:00:d0:23:2b * Ethernet88
10.3.147.40 0x1 0x2 3c:94:d5:68:4a:82 * eth0
10.0.0.59 0x1 0x2 52:54:00:ae:c8:01 * Ethernet116
10.3.146.74 0x1 0x2 00:a0:a5:7a:39:ea * eth0
10.0.0.5 0x1 0x2 52:54:00:fc:50:3c * Ethernet8
10.3.146.130 0x1 0x2 00:15:c7:21:dd:00 * eth0
10.3.146.81 0x1 0x2 5c:5e:ab:de:70:ff * eth0
10.0.0.55 0x1 0x2 52:54:00:1b:d6:95 * Ethernet108
10.0.0.11 0x1 0x0 00:00:00:00:00:00 * Ethernet20
10.3.146.14 0x1 0x2 00:1e:f7:f7:14:40 * eth0
10.0.0.61 0x1 0x0 00:00:00:00:00:00 * Ethernet120
10.0.0.3 0x1 0x0 00:00:00:00:00:00 * Ethernet4
10.3.146.70 0x1 0x2 00:a0:a5:77:ef:f1 * eth0
10.3.146.162 0x1 0x2 58:8d:09:8c:3c:bf * eth0
10.3.146.172 0x1 0x2 a4:93:4c:da:f7:bf * eth0
10.0.0.29 0x1 0x0 00:00:00:00:00:00 * Ethernet56
10.3.146.95 0x1 0x2 00:a0:a5:85:f8:98 * eth0
10.3.146.187 0x1 0x2 6c:20:56:cb:20:40 * eth0
10.0.0.31 0x1 0x0 00:00:00:00:00:00 * Ethernet60
10.3.146.10 0x1 0x2 4c:76:25:eb:52:42 * eth0
10.3.147.225 0x1 0x2 00:22:91:86:10:00 * eth0
10.0.0.53 0x1 0x2 52:54:00:c3:a1:2d * Ethernet104
10.0.0.41 0x1 0x2 52:54:00:08:de:c3 * Ethernet80
10.3.146.190 0x1 0x2 e4:d3:f1:51:33:20 * eth0
10.0.0.15 0x1 0x2 52:54:00:c6:31:42 * Ethernet28
10.0.0.43 0x1 0x2 52:54:00:44:73:a4 * Ethernet84
10.3.146.3 0x1 0x2 f4:b5:2f:72:bf:f0 * eth0
10.3.147.250 0x1 0x2 4c:76:25:f4:c6:02 * eth0
10.0.0.49 0x1 0x2 52:54:00:74:c5:38 * Ethernet96
10.3.146.91 0x1 0x2 54:e0:32:cf:6f:ff * eth0
10.0.0.63 0x1 0x0 00:00:00:00:00:00 * Ethernet124
10.0.0.27 0x1 0x2 52:54:00:1c:90:c4 * Ethernet52
10.0.0.9 0x1 0x2 52:54:00:71:ae:0e * Ethernet16
10.3.146.157 0x1 0x2 00:1e:be:38:44:ff * eth0
10.3.147.239 0x1 0x2 ec:f4:bb:fe:80:a1 * eth0
10.0.0.7 0x1 0x2 52:54:00:d1:75:b4 * Ethernet12
10.3.146.72 0x1 0x2 00:a0:a5:80:26:07 * eth0
10.3.146.164 0x1 0x2 00:15:c6:df:03:7f * eth0
10.3.146.150 0x1 0x2 00:05:9b:7e:61:00 * eth0
10.3.147.224 0x1 0x2 00:22:91:85:88:00 * eth0
10.3.146.87 0x1 0x2 00:a0:a5:80:2c:7a * eth0
10.0.0.37 0x1 0x2 52:54:00:30:a7:95 * Ethernet72
10.3.146.16 0x1 0x2 ec:bd:1d:f2:a6:00 * eth0
10.0.0.51 0x1 0x2 52:54:00:36:5b:05 * Ethernet100
10.3.146.2 0x1 0x2 f4:b5:2f:79:b3:f0 * eth0
10.0.0.1 0x1 0x2 7c:fe:90:5e:6b:a6 * Ethernet0
10.0.0.13 0x1 0x2 52:54:00:88:3c:5e * Ethernet24
10.3.146.90 0x1 0x2 54:e0:32:cf:76:ff * eth0
10.3.146.182 0x1 0x2 6c:20:56:ee:c0:80 * eth0
10.0.0.47 0x1 0x2 52:54:00:77:e3:91 * Ethernet92
10.3.146.156 0x1 0x2 00:18:73:b1:7d:bf * eth0
10.0.0.23 0x1 0x2 52:54:00:df:ec:bf * Ethernet44
10.3.146.83 0x1 0x2 00:a0:a5:87:1d:28 * eth0
10.3.146.93 0x1 0x2 54:e0:32:cf:77:ff * eth0
10.3.146.79 0x1 0x2 3c:94:d5:60:40:c2 * eth0
10.3.146.171 0x1 0x2 c8:9c:1d:ee:7f:7f * eth0
10.0.0.39 0x1 0x2 52:54:00:66:a7:29 * Ethernet76
10.0.0.17 0x1 0x2 52:54:00:e7:53:c2 * Ethernet32
7 changes: 6 additions & 1 deletion tests/mock_tables/python_arptable.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@

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

# Monkey patch
def get_arp_table():
with open(INPUT_DIR + '/arp.txt') as farp:
with open(INPUT_DIR + arp_filename) as farp:
file_content = mock_open(read_data = farp.read())
file_content.return_value.__iter__ = lambda self : iter(self.readline, '')
# file_content = MagicMock(name = 'open', spec = open)
Expand Down
Loading

0 comments on commit 4186b74

Please sign in to comment.