diff --git a/data/templates/frr/daemons.frr.tmpl b/data/templates/frr/daemons.frr.tmpl
index 339b4e52f..3506528d2 100644
--- a/data/templates/frr/daemons.frr.tmpl
+++ b/data/templates/frr/daemons.frr.tmpl
@@ -1,113 +1,113 @@
 #
 # The watchfrr, zebra, mgmtd and staticd daemons are always started.
 #
 # Note: The following FRR-services must be kept disabled because they are replaced by other packages in VyOS:
 #
 # pimd   Replaced by package igmpproxy.
 # nhrpd  Replaced by package opennhrp.
 # pbrd   Replaced by PBR in nftables.
 # vrrpd  Replaced by package keepalived.
 #
 # And these must be disabled aswell since they are currently missing a VyOS CLI:
 #
 # eigrp
 # sharpd
 # fabricd
 # pathd
 #
 # The zebra, mgmtd and staticd daemons are always started and can not be disabled
 #
 #zebra=yes
 #mgmtd=yes
 #staticd=yes
 
 bgpd=yes
 ospfd=yes
 ospf6d=yes
 ripd=yes
 ripngd=yes
 isisd=yes
 pimd=no
 pim6d=yes
 ldpd=yes
 nhrpd=no
 eigrpd=no
 babeld=yes
 sharpd=no
 pbrd=no
 bfdd=yes
-fabricd=no
+fabricd=yes
 vrrpd=no
 pathd=no
 
 #
 # Define defaults for all services even those who shall be kept disabled.
 #
 
 zebra_options="  --daemon -A 127.0.0.1 -s 90000000{{ ' -M snmp' if snmp.zebra is vyos_defined }}{{ ' -M irdp' if irdp is vyos_defined }}"
 mgmtd_options="  --daemon -A 127.0.0.1"
 staticd_options="--daemon -A 127.0.0.1"
 bgpd_options="   --daemon -A 127.0.0.1 -M rpki{{ ' -M snmp' if snmp.bgpd is vyos_defined }}{{ ' -M bmp' if bmp is vyos_defined }}"
 ospfd_options="  --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.ospfd is vyos_defined }}"
 ospf6d_options=" --daemon -A ::1{{ ' -M snmp' if snmp.ospf6d is vyos_defined }}"
 ripd_options="   --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.ripd is vyos_defined }}"
 ripngd_options=" --daemon -A ::1"
 isisd_options="  --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.isisd is vyos_defined }}"
 pimd_options="   --daemon -A 127.0.0.1"
 pim6d_options="  --daemon -A ::1"
 ldpd_options="   --daemon -A 127.0.0.1{{ ' -M snmp' if snmp.ldpd is vyos_defined }}"
 nhrpd_options="  --daemon -A 127.0.0.1"
 eigrpd_options=" --daemon -A 127.0.0.1"
 babeld_options=" --daemon -A 127.0.0.1"
 sharpd_options=" --daemon -A 127.0.0.1"
 pbrd_options="   --daemon -A 127.0.0.1"
 bfdd_options="   --daemon -A 127.0.0.1"
 fabricd_options="--daemon -A 127.0.0.1"
 vrrpd_options="  --daemon -A 127.0.0.1"
 pathd_options="  --daemon -A 127.0.0.1"
 
 #frr_global_options=""
 
 #zebra_wrap=""
 #mgmtd_wrap=""
 #staticd_wrap=""
 #bgpd_wrap=""
 #ospfd_wrap=""
 #ospf6d_wrap=""
 #ripd_wrap=""
 #ripngd_wrap=""
 #isisd_wrap=""
 #pimd_wrap=""
 #pim6d_wrap=""
 #ldpd_wrap=""
 #nhrpd_wrap=""
 #eigrpd_wrap=""
 #babeld_wrap=""
 #sharpd_wrap=""
 #pbrd_wrap=""
 #bfdd_wrap=""
 #fabricd_wrap=""
 #vrrpd_wrap=""
 #pathd_wrap=""
 
 #all_wrap=""
 
 #
 # Other options.
 #
 # For more information see:
 # https://github.com/FRRouting/frr/blob/stable/9.0/tools/etc/frr/daemons
 # https://docs.frrouting.org/en/stable-9.0/setup.html
 #
 
 vtysh_enable=yes
 watchfrr_enable=yes
 valgrind_enable=no
 
 #watchfrr_options=""
 
 frr_profile="traditional"
 
 MAX_FDS={{ descriptors }}
 
 #FRR_NO_ROOT="yes"
diff --git a/data/templates/frr/fabricd.frr.j2 b/data/templates/frr/fabricd.frr.j2
new file mode 100644
index 000000000..8f2ae6466
--- /dev/null
+++ b/data/templates/frr/fabricd.frr.j2
@@ -0,0 +1,72 @@
+!
+{% for name, router_config in domain.items() %}
+{%     if router_config.interface is vyos_defined %}
+{%         for iface, iface_config in router_config.interface.items() %}
+interface {{ iface }}
+{%             if iface_config.address_family.ipv4 is vyos_defined %}
+ ip router openfabric {{ name }}
+{%             endif %}
+{%             if iface_config.address_family.ipv6 is vyos_defined %}
+ ipv6 router openfabric {{ name }}
+{%             endif %}
+{%             if iface_config.csnp_interval is vyos_defined %}
+ openfabric csnp-interval {{ iface_config.csnp_interval }}
+{%             endif %}
+{%             if iface_config.hello_interval is vyos_defined %}
+ openfabric hello-interval {{ iface_config.hello_interval }}
+{%             endif %}
+{%             if iface_config.hello_multiplier is vyos_defined %}
+ openfabric hello-multiplier {{ iface_config.hello_multiplier }}
+{%             endif %}
+{%             if iface_config.metric is vyos_defined %}
+ openfabric metric {{ iface_config.metric }}
+{%             endif %}
+{%             if iface_config.passive is vyos_defined or iface == 'lo' %}
+ openfabric passive
+{%             endif %}
+{%             if iface_config.password.md5 is vyos_defined %}
+ openfabric password md5 {{ iface_config.password.md5 }}
+{%             elif iface_config.password.plaintext_password is vyos_defined %}
+ openfabric password clear {{ iface_config.password.plaintext_password }}
+{%             endif %}
+{%             if iface_config.psnp_interval is vyos_defined %}
+ openfabric psnp-interval {{ iface_config.psnp_interval }}
+{%             endif %}
+exit
+!
+{%         endfor %}
+{%     endif %}
+router openfabric {{ name }}
+ net {{ net }}
+{%     if router_config.domain_password.md5 is vyos_defined %}
+ domain-password md5 {{ router_config.domain_password.plaintext_password }}
+{%     elif router_config.domain_password.plaintext_password is vyos_defined %}
+ domain-password clear {{ router_config.domain_password.plaintext_password }}
+{%     endif %}
+{%     if router_config.log_adjacency_changes is vyos_defined %}
+ log-adjacency-changes
+{%     endif %}
+{%     if router_config.set_overload_bit is vyos_defined %}
+ set-overload-bit
+{%     endif %}
+{%     if router_config.purge_originator is vyos_defined %}
+ purge-originator
+{%     endif %}
+{%     if router_config.fabric_tier is vyos_defined %}
+ fabric-tier {{ router_config.fabric_tier }}
+{%     endif %}
+{%     if router_config.lsp_gen_interval is vyos_defined %}
+ lsp-gen-interval {{ router_config.lsp_gen_interval }}
+{%     endif %}
+{%     if router_config.lsp_refresh_interval is vyos_defined %}
+ lsp-refresh-interval  {{ router_config.lsp_refresh_interval }}
+{%     endif %}
+{%     if router_config.max_lsp_lifetime is vyos_defined %}
+ max-lsp-lifetime {{ router_config.max_lsp_lifetime }}
+{%     endif %}
+{%     if router_config.spf_interval is vyos_defined %}
+ spf-interval {{ router_config.spf_interval }}
+{%     endif %}
+exit
+!
+{% endfor %}
diff --git a/interface-definitions/include/isis/protocol-common-config.xml.i b/interface-definitions/include/isis/protocol-common-config.xml.i
index 0e79ca5f2..35ce80be9 100644
--- a/interface-definitions/include/isis/protocol-common-config.xml.i
+++ b/interface-definitions/include/isis/protocol-common-config.xml.i
@@ -1,745 +1,729 @@
 <!-- include start from isis/protocol-common-config.xml.i -->
 <leafNode name="advertise-high-metrics">
   <properties>
     <help>Advertise high metric value on all interfaces</help>
     <valueless/>
   </properties>
 </leafNode>
 <leafNode name="advertise-passive-only">
   <properties>
     <help>Advertise prefixes of passive interfaces only</help>
     <valueless/>
   </properties>
 </leafNode>
 <node name="area-password">
   <properties>
     <help>Configure the authentication password for an area</help>
   </properties>
   <children>
     #include <include/isis/password.xml.i>
   </children>
 </node>
 <node name="default-information">
   <properties>
     <help>Control distribution of default information</help>
   </properties>
   <children>
     <node name="originate">
       <properties>
         <help>Distribute a default route</help>
       </properties>
       <children>
         <node name="ipv4">
           <properties>
             <help>Distribute default route for IPv4</help>
           </properties>
           <children>
             #include <include/isis/default-information-level.xml.i>
           </children>
         </node>
         <node name="ipv6">
           <properties>
             <help>Distribute default route for IPv6</help>
           </properties>
           <children>
             #include <include/isis/default-information-level.xml.i>
           </children>
         </node>
       </children>
     </node>
   </children>
 </node>
 <node name="domain-password">
   <properties>
     <help>Set the authentication password for a routing domain</help>
   </properties>
   <children>
     #include <include/isis/password.xml.i>
   </children>
 </node>
 <leafNode name="dynamic-hostname">
   <properties>
     <help>Dynamic hostname for IS-IS</help>
     <valueless/>
   </properties>
 </leafNode>
 <leafNode name="level">
   <properties>
     <help>IS-IS level number</help>
     <completionHelp>
       <list>level-1 level-1-2 level-2</list>
     </completionHelp>
     <valueHelp>
       <format>level-1</format>
       <description>Act as a station router</description>
     </valueHelp>
     <valueHelp>
       <format>level-1-2</format>
       <description>Act as both a station and an area router</description>
     </valueHelp>
     <valueHelp>
       <format>level-2</format>
       <description>Act as an area router</description>
     </valueHelp>
     <constraint>
       <regex>(level-1|level-1-2|level-2)</regex>
     </constraint>
   </properties>
 </leafNode>
-<leafNode name="log-adjacency-changes">
-  <properties>
-    <help>Log adjacency state changes</help>
-    <valueless/>
-  </properties>
-</leafNode>
+#include <include/log-adjacency-changes.xml.i>
 <leafNode name="lsp-gen-interval">
   <properties>
     <help>Minimum interval between regenerating same LSP</help>
     <valueHelp>
       <format>u32:1-120</format>
       <description>Minimum interval in seconds</description>
     </valueHelp>
     <constraint>
       <validator name="numeric" argument="--range 1-120"/>
     </constraint>
   </properties>
 </leafNode>
 <leafNode name="lsp-mtu">
   <properties>
     <help>Configure the maximum size of generated LSPs</help>
     <valueHelp>
       <format>u32:128-4352</format>
       <description>Maximum size of generated LSPs</description>
     </valueHelp>
     <constraint>
       <validator name="numeric" argument="--range 128-4352"/>
     </constraint>
   </properties>
   <defaultValue>1497</defaultValue>
 </leafNode>
 <leafNode name="lsp-refresh-interval">
   <properties>
     <help>LSP refresh interval</help>
     <valueHelp>
       <format>u32:1-65235</format>
       <description>LSP refresh interval in seconds</description>
     </valueHelp>
     <constraint>
       <validator name="numeric" argument="--range 1-65235"/>
     </constraint>
   </properties>
 </leafNode>
 <leafNode name="max-lsp-lifetime">
   <properties>
     <help>Maximum LSP lifetime</help>
     <valueHelp>
       <format>u32:350-65535</format>
       <description>LSP lifetime in seconds</description>
     </valueHelp>
     <constraint>
       <validator name="numeric" argument="--range 1-65535"/>
     </constraint>
   </properties>
 </leafNode>
 <leafNode name="metric-style">
   <properties>
     <help>Use old-style (ISO 10589) or new-style packet formats</help>
     <completionHelp>
       <list>narrow transition wide</list>
     </completionHelp>
     <valueHelp>
       <format>narrow</format>
       <description>Use old style of TLVs with narrow metric</description>
     </valueHelp>
     <valueHelp>
       <format>transition</format>
       <description>Send and accept both styles of TLVs during transition</description>
     </valueHelp>
     <valueHelp>
       <format>wide</format>
       <description>Use new style of TLVs to carry wider metric</description>
     </valueHelp>
     <constraint>
       <regex>(narrow|transition|wide)</regex>
     </constraint>
   </properties>
 </leafNode>
 #include <include/isis/ldp-sync-protocol.xml.i>
 <leafNode name="topology">
   <properties>
     <help>Configure IS-IS topologies</help>
     <completionHelp>
       <list>ipv4-multicast ipv4-mgmt ipv6-unicast ipv6-multicast ipv6-mgmt ipv6-dstsrc</list>
     </completionHelp>
     <valueHelp>
       <format>ipv4-multicast</format>
       <description>Use IPv4 multicast topology</description>
     </valueHelp>
     <valueHelp>
       <format>ipv4-mgmt</format>
       <description>Use IPv4 management topology</description>
     </valueHelp>
     <valueHelp>
       <format>ipv6-unicast</format>
       <description>Use IPv6 unicast topology</description>
     </valueHelp>
     <valueHelp>
       <format>ipv6-multicast</format>
       <description>Use IPv6 multicast topology</description>
     </valueHelp>
     <valueHelp>
       <format>ipv6-mgmt</format>
       <description>Use IPv6 management topology</description>
     </valueHelp>
     <valueHelp>
       <format>ipv6-dstsrc</format>
       <description>Use IPv6 dst-src topology</description>
     </valueHelp>
     <constraint>
       <regex>(ipv4-multicast|ipv4-mgmt|ipv6-unicast|ipv6-multicast|ipv6-mgmt|ipv6-dstsrc)</regex>
     </constraint>
   </properties>
 </leafNode>
 <node name="fast-reroute">
   <properties>
     <help>IS-IS fast reroute configuration</help>
   </properties>
   <children>
     #include <include/isis/lfa-protocol.xml.i>
   </children>
 </node>
