Skip to content

Commit

Permalink
[icmp responder]: Allow hardcoding of ICMP responder MAC (#2970)
Browse files Browse the repository at this point in the history
ICMP responder needs to reply to linkmgrd heartbeats using VLAN MAC as the destination MAC. Linkmgrd sends the heartbeat with the interface MAC instead of the VLAN MAC, and ICMP responder simply re-uses the interface MAC.

This change allows ICMP responder to always reply with the VLAN MAC.
  • Loading branch information
theasianpianist authored Feb 11, 2021
1 parent eb77536 commit 2a11c0f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
4 changes: 4 additions & 0 deletions tests/common/fixtures/ptfhost_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,11 @@ def run_icmp_responder(duthost, ptfhost, tbinfo):
templ = Template(open(os.path.join(TEMPLATES_DIR, ICMP_RESPONDER_CONF_TEMPL)).read())
ptf_indices = duthost.get_extended_minigraph_facts(tbinfo)["minigraph_ptf_indices"]
vlan_intfs = duthost.get_vlan_intfs()
vlan_table = duthost.get_running_config_facts()['VLAN']
vlan_name = list(vlan_table.keys())[0]
vlan_mac = vlan_table[vlan_name]['mac']
icmp_responder_args = " ".join("-i eth%s" % ptf_indices[_] for _ in vlan_intfs)
icmp_responder_args += " " + "-m {}".format(vlan_mac)
ptfhost.copy(
content=templ.render(icmp_responder_args=icmp_responder_args),
dest=os.path.join(SUPERVISOR_CONFIG_DIR, "icmp_responder.conf")
Expand Down
19 changes: 14 additions & 5 deletions tests/scripts/icmp_responder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,21 @@
from select import select


def respond_to_icmp_request(socket, request):
def respond_to_icmp_request(socket, request, dst_mac=None):
"""Respond to ICMP request."""
reply = request.copy()
reply[ICMP].type = 0
# Force re-generation of the checksum
reply[ICMP].chksum = None
reply[IP].src, reply[IP].dst = request[IP].dst, request[IP].src
reply[IP].chksum = None
reply[Ether].src, reply[Ether].dst = request[Ether].dst, request[Ether].src

if dst_mac is None:
icmp_reply_dst_mac = request[Ether].src
else:
icmp_reply_dst_mac = dst_mac

reply[Ether].src, reply[Ether].dst = request[Ether].dst, icmp_reply_dst_mac
socket.send(reply)


Expand All @@ -23,7 +29,7 @@ class ICMPSniffer(object):

TYPE_ECHO_REQUEST = 8

def __init__(self, ifaces, request_handler=None):
def __init__(self, ifaces, request_handler=None, dst_mac=None):
"""
Init ICMP sniffer.
Expand All @@ -37,6 +43,7 @@ def __init__(self, ifaces, request_handler=None):
self.sniff_sockets.append(conf.L2socket(type=ETH_P_IP, iface=iface, filter="icmp"))
self.iface_hwaddr[iface] = get_if_hwaddr(iface)
self.request_handler = request_handler
self.dst_mac = dst_mac

def __call__(self):
try:
Expand All @@ -46,7 +53,7 @@ def __call__(self):
packet = s.recv()
if packet is not None:
if packet[ICMP].type == self.TYPE_ECHO_REQUEST and self.request_handler:
self.request_handler(s, packet)
self.request_handler(s, packet, self.dst_mac)
finally:
for s in self.sniff_sockets:
s.close()
Expand All @@ -55,8 +62,10 @@ def __call__(self):
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="ICMP responder")
parser.add_argument("--intf", "-i", dest="ifaces", required=True, action="append", help="interface to listen for ICMP request")
parser.add_argument("--dst_mac", "-m", dest="dst_mac", required=False, action="store", help="The destination MAC to use for ICMP echo replies")
args = parser.parse_args()
ifaces = args.ifaces
dst_mac = args.dst_mac

icmp_sniffer = ICMPSniffer(ifaces, request_handler=respond_to_icmp_request)
icmp_sniffer = ICMPSniffer(ifaces, request_handler=respond_to_icmp_request, dst_mac=dst_mac)
icmp_sniffer()

0 comments on commit 2a11c0f

Please sign in to comment.