From e559ff4e552a0959287bee7712d887e754b25fb7 Mon Sep 17 00:00:00 2001
From: Christian Breunig <christian@breunig.cc>
Date: Thu, 1 Feb 2024 17:10:18 +0100
Subject: bfd: T5967: add minimum-ttl option

* set protocols bfd peer <x.x.x.x> minimum-ttl <1-254>

(partially cherry-picked from 1f07dcbddfcfdbb9079936ec479c5633934dd547)
---
 data/templates/frr/bfd.frr.tmpl             |  3 +++
 interface-definitions/protocols-bfd.xml.in  | 12 ++++++++++++
 smoketest/scripts/cli/test_protocols_bfd.py |  5 +++++
 src/conf_mode/protocols_bfd.py              | 10 ++++++++++
 4 files changed, 30 insertions(+)

diff --git a/data/templates/frr/bfd.frr.tmpl b/data/templates/frr/bfd.frr.tmpl
index 9e5ad3379..c618efdc6 100644
--- a/data/templates/frr/bfd.frr.tmpl
+++ b/data/templates/frr/bfd.frr.tmpl
@@ -14,6 +14,9 @@ bfd
 {% if peer.echo_mode %}
  echo-mode
 {% endif %}
+{% if peer.minimum_ttl %}
+  minimum-ttl {{ peer.minimum_ttl }}
+{% endif %}
 {% if peer.echo_interval != '' %}
  echo-interval {{ peer.echo_interval }}
 {% endif %}
diff --git a/interface-definitions/protocols-bfd.xml.in b/interface-definitions/protocols-bfd.xml.in
index 8900e7955..0423ebcb2 100644
--- a/interface-definitions/protocols-bfd.xml.in
+++ b/interface-definitions/protocols-bfd.xml.in
@@ -125,6 +125,18 @@
                   <valueless/>
                 </properties>
               </leafNode>
+              <leafNode name="minimum-ttl">
+                <properties>
+                  <help>Expect packets with at least this TTL</help>
+                  <valueHelp>
+                    <format>u32:1-254</format>
+                    <description>Minimum TTL expected</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 1-254"/>
+                  </constraint>
+                </properties>
+              </leafNode>
               <leafNode name="echo-mode">
                 <properties>
                   <help>Enables the echo transmission mode</help>
diff --git a/smoketest/scripts/cli/test_protocols_bfd.py b/smoketest/scripts/cli/test_protocols_bfd.py
index 46a2bdcfa..7839aee12 100755
--- a/smoketest/scripts/cli/test_protocols_bfd.py
+++ b/smoketest/scripts/cli/test_protocols_bfd.py
@@ -32,6 +32,7 @@ neighbor_config = {
         'intv_rx'    : '500',
         'intv_tx'    : '600',
         'multihop'   : '',
+        'minimum_ttl': '50',
         'source_addr': '192.0.2.254',
         },
     '192.0.2.20' : {
@@ -86,6 +87,8 @@ class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
                 self.cli_set(base_path + ['peer', peer, 'interval', 'transmit', peer_config["intv_tx"]])
             if 'multihop' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'multihop'])
+            if 'minimum_ttl' in peer_config:
+                self.cli_set(base_path + ['peer', peer, 'minimum-ttl', peer_config["minimum_ttl"]])
             if 'shutdown' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'shutdown'])
             if 'source_addr' in peer_config:
@@ -112,6 +115,8 @@ class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
 
             if 'echo_mode' in peer_config:
                 self.assertIn(f' echo-mode', peerconfig)
+            if 'minimum_ttl' in peer_config:
+                self.assertIn(f' minimum-ttl {peer_config["minimum_ttl"]}', peerconfig)
             if 'intv_echo' in peer_config:
                 self.assertIn(f' echo-interval {peer_config["intv_echo"]}', peerconfig)
             if 'intv_mult' in peer_config:
diff --git a/src/conf_mode/protocols_bfd.py b/src/conf_mode/protocols_bfd.py
index d1e551cad..19076068d 100755
--- a/src/conf_mode/protocols_bfd.py
+++ b/src/conf_mode/protocols_bfd.py
@@ -51,6 +51,7 @@ def get_bfd_peer_config(peer, conf_mode="proposed"):
         'multihop': False,
         'echo_interval': '',
         'echo_mode': False,
+        'minimum_ttl': None,
     }
 
     # Check if individual peer is disabled
@@ -113,6 +114,12 @@ def get_bfd_peer_config(peer, conf_mode="proposed"):
     if conf_mode == "proposed" and conf.exists('echo-mode'):
         bfd_peer['echo_mode'] = True
 
+    # Enables or disables the echo transmission mode
+    if conf_mode == "effective" and conf.exists_effective('minimum-ttl'):
+        bfd_peer['minimum_ttl'] = conf.return_effective_value('minimum-ttl')
+    if conf_mode == "proposed" and conf.exists('minimum-ttl'):
+        bfd_peer['minimum_ttl'] = conf.return_value('minimum-ttl')
+
     return bfd_peer
 
 def get_config():
@@ -173,6 +180,9 @@ def verify(bfd):
         if peer['echo_interval'] != '' and not peer['echo_mode']:
             raise ConfigError('echo-interval can be configured only with enabled echo-mode')
 
+        if peer['minimum_ttl'] != None and peer['multihop'] != True:
+            raise ConfigError('Minimum TTL is only available for multihop BFD sessions!')
+
     # check if we deleted peers are not used in configuration
     if conf.exists('protocols bgp'):
         bgp_as = conf.list_nodes('protocols bgp')[0]
-- 
cgit v1.2.3