-<leafNode name="net">
-  <properties>
-    <help>A Network Entity Title for this process (ISO only)</help>
-    <valueHelp>
-      <format>XX.XXXX. ... .XXX.XX</format>
-      <description>Network entity title (NET)</description>
-    </valueHelp>
-    <constraint>
-      <regex>[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}</regex>
-    </constraint>
-  </properties>
-</leafNode>
+#include <include/net.xml.i>
 <leafNode name="purge-originator">
   <properties>
     <help>Use the RFC 6232 purge-originator</help>
     <valueless/>
   </properties>
 </leafNode>
 <node name="traffic-engineering">
   <properties>
     <help>IS-IS traffic engineering extensions</help>
   </properties>
   <children>
     <leafNode name="enable">
       <properties>
         <help>Enable MPLS traffic engineering extensions</help>
         <valueless/>
       </properties>
     </leafNode>
 <!--
     <node name="inter-as">
       <properties>
         <help>MPLS traffic engineering inter-AS support</help>
       </properties>
       <children>
         <leafNode name="level-1">
           <properties>
             <help>Area native mode self originate inter-AS LSP with L1 only flooding scope</help>
             <valueless/>
           </properties>
         </leafNode>
         <leafNode name="level-1-2">
           <properties>
             <help>Area native mode self originate inter-AS LSP with L1 and L2 flooding scope</help>
             <valueless/>
           </properties>
         </leafNode>
         <leafNode name="level-2">
           <properties>
             <help>Area native mode self originate inter-AS LSP with L2 only flooding scope</help>
             <valueless/>
           </properties>
         </leafNode>
       </children>
     </node>
     <leafNode name="inter-as">
       <properties>
         <help>MPLS traffic engineering inter-AS support</help>
         <valueless/>
       </properties>
     </leafNode>
 -->
     <leafNode name="address">
       <properties>
         <help>MPLS traffic engineering router ID</help>
         <valueHelp>
           <format>ipv4</format>
           <description>IPv4 address</description>
         </valueHelp>
         <constraint>
           <validator name="ipv4-address"/>
         </constraint>
       </properties>
     </leafNode>
   </children>
 </node>
 <node name="segment-routing">
   <properties>
     <help>Segment-Routing (SPRING) settings</help>
   </properties>
   <children>
     <node name="global-block">
       <properties>
         <help>Segment Routing Global Block label range</help>
       </properties>
       <children>
         #include <include/segment-routing-label-value.xml.i>
       </children>
     </node>
     <node name="local-block">
       <properties>
         <help>Segment Routing Local Block label range</help>
       </properties>
       <children>
         #include <include/segment-routing-label-value.xml.i>
       </children>
     </node>
     <leafNode name="maximum-label-depth">
       <properties>
         <help>Maximum MPLS labels allowed for this router</help>
         <valueHelp>
           <format>u32:1-16</format>
             <description>MPLS label depth</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 1-16"/>
         </constraint>
       </properties>
     </leafNode>
     <tagNode name="prefix">
       <properties>
         <help>Static IPv4/IPv6 prefix segment/label mapping</help>
         <valueHelp>
           <format>ipv4net</format>
           <description>IPv4 prefix segment</description>
         </valueHelp>
         <valueHelp>
           <format>ipv6net</format>
           <description>IPv6 prefix segment</description>
         </valueHelp>
         <constraint>
           <validator name="ipv4-prefix"/>
           <validator name="ipv6-prefix"/>
         </constraint>
       </properties>
       <children>
         <node name="absolute">
           <properties>
             <help>Specify the absolute value of prefix segment/label ID</help>
           </properties>
           <children>
             <leafNode name="value">
               <properties>
                 <help>Specify the absolute value of prefix segment/label ID</help>
                 <valueHelp>
                   <format>u32:16-1048575</format>
                     <description>The absolute segment/label ID value</description>
                 </valueHelp>
                 <constraint>
                   <validator name="numeric" argument="--range 16-1048575"/>
                 </constraint>
               </properties>
             </leafNode>
             <leafNode name="explicit-null">
               <properties>
                 <help>Request upstream neighbor to replace segment/label with explicit null label</help>
                 <valueless/>
               </properties>
             </leafNode>
             <leafNode name="no-php-flag">
               <properties>
                 <help>Do not request penultimate hop popping for segment/label</help>
                 <valueless/>
               </properties>
             </leafNode>
           </children>
         </node>
         <node name="index">
           <properties>
             <help>Specify the index value of prefix segment/label ID</help>
           </properties>
           <children>
             <leafNode name="value">
               <properties>
                 <help>Specify the index value of prefix segment/label ID</help>
                 <valueHelp>
                   <format>u32:0-65535</format>
                     <description>The index segment/label ID value</description>
                 </valueHelp>
                 <constraint>
                   <validator name="numeric" argument="--range 0-65535"/>
                 </constraint>
               </properties>
             </leafNode>
             <leafNode name="explicit-null">
               <properties>
                 <help>Request upstream neighbor to replace segment/label with explicit null label</help>
                 <valueless/>
               </properties>
             </leafNode>
             <leafNode name="no-php-flag">
               <properties>
                 <help>Do not request penultimate hop popping for segment/label</help>
                 <valueless/>
               </properties>
             </leafNode>
           </children>
         </node>
       </children>
     </tagNode>
   </children>
 </node>
 <node name="redistribute">
   <properties>
     <help>Redistribute information from another routing protocol</help>
   </properties>
   <children>
     <node name="ipv4">
       <properties>
         <help>Redistribute IPv4 routes</help>
       </properties>
       <children>
         <node name="bgp">
           <properties>
             <help>Border Gateway Protocol (BGP)</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="connected">
           <properties>
             <help>Redistribute connected routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="kernel">
           <properties>
             <help>Redistribute kernel routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="ospf">
           <properties>
             <help>Redistribute OSPF routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="rip">
           <properties>
             <help>Redistribute RIP routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="babel">
           <properties>
             <help>Redistribute Babel routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="static">
           <properties>
             <help>Redistribute static routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
       </children>
     </node>
     <node name="ipv6">
       <properties>
         <help>Redistribute IPv6 routes</help>
       </properties>
       <children>
         <node name="bgp">
           <properties>
             <help>Redistribute BGP routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="connected">
           <properties>
             <help>Redistribute connected routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="kernel">
           <properties>
             <help>Redistribute kernel routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="ospf6">
           <properties>
             <help>Redistribute OSPFv3 routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="ripng">
           <properties>
             <help>Redistribute RIPng routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="babel">
           <properties>
             <help>Redistribute Babel routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
         <node name="static">
           <properties>
             <help>Redistribute static routes into IS-IS</help>
           </properties>
           <children>
             #include <include/isis/redistribute-level-1-2.xml.i>
           </children>
         </node>
       </children>
     </node>
   </children>
 </node>
 <leafNode name="set-attached-bit">
   <properties>
     <help>Set attached bit to identify as L1/L2 router for inter-area traffic</help>
     <valueless/>
   </properties>
 </leafNode>
 <leafNode name="set-overload-bit">
   <properties>
     <help>Set overload bit to avoid any transit traffic</help>
     <valueless/>
   </properties>
 </leafNode>
 <node name="spf-delay-ietf">
   <properties>
     <help>IETF SPF delay algorithm</help>
   </properties>
   <children>
     <leafNode name="init-delay">
       <properties>
         <help>Delay used while in QUIET state</help>
         <valueHelp>
           <format>u32:0-60000</format>
           <description>Delay used while in QUIET state (in ms)</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 0-60000"/>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="short-delay">
       <properties>
         <help>Delay used while in SHORT_WAIT state</help>
         <valueHelp>
           <format>u32:0-60000</format>
           <description>Delay used while in SHORT_WAIT state (in ms)</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 0-60000"/>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="long-delay">
       <properties>
         <help>Delay used while in LONG_WAIT</help>
         <valueHelp>
           <format>u32:0-60000</format>
           <description>Delay used while in LONG_WAIT state in ms</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 0-60000"/>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="holddown">
       <properties>
         <help>Time with no received IGP events before considering IGP stable</help>
         <valueHelp>
           <format>u32:0-60000</format>
           <description>Time with no received IGP events before considering IGP stable in ms</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 0-60000"/>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="time-to-learn">
       <properties>
         <help>Maximum duration needed to learn all the events related to a single failure</help>
         <valueHelp>
           <format>u32:0-60000</format>
           <description>Maximum duration needed to learn all the events related to a single failure in ms</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 0-60000"/>
         </constraint>
       </properties>
     </leafNode>
   </children>
 </node>
 <leafNode name="spf-interval">
   <properties>
     <help>Minimum interval between SPF calculations</help>
     <valueHelp>
       <format>u32:1-120</format>
       <description>Interval in seconds</description>
     </valueHelp>
     <constraint>
       <validator name="numeric" argument="--range 1-120"/>
     </constraint>
   </properties>
 </leafNode>
 <tagNode name="interface">
   <properties>
     <help>Interface params</help>
     <completionHelp>
       <script>${vyos_completion_dir}/list_interfaces</script>
     </completionHelp>
   </properties>
   <children>
     #include <include/bfd/bfd.xml.i>
     <leafNode name="circuit-type">
       <properties>
         <help>Configure circuit type for interface</help>
         <completionHelp>
           <list>level-1 level-1-2 level-2-only</list>
         </completionHelp>
         <valueHelp>
           <format>level-1</format>
           <description>Level-1 only adjacencies are formed</description>
         </valueHelp>
         <valueHelp>
           <format>level-1-2</format>
           <description>Level-1-2 adjacencies are formed</description>
         </valueHelp>
         <valueHelp>
           <format>level-2-only</format>
           <description>Level-2 only adjacencies are formed</description>
         </valueHelp>
         <constraint>
           <regex>(level-1|level-1-2|level-2-only)</regex>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="hello-padding">
       <properties>
         <help>Add padding to IS-IS hello packets</help>
         <valueless/>
       </properties>
     </leafNode>
     <leafNode name="hello-interval">
       <properties>
         <help>Set Hello interval</help>
         <valueHelp>
           <format>u32:1-600</format>
           <description>Set Hello interval</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 1-600"/>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="hello-multiplier">
       <properties>
         <help>Set Hello interval</help>
         <valueHelp>
           <format>u32:2-100</format>
           <description>Set multiplier for Hello holding time</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 2-100"/>
         </constraint>
       </properties>
     </leafNode>
     #include <include/isis/metric.xml.i>
     #include <include/isis/ldp-sync-interface.xml.i>
     <node name="network">
       <properties>
         <help>Set network type</help>
       </properties>
       <children>
         <leafNode name="point-to-point">
           <properties>
             <help>point-to-point network type</help>
             <valueless/>
           </properties>
         </leafNode>
       </children>
     </node>
     #include <include/isis/passive.xml.i>
     <node name="password">
       <properties>
         <help>Configure the authentication password for a circuit</help>
       </properties>
       <children>
         #include <include/isis/password.xml.i>
       </children>
     </node>
     <leafNode name="priority">
       <properties>
         <help>Set priority for Designated Router election</help>
         <valueHelp>
           <format>u32:0-127</format>
           <description>Priority value</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 0-127"/>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="psnp-interval">
       <properties>
         <help>Set PSNP interval</help>
         <valueHelp>
           <format>u32:0-127</format>
           <description>PSNP interval in seconds</description>
         </valueHelp>
         <constraint>
           <validator name="numeric" argument="--range 0-127"/>
         </constraint>
       </properties>
     </leafNode>
     <leafNode name="no-three-way-handshake">
       <properties>
         <help>Disable three-way handshake</help>
         <valueless/>
       </properties>
     </leafNode>
   </children>
 </tagNode>
 <!-- include end -->
