From 006620a2cf0a095ead3296544266ea67531b393d Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Fri, 16 May 2025 16:07:10 +0100
Subject: [PATCH 1/3] `iptrunk` role: changes to accomodate trunks version 2.0

---
 .../roles/iptrunk/tasks/deploy_object.yaml    |  6 ++--
 .../gap_ansible/roles/iptrunk/tasks/main.yml  |  3 ++
 .../iptrunk/tasks/set_trunk_version.yaml      |  1 +
 .../templates/juniper/trunk_interface.j2      |  5 +++
 .../templates/nokia/trunk_interface.j2        | 31 ++++++++++++++-----
 geant/gap_ansible/roles/iptrunk/vars/main.yml |  1 +
 6 files changed, 37 insertions(+), 10 deletions(-)
 create mode 120000 geant/gap_ansible/roles/iptrunk/tasks/set_trunk_version.yaml

diff --git a/geant/gap_ansible/roles/iptrunk/tasks/deploy_object.yaml b/geant/gap_ansible/roles/iptrunk/tasks/deploy_object.yaml
index 81267508..511ef675 100644
--- a/geant/gap_ansible/roles/iptrunk/tasks/deploy_object.yaml
+++ b/geant/gap_ansible/roles/iptrunk/tasks/deploy_object.yaml
@@ -39,7 +39,8 @@
   geant.gap_ansible.nokia_netconf_config:
     format: xml
     default_operation: merge
-    content: "{{ lookup('ansible.builtin.template', '{{ local_side.iptrunk_side_node.vendor }}/{{ config_object }}.j2') }}"
+    content: "{{ lookup('ansible.builtin.file', '{{ play_storage_path }}/{{ config_object }}.conf') }}"
+    # content: "{{ lookup('ansible.builtin.template', '{{ local_side.iptrunk_side_node.vendor }}/{{ config_object }}.j2') }}"
     commit: true
     config_mode: private
   diff: true
@@ -65,7 +66,8 @@
   geant.gap_ansible.nokia_netconf_config:
     format: xml
     default_operation: merge
-    content: "{{ lookup('ansible.builtin.template', '{{ local_side.iptrunk_side_node.vendor }}/{{ config_object }}.j2') }}"
+    content: "{{ lookup('ansible.builtin.file', '{{ play_storage_path }}/{{ config_object }}.conf') }}"
+    # content: "{{ lookup('ansible.builtin.template', '{{ local_side.iptrunk_side_node.vendor }}/{{ config_object }}.j2') }}"
     commit: true
     commit_comment: "{{ commit_comment }}"
     config_mode: private
diff --git a/geant/gap_ansible/roles/iptrunk/tasks/main.yml b/geant/gap_ansible/roles/iptrunk/tasks/main.yml
index f3f0860e..9a357242 100644
--- a/geant/gap_ansible/roles/iptrunk/tasks/main.yml
+++ b/geant/gap_ansible/roles/iptrunk/tasks/main.yml
@@ -54,6 +54,9 @@
   when:
     ( local_side.iptrunk_side_node.router_access_via_ts | ansible.builtin.bool ) is true
 
+- name: Include setting the trunk version
+  ansible.builtin.include_tasks: set_trunk_version.yaml
+
 - name: Include compiling the template
   ansible.builtin.include_tasks: compile_object.yaml
   when: (verb in verbs)
diff --git a/geant/gap_ansible/roles/iptrunk/tasks/set_trunk_version.yaml b/geant/gap_ansible/roles/iptrunk/tasks/set_trunk_version.yaml
new file mode 120000
index 00000000..6616a247
--- /dev/null
+++ b/geant/gap_ansible/roles/iptrunk/tasks/set_trunk_version.yaml
@@ -0,0 +1 @@
+../../../tasks/set_trunk_version.yaml
\ No newline at end of file
diff --git a/geant/gap_ansible/roles/iptrunk/templates/juniper/trunk_interface.j2 b/geant/gap_ansible/roles/iptrunk/templates/juniper/trunk_interface.j2
index 156b2bcb..b864b69b 100644
--- a/geant/gap_ansible/roles/iptrunk/templates/juniper/trunk_interface.j2
+++ b/geant/gap_ansible/roles/iptrunk/templates/juniper/trunk_interface.j2
@@ -38,8 +38,13 @@
                 {% if common.trunk_type != "Dark_fiber" %}
                 bfd-liveness-detection {
                     minimum-interval {{ bfd_min_interval }};
+                  {% if trunk_version | float < 2.0 %}
                     neighbor {{ remote['loopback'] }};
                     local-address {{local['loopback']}};
+                  {% else %}
+                    neighbor {{ (remote.ipv4_address | split('/'))[0] }};
+                    local-address {{ (local.ipv4_address | split('/'))[0] }};
+                  {% endif %}
                 }
                 {% endif %}
                 {% if (common.minimum_links | int) > 0 %}
