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
@@ -1,22 +1,25 @@
 !
 bfd
 {% for peer in old_peers %}
  no peer {{ peer.remote }}{% if peer.multihop %} multihop{% endif %}{% if peer.src_addr %} local-address {{ peer.src_addr }}{% endif %}{% if peer.src_if %} interface {{ peer.src_if }}{% endif %}
 
 {% endfor %}
 !
 {% for peer in new_peers %}
  peer {{ peer.remote }}{% if peer.multihop %} multihop{% endif %}{% if peer.src_addr %} local-address {{ peer.src_addr }}{% endif %}{% if peer.src_if %} interface {{ peer.src_if }}{% endif %}
 
  detect-multiplier {{ peer.multiplier }}
  receive-interval {{ peer.rx_interval }}
  transmit-interval {{ peer.tx_interval }}
 {% 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 %}
  {% if not peer.shutdown %}no {% endif %}shutdown
 {% endfor %}
 !
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
@@ -1,140 +1,152 @@
 <?xml version="1.0"?>
 <!-- Bidirectional Forwarding Detection (BFD) configuration -->
 <interfaceDefinition>
   <node name="protocols">
     <children>
       <node name="bfd" owner="${vyos_conf_scripts_dir}/protocols_bfd.py">
         <properties>
           <help>Bidirectional Forwarding Detection (BFD)</help>
           <priority>820</priority>
         </properties>
         <children>
           <tagNode name="peer">
             <properties>
               <help>Configures a new BFD peer to listen and talk to</help>
               <valueHelp>
                 <format>ipv4</format>
                 <description>BFD peer IPv4 address</description>
               </valueHelp>
               <valueHelp>
                 <format>ipv6</format>
                 <description>BFD peer IPv6 address</description>
               </valueHelp>
               <constraint>
                 <validator name="ipv4-address"/>
                 <validator name="ipv6-address"/>
               </constraint>
             </properties>
             <children>
               <node name="source">
                 <properties>
                   <help>Bind listener to specified interface/address, mandatory for IPv6</help>
                 </properties>
                 <children>
                   <leafNode name="interface">
                     <properties>
                       <help>Local interface to bind our peer listener to</help>
                       <completionHelp>
                         <script>${vyos_completion_dir}/list_interfaces.py</script>
                       </completionHelp>
                     </properties>
                   </leafNode>
                   <leafNode name="address">
                     <properties>
                       <help>Local address to bind our peer listener to</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>Local IPv4 address used to connect to the peer</description>
                       </valueHelp>
                       <valueHelp>
                         <format>ipv6</format>
                         <description>Local IPv6 address used to connect to the peer</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                         <validator name="ipv6-address"/>
                       </constraint>
                     </properties>
                   </leafNode>
                 </children>
               </node>
               <node name="interval">
                 <properties>
                   <help>Configure timer intervals</help>
                 </properties>
                 <children>
                   <leafNode name="receive">
                     <properties>
                       <help>Minimum interval of receiving control packets</help>
                       <valueHelp>
                         <format>10-60000</format>
                         <description>Interval in milliseconds</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 10-60000"/>
                       </constraint>
                     </properties>
                   </leafNode>
                   <leafNode name="transmit">
                     <properties>
                       <help>Minimum interval of transmitting control packets</help>
                       <valueHelp>
                         <format>10-60000</format>
                         <description>Interval in milliseconds</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 10-60000"/>
                       </constraint>
                     </properties>
                   </leafNode>
                   <leafNode name="multiplier">
                     <properties>
                       <help>Multiplier to determine packet loss</help>
                       <valueHelp>
                         <format>2-255</format>
                         <description>Remote transmission interval will be multiplied by this value</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 2-255"/>
                       </constraint>
                     </properties>
                   </leafNode>
                   <leafNode name="echo-interval">
                     <properties>
                       <help>Echo receive transmission interval</help>
                       <valueHelp>
                         <format>10-60000</format>
                         <description>The minimal echo receive transmission interval that this system is capable of handling</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 10-60000"/>
                       </constraint>
                     </properties>
                   </leafNode>
                 </children>
               </node>
               <leafNode name="shutdown">
                 <properties>
                   <help>Disable this peer</help>
                   <valueless/>
                 </properties>
               </leafNode>
               <leafNode name="multihop">
                 <properties>
                   <help>Allow this BFD peer to not be directly connected</help>
                   <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>
                   <valueless/>
                 </properties>
               </leafNode>
             </children>
           </tagNode>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
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
@@ -1,127 +1,132 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2021 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
 
 from vyos.configsession import ConfigSessionError
 from vyos.util import cmd
 from vyos.util import process_named_running
 
 PROCESS_NAME = 'bfdd'
 base_path = ['protocols', 'bfd']
 
 dum_if = 'dum1001'
 neighbor_config = {
     '192.0.2.10' : {
         'intv_rx'    : '500',
         'intv_tx'    : '600',
         'multihop'   : '',
+        'minimum_ttl': '50',
         'source_addr': '192.0.2.254',
         },
     '192.0.2.20' : {
         'echo_mode'  : '',
         'intv_echo'  : '100',
         'intv_mult'  : '111',
         'intv_rx'    : '222',
         'intv_tx'    : '333',
         'shutdown'   : '',
         'source_intf': dum_if,
         },
     '2001:db8::a' : {
         'source_addr': '2001:db8::1',
         'source_intf': dum_if,
         },
     '2001:db8::b' : {
         'source_addr': '2001:db8::1',
         'multihop'   : '',
         },
 }
 
 def getFRRconfig():
     return cmd('vtysh -c "show run" | sed -n "/^bfd/,/^!/p"')
 
 def getBFDPeerconfig(peer):
     return cmd(f'vtysh -c "show run" | sed -n "/^ {peer}/,/^!/p"')
 
 class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
     def setUp(self):
         self.cli_set(['interfaces', 'dummy', dum_if, 'address', '192.0.2.1/24'])
         self.cli_set(['interfaces', 'dummy', dum_if, 'address', '2001:db8::1/64'])
 
     def tearDown(self):
         self.cli_delete(['interfaces', 'dummy', dum_if])
         self.cli_delete(base_path)
         self.cli_commit()
 
         # Check for running process
         self.assertTrue(process_named_running(PROCESS_NAME))
 
     def test_bfd_simple(self):
         for peer, peer_config in neighbor_config.items():
             if 'echo_mode' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'echo-mode'])
             if 'intv_echo' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'interval', 'echo-interval', peer_config["intv_echo"]])
             if 'intv_mult' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'interval', 'multiplier', peer_config["intv_mult"]])
             if 'intv_rx' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'interval', 'receive', peer_config["intv_rx"]])
             if 'intv_tx' in peer_config:
                 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:
                 self.cli_set(base_path + ['peer', peer, 'source', 'address', peer_config["source_addr"]])
             if 'source_intf' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'source', 'interface', peer_config["source_intf"]])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = getFRRconfig()
         for peer, peer_config in neighbor_config.items():
             tmp = f'peer {peer}'
             if 'multihop' in peer_config:
                 tmp += f' multihop'
             if 'source_addr' in peer_config:
                 tmp += f' local-address {peer_config["source_addr"]}'
             if 'source_intf' in peer_config:
                 tmp += f' interface {peer_config["source_intf"]}'
 
             self.assertIn(tmp, frrconfig)
             peerconfig = getBFDPeerconfig(tmp)
 
             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:
                 self.assertIn(f' detect-multiplier {peer_config["intv_mult"]}', peerconfig)
             if 'intv_rx' in peer_config:
                 self.assertIn(f' receive-interval {peer_config["intv_rx"]}', peerconfig)
             if 'intv_tx' in peer_config:
                 self.assertIn(f' transmit-interval {peer_config["intv_tx"]}', peerconfig)
             if 'shutdown' in peer_config:
                 self.assertIn(f' shutdown', peerconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
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
@@ -1,216 +1,226 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2019-2020 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
 from sys import exit
 from copy import deepcopy
 
 from vyos.config import Config
 from vyos.template import is_ipv6
 from vyos.template import render
 from vyos.util import call
 from vyos.validate import is_ipv6_link_local
 from vyos import ConfigError
 from vyos import airbag
 airbag.enable()
 
 config_file = r'/tmp/bfd.frr'
 
 default_config_data = {
     'new_peers': [],
     'old_peers' : []
 }
 
 # get configuration for BFD peer from proposed or effective configuration
 def get_bfd_peer_config(peer, conf_mode="proposed"):
     conf = Config()
     conf.set_level('protocols bfd peer {0}'.format(peer))
 
     bfd_peer = {
         'remote': peer,
         'shutdown': False,
         'src_if': '',
         'src_addr': '',
         'multiplier': '3',
         'rx_interval': '300',
         'tx_interval': '300',
         'multihop': False,
         'echo_interval': '',
         'echo_mode': False,
+        'minimum_ttl': None,
     }
 
     # Check if individual peer is disabled
     if conf_mode == "effective" and conf.exists_effective('shutdown'):
         bfd_peer['shutdown'] = True
     if conf_mode == "proposed" and conf.exists('shutdown'):
         bfd_peer['shutdown'] = True
 
     # Check if peer has a local source interface configured
     if conf_mode == "effective" and conf.exists_effective('source interface'):
         bfd_peer['src_if'] = conf.return_effective_value('source interface')
     if conf_mode == "proposed" and conf.exists('source interface'):
         bfd_peer['src_if'] = conf.return_value('source interface')
 
     # Check if peer has a local source address configured - this is mandatory for IPv6
     if conf_mode == "effective" and conf.exists_effective('source address'):
         bfd_peer['src_addr'] = conf.return_effective_value('source address')
     if conf_mode == "proposed" and conf.exists('source address'):
         bfd_peer['src_addr'] = conf.return_value('source address')
 
     # Tell BFD daemon that we should expect packets with TTL less than 254
     # (because it will take more than one hop) and to listen on the multihop
     # port (4784)
     if conf_mode == "effective" and conf.exists_effective('multihop'):
         bfd_peer['multihop'] = True
     if conf_mode == "proposed" and conf.exists('multihop'):
         bfd_peer['multihop'] = True
 
     # Configures the minimum interval that this system is capable of receiving
     # control packets. The default value is 300 milliseconds.
     if conf_mode == "effective" and conf.exists_effective('interval receive'):
         bfd_peer['rx_interval'] = conf.return_effective_value('interval receive')
     if conf_mode == "proposed" and conf.exists('interval receive'):
         bfd_peer['rx_interval'] = conf.return_value('interval receive')
 
     # The minimum transmission interval (less jitter) that this system wants
     # to use to send BFD control packets.
     if conf_mode == "effective" and conf.exists_effective('interval transmit'):
         bfd_peer['tx_interval'] = conf.return_effective_value('interval transmit')
     if conf_mode == "proposed" and conf.exists('interval transmit'):
         bfd_peer['tx_interval'] = conf.return_value('interval transmit')
 
     # Configures the detection multiplier to determine packet loss. The remote
     # transmission interval will be multiplied by this value to determine the
     # connection loss detection timer. The default value is 3.
     if conf_mode == "effective" and conf.exists_effective('interval multiplier'):
         bfd_peer['multiplier'] = conf.return_effective_value('interval multiplier')
     if conf_mode == "proposed" and conf.exists('interval multiplier'):
         bfd_peer['multiplier'] = conf.return_value('interval multiplier')
 
     # Configures the minimal echo receive transmission interval that this system is capable of handling
     if conf_mode == "effective" and conf.exists_effective('interval echo-interval'):
         bfd_peer['echo_interval'] = conf.return_effective_value('interval echo-interval')
     if conf_mode == "proposed" and conf.exists('interval echo-interval'):
         bfd_peer['echo_interval'] = conf.return_value('interval echo-interval')
 
     # Enables or disables the echo transmission mode
     if conf_mode == "effective" and conf.exists_effective('echo-mode'):
         bfd_peer['echo_mode'] = True
     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():
     bfd = deepcopy(default_config_data)
     conf = Config()
     if not (conf.exists('protocols bfd') or conf.exists_effective('protocols bfd')):
         return None
     else:
         conf.set_level('protocols bfd')
 
     # as we have to use vtysh to talk to FRR we also need to know
     # which peers are gone due to a config removal - thus we read in
     # all peers (active or to delete)
     for peer in conf.list_effective_nodes('peer'):
         bfd['old_peers'].append(get_bfd_peer_config(peer, "effective"))
 
     for peer in conf.list_nodes('peer'):
         bfd['new_peers'].append(get_bfd_peer_config(peer))
 
     # find deleted peers
     set_new_peers = set(conf.list_nodes('peer'))
     set_old_peers = set(conf.list_effective_nodes('peer'))
     bfd['deleted_peers'] = set_old_peers - set_new_peers
 
     return bfd
 
 def verify(bfd):
     if bfd is None:
         return None
 
     # some variables to use later
     conf = Config()
 
     for peer in bfd['new_peers']:
         # IPv6 link local peers require an explicit local address/interface
         if is_ipv6_link_local(peer['remote']):
             if not (peer['src_if'] and peer['src_addr']):
                 raise ConfigError('BFD IPv6 link-local peers require explicit local address and interface setting')
 
         # IPv6 peers require an explicit local address
         if is_ipv6(peer['remote']):
             if not peer['src_addr']:
                 raise ConfigError('BFD IPv6 peers require explicit local address setting')
 
         # multihop require source address
         if peer['multihop'] and not peer['src_addr']:
             raise ConfigError('Multihop require source address')
 
         # multihop and echo-mode cannot be used together
         if peer['multihop'] and peer['echo_mode']:
             raise ConfigError('Multihop and echo-mode cannot be used together')
 
         # multihop doesn't accept interface names
         if peer['multihop'] and peer['src_if']:
             raise ConfigError('Multihop and source interface cannot be used together')
 
         # echo interval can be configured only with enabled echo-mode
         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]
 
         # check BGP neighbors
         for peer in bfd['deleted_peers']:
             if conf.exists('protocols bgp {0} neighbor {1} bfd'.format(bgp_as, peer)):
                 raise ConfigError('Cannot delete BFD peer {0}: it is used in BGP configuration'.format(peer))
             if conf.exists('protocols bgp {0} neighbor {1} peer-group'.format(bgp_as, peer)):
                 peer_group = conf.return_value('protocols bgp {0} neighbor {1} peer-group'.format(bgp_as, peer))
                 if conf.exists('protocols bgp {0} peer-group {1} bfd'.format(bgp_as, peer_group)):
                     raise ConfigError('Cannot delete BFD peer {0}: it belongs to BGP peer-group {1} with enabled BFD'.format(peer, peer_group))
 
     return None
 
 def generate(bfd):
     if bfd is None:
         return None
 
     render(config_file, 'frr/bfd.frr.tmpl', bfd)
     return None
 
 def apply(bfd):
     if bfd is None:
         return None
 
     call("vtysh -d bfdd -f " + config_file)
     if os.path.exists(config_file):
         os.remove(config_file)
 
     return None
 
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
     except ConfigError as e:
         print(e)
         exit(1)