diff --git a/interface-definitions/include/log-adjacency-changes.xml.i b/interface-definitions/include/log-adjacency-changes.xml.i
new file mode 100644
index 000000000..a0628b8e2
--- /dev/null
+++ b/interface-definitions/include/log-adjacency-changes.xml.i
@@ -0,0 +1,8 @@
+<!-- include start from log-adjacency-changes.xml.i -->
+<leafNode name="log-adjacency-changes">
+  <properties>
+    <help>Log changes in adjacency state</help>
+    <valueless/>
+  </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/net.xml.i b/interface-definitions/include/net.xml.i
new file mode 100644
index 000000000..10b54ee49
--- /dev/null
+++ b/interface-definitions/include/net.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from net.xml.i -->
+<leafNode name="net">
+  <properties>
+    <help>A Network Entity Title for the process (ISO only)</help>
+    <valueHelp>
+      <format>XX.XXXX. ... .XXX.XX</format>
+      <description>Network entity title (NET)</description>
+    </valueHelp>
+    <constraint>
+      <regex>[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}</regex>
+    </constraint>
+  </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/openfabric/password.xml.i b/interface-definitions/include/openfabric/password.xml.i
new file mode 100644
index 000000000..fa34a4dab
--- /dev/null
+++ b/interface-definitions/include/openfabric/password.xml.i
@@ -0,0 +1,20 @@
+<!-- include start from openfabric/password.xml.i -->
+<leafNode name="plaintext-password">
+  <properties>
+    <help>Use plain text password</help>
+    <valueHelp>
+      <format>txt</format>
+      <description>Authentication password</description>
+    </valueHelp>
+  </properties>
+</leafNode>
+<leafNode name="md5">
+  <properties>
+    <help>Use MD5 hash authentication</help>
+    <valueHelp>
+      <format>txt</format>
+      <description>Authentication password</description>
+    </valueHelp>
+  </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/protocols_openfabric.xml.in b/interface-definitions/protocols_openfabric.xml.in
new file mode 100644
index 000000000..81200360e
--- /dev/null
+++ b/interface-definitions/protocols_openfabric.xml.in
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interfaceDefinition>
+  <node name="protocols">
+    <children>
+      <node name="openfabric" owner="${vyos_conf_scripts_dir}/protocols_openfabric.py">
+        <properties>
+          <help>OpenFabric protocol</help>
+          <priority>680</priority>
+        </properties>
+        <children>
+          #include <include/net.xml.i>
+          <tagNode name="domain">
+            <properties>
+              <help>OpenFabric process name</help>
+              <valueHelp>
+                <format>txt</format>
+                <description>Domain name</description>
+              </valueHelp>
+            </properties>
+            <children>
+              <tagNode name="interface">
+                <properties>
+                  <help>Interface params</help>
+                  <completionHelp>
+                    <script>${vyos_completion_dir}/list_interfaces</script>
+                  </completionHelp>
+                  <valueHelp>
+                    <format>txt</format>
+                    <description>Interface name</description>
+                  </valueHelp>
+                  <constraint>
+                    #include <include/constraint/interface-name.xml.i>
+                  </constraint>
+                </properties>
+                <children>
+                  <node name="address-family">
+                    <properties>
+                      <help>Openfabric address family</help>
+                    </properties>
+                    <children>
+                      <leafNode name="ipv4">
+                        <properties>
+                          <help>IPv4 OpenFabric</help>
+                          <valueless/>
+                        </properties>
+                      </leafNode>
+                      <leafNode name="ipv6">
+                        <properties>
+                          <help>IPv6 OpenFabric</help>
+                          <valueless/>
+                        </properties>
+                      </leafNode>
+                    </children>
+                  </node>
+                  <leafNode name="csnp-interval">
+                    <properties>
+                      <help>Complete Sequence Number Packets (CSNP) interval</help>
+                      <valueHelp>
+                        <format>u32:1-600</format>
+                        <description>CSNP interval in seconds</description>
+                      </valueHelp>
+                      <constraint>
+                        <validator name="numeric" argument="--range 1-600"/>
+                      </constraint>
+                    </properties>
+                  </leafNode>
+                  <leafNode name="hello-interval">
+                    <properties>
+                      <help>Hello interval</help>
+                      <valueHelp>
+                        <format>u32:1-600</format>
+                        <description>Hello interval in seconds</description>
+                      </valueHelp>
+                      <constraint>
+                        <validator name="numeric" argument="--range 1-600"/>
+                      </constraint>
+                    </properties>
+                  </leafNode>
+                  <leafNode name="hello-multiplier">
+                    <properties>
+                      <help>Multiplier for Hello holding time</help>
+                      <valueHelp>
+                        <format>u32:2-100</format>
+                        <description>Multiplier for Hello holding time</description>
+                      </valueHelp>
+                      <constraint>
+                        <validator name="numeric" argument="--range 2-100"/>
+                      </constraint>
+                    </properties>
+                  </leafNode>
+                  <leafNode name="metric">
+                    <properties>
+                      <help>Interface metric value</help>
+                      <valueHelp>
+                        <format>u32:0-16777215</format>
+                        <description>Interface metric value</description>
+                      </valueHelp>
+                      <constraint>
+                        <validator name="numeric" argument="--range 0-16777215"/>
+                      </constraint>
+                    </properties>
+                  </leafNode>
+                  <leafNode name="passive">
+                    <properties>
+                      <help>Do not initiate adjacencies to the interface</help>
+                      <valueless/>
+                    </properties>
+                  </leafNode>
+                  <node name="password">
+                    <properties>
+                      <help>Authentication password for the interface</help>
+                    </properties>
+                    <children>
+                      #include <include/openfabric/password.xml.i>
+                    </children>
+                  </node>
+                  <leafNode name="psnp-interval">
+                    <properties>
+                      <help>Partial Sequence Number Packets (PSNP) interval</help>
+                      <valueHelp>
+                        <format>u32:0-120</format>
+                        <description>PSNP interval in seconds</description>
+                      </valueHelp>
+                      <constraint>
+                        <validator name="numeric" argument="--range 0-120"/>
+                      </constraint>
+                    </properties>
+                  </leafNode>
+                </children>
+              </tagNode>
+              <node name="domain-password">
+                <properties>
+                  <help>Authentication password for a routing domain</help>
+                </properties>
+                <children>
+                  #include <include/openfabric/password.xml.i>
+                </children>
+              </node>
+              #include <include/log-adjacency-changes.xml.i>
+              <leafNode name="set-overload-bit">
+                <properties>
+                  <help>Overload bit to avoid any transit traffic</help>
+                  <valueless/>
+                </properties>
+              </leafNode>
+              <leafNode name="purge-originator">
+                <properties>
+                  <help>RFC 6232 purge originator identification</help>
+                  <valueless/>
+                </properties>
+              </leafNode>
+              <leafNode name="fabric-tier">
+                <properties>
+                  <help>Static tier number to advertise as location in the fabric</help>
+                  <valueHelp>
+                    <format>u32:0-14</format>
+                    <description>Static tier number</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 0-14"/>
+                  </constraint>
+                </properties>
+              </leafNode>
+              <leafNode name="lsp-gen-interval">
+                <properties>
+                  <help>Minimum interval between regenerating same link-state packet (LSP)</help>
+                  <valueHelp>
+                    <format>u32:1-120</format>
+                    <description>Minimum interval in seconds</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 1-120"/>
+                  </constraint>
+                </properties>
+              </leafNode>
+              <leafNode name="lsp-refresh-interval">
+                <properties>
+                  <help>Link-state packet (LSP) refresh interval</help>
+                  <valueHelp>
+                    <format>u32:1-65235</format>
+                    <description>LSP refresh interval in seconds</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 1-65235"/>
+                  </constraint>
+                </properties>
+              </leafNode>
+              <leafNode name="max-lsp-lifetime">
+                <properties>
+                  <help>Maximum link-state packet lifetime</help>
+                  <valueHelp>
+                    <format>u32:360-65535</format>
+                    <description>Maximum LSP lifetime in seconds</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 360-65535"/>
+                  </constraint>
+                </properties>
+              </leafNode>
+              <leafNode name="spf-interval">
+                <properties>
+                  <help>Minimum interval between SPF calculations</help>
+                  <valueHelp>
+                    <format>u32:1-120</format>
+                    <description>Interval in seconds</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 1-120"/>
+                  </constraint>
+                </properties>
+              </leafNode>
+            </children>
+          </tagNode>
+        </children>
+      </node>
+    </children>
+  </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/include/show-route-openfabric.xml.i b/op-mode-definitions/include/show-route-openfabric.xml.i
new file mode 100644
index 000000000..ae1ef380e
--- /dev/null
+++ b/op-mode-definitions/include/show-route-openfabric.xml.i
@@ -0,0 +1,8 @@
+<!-- included start from show-route-openfabric.xml.i -->
+<leafNode name="openfabric">
+  <properties>
+    <help>OpenFabric routes</help>
+  </properties>
+  <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<!-- included end -->
diff --git a/op-mode-definitions/monitor-log.xml.in b/op-mode-definitions/monitor-log.xml.in
index a2d5d924a..6a2b7e53b 100644
--- a/op-mode-definitions/monitor-log.xml.in
+++ b/op-mode-definitions/monitor-log.xml.in
@@ -1,407 +1,413 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="monitor">
     <properties>
       <help>Monitor system information</help>
     </properties>
     <children>
       <node name="log">
         <properties>
           <help>Monitor last lines of messages file</help>
         </properties>
         <command>SYSTEMD_LOG_COLOR=false journalctl --no-hostname --follow --boot</command>
         <children>
           <node name="color">
             <properties>
               <help>Output log in a colored fashion</help>
             </properties>
             <command>SYSTEMD_LOG_COLOR=false grc journalctl --no-hostname --follow --boot</command>
           </node>
           <node name="ids">
             <properties>
               <help>Monitor Intrusion Detection System log</help>
             </properties>
             <children>
               <leafNode name="ddos-protection">
                 <properties>
                   <help>Monitor last lines of DDOS protection</help>
                 </properties>
                 <command>journalctl --no-hostname --follow --boot --unit fastnetmon.service</command>
               </leafNode>
             </children>
           </node>
           <leafNode name="certbot">
             <properties>
               <help>Monitor last lines of certbot log</help>
             </properties>
             <command>if sudo test -f /var/log/letsencrypt/letsencrypt.log; then sudo tail --follow=name /var/log/letsencrypt/letsencrypt.log; else echo "Cerbot log does not exist"; fi</command>
           </leafNode>
           <leafNode name="conntrack-sync">
             <properties>
               <help>Monitor last lines of conntrack-sync log</help>
             </properties>
             <command>journalctl --no-hostname --follow --boot --unit conntrackd.service</command>
           </leafNode>
           <leafNode name="console-server">
             <properties>
               <help>Monitor last lines of console server log</help>
             </properties>
             <command>journalctl --no-hostname --follow --boot --unit conserver-server.service</command>
           </leafNode>
           <node name="dhcp">
             <properties>
               <help>Monitor last lines of Dynamic Host Control Protocol log</help>
             </properties>
             <children>
               <node name="server">
                 <properties>
                   <help>Monitor last lines of DHCP server log</help>
                 </properties>
                 <command>journalctl --no-hostname --follow --boot --unit kea-dhcp4-server.service</command>
               </node>
               <node name="client">
                 <properties>
                   <help>Monitor last lines of DHCP client log</help>
                 </properties>
                 <command>journalctl --no-hostname --follow --boot --unit "dhclient@*.service"</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Show DHCP client log on specific interface</help>
                       <completionHelp>
                         <script>${vyos_completion_dir}/list_interfaces --broadcast</script>
                       </completionHelp>
                     </properties>
                     <command>journalctl --no-hostname --follow --boot --unit "dhclient@$6.service"</command>
                   </tagNode>
                 </children>
               </node>
             </children>
           </node>
           <node name="dhcpv6">
             <properties>
               <help>Monitor last lines of Dynamic Host Control Protocol IPv6 log</help>
             </properties>
             <children>
               <node name="server">
                 <properties>
                   <help>Monitor last lines of DHCPv6 server log</help>
                 </properties>
                 <command>journalctl --no-hostname --follow --boot --unit kea-dhcp6-server.service</command>
               </node>
               <node name="client">
                 <properties>
                   <help>Monitor last lines of DHCPv6 client log</help>
                 </properties>
                 <command>journalctl --no-hostname --follow --boot --unit "dhcp6c@*.service"</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Show DHCPv6 client log on specific interface</help>
                       <completionHelp>
                         <script>${vyos_completion_dir}/list_interfaces</script>
                       </completionHelp>
                     </properties>
                     <command>journalctl --no-hostname --follow --boot --unit "dhcp6c@$6.service"</command>
                   </tagNode>
                 </children>
               </node>
             </children>
           </node>
           <leafNode name="flow-accounting">
             <properties>
               <help>Monitor last lines of flow-accounting log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit uacctd.service</command>
           </leafNode>
           <leafNode name="ipoe-server">
             <properties>
               <help>Monitor last lines of IP over Ethernet server log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit accel-ppp@ipoe.service</command>
           </leafNode>
           <leafNode name="kernel">
             <properties>
               <help>Monitor last lines of Linux Kernel log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --dmesg</command>
           </leafNode>
           <leafNode name="ndp-proxy">
             <properties>
               <help>Monitor last lines of Neighbor Discovery Protocol (NDP) Proxy</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit ndppd.service</command>
           </leafNode>
           <leafNode name="nhrp">
             <properties>
               <help>Monitor last lines of Next Hop Resolution Protocol log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit opennhrp.service</command>
           </leafNode>
           <leafNode name="ntp">
             <properties>
               <help>Monitor last lines of Network Time Protocol log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit chrony.service</command>
           </leafNode>
           <node name="openvpn">
             <properties>
               <help>Monitor last lines of OpenVPN log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit openvpn@*.service</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Monitor last lines of specific OpenVPN interface log</help>
                   <completionHelp>
                     <path>interfaces openvpn</path>
                   </completionHelp>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit openvpn@$5.service</command>
               </tagNode>
             </children>
           </node>
           <node name="pppoe">
             <properties>
               <help>Monitor last lines of PPPoE interface log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit "ppp@pppoe*.service"</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Monitor last lines of PPPoE log for specific interface</help>
                   <completionHelp>
                     <path>interfaces pppoe</path>
                   </completionHelp>
                 </properties>
                 <command>journalctl --no-hostname --boot --follow --unit "ppp@$5.service"</command>
               </tagNode>
             </children>
           </node>
           <leafNode name="pppoe-server">
             <properties>
               <help>Monitor last lines of PPPoE server log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit accel-ppp@pppoe.service</command>
           </leafNode>
           <node name="protocol">
             <properties>
               <help>Monitor routing protocol logs</help>
             </properties>
             <children>
               <leafNode name="ospf">
                 <properties>
                   <help>Monitor log for OSPF</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ospfd</command>
               </leafNode>
               <leafNode name="ospfv3">
                 <properties>
                   <help>Monitor log for OSPF for IPv6</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ospf6d</command>
               </leafNode>
               <leafNode name="bgp">
                 <properties>
                   <help>Monitor log for BGP</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/bgpd</command>
               </leafNode>
               <leafNode name="rip">
                 <properties>
                   <help>Monitor log for RIP</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ripd</command>
               </leafNode>
               <leafNode name="ripng">
                 <properties>
                   <help>Monitor log for RIPng</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ripngd</command>
               </leafNode>
               <leafNode name="static">
                 <properties>
                   <help>Monitor log for static route</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/staticd</command>
               </leafNode>
               <leafNode name="multicast">
                 <properties>
                   <help>Monitor log for Multicast protocol</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/pimd</command>
               </leafNode>
               <leafNode name="isis">
                 <properties>
                   <help>Monitor log for ISIS</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/isisd</command>
               </leafNode>
+              <leafNode name="openfabric">
+                <properties>
+                  <help>Monitor log for OpenFabric</help>
+                </properties>
+                <command>journalctl --follow --no-hostname --boot /usr/lib/frr/fabricd</command>
+              </leafNode>
               <leafNode name="nhrp">
                 <properties>
                   <help>Monitor log for NHRP</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/nhrpd</command>
               </leafNode>
               <leafNode name="bfd">
                 <properties>
                   <help>Monitor log for BFD</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/bfdd</command>
               </leafNode>
               <leafNode name="mpls">
                 <properties>
                   <help>Monitor log for MPLS</help>
                 </properties>
                 <command>journalctl --follow --no-hostname --boot /usr/lib/frr/ldpd</command>
               </leafNode>
             </children>
           </node>
           <node name="macsec">
             <properties>
               <help>Monitor last lines of MACsec</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit "wpa_supplicant-macsec@*.service"</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Monitor last lines of specific MACsec interface</help>
                   <completionHelp>
                     <path>interfaces macsec</path>
                   </completionHelp>
                 </properties>
                 <command>SRC=$(cli-shell-api returnValue interfaces macsec "$5" source-interface); journalctl --no-hostname --boot --follow --unit "wpa_supplicant-macsec@$SRC.service"</command>
               </tagNode>
             </children>
           </node>
           <leafNode name="router-advert">
             <properties>
               <help>Monitor last lines of Router Advertisement Daemon log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit radvd.service</command>
           </leafNode>
           <leafNode name="snmp">
             <properties>
               <help>Monitor last lines of Simple Network Monitoring Protocol log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit snmpd.service</command>
           </leafNode>
           <node name="ssh">
             <properties>
               <help>Monitor last lines of Secure Shell log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit ssh.service</command>
             <children>
               <node name="dynamic-protection">
                 <properties>
                   <help>Monitor last lines of SSH guard log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot --follow --unit sshguard.service</command>
               </node>
             </children>
           </node>
           <leafNode name="vpn">
             <properties>
               <help>Monitor last lines of ALL Virtual Private Network services</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit strongswan.service --unit accel-ppp@*.service --unit ocserv.service</command>
           </leafNode>
           <leafNode name="ipsec">
             <properties>
               <help>Monitor last lines of IPsec log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit strongswan.service</command>
           </leafNode>
           <leafNode name="l2tp">
             <properties>
               <help>Monitor last lines of L2TP log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit accel-ppp@l2tp.service</command>
           </leafNode>
           <leafNode name="openconnect">
             <properties>
               <help>Monitor last lines of OpenConnect log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit ocserv.service</command>
           </leafNode>
           <leafNode name="pptp">
             <properties>
               <help>Monitor last lines of PPTP log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit accel-ppp@pptp.service</command>
           </leafNode>
           <leafNode name="sstp">
             <properties>
               <help>Monitor last lines of Secure Socket Tunneling Protocol server</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit accel-ppp@sstp.service</command>
           </leafNode>
           <node name="sstpc">
             <properties>
               <help>Monitor last lines of Secure Socket Tunneling Protocol client</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit "ppp@sstpc*.service"</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Monitor last lines of SSTP client log for specific interface</help>
                   <completionHelp>
                     <path>interfaces sstpc</path>
                   </completionHelp>
                 </properties>
                 <command>journalctl --no-hostname --boot --follow --unit "ppp@$5.service"</command>
               </tagNode>
             </children>
           </node>
           <leafNode name="vrrp">
             <properties>
               <help>Monitor last lines of Virtual Router Redundancy Protocol log</help>
             </properties>
             <command>journalctl --no-hostname --boot --follow --unit keepalived.service</command>
           </leafNode>
           <node name="wireless">
             <properties>
               <help>Monitor last lines of Wireless interface log</help>
             </properties>
             <children>
               <node name="wpa-supplicant">
                 <properties>
                   <help>Monitor last lines of WPA supplicant</help>
                 </properties>
                 <command>if cli-shell-api existsActive interfaces wireless; then journalctl --no-hostname --boot --follow --unit "wpa_supplicant@*.service"; else echo "No wireless interface configured!"; fi</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Monitor last lines of specific wireless interface supplicant</help>
                       <completionHelp>
                         <path>interfaces wireless</path>
                       </completionHelp>
                     </properties>
                     <command>if [[ $(cli-shell-api returnActiveValue interfaces wireless $6 type) == "station" ]]; then journalctl --no-hostname --boot --follow --unit "wpa_supplicant@$6.service"; else echo "Wireless interface $6 not configured as station!"; fi</command>
                   </tagNode>
                 </children>
               </node>
               <node name="hostapd">
                 <properties>
                   <help>Monitor last lines of host access point daemon</help>
                 </properties>
                 <command>if cli-shell-api existsActive interfaces wireless; then journalctl --no-hostname --boot --follow --unit "hostapd@*.service"; else echo "No wireless interface configured!"; fi</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Monitor last lines of specific host access point interface</help>
                       <completionHelp>
                         <path>interfaces wireless</path>
                       </completionHelp>
                     </properties>
                     <command>if [[ $(cli-shell-api returnActiveValue interfaces wireless $6 type) == "access-point" ]]; then journalctl --no-hostname --boot --follow --unit "hostapd@$6.service"; else echo "Wireless interface $6 not configured as access-point!"; fi</command>
                   </tagNode>
                 </children>
               </node>
             </children>
           </node>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/op-mode-definitions/restart-frr.xml.in b/op-mode-definitions/restart-frr.xml.in