diff --git a/geant/gap_ansible/roles/iptrunk/templates/nokia/trunk_interface.j2 b/geant/gap_ansible/roles/iptrunk/templates/nokia/trunk_interface.j2
index f34d21e8..de0db07a 100644
--- a/geant/gap_ansible/roles/iptrunk/templates/nokia/trunk_interface.j2
+++ b/geant/gap_ansible/roles/iptrunk/templates/nokia/trunk_interface.j2
@@ -4,19 +4,19 @@
 {##}
 {% for trunk in trunks %}
     {% if inventory_hostname == trunk.config.nodeA.name  %}
-        {% set local= trunk.config.nodeA %}
-        {% set remote= trunk.config.nodeB %}
-        {% set common= trunk.config.common %}
+        {% set local = trunk.config.nodeA %}
+        {% set remote = trunk.config.nodeB %}
+        {% set common = trunk.config.common %}
         {% if removed_ae_members is defined %}
-            {% set side_removed_ae_members= removed_ae_members[0] %}
+            {% set side_removed_ae_members = removed_ae_members[0] %}
         {% endif %}
     {% endif %}
     {% if inventory_hostname == trunk.config.nodeB.name  %}
-        {% set local= trunk.config.nodeB %}
-        {% set remote= trunk.config.nodeA %}
-        {% set common= trunk.config.common %}
+        {% set local = trunk.config.nodeB %}
+        {% set remote = trunk.config.nodeA %}
+        {% set common = trunk.config.common %}
         {% if removed_ae_members is defined %}
-            {% set side_removed_ae_members= removed_ae_members[1] %}
+            {% set side_removed_ae_members = removed_ae_members[1] %}
         {% endif %}
     {% endif %}
 
@@ -50,6 +50,13 @@
                       </tx-tlvs>
                   </dest-mac>
               </lldp>
+            {% if trunk_version | float >= 2.0 %}
+              <network>
+                  <egress>
+                      <queue-policy>GEANT_BASIC</queue-policy>
+                  </egress>
+              </network>
+            {% endif %}
           </ethernet>
       </port>
 {% endfor %}
@@ -89,8 +96,14 @@
                   <multiplier>3</multiplier>
                   <receive-interval>{{ bfd_min_interval }}</receive-interval>
                   <transmit-interval>{{ bfd_min_interval }}</transmit-interval>
+              {% if trunk_version | float < 2.0 %}
                   <local-ip-address>{{ local['loopback'] }}</local-ip-address>
                   <remote-ip-address>{{ remote['loopback'] }}</remote-ip-address>
+              {% else %}
+                  <bfd-on-distributing-only>true</bfd-on-distributing-only>
+                  <local-ip-address>{{ (local.ipv4_address | split('/'))[0] }}</local-ip-address>
+                  <remote-ip-address>{{ (remote.ipv4_address | split('/'))[0] }}</remote-ip-address> 
+              {% endif %}
               </ipv4>
           </bfd-liveness>
           {% endif %}
@@ -101,7 +114,9 @@
               <interface-name>{{ local.ae_name | lower }}.0</interface-name>
               <admin-state>enable</admin-state>
               <description>SRV_GLOBAL INFRASTRUCTURE BACKBONE #{{ trunk_direction_name_sorted[0] }}-{{ trunk_direction_name_sorted[1] }}{{ trunk_suffix if trunk_suffix is defined }}-IPTRUNK ${{ trunk.id }} | {{ trunk_direction_name_sorted[0] }}-{{ trunk_direction_name_sorted[1] }} | {{ common.description }}</description>
+          {% if trunk_version | float < 2.0 %}
               <ip-mtu>{{ mtu_ip }}</ip-mtu>
+          {% endif %}
               <port>{{ local.ae_name | lower }}</port>
               <ipv4>
                   <icmp>
diff --git a/geant/gap_ansible/roles/iptrunk/vars/main.yml b/geant/gap_ansible/roles/iptrunk/vars/main.yml
index 109ee890..d215e9e9 100644
--- a/geant/gap_ansible/roles/iptrunk/vars/main.yml
+++ b/geant/gap_ansible/roles/iptrunk/vars/main.yml
@@ -39,6 +39,7 @@ trunks:
   - id: "{{ wfo_trunk.iptrunk.gs_id }}"
     config:
       common:
+        # trunk_version: "{{ wfo_trunk.iptrunk.iptrunk_config_version }}"
         description: "{{ wfo_trunk.iptrunk.iptrunk_description }}"
         speed: "{{ wfo_trunk.iptrunk.iptrunk_speed }}"
         isis_metric: "{{ wfo_trunk.iptrunk.iptrunk_isis_metric }}"
-- 
GitLab


From f8cf9f9eabe59a9a93afa668c57591d1203d2b81 Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Fri, 16 May 2025 16:07:39 +0100
Subject: [PATCH 2/3] `iptrunk_migrate` role: changes to accomodate trunks
 version 2.0

---
 .../tasks/calculate_ips.yaml                  |  2 ++
 .../roles/iptrunk_migration/tasks/main.yml    | 15 +++++++++----
 .../tasks/set_trunk_version.yaml              |  1 +
 .../templates/nokia/bfd_update.j2             |  4 ++++
 .../templates/nokia/trunk_interface.j2        | 21 +++++++++++++++----
 5 files changed, 35 insertions(+), 8 deletions(-)
 create mode 120000 geant/gap_ansible/roles/iptrunk_migration/tasks/set_trunk_version.yaml

diff --git a/geant/gap_ansible/roles/iptrunk_migration/tasks/calculate_ips.yaml b/geant/gap_ansible/roles/iptrunk_migration/tasks/calculate_ips.yaml
index f59f76fa..01795326 100644
--- a/geant/gap_ansible/roles/iptrunk_migration/tasks/calculate_ips.yaml
+++ b/geant/gap_ansible/roles/iptrunk_migration/tasks/calculate_ips.yaml
@@ -2,6 +2,7 @@
   ansible.builtin.set_fact:
     new_ipv4_address: "{{ side_a_ipv4_address }}"
     new_ipv6_address: "{{ side_a_ipv6_address }}"
+    remain_ipv4_address: "{{ side_b_ipv4_address }}"
   when:
     (replace_index|int) == 0
 
@@ -9,5 +10,6 @@
   ansible.builtin.set_fact:
     new_ipv4_address: "{{ side_b_ipv4_address }}"
     new_ipv6_address: "{{ side_b_ipv6_address }}"
+    remain_ipv4_address: "{{ side_a_ipv4_address }}"
   when:
     (replace_index|int) == 1
diff --git a/geant/gap_ansible/roles/iptrunk_migration/tasks/main.yml b/geant/gap_ansible/roles/iptrunk_migration/tasks/main.yml
index 6b475754..fcb50939 100644
--- a/geant/gap_ansible/roles/iptrunk_migration/tasks/main.yml
+++ b/geant/gap_ansible/roles/iptrunk_migration/tasks/main.yml
@@ -28,6 +28,9 @@
   ansible.builtin.debug:
     msg: "{{ new_node.router.router_fqdn }}"
 
+- name: Include set trunk version tasks
+  ansible.builtin.include_tasks: set_trunk_version.yaml
+
 - name: Include configure storage tasks
   ansible.builtin.include_tasks: configure_storage.yaml
 
@@ -80,9 +83,13 @@
   when: verb == "deploy" and inventory_hostname == new_node.router.router_fqdn
 
 - name: Compile update for the remaining node (BFD update)
-  ansible.builtin.include_tasks: compile_template.yaml
   when: verb == "update" and inventory_hostname == remaining_side.name
+  block:
+    - name: Include calculate_ips
+      ansible.builtin.include_tasks: calculate_ips.yaml
 
-- name: Include update for the remaining node (BFD update)
-  ansible.builtin.include_tasks: bfd_update.yaml
-  when: verb == "update" and inventory_hostname == remaining_side.name
+    - name: Include compiling template
+      ansible.builtin.include_tasks: compile_template.yaml
+
+    - name: Include BFD update
+      ansible.builtin.include_tasks: bfd_update.yaml
diff --git a/geant/gap_ansible/roles/iptrunk_migration/tasks/set_trunk_version.yaml b/geant/gap_ansible/roles/iptrunk_migration/tasks/set_trunk_version.yaml
new file mode 120000
index 00000000..6616a247
--- /dev/null
+++ b/geant/gap_ansible/roles/iptrunk_migration/tasks/set_trunk_version.yaml
@@ -0,0 +1 @@
+../../../tasks/set_trunk_version.yaml
\ No newline at end of file
diff --git a/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/bfd_update.j2 b/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/bfd_update.j2
index 7bbc7131..0d5e0c30 100644
--- a/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/bfd_update.j2
+++ b/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/bfd_update.j2
@@ -5,7 +5,11 @@
           <lag-name>{{ remaining_side.ae_name | lower }}</lag-name>
           <bfd-liveness>
               <ipv4>
+              {% if trunk_version | float < 2.0 %}
                   <remote-ip-address alu:operation="replace">{{ new_node.router.router_lo_ipv4_address }}</remote-ip-address>
+              {% else %}
+                  <remote-ip-address alu:operation="replace">{{ (new_ipv4_address | split('/'))[0] }}</remote-ip-address>
+              {% endif %}
               </ipv4>
           </bfd-liveness>
       </lag>
diff --git a/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/trunk_interface.j2 b/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/trunk_interface.j2
index 3168ab25..e49c7b32 100644
--- a/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/trunk_interface.j2
+++ b/geant/gap_ansible/roles/iptrunk_migration/templates/nokia/trunk_interface.j2
@@ -25,6 +25,13 @@
                       </tx-tlvs>
                   </dest-mac>
               </lldp>
+            {% if trunk_version | float >= 2.0 %}
+              <network>
+                  <egress>
+                      <queue-policy>GEANT_BASIC</queue-policy>
+                  </egress>
+              </network>
+            {% endif %}
           </ethernet>
       </port>
 {% endfor %}
@@ -55,8 +62,14 @@
                   <multiplier>3</multiplier>
                   <receive-interval>{{ bfd_min_interval }}</receive-interval>
                   <transmit-interval>{{ bfd_min_interval }}</transmit-interval>
+              {% if trunk_version | float < 2.0 %}
                   <local-ip-address>{{ new_node.router.router_lo_ipv4_address }}</local-ip-address>
                   <remote-ip-address>{{ remaining_side['loopback'] }}</remote-ip-address>
+              {% else %}
+                  <bfd-on-distributing-only>true</bfd-on-distributing-only>
+                  <local-ip-address>{{  (new_ipv4_address | split('/'))[0] }}</local-ip-address>
+                  <remote-ip-address>{{ (remain_ipv4_address | split('/'))[0] }}</remote-ip-address> 
+              {% endif %}
               </ipv4>
           </bfd-liveness>
           {% endif %}
@@ -78,14 +91,14 @@
                       </ttl-expired>
                   </icmp>
                   <primary>
-                      <address>{{(new_ipv4_address| split('/'))[0]}}</address>
-                      <prefix-length>{{(new_ipv4_address| split('/'))[1]}}</prefix-length>
+                      <address>{{ (new_ipv4_address| split('/'))[0] }}</address>
+                      <prefix-length>{{ (new_ipv4_address| split('/'))[1] }}</prefix-length>
                   </primary>
               </ipv4>
               <ipv6>
                   <address>
-                      <ipv6-address>{{(new_ipv6_address| split('/'))[0]}}</ipv6-address>
-                      <prefix-length>{{(new_ipv6_address| split('/'))[1]}}</prefix-length>
+                      <ipv6-address>{{ (new_ipv6_address| split('/'))[0] }}</ipv6-address>
+                      <prefix-length>{{ (new_ipv6_address| split('/'))[1] }}</prefix-length>
                   </address>
               </ipv6>
               <qos>
-- 
GitLab


From 7737102569ecb2791677fadf2467d8350122e7c8 Mon Sep 17 00:00:00 2001
From: Aleksandr Kurbatov <ak@geant.org>
Date: Fri, 16 May 2025 16:08:21 +0100
Subject: [PATCH 3/3] tasks/set_trunk_version - set trunk version either to GSO
 value or to 1.0

---
 geant/gap_ansible/tasks/set_trunk_version.yaml | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 geant/gap_ansible/tasks/set_trunk_version.yaml

diff --git a/geant/gap_ansible/tasks/set_trunk_version.yaml b/geant/gap_ansible/tasks/set_trunk_version.yaml
new file mode 100644
index 00000000..2d73f03c
--- /dev/null
+++ b/geant/gap_ansible/tasks/set_trunk_version.yaml
@@ -0,0 +1,17 @@
+---
+- name: Force trunk version when it is not defined in GSO
+  when: wfo_trunk.iptrunk.iptrunk_config_version is not defined
+  ansible.builtin.set_fact:
+    trunk_version: 1.0
+
+- name: Force trunk version to default 1.0 if is none in GSO
+  when: wfo_trunk.iptrunk.iptrunk_config_version is defined
+        and wfo_trunk.iptrunk.iptrunk_config_version is none
+  ansible.builtin.set_fact:
+    trunk_version: 1.0
+
+- name: Set trunk version to the GSO value
+  when: wfo_trunk.iptrunk.iptrunk_config_version is defined
+        and wfo_trunk.iptrunk.iptrunk_config_version is not none
+  ansible.builtin.set_fact:
+    trunk_version: "{{ wfo_trunk.iptrunk.iptrunk_config_version }}"
-- 
GitLab