Skip to content

Commit 359559b

Browse files
bluecmddal00
authored andcommitted
kamel: [caclmgrd] Handle BGP unnumbered neighbors
Signed-off-by: Christian Svensson <blue@cmd.nu>
1 parent 91bbce5 commit 359559b

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

scripts/caclmgrd

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -650,20 +650,44 @@ class ControlPlaneAclManager(logger.Logger):
650650
iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-A', 'INPUT', '-p', 'udp', '--dport', '546:547', '-j', 'ACCEPT'])
651651

652652
# Add iptables/ip6tables commands to allow relevant incoming BGP traffic
653+
# TODO: Break this out to a new function to aid writing unit tests
654+
#
655+
# This supports the following configurations:
656+
# - IPv4 neighbors w/ and w/o specified IPv4 source
657+
# - IPv6 neighbors w/ and w/o specified IPv6 source
658+
# - BGP Unnumbered, i.e. interface bound neighbors using link-local IPv6
653659
for key, config in self.config_db_map[namespace].get_table(self.BGP_NEIGHBOR).items():
654-
# Format can either be VRF|PeerIP or just PeerIP (older format)
655-
# Treat it as a potential CIDR to allow for e.g. dynamic BGP neighbors
656-
peer_cidr = key[-1] if isinstance(key, tuple) else key
657-
local_ip = config['local_addr']
660+
# Format can either be VRF|Peer or just Peer (older format)
661+
# Peer can be either a IPv4, IPv6, or an interface name.
662+
# Treat it as a potential CIDR to allow for e.g. dynamic BGP neighbors,
663+
# and if it does not parse then use it as an interface.
664+
peer = key[-1] if isinstance(key, tuple) else key
658665
name = config.get('name', 'unnamed')
659-
peer_network = ipaddress.ip_network(peer_cidr, strict=False)
660-
local_address = ipaddress.ip_address(local_ip)
661-
if isinstance(peer_network, ipaddress.IPv4Network) and isinstance(local_address, ipaddress.IPv4Address):
662-
iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['iptables', '-A', 'INPUT', '-s', peer_cidr, '-d', local_ip, '-p', 'tcp', '--dport', '179', '-j', 'ACCEPT'])
663-
elif isinstance(peer_network, ipaddress.IPv6Network) and isinstance(local_address, ipaddress.IPv6Address):
664-
iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-A', 'INPUT', '-s', peer_cidr, '-d', local_ip, '-p', 'tcp', '--dport', '179', '-j', 'ACCEPT'])
666+
local_ip = config.get('local_addr', None)
667+
local_network = None
668+
local_match = []
669+
if local_ip is not None:
670+
# Use network to aid comparision between peer and local network object
671+
local_network = ipaddress.ip_network(local_ip)
672+
local_match = ['-d', local_ip]
673+
try:
674+
peer_network = ipaddress.ip_network(peer, strict=False)
675+
if local_network is not None and peer_network.__class__ != local_network.__class__:
676+
self.log_warning("Inconsistent IP address types on BGP neighbor '{}'".format(key))
677+
continue
678+
# Treat as IPv4/IPv6 address source
679+
peer_match = ['-s', peer]
680+
except ValueError:
681+
# Treat as incoming interface for BGP Unnumbered
682+
peer_match = ['-i', peer]
683+
local_network = ipaddress.ip_network('fe80::/10')
684+
local_match = ['-d', 'fe80::/10']
685+
if isinstance(local_network, ipaddress.IPv4Network):
686+
iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['iptables', '-A', 'INPUT'] + peer_match + local_match + ['-p', 'tcp', '--dport', '179', '-j', 'ACCEPT'])
687+
elif isinstance(local_network, ipaddress.IPv6Network):
688+
iptables_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['ip6tables', '-A', 'INPUT'] + peer_match + local_match + ['-p', 'tcp', '--dport', '179', '-j', 'ACCEPT'])
665689
else:
666-
self.log_warning("Unrecognized or inconsistent IP address type on BGP neighbor '{}'".format(key))
690+
self.log_warning("Unrecognized IP address type on BGP neighbor '{}'".format(key))
667691

668692
# TODO: BGP_PEER_RANGE and BGP_PEER_GROUP is not implemented yet, so if they are defined allow BGP from everyone
669693
if self.config_db_map[namespace].get_table(self.BGP_PEER_RANGE) or self.config_db_map[namespace].get_table(self.BGP_PEER_GROUP):

0 commit comments

Comments
 (0)