index 2c9d4b1cc..4772e8dd2 100644
--- a/op-mode-definitions/restart-frr.xml.in
+++ b/op-mode-definitions/restart-frr.xml.in
@@ -1,85 +1,91 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="restart">
     <children>
       <leafNode name="all">
         <properties>
           <help>Restart all routing daemons</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart</command>
       </leafNode>
       <leafNode name="zebra">
         <properties>
           <help>Restart Routing Information Base (RIB) IP manager daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon zebra</command>
       </leafNode>
       <leafNode name="static">
         <properties>
           <help>Restart static routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon staticd</command>
       </leafNode>
       <leafNode name="bgp">
         <properties>
           <help>Restart Border Gateway Protocol (BGP) routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bgpd</command>
       </leafNode>
       <leafNode name="ospf">
         <properties>
           <help>Restart Open Shortest Path First (OSPF) routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospfd</command>
       </leafNode>
       <leafNode name="ospfv3">
         <properties>
           <help>Restart IPv6 Open Shortest Path First (OSPFv3) routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ospf6d</command>
       </leafNode>
       <leafNode name="rip">
         <properties>
           <help>Restart Routing Information Protocol (RIP) routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripd</command>
       </leafNode>
       <leafNode name="ripng">
         <properties>
           <help>Restart IPv6 Routing Information Protocol (RIPng) routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ripngd</command>
       </leafNode>
       <leafNode name="isis">
         <properties>
           <help>Restart Intermediate System to Intermediate System (IS-IS) routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon isisd</command>
       </leafNode>
+      <leafNode name="openfabric">
+        <properties>
+          <help>Restart OpenFabric routing daemon</help>
+        </properties>
+        <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon fabricd</command>
+      </leafNode>
       <leafNode name="pim6">
         <properties>
           <help>Restart IPv6 Protocol Independent Multicast (PIM) daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon pim6d</command>
       </leafNode>
       <leafNode name="ldp">
         <properties>
           <help>Restart Label Distribution Protocol (LDP) daemon used by MPLS</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon ldpd</command>
       </leafNode>
       <leafNode name="babel">
         <properties>
           <help>Restart Babel routing daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon babeld</command>
       </leafNode>
       <leafNode name="bfd">
         <properties>
           <help>Restart Bidirectional Forwarding Detection (BFD) daemon</help>
         </properties>
         <command>sudo ${vyos_op_scripts_dir}/restart_frr.py --action restart --daemon bfdd</command>
       </leafNode>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/op-mode-definitions/show-ip-route.xml.in b/op-mode-definitions/show-ip-route.xml.in
index c878bf712..37279d3d2 100644
--- a/op-mode-definitions/show-ip-route.xml.in
+++ b/op-mode-definitions/show-ip-route.xml.in
@@ -1,137 +1,138 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="show">
     <children>
       <node name="ip">
         <properties>
           <help>Show IPv4 routing information</help>
         </properties>
         <children>
           <node name="route">
             <properties>
               <help>Show IP routes</help>
             </properties>
             <command>vtysh -c "show ip route"</command>
             <children>
               #include <include/show-route-bgp.xml.i>
               <node name="cache">
                 <properties>
                   <help>Show kernel route cache</help>
                 </properties>
                 <command>ip -s route list cache</command>
               </node>
               <tagNode name="cache">
                 <properties>
                   <help>Show kernel route cache for a given route</help>
                   <completionHelp>
                     <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
                   </completionHelp>
                 </properties>
                 <command>ip -s route list cache $5</command>
               </tagNode>
               #include <include/show-route-connected.xml.i>
               <node name="forward">
                 <properties>
                   <help>Show kernel route table</help>
                 </properties>
                 <command>ip route list</command>
               </node>
               <tagNode name="forward">
                 <properties>
                   <help>Show kernel route table for a given route</help>
                   <completionHelp>
                     <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
                   </completionHelp>
                 </properties>
                 <command>ip -s route list $5</command>
               </tagNode>
               #include <include/show-route-isis.xml.i>
+              #include <include/show-route-openfabric.xml.i>
               #include <include/show-route-kernel.xml.i>
               #include <include/show-route-ospf.xml.i>
               #include <include/show-route-rip.xml.i>
               #include <include/show-route-static.xml.i>
               #include <include/show-route-supernets-only.xml.i>
               #include <include/show-route-table.xml.i>
               #include <include/show-route-tag.xml.i>
               <node name="summary">
                 <properties>
                   <help>Summary of all routes</help>
                 </properties>
                 <command>${vyos_op_scripts_dir}/route.py show_summary --family inet</command>
                 <children>
                   <tagNode name="table">
                     <properties>
                       <help>Summary of routes in a particular table</help>
                     </properties>
                     <command>${vyos_op_scripts_dir}/route.py show_summary --family inet --table $6</command>
                   </tagNode>
                 </children>
               </node>
               <tagNode name="vrf">
                 <properties>
                   <help>Show IP routes in VRF</help>
                   <completionHelp>
                     <list>all</list>
                     <path>vrf name</path>
                   </completionHelp>
                 </properties>
                 <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
                 <children>
                   <node name="summary">
                     <properties>
                       <help>Summary of all routes in the VRF</help>
                     </properties>
                     <command>${vyos_op_scripts_dir}/route.py show_summary --family inet --vrf $5</command>
                   </node>
                   #include <include/show-route-bgp.xml.i>
                   #include <include/show-route-connected.xml.i>
                   #include <include/show-route-isis.xml.i>
                   #include <include/show-route-kernel.xml.i>
                   #include <include/show-route-ospf.xml.i>
                   #include <include/show-route-rip.xml.i>
                   #include <include/show-route-static.xml.i>
                   #include <include/show-route-supernets-only.xml.i>
                   #include <include/show-route-tag.xml.i>
                   <node name="node.tag">
                     <properties>
                       <help>Show IP routes of specified IP address or prefix</help>
                       <completionHelp>
                         <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
                       </completionHelp>
                     </properties>
                     <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
                     <children>
                       <leafNode name="longer-prefixes">
                         <properties>
                           <help>Show longer prefixes of routes for specified prefix</help>
                         </properties>
                         <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
                       </leafNode>
                     </children>
                   </node>
                 </children>
               </tagNode>
             </children>
           </node>
           <tagNode name="route">
             <properties>
               <help>Show IP routes of specified IP address or prefix</help>
               <completionHelp>
                 <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
               </completionHelp>
             </properties>
             <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
             <children>
               <leafNode name="longer-prefixes">
                 <properties>
                   <help>Show longer prefixes of routes for specified prefix</help>
                 </properties>
                 <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
               </leafNode>
             </children>
           </tagNode>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/op-mode-definitions/show-ipv6-route.xml.in b/op-mode-definitions/show-ipv6-route.xml.in
index d73fb46b4..f68a94971 100644
--- a/op-mode-definitions/show-ipv6-route.xml.in
+++ b/op-mode-definitions/show-ipv6-route.xml.in
@@ -1,137 +1,138 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="show">
     <children>
       <node name="ipv6">
         <properties>
           <help>Show IPv6 routing information</help>
         </properties>
         <children>
           <node name="route">
             <properties>
               <help>Show IPv6 routes</help>
             </properties>
             <command>vtysh -c "show ipv6 route"</command>
             <children>
               #include <include/show-route-bgp.xml.i>
               <node name="cache">
                 <properties>
                   <help>Show kernel IPv6 route cache</help>
                 </properties>
                 <command>ip -s -f inet6 route list cache</command>
               </node>
               <tagNode name="cache">
                 <properties>
                   <help>Show kernel IPv6 route cache for a given route</help>
                   <completionHelp>
                     <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
                   </completionHelp>
                 </properties>
                 <command>ip -s -f inet6 route list cache $5</command>
               </tagNode>
               #include <include/show-route-connected.xml.i>
               <node name="forward">
                 <properties>
                   <help>Show kernel IPv6 route table</help>
                 </properties>
                 <command>ip -f inet6 route list</command>
               </node>
               <tagNode name="forward">
                 <properties>
                   <help>Show kernel IPv6 route table for a given route</help>
                   <completionHelp>
                     <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
                   </completionHelp>
                 </properties>
                 <command>ip -s -f inet6 route list $5</command>
               </tagNode>
               #include <include/show-route-isis.xml.i>
+              #include <include/show-route-openfabric.xml.i>
               #include <include/show-route-kernel.xml.i>
               #include <include/show-route-ospfv3.xml.i>
               #include <include/show-route-ripng.xml.i>
               #include <include/show-route-static.xml.i>
               #include <include/show-route-table.xml.i>
               #include <include/show-route-tag.xml.i>
               <node name="summary">
                 <properties>
                   <help>Summary of all routes</help>
                 </properties>
                 <command>${vyos_op_scripts_dir}/route.py show_summary --family inet6</command>
                 <children>
                   <tagNode name="table">
                     <properties>
                       <help>Summary of routes in a particular table</help>
                     </properties>
                     <command>${vyos_op_scripts_dir}/route.py show_summary --family inet6 --table $6</command>
                   </tagNode>
                 </children>
               </node>
               <tagNode name="vrf">
                 <properties>
                   <help>Show IPv6 routes in VRF</help>
                   <completionHelp>
                     <list>all</list>
                     <path>vrf name</path>
                   </completionHelp>
                 </properties>
                 <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
                 <children>
                   <node name="summary">
                     <properties>
                       <help>Summary of all routes in the VRF</help>
                     </properties>
                     <command>${vyos_op_scripts_dir}/route.py show_summary --family inet6 --vrf $5</command>
                   </node>
                   <node name="node.tag">
                     <properties>
                       <help>Show IPv6 routes of given address or prefix</help>
                       <completionHelp>
                         <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
                       </completionHelp>
                     </properties>
                     <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
                     <children>
                       <node name="longer-prefixes">
                         <properties>
                           <help>Show longer prefixes of routes for given prefix</help>
                         </properties>
                         <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
                       </node>
                     </children>
                   </node>
                   #include <include/show-route-bgp.xml.i>
                   #include <include/show-route-connected.xml.i>
                   #include <include/show-route-isis.xml.i>
                   #include <include/show-route-kernel.xml.i>
                   #include <include/show-route-ospfv3.xml.i>
                   #include <include/show-route-ripng.xml.i>
                   #include <include/show-route-static.xml.i>
                   #include <include/show-route-supernets-only.xml.i>
                   #include <include/show-route-table.xml.i>
                   #include <include/show-route-tag.xml.i>
                 </children>
               </tagNode>
             </children>
           </node>
           <tagNode name="route">
             <properties>
               <help>Show IPv6 routes of given address or prefix</help>
               <completionHelp>
                 <list>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</list>
               </completionHelp>
             </properties>
             <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
             <children>
               <node name="longer-prefixes">
                 <properties>
                   <help>Show longer prefixes of routes for given prefix</help>
                 </properties>
                 <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
               </node>
             </children>
           </tagNode>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/op-mode-definitions/show-log.xml.in b/op-mode-definitions/show-log.xml.in
