add peeringdb support

master
FAELIX SALT 4 years ago
parent 29cd4ee90e
commit 538dd78cca

@ -1,5 +1,3 @@
/* -=-=-=-=-=-=-=-=-=-=-=-=-=- INTERFACES -=-=-=-=-=-=-=-=-=-=-=-=-=- */
{% macro interface_ip_ospf(iface_name) %}
{% if salt['pillar.get']('interfaces:'+iface_name+':ip:ospf') %}
ospf {
@ -35,6 +33,135 @@
{% endif %}
{% endmacro %}
{% macro bgp_neighbor(neighbor, neighbor_data) %}
neighbor {{ neighbor }} {
remote-as {{ neighbor_data['remote-as'] }}
{% if 'password' in neighbor_data %}password {{ neighbor_data['password'] }}{% endif %}
{% if 'update-source' in neighbor_data %}update-source {{ neighbor_data['update-source'] }}{% endif %}
{% if 'ebgp-multihop' in neighbor_data %}ebgp-multihop {{ neighbor_data['ebgp-multihop'] }}{% endif %}
{% if 'address-family' in neighbor_data %}
address-family {
{% if 'ipv4-unicast' in neighbor_data['address-family'] %}
ipv4-unicast {
{% if neighbor_data['address-family']['ipv4-unicast'].get('route-reflector-client',False) %}route-reflector-client{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('route-server-client',False) %}route-server-client{% endif %}
{% if 'prefix-list' in neighbor_data['address-family']['ipv4-unicast'] %}
prefix-list {
{% if 'export' in neighbor_data['address-family']['ipv4-unicast']['prefix-list'] %}export {{ neighbor_data['address-family']['ipv4-unicast']['prefix-list']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv4-unicast']['prefix-list'] %}import {{ neighbor_data['address-family']['ipv4-unicast']['prefix-list']['import'] }}{% endif %}
}
{% endif %}
{% if 'route-map' in neighbor_data['address-family']['ipv4-unicast'] %}
route-map {
{% if 'export' in neighbor_data['address-family']['ipv4-unicast']['route-map'] %}export {{ neighbor_data['address-family']['ipv4-unicast']['route-map']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv4-unicast']['route-map'] %}import {{ neighbor_data['address-family']['ipv4-unicast']['route-map']['import'] }}{% endif %}
}
{% endif %}
{% if 'soft-reconfiguration' in neighbor_data['address-family']['ipv4-unicast'] %}
soft-reconfiguration {
{% for softreconf in neighbor_data['address-family']['ipv4-unicast']['soft-reconfiguration'] %}
{{ softreconf }}
{% endfor %}
}
{% endif %}
{% if 'allowas-in' in neighbor_data['address-family']['ipv4-unicast'] %}
allowas-in {
{# neighbor_data['address-family']['ipv4-unicast']['allowas-in'] #}
}
{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('nexthop-self',False) %}
nexthop-self
{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('maximum-prefix',None) != None %}
maximum-prefix {{ neighbor_data['address-family']['ipv4-unicast'].get('maximum-prefix',None) }}
{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('default-originate',False) %}
default-originate {
}
{% endif %}
}
{% endif %}
{% if 'ipv6-unicast' in neighbor_data['address-family'] %}
ipv6-unicast {
{% if neighbor_data['address-family']['ipv6-unicast'].get('route-reflector-client',False) %}route-reflector-client{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('route-server-client',False) %}route-server-client{% endif %}
{% if 'prefix-list' in neighbor_data['address-family']['ipv6-unicast'] %}
prefix-list {
{% if 'export' in neighbor_data['address-family']['ipv6-unicast']['prefix-list'] %}export {{ neighbor_data['address-family']['ipv6-unicast']['prefix-list']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv6-unicast']['prefix-list'] %}import {{ neighbor_data['address-family']['ipv6-unicast']['prefix-list']['import'] }}{% endif %}
}
{% endif %}
{% if 'route-map' in neighbor_data['address-family']['ipv6-unicast'] %}
route-map {
{% if 'export' in neighbor_data['address-family']['ipv6-unicast']['route-map'] %}export {{ neighbor_data['address-family']['ipv6-unicast']['route-map']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv6-unicast']['route-map'] %}import {{ neighbor_data['address-family']['ipv6-unicast']['route-map']['import'] }}{% endif %}
}
{% endif %}
{% if 'soft-reconfiguration' in neighbor_data['address-family']['ipv6-unicast'] %}
soft-reconfiguration {
{% for softreconf in neighbor_data['address-family']['ipv6-unicast']['soft-reconfiguration'] %}
{{ softreconf }}
{% endfor %}
}
{% endif %}
{% if 'allowas-in' in neighbor_data['address-family']['ipv6-unicast'] %}
allowas-in {
{# neighbor_data['address-family']['ipv6-unicast']['allowas-in'] #}
}
{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('nexthop-self',False) %}
nexthop-self
{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('maximum-prefix',None) != None %}
maximum-prefix {{ neighbor_data['address-family']['ipv6-unicast'].get('maximum-prefix',None) }}
{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('default-originate',False) %}
default-originate {
}
{% endif %}
}
{% endif %}
}
{% endif %}
}
{% endmacro %}
{%- macro deep_merge(a, b): %}
{%- for k,v in b.items(): %}
{%- if v is not defined: %}
{%- do a.pop(k) %}
{%- else: %}
{%- if v is mapping: %}
{%- if a[k] is not mapping: %}
{%- do a.update({ k: { } }) %}
{%- endif %}
{%- do deep_merge(a[k], v) %}
{%- else: %}
{%- do a.update({ k: v }) %}
{%- endif %}
{% endif %}
{%- endfor %}
{%- endmacro %}
{%- macro normalise_peeringdb_as_set(prefix_list, pdb) %}
{%- if '::' in pdb %}
{%- set bits = pdb.split("::") %}
{%- do prefix_list.update({'sources': bits[0], 'name': 'peeringdb-' + bits[1].upper(), 'as-set': bits[1].upper()}) %}
{%- elif '@' in pdb %}
{%- set bits = pdb.split("@") %}
{%- do prefix_list.update({'sources': bits[1], 'name': 'peeringdb-' + bits[0].upper(), 'as-set': bits[0].upper()}) %}
{%- else %}
{%- do prefix_list.update({'sources': 'RIPE,RADB,ARIN,APNIC,AFRINIC,LACNIC', 'name': 'peeringdb-' + pdb, 'as-set': pdb}) %}
{% endif %}
{% endmacro %}
{% set peeringdb_prefixlist_4 = {} %}
{% set peeringdb_prefixlist_6 = {} %}
/* -=-=-=-=-=-=-=-=-=-=-=-=-=- INTERFACES -=-=-=-=-=-=-=-=-=-=-=-=-=- */
interfaces {
{% for iface_name, iface_data in pillar['netbox']['interfaces'].items() %}{% if iface_data['mgmt_only'] %}
{% elif iface_name == 'lo' %}
@ -270,100 +397,58 @@ protocols {
{% endif %}
{% for neighbor, neighbor_data in as_data.get('neighbor',{}).items() %}
neighbor {{ neighbor }} {
remote-as {{ neighbor_data['remote-as'] }}
{% if 'password' in neighbor_data %}password {{ neighbor_data['password'] }}{% endif %}
{% if 'update-source' in neighbor_data %}update-source {{ neighbor_data['update-source'] }}{% endif %}
{% if 'ebgp-multihop' in neighbor_data %}ebgp-multihop {{ neighbor_data['ebgp-multihop'] }}{% endif %}
{% if 'address-family' in neighbor_data %}
address-family {
{% if 'ipv4-unicast' in neighbor_data['address-family'] %}
ipv4-unicast {
{% if neighbor_data['address-family']['ipv4-unicast'].get('route-reflector-client',False) %}route-reflector-client{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('route-server-client',False) %}route-server-client{% endif %}
{% if 'prefix-list' in neighbor_data['address-family']['ipv4-unicast'] %}
prefix-list {
{% if 'export' in neighbor_data['address-family']['ipv4-unicast']['prefix-list'] %}export {{ neighbor_data['address-family']['ipv4-unicast']['prefix-list']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv4-unicast']['prefix-list'] %}import {{ neighbor_data['address-family']['ipv4-unicast']['prefix-list']['import'] }}{% endif %}
}
{% endif %}
{% if 'route-map' in neighbor_data['address-family']['ipv4-unicast'] %}
route-map {
{% if 'export' in neighbor_data['address-family']['ipv4-unicast']['route-map'] %}export {{ neighbor_data['address-family']['ipv4-unicast']['route-map']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv4-unicast']['route-map'] %}import {{ neighbor_data['address-family']['ipv4-unicast']['route-map']['import'] }}{% endif %}
}
{% endif %}
{% if 'soft-reconfiguration' in neighbor_data['address-family']['ipv4-unicast'] %}
soft-reconfiguration {
{% for softreconf in neighbor_data['address-family']['ipv4-unicast']['soft-reconfiguration'] %}
{{ softreconf }}
{% endfor %}
}
{% endif %}
{% if 'allowas-in' in neighbor_data['address-family']['ipv4-unicast'] %}
allowas-in {
{# neighbor_data['address-family']['ipv4-unicast']['allowas-in'] #}
}
{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('nexthop-self',False) %}
nexthop-self
{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('maximum-prefix',None) != None %}
maximum-prefix {{ neighbor_data['address-family']['ipv4-unicast'].get('maximum-prefix',None) }}
{% endif %}
{% if neighbor_data['address-family']['ipv4-unicast'].get('default-originate',False) %}
default-originate {
}
{% endif %}
}
{% endif %}
{% if 'ipv6-unicast' in neighbor_data['address-family'] %}
ipv6-unicast {
{% if neighbor_data['address-family']['ipv6-unicast'].get('route-reflector-client',False) %}route-reflector-client{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('route-server-client',False) %}route-server-client{% endif %}
{% if 'prefix-list' in neighbor_data['address-family']['ipv6-unicast'] %}
prefix-list {
{% if 'export' in neighbor_data['address-family']['ipv6-unicast']['prefix-list'] %}export {{ neighbor_data['address-family']['ipv6-unicast']['prefix-list']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv6-unicast']['prefix-list'] %}import {{ neighbor_data['address-family']['ipv6-unicast']['prefix-list']['import'] }}{% endif %}
}
{% endif %}
{% if 'route-map' in neighbor_data['address-family']['ipv6-unicast'] %}
route-map {
{% if 'export' in neighbor_data['address-family']['ipv6-unicast']['route-map'] %}export {{ neighbor_data['address-family']['ipv6-unicast']['route-map']['export'] }}{% endif %}
{% if 'import' in neighbor_data['address-family']['ipv6-unicast']['route-map'] %}import {{ neighbor_data['address-family']['ipv6-unicast']['route-map']['import'] }}{% endif %}
}
{% endif %}
{% if 'soft-reconfiguration' in neighbor_data['address-family']['ipv6-unicast'] %}
soft-reconfiguration {
{% for softreconf in neighbor_data['address-family']['ipv6-unicast']['soft-reconfiguration'] %}
{{ softreconf }}
{% endfor %}
}
{% endif %}
{% if 'allowas-in' in neighbor_data['address-family']['ipv6-unicast'] %}
allowas-in {
{# neighbor_data['address-family']['ipv6-unicast']['allowas-in'] #}
}
{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('nexthop-self',False) %}
nexthop-self
{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('maximum-prefix',None) != None %}
maximum-prefix {{ neighbor_data['address-family']['ipv6-unicast'].get('maximum-prefix',None) }}
{% endif %}
{% if neighbor_data['address-family']['ipv6-unicast'].get('default-originate',False) %}
default-originate {
}
{% endif %}
}
{% endif %}
}
{% endif %}
}
{{ bgp_neighbor(neighbor, neighbor_data) }}
{% endfor %}
{% set peeringdb = as_data.get('peeringdb',{}) %}
{% if peeringdb %}
{% for ix_name, ix_data in peeringdb.get('ix',{}).items() %}
/* {{ ix_name }} */
{% for asn, asn_data in ix_data.get('asn',{}).items() %}
{% set net_data = salt['peeringdb.get_net'](asn=asn)['out'][0] %}
{% set pdb_data = salt['peeringdb.get_netixlan'](asn=asn,ixlan=ix_data['peeringdb_ixlan'])['out'] %}
{% for peer in pdb_data %}
{% set neighbor_data = {'description': net_data.get('name','AS%d'%asn) + ' at ' + ix_name, 'address-family':{'ipv4-unicast':{},'ipv6-unicast':{}}} %}
{%- do deep_merge(neighbor_data, peeringdb.get('default',{})) %}
{%- do deep_merge(neighbor_data, ix_data.get('default',{})) %}
{%- do deep_merge(neighbor_data, {'remote-as':asn}) %}
{% set as_set = {} %}
{%- do normalise_peeringdb_as_set(as_set, net_data['irr_as_set']) %}
{% if peer.get('operational',False) %}
{% if peer.get('ipaddr4',None) %}
{% set neighbor4_data = {} %}
{%- do deep_merge(neighbor4_data, neighbor_data) %}
{%- do deep_merge(neighbor4_data, {'address-family': {'ipv4-unicast': {'prefix-list':{'import':as_set['name']},'maximum-prefix': net_data['info_prefixes4']}}}) %}
{%- do deep_merge(neighbor4_data, asn_data.get('default',{})) %}
{% if peer['ipaddr4'] in asn_data.get('neighbor',{}) %}
{%- do deep_merge(neighbor4_data, asn_data['neighbor'][peer['ipaddr4']]) %}
{% endif %}
{%- do neighbor4_data['address-family'].pop('ipv6-unicast') %}
{{ bgp_neighbor(peer['ipaddr4'], neighbor4_data) }}
{% if neighbor4_data['address-family']['ipv4-unicast']['prefix-list']['import'] == as_set['name'] %}
{%- do peeringdb_prefixlist_4.update({as_set['name']: as_set}) %}
{% endif %}
{% endif %}
{% if peer.get('ipaddr6',None) %}
{% set neighbor6_data = {} %}
{%- do deep_merge(neighbor6_data, neighbor_data) %}
{%- do deep_merge(neighbor6_data, {'address-family': {'ipv6-unicast': {'prefix-list':{'import':as_set['name']},'maximum-prefix': net_data['info_prefixes4']}}}) %}
{%- do deep_merge(neighbor6_data, asn_data.get('default',{})) %}
{% if peer['ipaddr6'] in asn_data.get('neighbor',{}) %}
{%- do deep_merge(neighbor6_data, asn_data['neighbor'][peer['ipaddr6']]) %}
{% endif %}
{%- do neighbor6_data['address-family'].pop('ipv4-unicast') %}
{{ bgp_neighbor(peer['ipaddr6'], neighbor6_data) }}
{% if neighbor6_data['address-family']['ipv6-unicast']['prefix-list']['import'] == as_set['name'] %}
{%- do peeringdb_prefixlist_6.update({as_set['name']: as_set}) %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endif %}
}
{% endfor %}
}
@ -1259,6 +1344,29 @@ policy {
}
{% endfor %}
{% for prefix_list_name, prefix_data in peeringdb_prefixlist_4.items() %}
prefix-list {{ prefix_list_name }} {
{% if prefix_data['as-set'] %}
{% set jsonblob = salt['cmd.run']('/tmp/bgpq3 -A -4 -S ' + prefix_data["sources"] + ' -j ' + prefix_data["as-set"], env={'BIND_ADDR':pillar['loopback']['IPv4'], 'BIND_ADDR6':pillar['loopback']['IPv6'], 'LD_PRELOAD':'/tmp/bind.so'})|load_json %}
{#% set jsonblob = salt['cmd.run']('/tmp/bgpq3 -A -4 -j ' + prefix_data["as-set"], env={'BIND_ADDR':pillar['loopback']['IPv4'], 'BIND_ADDR6':pillar['loopback']['IPv6'], 'LD_PRELOAD':'/tmp/bind.so'})|load_json %#}
/* {{ '/tmp/bgpq3 -A -4 -j ' + prefix_data["as-set"] }} */
{% for prefix in jsonblob.NN %}
rule {{ loop.index }} {
action permit
prefix {{ prefix['prefix'] }}
{% if prefix.get('less-equal',None) != None %}le {{ prefix['less-equal'] }}{% endif %}
{% if prefix.get('greater-equal',None) != None %}ge {{ prefix['greater-equal'] }}{% endif %}
}
{% endfor %}
{% endif %}
rule 65535 {
prefix 0.0.0.0/0
le 32
action deny
}
}
{% endfor %}
{% for prefix_list_name, prefix_data in salt['pillar.get']("policy:prefix-list",{}).items() %}
prefix-list6 {{ prefix_list_name }} {
{% if 'bgpq3' in prefix_data %}
@ -1294,6 +1402,29 @@ policy {
}
{% endfor %}
{% for prefix_list_name, prefix_data in peeringdb_prefixlist_6.items() %}
prefix-list6 {{ prefix_list_name }} {
{% if prefix_data['as-set'] %}
{% set jsonblob = salt['cmd.run']('/tmp/bgpq3 -A -6 -S ' + prefix_data["sources"] + ' -j ' + prefix_data["as-set"], env={'BIND_ADDR':pillar['loopback']['IPv4'], 'BIND_ADDR6':pillar['loopback']['IPv6'], 'LD_PRELOAD':'/tmp/bind.so'})|load_json %}
{#% set jsonblob = salt['cmd.run']('/tmp/bgpq3 -A -6 -j ' + prefix_data["as-set"], env={'BIND_ADDR':pillar['loopback']['IPv4'], 'BIND_ADDR6':pillar['loopback']['IPv6'], 'LD_PRELOAD':'/tmp/bind.so'})|load_json %#}
/* {{ '/tmp/bgpq3 -A -4 -j ' + prefix_data["as-set"] }} */
{% for prefix in jsonblob.NN %}
rule {{ loop.index }} {
action permit
prefix {{ prefix['prefix'] }}
{% if prefix.get('less-equal',None) != None %}le {{ prefix['less-equal'] }}{% endif %}
{% if prefix.get('greater-equal',None) != None %}ge {{ prefix['greater-equal'] }}{% endif %}
}
{% endfor %}
{% endif %}
rule 65535 {
prefix ::/0
le 128
action deny
}
}
{% endfor %}
}
/* -=-=-=-=-=-=-=-=-=-=-=-=-=- SERVICE -=-=-=-=-=-=-=-=-=-=-=-=-=- */

Loading…
Cancel
Save