From 3dc20e7daa156fd45e37efb3d629c09ebc55522e Mon Sep 17 00:00:00 2001 From: Seb d'Argoeuves Date: Wed, 14 Oct 2026 23:09:29 +0000 Subject: [PATCH 1/4] ASAv: loopback interface --- netsim/ansible/templates/initial/asa.j2 | 11 +++++++++++ netsim/devices/asav.yml | 2 ++ 2 files changed, 13 insertions(+) diff --git a/netsim/ansible/templates/initial/asa.j2 b/netsim/ansible/templates/initial/asa.j2 index 35edda3197..29beb07c6c 100644 --- a/netsim/ansible/templates/initial/asa.j2 +++ b/netsim/ansible/templates/initial/asa.j2 @@ -9,6 +9,17 @@ name {{ v.loopback.ipv4|ansible.utils.ipaddr('address') }} {{ k }} {% endfor %} {% endif %} ! +{% if loopback is defined %} +interface {{ loopback.ifname }} + nameif {{ loopback.ifname }} +{% if 'ipv4' in loopback %} + ip address {{ loopback.ipv4|ansible.utils.ipaddr('address') }} {{ loopback.ipv4|ansible.utils.ipaddr('netmask') }} +{% endif %} +{% if 'ipv6' in loopback %} + ipv6 address {{ loopback.ipv6|upper }} +{% endif %} +{% endif %} +! {% for l in interfaces|default([]) %} interface {{ l.ifname }} {% if l.shutdown|default(False) %} diff --git a/netsim/devices/asav.yml b/netsim/devices/asav.yml index 8db41902cc..30dad548e4 100644 --- a/netsim/devices/asav.yml +++ b/netsim/devices/asav.yml @@ -2,6 +2,8 @@ description: Cisco ASAv support: level: minimal +loopback_interface_name: Loopback{ifindex} +loopback: false interface_name: GigabitEthernet0/{ifindex} ifindex_offset: 0 mgmt_if: Management0/0 From 3516b728f6b3dbd24b34f4718567cc0b01655a89 Mon Sep 17 00:00:00 2001 From: Seb d'Argoeuves Date: Wed, 14 Oct 2026 23:21:14 +0000 Subject: [PATCH 2/4] ASAv: use update-source with Loopback for iBGP --- netsim/ansible/templates/bgp/asa.j2 | 3 +-- netsim/ansible/templates/bgp/asa.macro.j2 | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/netsim/ansible/templates/bgp/asa.j2 b/netsim/ansible/templates/bgp/asa.j2 index 635d28e029..ff50f3afa3 100644 --- a/netsim/ansible/templates/bgp/asa.j2 +++ b/netsim/ansible/templates/bgp/asa.j2 @@ -9,8 +9,7 @@ router bgp {{ bgp.as }} {% for af in ['ipv4','ipv6'] if bgp[af] is defined %} address-family {{ af }} unicast {% for n in bgp.neighbors if n[af] is defined %} - neighbor {{ n[af] }} remote-as {{ n.as }} - neighbor {{ n[af] }} description {{ n.name }} +{{ bgpcfg.neighbor_global(n,n[af]) }} {% endfor %} {% if bgp.import is defined %} {{ redistribute.config(bgp,af=af,ospf_pid=ospf.process|default(1))|indent(2,first=True) }} diff --git a/netsim/ansible/templates/bgp/asa.macro.j2 b/netsim/ansible/templates/bgp/asa.macro.j2 index 5b4065d6f6..aa3f7d1409 100644 --- a/netsim/ansible/templates/bgp/asa.macro.j2 +++ b/netsim/ansible/templates/bgp/asa.macro.j2 @@ -1,3 +1,13 @@ +{# + BGP neighbor definition: remote-as, description, update-source +#} +{% macro neighbor_global(n,ip) %} + neighbor {{ ip }} remote-as {{ n.as }} + neighbor {{ ip }} description {{ n.name }} +{% if n._source_intf is defined %} + neighbor {{ ip }} update-source {{ n._source_intf.ifname }} +{% endif %} +{%- endmacro -%} {# Address family BGP neighbor definition #} From a520545543bbd2dd0f8bb4b1dced27f7b601ba8b Mon Sep 17 00:00:00 2001 From: Seb d'Argoeuves Date: Wed, 14 Oct 2026 23:42:40 +0000 Subject: [PATCH 3/4] ASAv: add Quirk to check for Loopback with IBGP --- netsim/devices/asav.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/netsim/devices/asav.py b/netsim/devices/asav.py index 897c4e366a..c4674808e3 100644 --- a/netsim/devices/asav.py +++ b/netsim/devices/asav.py @@ -21,6 +21,19 @@ def check_isis_p2p_interfaces(node: Box, topology: Box, igp: str = 'isis') -> No more_data=[ f'Node {node.name} {intf.ifname} ({intf.name})' ], category=log.IncorrectType) +def check_ibgp_loopback(node: Box) -> None: + if 'loopback' in node: + return + if not any(n.type == 'ibgp' for n in node.get('bgp.neighbors',[])): + return + + report_quirk( + text=f"ASAv node '{node.name}' has no loopback, iBGP sessions will not work", + node=node, + quirk='ibgp_no_loopback', + more_hints=[ 'Set loopback: true on ASAv 9.18(2) or later, or use eBGP' ], + category=Warning) + class ASA(_Quirks): @classmethod @@ -36,3 +49,6 @@ def device_quirks(self, node: Box, topology: Box) -> None: text=f"netlab cannot configure OSPFv3 on ASAv node '{node.name}'", node=node, category=log.IncorrectType) + + if 'bgp' in mods: + check_ibgp_loopback(node) From 1c5122da1d5985fe1d88cbb07469752438570270 Mon Sep 17 00:00:00 2001 From: Seb d'Argoeuves Date: Wed, 14 Oct 2026 23:45:34 +0000 Subject: [PATCH 4/4] ASAv: Docs for IBGP requiring Loopback --- docs/caveats.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/caveats.md b/docs/caveats.md index 7536ddcd36..0781ff5913 100644 --- a/docs/caveats.md +++ b/docs/caveats.md @@ -169,7 +169,8 @@ and validation. Configuration is deployed with a bash script executed within the * We did not implement OSPFv3 for ASAv * ASAv static routes require an outgoing interface. *netlab* does not configure static routes with indirect next hops on ASAv. * ASAv does not support equal-cost static routes over multiple interfaces. *netlab* configures only the first next hop of a static route. -* ASAv releases before 9.18(2) do not support loopback interfaces. As *netlab* uses loopback interfaces for iBGP sessions, iBGP sessions with ASAv nodes are not configured. Use eBGP sessions instead. +* ASAv releases before 9.18(2) do not support loopback interfaces; *netlab* does not configure them by default. Set `loopback: true` on ASAv nodes running release 9.18(2) or later. +* *netlab* uses loopback interfaces for IBGP sessions. IBGP sessions with ASAv nodes that have no loopback interface do not work; use EBGP sessions instead. * OSPF routes are not imported into the IPv6 BGP address family (OSPFv3 is not implemented). Routing policies cannot be used with route import. (caveats-cat8000v)=