index 7ae3b890b..f0fad63d2 100644
--- a/op-mode-definitions/show-log.xml.in
+++ b/op-mode-definitions/show-log.xml.in
@@ -1,816 +1,822 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="show">
     <properties>
       <help>Show system information</help>
     </properties>
     <children>
       <tagNode name="log">
         <properties>
           <help>Show last number of messages in master logging buffer</help>
           <completionHelp>
             <list>&lt;1-9999&gt;</list>
           </completionHelp>
         </properties>
         <command>if ${vyos_validators_dir}/numeric --range 1-9999 "$3"; then journalctl --no-hostname --boot --lines "$3"; fi</command>
       </tagNode>
       <node name="log">
         <properties>
           <help>Show contents of current master logging buffer</help>
         </properties>
         <command>journalctl --no-hostname --boot</command>
         <children>
           <leafNode name="audit">
             <properties>
               <help>Show audit logs</help>
             </properties>
             <command>cat /var/log/audit/audit.log</command>
           </leafNode>
           <leafNode name="all">
             <properties>
               <help>Show contents of all master log files</help>
             </properties>
             <command>sudo bash -c 'eval $(lesspipe); less $_vyatta_less_options --prompt=".logm, file %i of %m., page %dt of %D" -- `printf "%s\n" /var/log/messages* | sort -nr`'</command>
           </leafNode>
           <leafNode name="authorization">
             <properties>
               <help>Show listing of authorization attempts</help>
             </properties>
             <command>journalctl --no-hostname --boot --quiet SYSLOG_FACILITY=10 SYSLOG_FACILITY=4</command>
           </leafNode>
           <leafNode name="certbot">
             <properties>
               <help>Show log for certbot</help>
             </properties>
             <command>if sudo test -f /var/log/letsencrypt/letsencrypt.log; then sudo cat /var/log/letsencrypt/letsencrypt.log; else echo "Cerbot log does not exist"; fi</command>
           </leafNode>
           <leafNode name="cluster">
             <properties>
               <help>Show log for Cluster</help>
             </properties>
             <command>cat $(printf "%s\n" /var/log/messages* | sort -nr) | grep -e heartbeat -e cl_status -e mach_down -e ha_log</command>
           </leafNode>
           <leafNode name="conntrack-sync">
             <properties>
               <help>Show log for Conntrack-sync</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit conntrackd.service</command>
           </leafNode>
           <leafNode name="console-server">
             <properties>
               <help>Show log for console server</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit conserver-server.service</command>
           </leafNode>
           <node name="ids">
             <properties>
               <help>Show log for for Intrusion Detection System</help>
             </properties>
             <children>
               <leafNode name="ddos-protection">
                 <properties>
                   <help>Show log for DDOS protection</help>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit fastnetmon.service</command>
               </leafNode>
             </children>
           </node>
           <node name="dhcp">
             <properties>
               <help>Show log for Dynamic Host Control Protocol (DHCP)</help>
             </properties>
             <children>
               <node name="server">
                 <properties>
                   <help>Show log for DHCP server</help>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit kea-dhcp4-server.service</command>
               </node>
               <node name="client">
                 <properties>
                   <help>Show DHCP client logs</help>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit "dhclient@*.service"</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Show DHCP client log on specific interface</help>
                       <completionHelp>
                         <script>${vyos_completion_dir}/list_interfaces --broadcast</script>
                       </completionHelp>
                     </properties>
                     <command>journalctl --no-hostname --boot --unit "dhclient@$6.service"</command>
                   </tagNode>
                 </children>
               </node>
             </children>
           </node>
           <node name="dhcpv6">
             <properties>
               <help>Show log for Dynamic Host Control Protocol IPv6 (DHCPv6)</help>
             </properties>
             <children>
               <node name="server">
                 <properties>
                   <help>Show log for DHCPv6 server</help>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit kea-dhcp6-server.service</command>
               </node>
               <node name="client">
                 <properties>
                   <help>Show DHCPv6 client logs</help>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit "dhcp6c@*.service"</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Show DHCPv6 client log on specific interface</help>
                       <completionHelp>
                         <script>${vyos_completion_dir}/list_interfaces</script>
                       </completionHelp>
                     </properties>
                     <command>journalctl --no-hostname --boot --unit "dhcp6c@$6.service"</command>
                   </tagNode>
                 </children>
               </node>
             </children>
           </node>
           <node name="firewall">
             <properties>
               <help>Show log for Firewall</help>
             </properties>
             <command>journalctl --no-hostname --boot -k | egrep "(ipv[46]|bri)-(FWD|INP|OUT|NAM)"</command>
             <children>
               <node name="bridge">
                 <properties>
                   <help>Show firewall bridge log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot -k | egrep "bri-(FWD|INP|OUT|NAM)"</command>
                 <children>
                   <node name="forward">
                     <properties>
                       <help>Show Bridge forward firewall log</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep bri-FWD</command>
                     <children>
                       <node name="filter">
                         <properties>
                           <help>Show Bridge firewall forward filter</help>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | grep bri-FWD-filter</command>
                         <children>
                           <tagNode name="rule">
                             <properties>
                               <help>Show log for a rule in the specified firewall</help>
                               <completionHelp>
                                 <path>firewall bridge forward filter rule</path>
                               </completionHelp>
                             </properties>
                             <command>journalctl --no-hostname --boot -k | egrep "\[bri-FWD-filter-$8-[ADRJC]\]"</command>
                           </tagNode>
                         </children>
                       </node>
                     </children>
                   </node>
                   <tagNode name="name">
                     <properties>
                       <help>Show custom Bridge firewall log</help>
                       <completionHelp>
                         <path>firewall bridge name</path>
                       </completionHelp>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep bri-NAM-$6</command>
                     <children>
                       <tagNode name="rule">
                         <properties>
                           <help>Show log for a rule in the specified firewall</help>
                           <completionHelp>
                             <path>firewall bridge name ${COMP_WORDS[5]} rule</path>
                           </completionHelp>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | egrep "\[bri-NAM-$6-$8-[ADRJC]\]"</command>
                       </tagNode>
                     </children>
                   </tagNode>
                 </children>
               </node>
               <node name="ipv4">
                 <properties>
                   <help>Show firewall IPv4 log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot -k | egrep "ipv4-(FWD|INP|OUT|NAM)"</command>
                 <children>
                   <node name="forward">
                     <properties>
                       <help>Show firewall IPv4 forward log</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv4-FWD</command>
                     <children>
                       <node name="filter">
                         <properties>
                           <help>Show firewall IPv4 forward filter log</help>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | grep ipv4-FWD-filter</command>
                         <children>
                           <tagNode name="rule">
                             <properties>
                               <help>Show log for a rule in the specified firewall</help>
                               <completionHelp>
                                 <path>firewall ipv4 forward filter rule</path>
                               </completionHelp>
                             </properties>
                             <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-FWD-filter-$8-[ADRJCO]\]"</command>
                           </tagNode>
                         </children>
                       </node>
                     </children>
                   </node>
                   <node name="input">
                     <properties>
                       <help>Show firewall IPv4 input log</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv4-INP</command>
                     <children>
                       <node name="filter">
                         <properties>
                           <help>Show firewall IPv4 input filter log</help>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | grep ipv4-INP-filter</command>
                         <children>
                           <tagNode name="rule">
                             <properties>
                               <help>Show log for a rule in the specified firewall</help>
                               <completionHelp>
                                 <path>firewall ipv4 input filter rule</path>
                               </completionHelp>
                             </properties>
                             <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-INP-filter-$8-[ADRJC]\]"</command>
                           </tagNode>
                         </children>
                       </node>
                     </children>
                   </node>
                   <tagNode name="name">
                     <properties>
                       <help>Show custom IPv4 firewall log</help>
                       <completionHelp>
                         <path>firewall ipv4 name</path>
                       </completionHelp>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv4-NAM-$6</command>
                     <children>
                       <tagNode name="rule">
                         <properties>
                           <help>Show log for a rule in the specified firewall</help>
                           <completionHelp>
                             <path>firewall ipv4 name ${COMP_WORDS[5]} rule</path>
                           </completionHelp>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-NAM-$6-$8-[ADRJC]\]"</command>
                       </tagNode>
                     </children>
                   </tagNode>
                   <node name="output">
                     <properties>
                       <help>Show firewall IPv4 output log</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv4-OUT</command>
                     <children>
                       <node name="filter">
                         <properties>
                           <help>Show firewall IPv4 output filter log</help>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | grep ipv4-OUT-filter</command>
                         <children>
                           <tagNode name="rule">
                             <properties>
                               <help>Show log for a rule in the specified firewall</help>
                               <completionHelp>
                                 <path>firewall ipv4 output filter rule</path>
                               </completionHelp>
                             </properties>
                             <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-OUT-filter-$8-[ADRJC]\]"</command>
                           </tagNode>
                         </children>
                       </node>
                     </children>
                   </node>
                 </children>
               </node>
               <node name="ipv6">
                 <properties>
                   <help>Show firewall IPv6 log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot -k | egrep "ipv6-(FWD|INP|OUT|NAM)"</command>
                 <children>
                   <node name="forward">
                     <properties>
                       <help>Show firewall IPv6 forward log</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv6-FWD</command>
                     <children>
                       <node name="filter">
                         <properties>
                           <help>Show firewall IPv6 forward filter log</help>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | grep ipv6-FWD-filter</command>
                         <children>
                           <tagNode name="rule">
                             <properties>
                               <help>Show log for a rule in the specified firewall</help>
                               <completionHelp>
                                 <path>firewall ipv6 forward filter rule</path>
                               </completionHelp>
                             </properties>
                             <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-FWD-filter-$8-[ADRJCO]\]"</command>
                           </tagNode>
                         </children>
                       </node>
                     </children>
                   </node>
                   <node name="input">
                     <properties>
                       <help>Show firewall IPv6 input log</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv6-INP</command>
                     <children>
                       <node name="filter">
                         <properties>
                           <help>Show firewall IPv6 input filter log</help>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | grep ipv6-INP-filter</command>
                         <children>
                           <tagNode name="rule">
                             <properties>
                               <help>Show log for a rule in the specified firewall</help>
                               <completionHelp>
                                 <path>firewall ipv6 input filter rule</path>
                               </completionHelp>
                             </properties>
                             <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-INP-filter-$8-[ADRJC]\]"</command>
                           </tagNode>
                         </children>
                       </node>
                     </children>
                   </node>
                   <tagNode name="name">
                     <properties>
                       <help>Show custom IPv6 firewall log</help>
                       <completionHelp>
                         <path>firewall ipv6 name</path>
                       </completionHelp>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv6-NAM-$6</command>
                     <children>
                       <tagNode name="rule">
                         <properties>
                           <help>Show log for a rule in the specified firewall</help>
                           <completionHelp>
                             <path>firewall ipv6 name ${COMP_WORDS[5]} rule</path>
                           </completionHelp>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-NAM-$6-$8-[ADRJC]\]"</command>
                       </tagNode>
                     </children>
                   </tagNode>
                   <node name="output">
                     <properties>
                       <help>Show firewall IPv6 output log</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | grep ipv6-OUT</command>
                     <children>
                       <node name="filter">
                         <properties>
                           <help>Show firewall IPv6 output filter log</help>
                         </properties>
                         <command>journalctl --no-hostname --boot -k | grep ipv6-OUT-filter</command>
                         <children>
                           <tagNode name="rule">
                             <properties>
                               <help>Show log for a rule in the specified firewall</help>
                               <completionHelp>
                                 <path>firewall ipv6 output filter rule</path>
                               </completionHelp>
                             </properties>
                             <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-OUT-filter-$8-[ADRJC]\]"</command>
                           </tagNode>
                         </children>
                       </node>
                     </children>
                   </node>
                 </children>
               </node>
             </children>
           </node>
           <leafNode name="flow-accounting">
             <properties>
               <help>Show log for flow-accounting</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit uacctd.service</command>
           </leafNode>
           <leafNode name="https">
             <properties>
               <help>Show log for HTTPs</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit nginx.service</command>
           </leafNode>
           <tagNode name="image">
             <properties>
               <help>Show contents of master log file for image</help>
               <completionHelp>
                 <script>compgen -f /lib/live/mount/persistence/boot/ | grep -v grub | sed -e s@/lib/live/mount/persistence/boot/@@</script>
               </completionHelp>
             </properties>
             <command>less $_vyatta_less_options --prompt=".log, page %dt of %D" -- /lib/live/mount/persistence/boot/$4/rw/var/log/messages</command>
             <children>
               <leafNode name="all">
                 <properties>
                   <help>Show contents of all master log files for image</help>
                 </properties>
                 <command>eval $(lesspipe); less $_vyatta_less_options --prompt=".log?m, file %i of %m., page %dt of %D" -- `printf "%s\n" /lib/live/mount/persistence/boot/$4/rw/var/log/messages* | sort -nr`</command>
               </leafNode>
               <leafNode name="authorization">
                 <properties>
                   <help>Show listing of authorization attempts for image</help>
                 </properties>
                 <command>less $_vyatta_less_options --prompt=".log, page %dt of %D" -- /lib/live/mount/persistence/boot/$4/rw/var/log/auth.log</command>
               </leafNode>
               <tagNode name="tail">
                 <properties>
                   <help>Show last changes to messages</help>
                   <completionHelp>
                     <list>&lt;NUMBER&gt;</list>
                   </completionHelp>
                 </properties>
                 <command>tail -n "$6" /lib/live/mount/persistence/boot/$4/rw/var/log/messages | ${VYATTA_PAGER:-cat}</command>
               </tagNode>
             </children>
           </tagNode>
           <leafNode name="ipoe-server">
             <properties>
               <help>Show log for IPoE server</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit accel-ppp@ipoe.service</command>
           </leafNode>
           <leafNode name="kernel">
             <properties>
               <help>Show log for Linux Kernel</help>
             </properties>
             <command>journalctl --no-hostname --boot --dmesg</command>
           </leafNode>
           <leafNode name="lldp">
             <properties>
               <help>Show log for Link Layer Discovery Protocol (LLDP)</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit lldpd.service</command>
           </leafNode>
           <node name="nat">
             <properties>
               <help>Show log for Network Address Translation (NAT)</help>
             </properties>
             <children>
               <node name="destination">
                 <properties>
                   <help>Show NAT destination log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot -k | egrep "\[DST-NAT-[0-9]+\]"</command>
                 <children>
                   <tagNode name="rule">
                     <properties>
                       <help>Show NAT destination log for specified rule</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | egrep "\[DST-NAT-$6\]"</command>
                   </tagNode>
                 </children>
               </node>
               <node name="source">
                 <properties>
                   <help>Show NAT source log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot -k | egrep "\[SRC-NAT-[0-9]+(-MASQ)?\]"&quot;"</command>
                 <children>
                   <tagNode name="rule">
                     <properties>
                       <help>Show NAT source log for specified rule</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | egrep "\[SRC-NAT-$6(-MASQ)?\]"</command>
                   </tagNode>
                 </children>
               </node>
               <node name="static">
                 <properties>
                   <help>Show NAT static log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot -k | egrep "\[STATIC-(SRC|DST)-NAT-[0-9]+\]"</command>
                 <children>
                   <tagNode name="rule">
                     <properties>
                       <help>Show NAT static log for specified rule</help>
                     </properties>
                     <command>journalctl --no-hostname --boot -k | egrep "\[STATIC-(SRC|DST)-NAT-$6\]"</command>
                   </tagNode>
                 </children>
               </node>
             </children>
             <command>journalctl --no-hostname --boot -k | egrep "\[(STATIC-)?(DST|SRC)-NAT-[0-9]+(-MASQ)?\]"</command>
           </node>
           <leafNode name="ndp-proxy">
             <properties>
               <help>Show log for Neighbor Discovery Protocol (NDP) Proxy</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit ndppd.service</command>
           </leafNode>
           <leafNode name="nhrp">
             <properties>
               <help>Show log for Next Hop Resolution Protocol (NHRP)</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit opennhrp.service</command>
           </leafNode>
           <leafNode name="ntp">
             <properties>
               <help>Show log for Network Time Protocol (NTP)</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit chrony.service</command>
           </leafNode>
           <node name="macsec">
             <properties>
               <help>Show log for MACsec</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit "wpa_supplicant-macsec@*.service"</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Show MACsec log on specific interface</help>
                   <completionHelp>
                     <path>interfaces macsec</path>
                   </completionHelp>
                 </properties>
                 <command>SRC=$(cli-shell-api returnValue interfaces macsec "$5" source-interface); journalctl --no-hostname --boot --unit "wpa_supplicant-macsec@$SRC.service"</command>
               </tagNode>
             </children>
           </node>
           <node name="openvpn">
             <properties>
               <help>Show log for OpenVPN</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit openvpn@*.service</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Show OpenVPN log on specific interface</help>
                   <completionHelp>
                     <path>interfaces openvpn</path>
                   </completionHelp>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit openvpn@$5.service</command>
               </tagNode>
             </children>
           </node>
           <node name="pppoe">
             <properties>
               <help>Show log for PPPoE interface</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit "ppp@pppoe*.service"</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Show PPPoE log on specific interface</help>
                   <completionHelp>
                     <path>interfaces pppoe</path>
                   </completionHelp>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit "ppp@$5.service"</command>
               </tagNode>
             </children>
           </node>
           <leafNode name="pppoe-server">
             <properties>
               <help>Show log for PPPoE server</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit accel-ppp@pppoe.service</command>
           </leafNode>
           <node name="protocol">
             <properties>
               <help>Show log for Routing Protocol</help>
             </properties>
             <children>
               <leafNode name="ospf">
                 <properties>
                   <help>Show log for OSPF</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/ospfd</command>
               </leafNode>
               <leafNode name="ospfv3">
                 <properties>
                   <help>Show log for OSPF for IPv6</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/ospf6d</command>
               </leafNode>
               <leafNode name="bgp">
                 <properties>
                   <help>Show log for BGP</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/bgpd</command>
               </leafNode>
               <leafNode name="rip">
                 <properties>
                   <help>Show log for RIP</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/ripd</command>
               </leafNode>
               <leafNode name="ripng">
                 <properties>
                   <help>Show log for RIPng</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/ripngd</command>
               </leafNode>
               <leafNode name="static">
                 <properties>
                   <help>Show log for static route</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/staticd</command>
               </leafNode>
               <leafNode name="multicast">
                 <properties>
                   <help>Show log for Multicast protocol</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/pimd</command>
               </leafNode>
               <leafNode name="isis">
                 <properties>
                   <help>Show log for ISIS</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/isisd</command>
               </leafNode>
