diff options
author | Sugandha Gupta <sugandha.gupta@ettus.com> | 2018-07-25 18:07:40 -0700 |
---|---|---|
committer | Brent Stapleton <brent.stapleton@ettus.com> | 2019-01-17 15:38:23 -0800 |
commit | 169e3c4bef2bd6b6bae5bb68174a5b09ec10490e (patch) | |
tree | c0b27eab5cd6d22d81d7a9f9555489381b6aa257 | |
parent | c81b4ac99f534f835166bc814839757e37ae13cb (diff) | |
download | uhd-169e3c4bef2bd6b6bae5bb68174a5b09ec10490e.tar.gz uhd-169e3c4bef2bd6b6bae5bb68174a5b09ec10490e.tar.bz2 uhd-169e3c4bef2bd6b6bae5bb68174a5b09ec10490e.zip |
mpm: ethtable: Add support for bridge mode to Ethernet dispatcher
In bridge mode, packets may be arriving at the Ethernet device which
aren't meant for this device, and thus need different routing
instructions.
-rw-r--r-- | mpm/python/usrp_mpm/ethtable.py | 100 |
1 files changed, 79 insertions, 21 deletions
diff --git a/mpm/python/usrp_mpm/ethtable.py b/mpm/python/usrp_mpm/ethtable.py index 1721f4724..4a6566987 100644 --- a/mpm/python/usrp_mpm/ethtable.py +++ b/mpm/python/usrp_mpm/ethtable.py @@ -1,5 +1,5 @@ # -# Copyright 2017 Ettus Research, a National Instruments Company +# Copyright 2017-2018 Ettus Research, a National Instruments Company # # SPDX-License-Identifier: GPL-3.0-or-later # @@ -21,12 +21,21 @@ class EthDispatcherTable(object): """ DEFAULT_VITA_PORT = (49153, 49154) # Address offsets: - OWN_IP_OFFSET = 0x0000 - OWN_PORT_OFFSET = 0x0004 + ETH_IP_OFFSET = 0x0000 + ETH_PORT_OFFSET = 0x0004 FORWARD_ETH_BCAST_OFFSET = 0x0008 + BRIDGE_MAC_LO_OFFSET = 0x0010 + BRIDGE_MAC_HI_OFFSET = 0x0014 + BRIDGE_IP_OFFSET = 0x0018 + BRIDGE_PORT_OFFSET = 0x001c + BRIDGE_ENABLE_OFFSET = 0x0020 SID_IP_OFFSET = 0x1000 SID_PORT_MAC_HI_OFFSET = 0x1400 SID_MAC_LO_OFFSET = 0x1800 + LADDR_IP_OFFSET = 0x1D00 + LADDR_PORT_MAC_HI_OFFSET = 0x1E00 + LADDR_MAC_LO_OFFSET = 0x1F00 + def __init__(self, label): self.log = get_logger(label) @@ -34,17 +43,44 @@ class EthDispatcherTable(object): self.poke32 = self._regs.poke32 self.peek32 = self._regs.peek32 - def set_ipv4_addr(self, ip_addr): + def set_bridge_mode(self, bridge_mode): + " Enable/Disable Bridge Mode " + self.log.trace("Bridge Mode {}".format( + "Enabled" if bridge_mode else "Disabled" + )) + self.poke32(self.BRIDGE_ENABLE_OFFSET, int(bridge_mode)) + + def set_bridge_mac_addr(self, mac_addr): + """ + Set the bridge MAC address for this Ethernet dispatcher. + Outgoing packets will have this MAC address. + """ + self.log.debug("Setting bridge MAC address to `{}'".format(mac_addr)) + mac_addr_int = int(netaddr.EUI(mac_addr)) + self.log.trace("Writing to address 0x{:04X}: 0x{:04X}".format( + self.BRIDGE_MAC_LO_OFFSET, mac_addr_int & 0xFFFFFFFF + )) + self.poke32(self.BRIDGE_MAC_LO_OFFSET, mac_addr_int & 0xFFFFFFFF) + self.log.trace("Writing to address 0x{:04X}: 0x{:04X}".format( + self.BRIDGE_MAC_HI_OFFSET, mac_addr_int >> 32 + )) + self.poke32(self.BRIDGE_MAC_HI_OFFSET, mac_addr_int >> 32) + + def set_ipv4_addr(self, ip_addr, bridge_en=False): """ Set the own IPv4 address for this Ethernet dispatcher. Outgoing packets will have this IP address. """ + if bridge_en: + own_ip_offset = self.BRIDGE_IP_OFFSET + else: + own_ip_offset = self.ETH_IP_OFFSET self.log.debug("Setting my own IP address to `{}'".format(ip_addr)) ip_addr_int = int(netaddr.IPAddress(ip_addr)) with self._regs: - self.poke32(self.OWN_IP_OFFSET, ip_addr_int) + self.poke32(own_ip_offset, ip_addr_int) - def set_vita_port(self, port_value=None, port_idx=None): + def set_vita_port(self, port_value=None, port_idx=None, bridge_en=False): """ Set the port that is used for incoming VITA traffic. This is used to distinguish traffic that goes to the FPGA from that going to the ARM. @@ -52,7 +88,10 @@ class EthDispatcherTable(object): port_idx = port_idx or 0 port_value = port_value or self.DEFAULT_VITA_PORT[port_idx] assert port_idx in (0) #FIXME: Fix port_idx = 1 - port_reg_addr = self.OWN_PORT_OFFSET + if bridge_en: + port_reg_addr = self.BRIDGE_PORT_OFFSET + else: + port_reg_addr = self.ETH_PORT_OFFSET with self._regs: self.poke32(port_reg_addr, port_value) @@ -80,20 +119,39 @@ class EthDispatcherTable(object): self.log.error( "Could not resolve a MAC address for IP address `{}'".format(ip_addr) ) - dst_ep = sid.dst_ep - self.log.debug( - "Routing SID `{sid}' (endpoint `{ep}') to IP address `{ip}', " \ - "MAC address `{mac}', port `{port}'".format( - sid=str(sid), - ep=dst_ep, - ip=ip_addr, - mac=mac_addr, - port=udp_port + if sid.dst_addr == 0 or sid.dst_addr == 1: + table_addr = sid.dst_ep + ip_base_offset = self.SID_IP_OFFSET + port_mac_hi_base_offset = self.SID_PORT_MAC_HI_OFFSET + mac_lo_base_offset = self.SID_MAC_LO_OFFSET + self.log.debug( + "Routing SID `{sid}' (endpoint `{ep}') to IP address `{ip}', " \ + "MAC address `{mac}', port `{port}'".format( + sid=str(sid), + ep=table_addr, + ip=ip_addr, + mac=mac_addr, + port=udp_port + ) + ) + else: #populate local addr eth dispatch table + table_addr = sid.dst_addr + ip_base_offset = self.LADDR_IP_OFFSET + port_mac_hi_base_offset = self.LADDR_PORT_MAC_HI_OFFSET + mac_lo_base_offset = self.LADDR_MAC_LO_OFFSET + self.log.debug( + "Routing SID `{sid}' (local addr`{addr}') to IP address `{ip}', " \ + "MAC address `{mac}', port `{port}'".format( + sid=str(sid), + addr=table_addr, + ip=ip_addr, + mac=mac_addr, + port=udp_port + ) ) - ) ip_addr_int = int(netaddr.IPAddress(ip_addr)) mac_addr_int = int(netaddr.EUI(mac_addr)) - sid_offset = 4 * dst_ep + dst_offset = 4 * table_addr def poke_and_trace(addr, data): " Do a poke32() and log.trace() " @@ -104,15 +162,15 @@ class EthDispatcherTable(object): with self._regs: poke_and_trace( - self.SID_IP_OFFSET + sid_offset, + ip_base_offset + dst_offset, ip_addr_int ) poke_and_trace( - self.SID_MAC_LO_OFFSET + sid_offset, + mac_lo_base_offset + dst_offset, mac_addr_int & 0xFFFFFFFF, ) poke_and_trace( - self.SID_PORT_MAC_HI_OFFSET + sid_offset, + port_mac_hi_base_offset + dst_offset, (udp_port << 16) | (mac_addr_int >> 32) ) |