Browse Source

nftables: Generate set of iBGP peers

Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
Maximilian Wilhelm 11 months ago
parent
commit
56639cfd8e
2 changed files with 52 additions and 8 deletions
  1. 39 0
      _modules/ffho_netfilter.py
  2. 13 8
      nftables/nftables.conf.tmpl

+ 39 - 0
_modules/ffho_netfilter.py

@@ -16,6 +16,21 @@ vlan_re = re.compile (r'^(vlan|br0\.)(\d+)$')
 #                          Internal helper functions                           #
 ################################################################################
 
+def get_nodeconfig_section (section: str) -> {}:
+	fqdn = __grains__["id"]
+	node_config = __pillar__.get("nodes", {}).get(fqdn)
+
+	if node_config is None:
+		return {}
+
+	ret = node_config
+
+	for entry in section.split(":"):
+		ret = ret.get(entry, {})
+
+	return ret
+
+
 #
 # Check if at least one of the node roles are supposed to run DHCP
 def _allow_dhcp (fw_policy, roles):
@@ -393,6 +408,30 @@ def get_ospf_active_interface (node_config):
 
 	return ifaces
 
+#
+# Get a dict of all configured BGP peers per AF
+def get_bgp_peers ():
+	peers = {
+		4: {
+			# IP -> peer name
+		},
+		6: {},
+	}
+
+	bgp_cfg = get_nodeconfig_section("routing:bgp")
+	if bgp_cfg is None:
+		return peers
+
+	ibgp_peers = bgp_cfg.get('internal', {}).get('peers', {})
+	if ibgp_peers is None:
+		return peers
+
+	for af in [4, 6]:
+		for peer_cfg in ibgp_peers[str(af)]:
+			peers[af][peer_cfg["ip"]] = peer_cfg["node"]
+
+	return peers
+
 #
 # Get a list of interfaces to allow VXLAN encapsulated traffic on
 def get_vxlan_interfaces (interfaces):

+ 13 - 8
nftables/nftables.conf.tmpl

@@ -18,18 +18,21 @@
 {%- set urpf = salt['ffho_netfilter.generate_urpf_policy'](node_config) %}
 {%- set ospf_ifaces = salt['ffho_netfilter.get_ospf_active_interface'](node_config) %}
 {%- set vxlan_ifaces = salt['ffho_netfilter.get_vxlan_interfaces'](node_config['ifaces']) %}
+{%- set bgp_peers = salt['ffho_netfilter.get_bgp_peers']() %}
 
 flush ruleset
 
 table ip filter {
+{%- if bgp_peers[4]|length > 0 %}
 	set ibgp-peers {
 		type ipv4_addr
 		elements = {
-			10.132.255.1,	# cr01.in.ffho.net
-			10.132.255.2,	# cr02.in.ffho.net
-			10.132.255.3,	# cr03.in.ffho.net
+  {%- for ip, name in bgp_peers[4].items () %}
+			{{ ip }},	# {{ name }}
+  {%- endfor %}
 		}
 	}
+{%- endif %}
 
 	chain input {
 		type filter hook input priority 0; policy drop;
@@ -51,7 +54,7 @@ table ip filter {
 		{#- ifname sets are introduced in nftables 2.11 #}
 		meta l4proto ospf iifname { {{ ospf_ifaces|join(', ') }} } counter accept
 {%- endif %}
-{%- if 'router' in roles %}
+{%- if bgp_peers[4]|length > 0  %}
 		tcp dport 179 counter jump bgp
 {%- endif %}
 		ct state related,established counter accept
@@ -160,14 +163,16 @@ table ip filter {
 }
 
 table ip6 filter {
+{%- if bgp_peers[6]|length > 0 %}
 	set ibgp-peers {
 		type ipv6_addr
 		elements = {
-			2a03:2260:2342:ffff::1,	# cr01.in.ffho.net
-			2a03:2260:2342:ffff::2,	# cr02.in.ffho.net
-			2a03:2260:2342:ffff::3,	# cr03.in.ffho.net
+  {%- for ip, name in bgp_peers[6].items () %}
+			{{ ip }},	# {{ name }}
+  {%- endfor %}
 		}
 	}
+{%- endif %}
 
 	chain input {
 		type filter hook input priority 0; policy drop;
@@ -188,7 +193,7 @@ table ip6 filter {
 		{#- ifname sets are introduced in nftables 2.11 #}
 		meta l4proto ospf iifname { {{ ospf_ifaces|join(', ') }} } counter accept
 {%- endif %}
-{%- if 'router' in roles %}
+{%- if bgp_peers[6]|length > 0  %}
 		tcp dport 179 counter jump bgp
 {%- endif %}
 		ct state related,established counter accept