+              <leafNode name="openfabric">
+                <properties>
+                  <help>Show log for OpenFabric</help>
+                </properties>
+                <command>journalctl --boot /usr/lib/frr/fabricd</command>
+              </leafNode>
               <leafNode name="nhrp">
                 <properties>
                   <help>Show log for NHRP</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/nhrpd</command>
               </leafNode>
               <leafNode name="bfd">
                 <properties>
                   <help>Show log for BFD</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/bfdd</command>
               </leafNode>
               <leafNode name="mpls">
                 <properties>
                   <help>Show log for MPLS</help>
                 </properties>
                 <command>journalctl --boot /usr/lib/frr/ldpd</command>
               </leafNode>
             </children>
           </node>
           <leafNode name="router-advert">
             <properties>
               <help>Show log for Router Advertisement Daemon (radvd)</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit radvd.service</command>
           </leafNode>
           <leafNode name="snmp">
             <properties>
               <help>Show log for Simple Network Monitoring Protocol (SNMP)</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit snmpd.service</command>
           </leafNode>
           <node name="ssh">
             <properties>
               <help>Show log for Secure Shell (SSH)</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit ssh.service</command>
             <children>
               <node name="dynamic-protection">
                 <properties>
                   <help>Show SSH guard log</help>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit sshguard.service</command>
               </node>
             </children>
           </node>
           <tagNode name="tail">
             <properties>
               <help>Show last n changes to messages</help>
               <completionHelp>
                 <list>&lt;NUMBER&gt;</list>
               </completionHelp>
             </properties>
             <command>tail -n "$4" /var/log/messages | ${VYATTA_PAGER:-cat}</command>
           </tagNode>
           <node name="tail">
             <properties>
               <help>Show last 10 lines of /var/log/messages file</help>
             </properties>
             <command>tail -n 10 /var/log/messages</command>
           </node>
           <leafNode name="vpn">
             <properties>
               <help>Monitor last lines of ALL Virtual Private Network services</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit strongswan.service --unit accel-ppp@*.service --unit ocserv.service</command>
           </leafNode>
           <leafNode name="ipsec">
             <properties>
               <help>Show log for IPsec</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit strongswan.service</command>
           </leafNode>
           <leafNode name="l2tp">
             <properties>
               <help>Show log for L2TP</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit accel-ppp@l2tp.service</command>
           </leafNode>
           <leafNode name="openconnect">
             <properties>
               <help>Show log for OpenConnect</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit ocserv.service</command>
           </leafNode>
           <leafNode name="pptp">
             <properties>
               <help>Show log for PPTP</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit accel-ppp@pptp.service</command>
           </leafNode>
           <leafNode name="sstp">
             <properties>
               <help>Show log for Secure Socket Tunneling Protocol (SSTP) server</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit accel-ppp@sstp.service</command>
           </leafNode>
           <node name="sstpc">
             <properties>
               <help>Show log for Secure Socket Tunneling Protocol (SSTP) client</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit "ppp@sstpc*.service"</command>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Show SSTP client log on specific interface</help>
                   <completionHelp>
                     <path>interfaces sstpc</path>
                   </completionHelp>
                 </properties>
                 <command>journalctl --no-hostname --boot --unit "ppp@$5.service"</command>
               </tagNode>
             </children>
           </node>
           <leafNode name="vrrp">
             <properties>
               <help>Show log for Virtual Router Redundancy Protocol (VRRP)</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit keepalived.service</command>
           </leafNode>
           <node name="wireless">
             <properties>
               <help>Show log for Wireless interface</help>
             </properties>
             <children>
               <node name="wpa-supplicant">
                 <properties>
                   <help>Show log for WPA supplicant</help>
                 </properties>
                 <command>if cli-shell-api existsActive interfaces wireless; then journalctl --no-hostname --boot --unit "wpa_supplicant@*.service"; else echo "No wireless interface configured!"; fi</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Show log for specific wireless interface supplicant</help>
                       <completionHelp>
                         <path>interfaces wireless</path>
                       </completionHelp>
                     </properties>
                     <command>if [[ $(cli-shell-api returnActiveValue interfaces wireless $6 type) == "station" ]]; then journalctl --no-hostname --boot --unit "wpa_supplicant@$6.service"; else echo "Wireless interface $6 not configured as station!"; fi</command>
                   </tagNode>
                 </children>
               </node>
               <node name="hostapd">
                 <properties>
                   <help>Show log for host access point daemon</help>
                 </properties>
                 <command>if cli-shell-api existsActive interfaces wireless; then journalctl --no-hostname --boot --unit "hostapd@*.service"; else echo "No wireless interface configured!"; fi</command>
                 <children>
                   <tagNode name="interface">
                     <properties>
                       <help>Show log for specific host access point daemon interface</help>
                       <completionHelp>
                         <path>interfaces wireless</path>
                       </completionHelp>
                     </properties>
                     <command>if [[ $(cli-shell-api returnActiveValue interfaces wireless $6 type) == "access-point" ]]; then journalctl --no-hostname --boot --unit "hostapd@$6.service"; else echo "Wireless interface $6 not configured as access-point!"; fi</command>
                   </tagNode>
                 </children>
               </node>
             </children>
           </node>
           <leafNode name="webproxy">
             <properties>
               <help>Show log for Webproxy</help>
             </properties>
             <command>journalctl --no-hostname --boot --unit squid.service</command>
           </leafNode>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/op-mode-definitions/show-openfabric.xml.in b/op-mode-definitions/show-openfabric.xml.in
