diff --git a/docs/module/gateway.md b/docs/module/gateway.md index 839fe56f21..29829c1c66 100644 --- a/docs/module/gateway.md +++ b/docs/module/gateway.md @@ -21,6 +21,7 @@ The module is supported on these platforms: | --------------------- | :-: | :-: | :-: | | Arista EOS | ✅ | ✅ | ✅ | | Aruba AOS-CX | ✅ | ✅ | ✅ | +| BIRD | ✅ | ❌ | ❌ | | Cisco IOS XE[^18v] | ❌ | ✅ | ✅ | | Cisco IOS XR[^XR] | ❌ | ✅ | ✅ | | Cisco Nexus OS | ❌ | ✅ | ✅ | diff --git a/docs/platforms.md b/docs/platforms.md index 939a17d6b1..d1e35414ce 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -418,6 +418,7 @@ These devices support additional control-plane protocols or BGP address families | --------------------- | :-: | :-: | :-: | :-: | | Arista EOS | ✅ | ✅ | ✅ | ✅ | | Aruba AOS-CX | ✅ | ✅ | ✅ | ✅ | +| BIRD | ❌ | ❌ | ❌ | ✅ | | Cisco IOS XE[^XE] | ✅ | ✅ | ✅ | ✅ | | Cisco IOSv/IOSvL2 | ✅ | ❌ | ✅ | ✅ | | Cisco IOS XR[^XR] | ❌ | ✅ | ✅ | ✅ | diff --git a/netsim/ansible/templates/gateway/bird.j2 b/netsim/ansible/templates/gateway/bird.j2 new file mode 100644 index 0000000000..dc821fc0b7 --- /dev/null +++ b/netsim/ansible/templates/gateway/bird.j2 @@ -0,0 +1,5 @@ +#!/bin/bash +# +set -e +# +{% include 'frr/anycast-dp.j2' +%} diff --git a/netsim/ansible/templates/gateway/frr.j2 b/netsim/ansible/templates/gateway/frr.j2 index 72d59ebace..7e42545874 100644 --- a/netsim/ansible/templates/gateway/frr.j2 +++ b/netsim/ansible/templates/gateway/frr.j2 @@ -1,56 +1,6 @@ #!/bin/bash # -set -e # Exit immediately when any command fails +set -e # -sysctl -w net.ipv6.conf.all.enhanced_dad=0 -sysctl -w net.ipv6.conf.default.enhanced_dad=0 -{% for intf in interfaces if intf.gateway.protocol|default('none') == 'vrrp' %} -{% for afm in ['ipv4','ipv6'] if afm in intf.gateway %} -{% set v_if = 'vrrp%s-%s-%s'|format('6' if afm == 'ipv6' else '',intf.ifindex,intf.gateway.vrrp.group) %} -{% set v_mac = intf.gateway.vrrp.mac[afm] %} -if [ ! -e /sys/class/net/{{ v_if }} ]; then - ip link add {{ v_if }} link {{ intf.ifname }} type macvlan mode bridge - ip link set dev {{ v_if }} address {{ v_mac }} addrgenmode {{ 'none' if afm == 'ipv4' else 'random' }} - ip addr add {{ intf.gateway[afm] }} dev {{ v_if }} -{% if afm=='ipv4' %} - sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_announce=2 - sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_ignore=2 - sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_accept=1 -{% endif %} -{% if 'vrf' in intf %} - ip link set dev {{ v_if }} master {{ intf.vrf }} -{% endif %} - ip link set dev {{ v_if }} up -fi -{% endfor %} -{% endfor %} -{% for intf in interfaces if intf.gateway.protocol|default('none') == 'anycast' %} -{% set v_if = 'varp-%s'|format(intf.ifindex) %} -if [ ! -e /sys/class/net/{{ v_if }} ]; then - ip link add {{ v_if }} link {{ intf.ifname }} type macvlan mode private - ip link set dev {{ v_if }} address {{ intf.gateway.anycast.mac|ansible.utils.hwaddr('linux') }} -{% if intf.type == 'svi' %} - bridge fdb replace {{ intf.gateway.anycast.mac|ansible.utils.hwaddr('linux') }} dev {{ intf.ifname }} self -{% endif %} -{% for afm in ['ipv4','ipv6'] if afm in intf.gateway %} - ip addr add {{ intf.gateway[afm] }} dev {{ v_if }} metric 1024 -{% endfor %} -{% if 'ipv4' in intf.gateway %} - sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_announce=2 - sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_ignore=2 - sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_accept=1 -{% endif %} -{% if 'ipv6' in intf.gateway %} - sysctl -w net.ipv6.conf.{{ v_if }}.enhanced_dad=0 - sysctl -w net.ipv6.conf.{{ v_if }}.accept_dad=0 - sysctl -w net.ipv6.conf.{{ v_if }}.dad_transmits=0 -{% else %} - sysctl -w net.ipv6.conf.{{ v_if }}.disable_ipv6=1 -{% endif %} -{% if 'vrf' in intf %} - ip link set dev {{ v_if }} master {{ intf.vrf }} -{% endif %} - ip link set dev {{ v_if }} up -fi -{% endfor %} -{% include 'frr.vrrp-config.j2' %} +{% include 'frr/data-plane.j2' +%} +{% include 'frr/vrrp-cp.j2' +%} diff --git a/netsim/ansible/templates/gateway/frr/anycast-dp.j2 b/netsim/ansible/templates/gateway/frr/anycast-dp.j2 new file mode 100644 index 0000000000..5d1f1cad4f --- /dev/null +++ b/netsim/ansible/templates/gateway/frr/anycast-dp.j2 @@ -0,0 +1,29 @@ +{% for intf in interfaces if intf.gateway.protocol|default('none') == 'anycast' %} +{% set v_if = 'varp-%s'|format(intf.ifindex) %} +if [ ! -e /sys/class/net/{{ v_if }} ]; then + ip link add {{ v_if }} link {{ intf.ifname }} type macvlan mode private + ip link set dev {{ v_if }} address {{ intf.gateway.anycast.mac|ansible.utils.hwaddr('linux') }} +{% if intf.type == 'svi' %} + bridge fdb replace {{ intf.gateway.anycast.mac|ansible.utils.hwaddr('linux') }} dev {{ intf.ifname }} self +{% endif %} +{% for afm in ['ipv4','ipv6'] if afm in intf.gateway %} + ip addr add {{ intf.gateway[afm] }} dev {{ v_if }} metric 1024 +{% endfor %} +{% if 'ipv4' in intf.gateway %} + sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_announce=2 + sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_ignore=2 + sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_accept=1 +{% endif %} +{% if 'ipv6' in intf.gateway %} + sysctl -w net.ipv6.conf.{{ v_if }}.enhanced_dad=0 + sysctl -w net.ipv6.conf.{{ v_if }}.accept_dad=0 + sysctl -w net.ipv6.conf.{{ v_if }}.dad_transmits=0 +{% else %} + sysctl -w net.ipv6.conf.{{ v_if }}.disable_ipv6=1 +{% endif %} +{% if 'vrf' in intf %} + ip link set dev {{ v_if }} master {{ intf.vrf }} +{% endif %} + ip link set dev {{ v_if }} up +fi +{% endfor %} diff --git a/netsim/ansible/templates/gateway/frr/data-plane.j2 b/netsim/ansible/templates/gateway/frr/data-plane.j2 new file mode 100644 index 0000000000..1ce607365b --- /dev/null +++ b/netsim/ansible/templates/gateway/frr/data-plane.j2 @@ -0,0 +1,5 @@ +sysctl -w net.ipv6.conf.all.enhanced_dad=0 +sysctl -w net.ipv6.conf.default.enhanced_dad=0 +# +{% include 'frr/anycast-dp.j2' +%} +{% include 'frr/vrrp-dp.j2' %} diff --git a/netsim/ansible/templates/gateway/frr.vrrp-config.j2 b/netsim/ansible/templates/gateway/frr/vrrp-cp.j2 similarity index 100% rename from netsim/ansible/templates/gateway/frr.vrrp-config.j2 rename to netsim/ansible/templates/gateway/frr/vrrp-cp.j2 diff --git a/netsim/ansible/templates/gateway/frr/vrrp-dp.j2 b/netsim/ansible/templates/gateway/frr/vrrp-dp.j2 new file mode 100644 index 0000000000..9fc6978d0c --- /dev/null +++ b/netsim/ansible/templates/gateway/frr/vrrp-dp.j2 @@ -0,0 +1,20 @@ +{% for intf in interfaces if intf.gateway.protocol|default('none') == 'vrrp' %} +{% for afm in ['ipv4','ipv6'] if afm in intf.gateway %} +{% set v_if = 'vrrp%s-%s-%s'|format('6' if afm == 'ipv6' else '',intf.ifindex,intf.gateway.vrrp.group) %} +{% set v_mac = intf.gateway.vrrp.mac[afm] %} +if [ ! -e /sys/class/net/{{ v_if }} ]; then + ip link add {{ v_if }} link {{ intf.ifname }} type macvlan mode bridge + ip link set dev {{ v_if }} address {{ v_mac }} addrgenmode {{ 'none' if afm == 'ipv4' else 'random' }} + ip addr add {{ intf.gateway[afm] }} dev {{ v_if }} +{% if afm=='ipv4' %} + sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_announce=2 + sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_ignore=2 + sysctl -w net.ipv4.conf.{{ intf.ifname }}.arp_accept=1 +{% endif %} +{% if 'vrf' in intf %} + ip link set dev {{ v_if }} master {{ intf.vrf }} +{% endif %} + ip link set dev {{ v_if }} up +fi +{% endfor %} +{% endfor %} diff --git a/netsim/daemons/bird.yml b/netsim/daemons/bird.yml index 1b56e9875b..85f0a9585b 100644 --- a/netsim/daemons/bird.yml +++ b/netsim/daemons/bird.yml @@ -72,6 +72,8 @@ features: routing: static.discard: true dhcp: false + gateway: + protocol: [ anycast ] initial: ipv4: unnumbered: peer