[tun_pkt]: Wait for AsyncSniffer to init fully (#10346)
Fix for Tunnel packet handler can crash at system startup Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
This commit is contained in:
parent
1e2e493daa
commit
b31df59c7c
@ -51,6 +51,10 @@ class TunnelPacketHandler(object):
|
||||
self._portchannel_intfs = None
|
||||
self.up_portchannels = None
|
||||
self.netlink_api = IPRoute()
|
||||
self.sniffer = None
|
||||
self.self_ip = ''
|
||||
self.packet_filter = ''
|
||||
self.sniff_intfs = []
|
||||
|
||||
@property
|
||||
def portchannel_intfs(self):
|
||||
@ -270,6 +274,39 @@ class TunnelPacketHandler(object):
|
||||
return True
|
||||
return False
|
||||
|
||||
def start_sniffer(self):
|
||||
"""
|
||||
Starts an AsyncSniffer and waits for it to inititalize fully
|
||||
"""
|
||||
self.sniffer = AsyncSniffer(
|
||||
iface=self.sniff_intfs,
|
||||
filter=self.packet_filter,
|
||||
prn=self.ping_inner_dst,
|
||||
store=0
|
||||
)
|
||||
self.sniffer.start()
|
||||
|
||||
while not hasattr(self.sniffer, 'stop_cb'):
|
||||
time.sleep(0.1)
|
||||
|
||||
def ping_inner_dst(self, packet):
|
||||
"""
|
||||
Pings the inner destination IP for an encapsulated packet
|
||||
|
||||
Args:
|
||||
packet: The encapsulated packet received
|
||||
"""
|
||||
inner_packet_type = self.get_inner_pkt_type(packet)
|
||||
if inner_packet_type and packet[IP].dst == self.self_ip:
|
||||
cmds = ['timeout', '0.2', 'ping', '-c1',
|
||||
'-W1', '-i0', '-n', '-q']
|
||||
if inner_packet_type == IPv6:
|
||||
cmds.append('-6')
|
||||
dst_ip = packet[IP].payload[inner_packet_type].dst
|
||||
cmds.append(dst_ip)
|
||||
logger.log_info("Running command '{}'".format(' '.join(cmds)))
|
||||
subprocess.run(cmds, stdout=subprocess.DEVNULL)
|
||||
|
||||
def listen_for_tunnel_pkts(self):
|
||||
"""
|
||||
Listens for tunnel packets that are trapped to CPU
|
||||
@ -277,59 +314,28 @@ class TunnelPacketHandler(object):
|
||||
These packets may be trapped if there is no neighbor info for the
|
||||
inner packet destination IP in the hardware.
|
||||
"""
|
||||
|
||||
def _ping_inner_dst(packet):
|
||||
"""
|
||||
Pings the inner destination IP for an encapsulated packet
|
||||
|
||||
Args:
|
||||
packet: The encapsulated packet received
|
||||
"""
|
||||
inner_packet_type = self.get_inner_pkt_type(packet)
|
||||
if inner_packet_type and packet[IP].dst == self_ip:
|
||||
cmds = ['timeout', '0.2', 'ping', '-c1',
|
||||
'-W1', '-i0', '-n', '-q']
|
||||
if inner_packet_type == IPv6:
|
||||
cmds.append('-6')
|
||||
dst_ip = packet[IP].payload[inner_packet_type].dst
|
||||
cmds.append(dst_ip)
|
||||
logger.log_info("Running command '{}'".format(' '.join(cmds)))
|
||||
subprocess.run(cmds, stdout=subprocess.DEVNULL)
|
||||
|
||||
self_ip, peer_ip = self.get_ipinip_tunnel_addrs()
|
||||
if self_ip is None or peer_ip is None:
|
||||
self.self_ip, peer_ip = self.get_ipinip_tunnel_addrs()
|
||||
if self.self_ip is None or peer_ip is None:
|
||||
logger.log_notice('Could not get tunnel addresses from '
|
||||
'config DB, exiting...')
|
||||
return None
|
||||
|
||||
packet_filter = 'host {} and host {}'.format(self_ip, peer_ip)
|
||||
self.packet_filter = 'host {} and host {}'.format(self.self_ip, peer_ip)
|
||||
logger.log_notice('Starting tunnel packet handler for {}'
|
||||
.format(packet_filter))
|
||||
.format(self.packet_filter))
|
||||
|
||||
sniff_intfs = self.get_up_portchannels()
|
||||
logger.log_info("Listening on interfaces {}".format(sniff_intfs))
|
||||
self.sniff_intfs = self.get_up_portchannels()
|
||||
logger.log_info("Listening on interfaces {}".format(self.sniff_intfs))
|
||||
|
||||
sniffer = AsyncSniffer(
|
||||
iface=sniff_intfs,
|
||||
filter=packet_filter,
|
||||
prn=_ping_inner_dst,
|
||||
store=0
|
||||
)
|
||||
sniffer.start()
|
||||
self.start_sniffer()
|
||||
while True:
|
||||
msgs = self.wait_for_netlink_msgs()
|
||||
if self.sniffer_restart_required(msgs):
|
||||
sniffer.stop()
|
||||
self.sniffer.stop()
|
||||
sniff_intfs = self.get_up_portchannels()
|
||||
logger.log_notice('Restarting tunnel packet handler on '
|
||||
'interfaces {}'.format(sniff_intfs))
|
||||
sniffer = AsyncSniffer(
|
||||
iface=sniff_intfs,
|
||||
filter=packet_filter,
|
||||
prn=_ping_inner_dst,
|
||||
store=0
|
||||
)
|
||||
sniffer.start()
|
||||
self.start_sniffer()
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user