new file mode 100644
index 000000000..2f489866e
--- /dev/null
+++ b/op-mode-definitions/show-openfabric.xml.in
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+  <node name="show">
+    <children>
+      <node name="openfabric">
+        <properties>
+          <help>Show OpenFabric routing protocol</help>
+        </properties>
+        <children>
+          <node name="database">
+            <properties>
+              <help>Show OpenFabric link state database</help>
+            </properties>
+            <children>
+              #include <include/vtysh-generic-detail.xml.i>
+            </children>
+            <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+          </node>
+          <node name="interface">
+            <properties>
+              <help>Show OpenFabric interfaces</help>
+              <completionHelp>
+                <script>${vyos_completion_dir}/list_interfaces</script>
+              </completionHelp>
+            </properties>
+            <children>
+              #include <include/vtysh-generic-detail.xml.i>
+            </children>
+            <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+          </node>
+          #include <include/vtysh-generic-interface-tagNode.xml.i>
+          <node name="neighbor">
+            <properties>
+              <help>Show OpenFabric neighbor adjacencies</help>
+            </properties>
+            <children>
+              #include <include/vtysh-generic-detail.xml.i>
+            </children>
+            <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+          </node>
+          <leafNode name="summary">
+            <properties>
+              <help>Show OpenFabric information summary</help>
+            </properties>
+            <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+          </leafNode>
+        </children>
+      </node>
+    </children>
+  </node>
+</interfaceDefinition>
diff --git a/python/vyos/frr.py b/python/vyos/frr.py
index e7743e9d5..6fb81803f 100644
--- a/python/vyos/frr.py
+++ b/python/vyos/frr.py
@@ -1,551 +1,551 @@
 # Copyright 2020-2024 VyOS maintainers and contributors <maintainers@vyos.io>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
 # version 2.1 of the License, or (at your option) any later version.
 #
 # This library 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
 # Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
 r"""
 A Library for interracting with the FRR daemon suite.
 It supports simple configuration manipulation and loading using the official tools
 supplied with FRR (vtysh and frr-reload)
 
 All configuration management and manipulation is done using strings and regex.
 
 
 Example Usage
 #####
 
 # Reading configuration from frr:
 ```
 >>> original_config = get_configuration()
 >>> repr(original_config)
 '!\nfrr version 7.3.1\nfrr defaults traditional\nhostname debian\n......
 ```
 
 
 # Modify a configuration section:
 ```
 >>> new_bgp_section = 'router bgp 65000\n neighbor 192.0.2.1 remote-as 65000\n'
 >>> modified_config = replace_section(original_config, new_bgp_section, replace_re=r'router bgp \d+')
 >>> repr(modified_config)
 '............router bgp 65000\n neighbor 192.0.2.1 remote-as 65000\n...........'
 ```
 
 Remove a configuration section:
 ```
 >>> modified_config = remove_section(original_config, r'router ospf')
 ```
 
 Test the new configuration:
 ```
 >>> try:
 >>>     mark_configuration(modified configuration)
 >>> except ConfigurationNotValid as e:
 >>>     print('resulting configuration is not valid')
 >>>     sys.exit(1)
 ```
 
 Apply the new configuration:
 ```
 >>> try:
 >>>     replace_configuration(modified_config)
 >>> except CommitError as e:
 >>>     print('Exception while commiting the supplied configuration')
 >>>     print(e)
 >>>     exit(1)
 ```
 """
 
 import tempfile
 import re
 
 from vyos import ConfigError
 from vyos.utils.process import cmd
 from vyos.utils.process import popen
 from vyos.utils.process import STDOUT
 
 import logging
 from logging.handlers import SysLogHandler
 import os
 import sys
 
 LOG = logging.getLogger(__name__)
 DEBUG = False
 
 ch = SysLogHandler(address='/dev/log')
 ch2 = logging.StreamHandler(stream=sys.stdout)
 LOG.addHandler(ch)
 LOG.addHandler(ch2)
 
 _frr_daemons = ['zebra', 'staticd', 'bgpd', 'ospfd', 'ospf6d', 'ripd', 'ripngd',
-                'isisd', 'pimd', 'pim6d', 'ldpd', 'eigrpd', 'babeld', 'bfdd']
+                'isisd', 'pimd', 'pim6d', 'ldpd', 'eigrpd', 'babeld', 'bfdd', 'fabricd']
 
 path_vtysh = '/usr/bin/vtysh'
 path_frr_reload = '/usr/lib/frr/frr-reload.py'
 path_config = '/run/frr'
 
 default_add_before = r'(ip prefix-list .*|route-map .*|line vty|end)'
 
 
 class FrrError(Exception):
     pass
 
 
 class ConfigurationNotValid(FrrError):
     """
     The configuratioin supplied to vtysh is not valid
     """
     pass
 
 
 class CommitError(FrrError):
     """
     Commiting the supplied configuration failed to commit by a unknown reason
     see commit error and/or run mark_configuration on the specified configuration
     to se error generated
 
     used by: reload_configuration()
     """
     pass
 
 
 class ConfigSectionNotFound(FrrError):
     """
     Removal of configuration failed because it is not existing in the supplied configuration
     """
     pass
 
 def init_debugging():
     global DEBUG
 
     DEBUG = os.path.exists('/tmp/vyos.frr.debug')
     if DEBUG:
         LOG.setLevel(logging.DEBUG)
 
 def get_configuration(daemon=None, marked=False):
     """ Get current running FRR configuration
     daemon:  Collect only configuration for the specified FRR daemon,
              supplying daemon=None retrieves the complete configuration
     marked:  Mark the configuration with "end" tags
 
     return:  string containing the running configuration from frr
 
     """
     if daemon and daemon not in _frr_daemons:
         raise ValueError(f'The specified daemon type is not supported {repr(daemon)}')
 
     cmd = f"{path_vtysh} -c 'show run'"
     if daemon:
         cmd += f' -d {daemon}'
 
     output, code = popen(cmd, stderr=STDOUT)
     if code:
         raise OSError(code, output)
 
     config = output.replace('\r', '')
     # Remove first header lines from FRR config
     config = config.split("\n", 3)[-1]
     # Mark the configuration with end tags
     if marked:
         config = mark_configuration(config)
 
     return config
 
 
 def mark_configuration(config):
     """ Add end marks and Test the configuration for syntax faults
     If the configuration is valid a marked version of the configuration is returned,
     or else it failes with a ConfigurationNotValid Exception
 
     config:  The configuration string to mark/test
     return:  The marked configuration from FRR
     """
     output, code = popen(f"{path_vtysh} -m -f -", stderr=STDOUT, input=config)
 
     if code == 2:
         raise ConfigurationNotValid(str(output))
     elif code:
         raise OSError(code, output)
 
     config = output.replace('\r', '')
     return config
 
 
 def reload_configuration(config, daemon=None):
     """ Execute frr-reload with the new configuration
     This will try to reapply the supplied configuration inside FRR.
     The configuration needs to be a complete configuration from the integrated config or
     from a daemon.
 
     config:  The configuration to apply
     daemon:  Apply the conigutaion to the specified FRR daemon,
              supplying daemon=None applies to the integrated configuration
     return:  None
     """
     if daemon and daemon not in _frr_daemons:
         raise ValueError(f'The specified daemon type is not supported {repr(daemon)}')
 
     f = tempfile.NamedTemporaryFile('w')
     f.write(config)
     f.flush()
 
     LOG.debug(f'reload_configuration: Reloading config using temporary file: {f.name}')
     cmd = f'{path_frr_reload} --reload'
     if daemon:
         cmd += f' --daemon {daemon}'
 
     if DEBUG:
         cmd += f' --debug --stdout'
 
     cmd += f' {f.name}'
 
     LOG.debug(f'reload_configuration: Executing command against frr-reload: "{cmd}"')
     output, code = popen(cmd, stderr=STDOUT)
     f.close()
 
     for i, e in enumerate(output.split('\n')):
         LOG.debug(f'frr-reload output: {i:3} {e}')
 
     if code == 1:
         raise ConfigError(output)
     elif code:
         raise OSError(code, output)
 
     return output
 
 
 def save_configuration():
     """ T3217: Save FRR configuration to /run/frr/config/frr.conf """
     return cmd(f'{path_vtysh} -n -w')
 
 
 def execute(command):
     """ Run commands inside vtysh
     command:  str containing commands to execute inside a vtysh session
     """
     if not isinstance(command, str):
         raise ValueError(f'command needs to be a string: {repr(command)}')
 
     cmd = f"{path_vtysh} -c '{command}'"
 
     output, code = popen(cmd, stderr=STDOUT)
     if code:
         raise OSError(code, output)
 
     config = output.replace('\r', '')
     return config
 
 
 def configure(lines, daemon=False):
     """ run commands inside config mode vtysh
     lines:  list or str conaining commands to execute inside a configure session
             only one command executed on each configure()
             Executing commands inside a subcontext uses the list to describe the context
             ex: ['router bgp 6500', 'neighbor 192.0.2.1 remote-as 65000']
     return: None
     """
     if isinstance(lines, str):
         lines = [lines]
     elif not isinstance(lines, list):
         raise ValueError('lines needs to be string or list of commands')
 
     if daemon and daemon not in _frr_daemons:
         raise ValueError(f'The specified daemon type is not supported {repr(daemon)}')
 
     cmd = f'{path_vtysh}'
     if daemon:
         cmd += f' -d {daemon}'
 
     cmd += " -c 'configure terminal'"
     for x in lines:
         cmd += f" -c '{x}'"
 
     output, code = popen(cmd, stderr=STDOUT)
     if code == 1:
         raise ConfigurationNotValid(f'Configuration FRR failed: {repr(output)}')
     elif code:
         raise OSError(code, output)
 
     config = output.replace('\r', '')
     return config
 
 
 def _replace_section(config, replacement, replace_re, before_re):
     r"""Replace a section of FRR config
     config:      full original configuration
     replacement: replacement configuration section
     replace_re:  The regex to replace
                  example: ^router bgp \d+$.?*^!$
                  this will replace everything between ^router bgp X$ and ^!$
     before_re:   When replace_re is not existant, the config will be added before this tag
                  example: ^line vty$
 
     return:      modified configuration as a text file
     """
     # DEPRECATED, this is replaced by a new implementation
     # Check if block is configured, remove the existing instance else add a new one
     if re.findall(replace_re, config, flags=re.MULTILINE | re.DOTALL):
         # Section is in the configration, replace it
         return re.sub(replace_re, replacement, config, count=1,
                       flags=re.MULTILINE | re.DOTALL)
     if before_re:
         if not re.findall(before_re, config, flags=re.MULTILINE | re.DOTALL):
             raise ConfigSectionNotFound(f"Config section {before_re} not found in config")
 
         # If no section is in the configuration, add it before the line vty line
         return re.sub(before_re, rf'{replacement}\n\g<1>', config, count=1,
                       flags=re.MULTILINE | re.DOTALL)
 
     raise ConfigSectionNotFound(f"Config section {replacement} not found in config")
 
 
 def replace_section(config, replacement, from_re, to_re=r'!', before_re=r'line vty'):
     r"""Replace a section of FRR config
     config:      full original configuration
     replacement: replacement configuration section
     from_re:     Regex for the start of section matching
                  example: 'router bgp \d+'
     to_re:       Regex for stop of section matching
                  default: '!'
                  example: '!'  or  'end'
     before_re:   When from_re/to_re  does not return a match, the config will
                  be added before this tag
                  default: ^line vty$
 
     startline and endline tags will be automatically added to the resulting from_re/to_re and before_re regex'es
     """
     # DEPRECATED, this is replaced by a new implementation
     return _replace_section(config, replacement, replace_re=rf'^{from_re}$.*?^{to_re}$', before_re=rf'^({before_re})$')
 
 
 def remove_section(config, from_re, to_re='!'):
     # DEPRECATED, this is replaced by a new implementation
     return _replace_section(config, '', replace_re=rf'^{from_re}$.*?^{to_re}$', before_re=None)
 
 
 def _find_first_block(config, start_pattern, stop_pattern, start_at=0):
     '''Find start and stop line numbers for a config block
     config:        (list) A list conaining the configuration that is searched
     start_pattern: (raw-str) The pattern searched for a a start of block tag
     stop_pattern:  (raw-str) The pattern searched for to signify the end of the block
     start_at:      (int) The index to start searching at in the <config>
 
     Returns:
         None: No complete block could be found
         set(int, int): A complete block found between the line numbers returned in the set
 
     The object <config> is searched from the start for the regex <start_pattern> until the first match is found.
     On a successful match it continues the search for the regex <stop_pattern> until it is found.
     After a successful run a set is returned containing the start and stop line numbers.
     '''
     LOG.debug(f'_find_first_block: find start={repr(start_pattern)} stop={repr(stop_pattern)} start_at={start_at}')
     _start = None
     for i, element in enumerate(config[start_at:], start=start_at):
         # LOG.debug(f'_find_first_block: running line {i:3} "{element}"')
         if not _start:
             if not re.match(start_pattern, element):
                 LOG.debug(f'_find_first_block: no match     {i:3} "{element}"')
                 continue
             _start = i
             LOG.debug(f'_find_first_block: Found start  {i:3} "{element}"')
             continue
 
         if not re.match(stop_pattern, element):
             LOG.debug(f'_find_first_block: no match     {i:3} "{element}"')
             continue
 
         LOG.debug(f'_find_first_block: Found stop   {i:3} "{element}"')
         return (_start, i)
 
     LOG.debug('_find_first_block: exit start={repr(start_pattern)} stop={repr(stop_pattern)} start_at={start_at}')
     return None
 
 
 def _find_first_element(config, pattern, start_at=0):
     '''Find the first element that matches the current pattern in config
     config:        (list) A list containing the configuration that is searched
     start_pattern: (raw-str) The pattern searched for
     start_at:      (int) The index to start searching at in the <config>
 
     return:   Line index of the line containing the searched pattern
 
     TODO: for now it returns -1 on a no-match because 0 also returns as False
     TODO: that means that we can not use False matching to tell if its
     '''
     LOG.debug(f'_find_first_element: find start="{pattern}" start_at={start_at}')
     for i, element in enumerate(config[start_at:], start=0):
         if re.match(pattern + '$', element):
             LOG.debug(f'_find_first_element: Found stop {i:3} "{element}"')
             return i
         LOG.debug(f'_find_first_element: no match   {i:3} "{element}"')
     LOG.debug(f'_find_first_element: Did not find any match, exiting')
     return -1
 
 
 def _find_elements(config, pattern, start_at=0):
     '''Find all instances of pattern and return a list containing all element indexes
     config:        (list) A list containing the configuration that is searched
     start_pattern: (raw-str) The pattern searched for
     start_at:      (int) The index to start searching at in the <config>
 
     return:    A list of line indexes containing the searched pattern
     TODO: refactor this to return a generator instead
     '''
     return [i for i, element in enumerate(config[start_at:], start=0) if re.match(pattern + '$', element)]
 
 
 class FRRConfig:
     '''Main FRR Configuration manipulation object
     Using this object the user could load, manipulate and commit the configuration to FRR
     '''
     def __init__(self, config=[]):
         self.imported_config = ''
 
         if isinstance(config, list):
             self.config = config.copy()
             self.original_config = config.copy()
         elif isinstance(config, str):
             self.config = config.split('\n')
             self.original_config = self.config.copy()
         else:
             raise ValueError(
                 'The config element needs to be a string or list type object')
 
         if config:
             LOG.debug(f'__init__: frr library initiated with initial config')
             for i, e in enumerate(self.config):
                 LOG.debug(f'__init__: initial              {i:3} {e}')
 
     def load_configuration(self, daemon=None):
         '''Load the running configuration from FRR into the config object
         daemon: str with name of the FRR Daemon to load configuration from or
                 None to load the consolidated config
 
         Using this overwrites the current loaded config objects and replaces the original loaded config
         '''
         init_debugging()
 
         self.imported_config = get_configuration(daemon=daemon)
         if daemon:
             LOG.debug(f'load_configuration: Configuration loaded from FRR daemon {daemon}')
         else:
             LOG.debug(f'load_configuration: Configuration loaded from FRR integrated config')
 
         self.original_config = self.imported_config.split('\n')
         self.config = self.original_config.copy()
 
         for i, e in enumerate(self.imported_config.split('\n')):
             LOG.debug(f'load_configuration:  loaded    {i:3} {e}')
         return
 
     def test_configuration(self):
         '''Test the current configuration against FRR
         This will exception if FRR failes to load the current configuration object
         '''
         LOG.debug('test_configation: Testing configuration')
         mark_configuration('\n'.join(self.config))
 
     def commit_configuration(self, daemon=None):
         '''
         Commit the current configuration to FRR daemon: str with name of the
         FRR daemon to commit to or None to use the consolidated config.
 
         Configuration is automatically saved after apply
         '''
         LOG.debug('commit_configuration:  Commiting configuration')
         for i, e in enumerate(self.config):
             LOG.debug(f'commit_configuration: new_config {i:3} {e}')
 
         # https://github.com/FRRouting/frr/issues/10132
         # https://github.com/FRRouting/frr/issues/10133
         count = 0
         count_max = 5
         emsg = ''
         while count < count_max:
             count += 1
             try:
                 reload_configuration('\n'.join(self.config), daemon=daemon)
                 break
             except ConfigError as e:
                 emsg = str(e)
             except:
                 # we just need to re-try the commit of the configuration
                 # for the listed FRR issues above
                 pass
         if count >= count_max:
             if emsg:
                 raise ConfigError(emsg)
             raise ConfigurationNotValid(f'Config commit retry counter ({count_max}) exceeded for {daemon} daemon!')
 
         # Save configuration to /run/frr/config/frr.conf
         save_configuration()
 
 
     def modify_section(self, start_pattern, replacement='!', stop_pattern=r'\S+', remove_stop_mark=False, count=0):
         if isinstance(replacement, str):
             replacement = replacement.split('\n')
         elif not isinstance(replacement, list):
             return ValueError("The replacement element needs to be a string or list type object")
         LOG.debug(f'modify_section: starting search for {repr(start_pattern)} until {repr(stop_pattern)}')
 
         _count = 0
         _next_start = 0
         while True:
             if count and count <= _count:
                 # Break out of the loop after specified amount of matches
                 LOG.debug(f'modify_section: reached limit ({_count}), exiting loop at line {_next_start}')
                 break
             # While searching, always assume that the user wants to search for the exact pattern he entered
             # To be more specific the user needs a override, eg. a "pattern.*"
             _w = _find_first_block(
                 self.config, start_pattern+'$', stop_pattern, start_at=_next_start)
             if not _w:
                 # Reached the end, no more elements to remove
                 LOG.debug(f'modify_section: No more config sections found, exiting')
                 break
             start_element, end_element = _w
             LOG.debug(f'modify_section:   found match between {start_element} and {end_element}')
             for i, e in enumerate(self.config[start_element:end_element+1 if remove_stop_mark else end_element],
                                   start=start_element):
                 LOG.debug(f'modify_section:   remove       {i:3} {e}')
             del self.config[start_element:end_element +
                             1 if remove_stop_mark else end_element]
             if replacement:
                 # Append the replacement config at the current position
                 for i, e in enumerate(replacement, start=start_element):
                     LOG.debug(f'modify_section:   add          {i:3} {e}')
                 self.config[start_element:start_element] = replacement
             _count += 1
             _next_start = start_element + len(replacement)
 
         return _count
 
     def add_before(self, before_pattern, addition):
         '''Add config block before this element in the configuration'''
         if isinstance(addition, str):
             addition = addition.split('\n')
         elif not isinstance(addition, list):
             return ValueError("The replacement element needs to be a string or list type object")
 
         start = _find_first_element(self.config, before_pattern)
         if start < 0:
             return False
         for i, e in enumerate(addition, start=start):
             LOG.debug(f'add_before:   add          {i:3} {e}')
         self.config[start:start] = addition
         return True
 
     def __str__(self):
         return '\n'.join(self.config)
 
     def __repr__(self):
         return f'frr({repr(str(self))})'
diff --git a/smoketest/scripts/cli/test_protocols_openfabric.py b/smoketest/scripts/cli/test_protocols_openfabric.py
new file mode 100644
index 000000000..e37aed456
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_openfabric.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2024 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 unittest
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+from vyos.configsession import ConfigSessionError
+from vyos.utils.process import process_named_running
+
+PROCESS_NAME = 'fabricd'
+base_path = ['protocols', 'openfabric']
+
+domain = 'VyOS'
+net = '49.0001.1111.1111.1111.00'
+dummy_if = 'dum1234'
+address_families = ['ipv4', 'ipv6']
+
+path = base_path + ['domain', domain]
+
+class TestProtocolsOpenFabric(VyOSUnitTestSHIM.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # call base-classes classmethod
+        super(TestProtocolsOpenFabric, cls).setUpClass()
+        # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
+        cls.daemon_pid = process_named_running(PROCESS_NAME)
+        # ensure we can also run this test on a live system - so lets clean
+        # out the current configuration :)
+        cls.cli_delete(cls, base_path)
+
+    def tearDown(self):
+        self.cli_delete(base_path)
+        self.cli_commit()
+
+        # check process health and continuity
+        self.assertEqual(self.daemon_pid, process_named_running(PROCESS_NAME))
+
+    def openfabric_base_config(self):
+        self.cli_set(['interfaces', 'dummy', dummy_if])
+        self.cli_set(base_path + ['net', net])
+        for family in address_families:
+            self.cli_set(path + ['interface', dummy_if, 'address-family', family])
+
+    def test_openfabric_01_router_params(self):
+        fabric_tier = '5'
+        lsp_gen_interval = '20'
+
+        self.cli_set(base_path)
+
+        # verify() - net id and domain name are mandatory
+        with self.assertRaises(ConfigSessionError):
+            self.cli_commit()
+
+        self.openfabric_base_config()
+
+        self.cli_set(path + ['log-adjacency-changes'])
+        self.cli_set(path + ['set-overload-bit'])
+        self.cli_set(path + ['fabric-tier', fabric_tier])
+        self.cli_set(path + ['lsp-gen-interval', lsp_gen_interval])
+
+        # Commit all changes
+        self.cli_commit()
+
+        # Verify all changes
+        tmp = self.getFRRconfig(f'router openfabric {domain}', daemon='fabricd')
+        self.assertIn(f' net {net}', tmp)
+        self.assertIn(f' log-adjacency-changes', tmp)
+        self.assertIn(f' set-overload-bit', tmp)
+        self.assertIn(f' fabric-tier {fabric_tier}', tmp)
+        self.assertIn(f' lsp-gen-interval {lsp_gen_interval}', tmp)
+
+        tmp = self.getFRRconfig(f'interface {dummy_if}', daemon='fabricd')
+        self.assertIn(f' ip router openfabric {domain}', tmp)
+        self.assertIn(f' ipv6 router openfabric {domain}', tmp)
+
+    def test_openfabric_02_loopback_interface(self):
+        interface = 'lo'
+        hello_interval = '100'
+        metric = '24478'
+
+        self.openfabric_base_config()
+        self.cli_set(path + ['interface', interface, 'address-family', 'ipv4'])
+
+        self.cli_set(path + ['interface', interface, 'hello-interval', hello_interval])
+        self.cli_set(path + ['interface', interface, 'metric', metric])
+
+        # Commit all changes
+        self.cli_commit()
+
+        # Verify FRR openfabric configuration
+        tmp = self.getFRRconfig(f'router openfabric {domain}', daemon='fabricd')
+        self.assertIn(f'router openfabric {domain}', tmp)
+        self.assertIn(f' net {net}', tmp)
+
+        # Verify interface configuration
+        tmp = self.getFRRconfig(f'interface {interface}', daemon='fabricd')
+        self.assertIn(f' ip router openfabric {domain}', tmp)
+        # for lo interface 'openfabric passive' is implied
+        self.assertIn(f' openfabric passive', tmp)
+        self.assertIn(f' openfabric metric {metric}', tmp)
+
+    def test_openfabric_03_password(self):
+        password = 'foo'
+
+        self.openfabric_base_config()
+
+        self.cli_set(path + ['interface', dummy_if, 'password', 'plaintext-password', f'{password}-{dummy_if}'])
+        self.cli_set(path + ['interface', dummy_if, 'password', 'md5', f'{password}-{dummy_if}'])
+
+        # verify() - can not use both md5 and plaintext-password for password for the interface
+        with self.assertRaises(ConfigSessionError):
+            self.cli_commit()
+        self.cli_delete(path + ['interface', dummy_if, 'password', 'md5'])
+
+        self.cli_set(path + ['domain-password', 'plaintext-password', password])
+        self.cli_set(path + ['domain-password', 'md5', password])
+
+        # verify() - can not use both md5 and plaintext-password for domain-password
+        with self.assertRaises(ConfigSessionError):
+            self.cli_commit()
+        self.cli_delete(path + ['domain-password', 'md5'])
+
+        # Commit all changes
+        self.cli_commit()
+
+        # Verify all changes
+        tmp = self.getFRRconfig(f'router openfabric {domain}', daemon='fabricd')
+        self.assertIn(f' net {net}', tmp)
+        self.assertIn(f' domain-password clear {password}', tmp)
+
+        tmp = self.getFRRconfig(f'interface {dummy_if}', daemon='fabricd')
+        self.assertIn(f' openfabric password clear {password}-{dummy_if}', tmp)
+
+    def test_openfabric_multiple_domains(self):
+        domain_2 = 'VyOS_2'
+        interface = 'dum5678'
+        new_path = base_path + ['domain', domain_2]
+
+        self.openfabric_base_config()
+
+        # set same interface for 2 OpenFabric domains
+        self.cli_set(['interfaces', 'dummy', interface])
+        self.cli_set(new_path + ['interface', interface, 'address-family', 'ipv4'])
+        self.cli_set(path + ['interface', interface, 'address-family', 'ipv4'])
+
+        # verify() - same interface can be used only for one OpenFabric instance
+        with self.assertRaises(ConfigSessionError):
+            self.cli_commit()
+        self.cli_delete(path + ['interface', interface])
+
+        # Commit all changes
+        self.cli_commit()
+
+        # Verify FRR openfabric configuration
+        tmp = self.getFRRconfig(f'router openfabric {domain}', daemon='fabricd')
+        self.assertIn(f'router openfabric {domain}', tmp)
+        self.assertIn(f' net {net}', tmp)
+
+        tmp = self.getFRRconfig(f'router openfabric {domain_2}', daemon='fabricd')
+        self.assertIn(f'router openfabric {domain_2}', tmp)
+        self.assertIn(f' net {net}', tmp)
+
+        # Verify interface configuration
+        tmp = self.getFRRconfig(f'interface {dummy_if}', daemon='fabricd')
+        self.assertIn(f' ip router openfabric {domain}', tmp)
+        self.assertIn(f' ipv6 router openfabric {domain}', tmp)
+
+        tmp = self.getFRRconfig(f'interface {interface}', daemon='fabricd')
+        self.assertIn(f' ip router openfabric {domain_2}', tmp)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/src/conf_mode/protocols_openfabric.py b/src/conf_mode/protocols_openfabric.py
new file mode 100644
index 000000000..8e8c50c06
--- /dev/null
+++ b/src/conf_mode/protocols_openfabric.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2024 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/>.
+
+from sys import exit
+
+from vyos.base import Warning
+from vyos.config import Config
+from vyos.configdict import node_changed
+from vyos.configverify import verify_interface_exists
+from vyos.template import render_to_string
+from vyos import ConfigError
+from vyos import frr
+from vyos import airbag
+
+airbag.enable()
+
+def get_config(config=None):
+    if config:
+        conf = config
+    else:
+        conf = Config()
+
+    base_path = ['protocols', 'openfabric']
+
+    openfabric = conf.get_config_dict(base_path, key_mangling=('-', '_'),
+                                get_first_key=True,
+                                no_tag_node_value_mangle=True)
+
+    # Remove per domain MPLS configuration - get a list of all changed Openfabric domains
+    # (removed and added) so that they will be properly rendered for the FRR config.
+    openfabric['domains_all'] = list(conf.list_nodes(' '.join(base_path) + f' domain') +
+                                         node_changed(conf, base_path + ['domain']))
+
+    # Get a list of all interfaces
+    openfabric['interfaces_all'] = []
+    for domain in openfabric['domains_all']:
+        interfaces_modified = list(node_changed(conf, base_path + ['domain', domain, 'interface']) +
+                                  conf.list_nodes(' '.join(base_path) + f' domain {domain} interface'))
+        openfabric['interfaces_all'].extend(interfaces_modified)
+
+    if not conf.exists(base_path):
+        openfabric.update({'deleted': ''})
+
+    return openfabric
+
+def verify(openfabric):
+    # bail out early - looks like removal from running config
+    if not openfabric or 'deleted' in openfabric:
+        return None
+
+    if 'net' not in openfabric:
+        raise ConfigError('Network entity is mandatory!')
+
+    # last byte in OpenFabric area address must be 0
+    tmp = openfabric['net'].split('.')
+    if int(tmp[-1]) != 0:
+        raise ConfigError('Last byte of OpenFabric network entity title must always be 0!')
+
+    if 'domain' not in openfabric:
+        raise ConfigError('OpenFabric domain name is mandatory!')
+
+    interfaces_used = []
+
+    for domain, domain_config in openfabric['domain'].items():
+        # If interface not set
+        if 'interface' not in domain_config:
+            raise ConfigError(f'Interface used for routing updates in OpenFabric "{domain}" is mandatory!')
+
+        for iface, iface_config in domain_config['interface'].items():
+            verify_interface_exists(openfabric, iface)
+
+            # interface can be activated only on one OpenFabric instance
+            if iface in interfaces_used:
+                raise ConfigError(f'Interface {iface} is already used in different OpenFabric instance!')
+
+            if 'address_family' not in iface_config or len(iface_config['address_family']) < 1:
+                raise ConfigError(f'Need to specify address family for the interface "{iface}"!')
+
+            # If md5 and plaintext-password set at the same time
+            if 'password' in iface_config:
+                if {'md5', 'plaintext_password'} <= set(iface_config['password']):
+                    raise ConfigError(f'Can use either md5 or plaintext-password for password for the interface!')
+
+            if iface == 'lo' and 'passive' not in iface_config:
+                Warning('For loopback interface passive mode is implied!')
+
+            interfaces_used.append(iface)
+
+        # If md5 and plaintext-password set at the same time
+        password = 'domain_password'
+        if password in domain_config:
+            if {'md5', 'plaintext_password'} <= set(domain_config[password]):
+                raise ConfigError(f'Can use either md5 or plaintext-password for domain-password!')
+
+    return None
+
+def generate(openfabric):
+    if not openfabric or 'deleted' in openfabric:
+        return None
+
+    openfabric['frr_fabricd_config'] = render_to_string('frr/fabricd.frr.j2', openfabric)
+    return None
+
+def apply(openfabric):
+    openfabric_daemon = 'fabricd'
+
+    # Save original configuration prior to starting any commit actions
+    frr_cfg = frr.FRRConfig()
+
+    frr_cfg.load_configuration(openfabric_daemon)
+    for domain in openfabric['domains_all']:
+        frr_cfg.modify_section(f'^router openfabric {domain}', stop_pattern='^exit', remove_stop_mark=True)
+
+    for interface in openfabric['interfaces_all']:
+        frr_cfg.modify_section(f'^interface {interface}', stop_pattern='^exit', remove_stop_mark=True)
+
+    if 'frr_fabricd_config' in openfabric:
+        frr_cfg.add_before(frr.default_add_before, openfabric['frr_fabricd_config'])
+
+    frr_cfg.commit_configuration(openfabric_daemon)
+
+    return None
+
+if __name__ == '__main__':
+    try:
+        c = get_config()
+        verify(c)
+        generate(c)
+        apply(c)
+    except ConfigError as e:
+        print(e)
+        exit(1)
diff --git a/src/op_mode/restart_frr.py b/src/op_mode/restart_frr.py
index 8841b0eca..83146f5ec 100755
--- a/src/op_mode/restart_frr.py
+++ b/src/op_mode/restart_frr.py
@@ -1,181 +1,181 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2019-2023 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 argparse
 import logging
 import psutil
 
 from logging.handlers import SysLogHandler
 from shutil import rmtree
 
 from vyos.base import Warning
 from vyos.utils.io import ask_yes_no
 from vyos.utils.file import makedir
 from vyos.utils.process import call
 from vyos.utils.process import process_named_running
 
 # some default values
 watchfrr = '/usr/lib/frr/watchfrr.sh'
 vtysh = '/usr/bin/vtysh'
 frrconfig_tmp = '/tmp/frr_restart'
 
 # configure logging
 logger = logging.getLogger(__name__)
 logs_handler = SysLogHandler('/dev/log')
 logs_handler.setFormatter(logging.Formatter('%(filename)s: %(message)s'))
 logger.addHandler(logs_handler)
 logger.setLevel(logging.INFO)
 
 # check if it is safe to restart FRR
 def _check_safety():
     try:
         # print warning
         if not ask_yes_no('WARNING: This is a potentially unsafe function!\n' \
                           'You may lose the connection to the router or active configuration after\n' \
                           'running this command. Use it at your own risk!\n\n'
                           'Continue?'):
             return False
 
         # check if another restart process already running
         if len([process for process in psutil.process_iter(attrs=['pid', 'name', 'cmdline']) if 'python' in process.info['name'] and 'restart_frr.py' in process.info['cmdline'][1]]) > 1:
             message = 'Another restart_frr.py process is already running!'
             logger.error(message)
             if not ask_yes_no(f'\n{message} It is unsafe to continue.\n\n' \
                               'Do you want to process anyway?'):
                 return False
 
         # check if watchfrr.sh is running
         tmp = os.path.basename(watchfrr)
         if process_named_running(tmp):
             message = f'Another {tmp} process is already running.'
             logger.error(message)
             if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \
                               'Do you want to process anyway?'):
                 return False
 
         # check if vtysh is running
         if process_named_running('vtysh'):
             message = 'vtysh process is executed by another task.'
             logger.error(message)
             if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \
                               'Do you want to process anyway?'):
                 return False
 
         # check if temporary directory exists
         if os.path.exists(frrconfig_tmp):
             message = f'Temporary directory "{frrconfig_tmp}" already exists!'
             logger.error(message)
             if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \
                               'Do you want to process anyway?'):
                 return False
 
     except:
         logger.error("Something goes wrong in _check_safety()")
         return False
 
     # return True if all check was passed or user confirmed to ignore they results
     return True
 
 # write active config to file
 def _write_config():
     # create temporary directory
     makedir(frrconfig_tmp)
     # save frr.conf to it
     command = f'{vtysh} -n -w --config_dir {frrconfig_tmp} 2> /dev/null'
     return_code = call(command)
     if return_code != 0:
         logger.error(f'Failed to save active config: "{command}" returned exit code: {return_code}')
         return False
     logger.info(f'Active config saved to {frrconfig_tmp}')
     return True
 
 # clear and remove temporary directory
 def _cleanup():
     if os.path.isdir(frrconfig_tmp):
         rmtree(frrconfig_tmp)
 
 # restart daemon
 def _daemon_restart(daemon):
     command = f'{watchfrr} restart {daemon}'
     return_code = call(command)
     if not return_code == 0:
         logger.error(f'Failed to restart daemon "{daemon}"!')
         return False
 
     # return True if restarted successfully
     logger.info(f'Daemon "{daemon}" restarted!')
     return True
 
 # reload old config
 def _reload_config(daemon):
     if daemon != '':
         command = f'{vtysh} -n -b --config_dir {frrconfig_tmp} -d {daemon} 2> /dev/null'
     else:
         command = f'{vtysh} -n -b --config_dir {frrconfig_tmp} 2> /dev/null'
 
     return_code = call(command)
     if not return_code == 0:
         logger.error('Failed to re-install configuration!')
         return False
 
     # return True if restarted successfully
     logger.info('Configuration re-installed successfully!')
     return True
 
 # define program arguments
 cmd_args_parser = argparse.ArgumentParser(description='restart frr daemons')
 cmd_args_parser.add_argument('--action', choices=['restart'], required=True, help='action to frr daemons')
-cmd_args_parser.add_argument('--daemon', choices=['zebra', 'staticd', 'bgpd', 'eigrpd', 'ospfd', 'ospf6d', 'ripd', 'ripngd', 'isisd', 'pimd', 'pim6d', 'ldpd', 'babeld', 'bfdd'], required=False,  nargs='*', help='select single or multiple daemons')
+cmd_args_parser.add_argument('--daemon', choices=['zebra', 'staticd', 'bgpd', 'eigrpd', 'ospfd', 'ospf6d', 'ripd', 'ripngd', 'isisd', 'pimd', 'pim6d', 'ldpd', 'babeld', 'bfdd', 'fabricd'], required=False,  nargs='*', help='select single or multiple daemons')
 # parse arguments
 cmd_args = cmd_args_parser.parse_args()
 
 # main logic
 # restart daemon
 if cmd_args.action == 'restart':
     # check if it is safe to restart FRR
     if not _check_safety():
         print("\nOne of the safety checks was failed or user aborted command. Exiting.")
         exit(1)
 
     if not _write_config():
         print("Failed to save active config")
         _cleanup()
         exit(1)
 
     # a little trick to make further commands more clear
     if not cmd_args.daemon:
         cmd_args.daemon = ['']
 
     # check all daemons if they are running
     if cmd_args.daemon != ['']:
         for daemon in cmd_args.daemon:
             if not process_named_running(daemon):
                 Warning('some of listed daemons are not running!')
 
     # run command to restart daemon
     for daemon in cmd_args.daemon:
         if not _daemon_restart(daemon):
             print('Failed to restart daemon: {daemon}')
             _cleanup()
             exit(1)
         # reinstall old configuration
         _reload_config(daemon)
 
     # cleanup after all actions
     _cleanup()
 
 exit(0)