]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #3448 from chiragshah6/evpn_dev1
authorSri Mohana Singamsetty <srimohans@gmail.com>
Wed, 19 Dec 2018 02:12:18 +0000 (18:12 -0800)
committerGitHub <noreply@github.com>
Wed, 19 Dec 2018 02:12:18 +0000 (18:12 -0800)
bgpd: l3vni add-del handle non-defualt route-target

203 files changed:
.github/ISSUE_TEMPLATE.md
alpine/APKBUILD.in
bgpd/BGP4-MIB.txt [deleted file]
bgpd/bgp_addpath.c
bgpd/bgp_dump.c
bgpd/bgp_evpn.c
bgpd/bgp_evpn_vty.c
bgpd/bgp_flowspec_vty.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_rpki.c
bgpd/bgp_snmp.c
bgpd/bgp_table.c
bgpd/bgp_table.h
bgpd/bgp_updgrp_adv.c
bgpd/bgp_vpn.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/rfapi/rfapi.c
bgpd/rfapi/rfapi_import.c
bgpd/rfapi/rfapi_vty.c
bgpd/rfapi/vnc_export_bgp.c
bgpd/rfapi/vnc_import_bgp.c
bgpd/rfapi/vnc_zebra.c
bgpd/subdir.am
configure.ac
debianpkg/README.Debian
debianpkg/backports/ubuntu12.04/debian/control [deleted file]
debianpkg/backports/ubuntu12.04/debian/frr.install [deleted symlink]
debianpkg/backports/ubuntu12.04/debian/frr.postinst [deleted symlink]
debianpkg/backports/ubuntu12.04/debian/frr.postrm [deleted symlink]
debianpkg/backports/ubuntu12.04/debian/rules [deleted file]
debianpkg/backports/ubuntu12.04/debian/source/format [deleted file]
debianpkg/backports/ubuntu12.04/exclude [deleted file]
debianpkg/backports/ubuntu12.04/versionext [deleted file]
debianpkg/backports/ubuntu14.04/debian/frr.install
debianpkg/backports/ubuntu14.04/debian/frr.postinst [deleted file]
debianpkg/backports/ubuntu14.04/debian/frr.postrm [deleted file]
debianpkg/backports/ubuntu14.04/debian/rules
debianpkg/rules
debianpkg/subdir.am
doc/developer/building-frr-for-alpine.rst
doc/developer/building-frr-for-ubuntu1204.rst
doc/developer/building-frr-for-ubuntu1404.rst
doc/developer/building-frr-for-ubuntu1604.rst
doc/developer/building-frr-for-ubuntu1804.rst
doc/developer/workflow.rst
doc/user/index.rst
doc/user/rpki.rst
doc/user/setup.rst
eigrpd/EIGRP-MIB.txt [deleted file]
eigrpd/subdir.am
fpm/subdir.am
isisd/fabricd.c
isisd/fabricd.h
isisd/isis_adjacency.c
isisd/isis_circuit.c
isisd/isis_circuit.h
isisd/isis_cli.c [new file with mode: 0644]
isisd/isis_cli.h [new file with mode: 0644]
isisd/isis_lsp.c
isisd/isis_lsp.h
isisd/isis_main.c
isisd/isis_northbound.c [new file with mode: 0644]
isisd/isis_pdu.c
isisd/isis_pdu.h
isisd/isis_pdu_counter.c [new file with mode: 0644]
isisd/isis_pdu_counter.h [new file with mode: 0644]
isisd/isis_redist.c
isisd/isis_redist.h
isisd/isis_te.c
isisd/isis_tlvs.c
isisd/isis_tlvs.h
isisd/isis_tx_queue.c
isisd/isis_tx_queue.h
isisd/isis_vty_common.c
isisd/isis_vty_common.h
isisd/isis_vty_fabricd.c
isisd/isis_vty_isisd.c [deleted file]
isisd/isisd.c
isisd/isisd.h
isisd/subdir.am
lib/hook.c
lib/hook.h
lib/lib_errors.c
lib/lib_errors.h
lib/libfrr.c
lib/module.c
lib/module.h
lib/northbound.c
lib/northbound.h
lib/northbound_cli.c
lib/northbound_cli.h
lib/northbound_confd.c
lib/northbound_sysrepo.c
lib/vty.c
lib/vty.h
lib/workqueue.c
lib/workqueue.h
lib/yang.c
lib/yang_wrappers.c
lib/zebra.h
ospf6d/OSPFv3-MIB.txt [deleted file]
ospfd/OSPF-MIB.txt [deleted file]
ospfd/OSPF-TRAP-MIB.txt [deleted file]
ospfd/ospf_te.c
ospfd/ospf_vty.c
ospfd/subdir.am
redhat/daemons
redhat/frr.init
redhat/frr.spec.in
ripd/RIPv2-MIB.txt [deleted file]
ripd/rip_cli.c
ripd/rip_debug.c
ripd/rip_debug.h
ripd/rip_interface.c
ripd/rip_northbound.c
ripd/rip_routemap.c
ripd/rip_zebra.c
ripd/ripd.c
ripd/ripd.h
ripd/subdir.am
ripngd/ripng_cli.c [new file with mode: 0644]
ripngd/ripng_cli.h [new file with mode: 0644]
ripngd/ripng_debug.c
ripngd/ripng_debug.h
ripngd/ripng_interface.c
ripngd/ripng_main.c
ripngd/ripng_northbound.c [new file with mode: 0644]
ripngd/ripng_offset.c
ripngd/ripng_routemap.c
ripngd/ripng_zebra.c
ripngd/ripngd.c
ripngd/ripngd.h
ripngd/subdir.am
tests/bgpd/test_peer_attr.c
tests/helpers/c/main.c
tests/lib/cli/common_cli.c
tests/lib/cli/test_cli.refout.in
tests/lib/cli/test_commands.c
tests/lib/northbound/test_oper_data.c
tests/topotests/all-protocol-startup/r1/show_bgp_ipv4-post6.1.ref [new file with mode: 0644]
tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_post6.1.ref [new file with mode: 0644]
tests/topotests/bgp-vrf-route-leak-basic/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp-vrf-route-leak-basic/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp-vrf-route-leak-basic/setup_vrfs [new file with mode: 0644]
tests/topotests/bgp-vrf-route-leak-basic/test_bgp.py [new file with mode: 0644]
tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf
tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf
tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py
tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/adjacencies.py
tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py
tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py
tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py
tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1-post6.1.ref [new file with mode: 0644]
tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2-post6.1.ref [new file with mode: 0644]
tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3-post6.1.ref [new file with mode: 0644]
tests/topotests/docker/README.md
tests/topotests/docker/frr-topotests.sh
tests/topotests/lib/bgprib.py
tests/topotests/lib/topogen.py
tests/topotests/lib/topotest.py
tools/.gitignore
tools/checkpatch.pl
tools/etc/default/frr [deleted file]
tools/etc/frr/daemons
tools/etc/frr/daemons.conf
tools/etc/frr/vtysh.conf
tools/frr-reload.py
tools/frr.in
tools/frr.service
tools/frrcommon.sh.in [new file with mode: 0644]
tools/frrinit.sh.in [new file with mode: 0644]
tools/subdir.am
tools/watchfrr.sh.in [new file with mode: 0644]
vtysh/vtysh.c
vtysh/vtysh.h
vtysh/vtysh_main.c
watchfrr/watchfrr.c
watchfrr/watchfrr.h
watchfrr/watchfrr_vty.c
yang/confd/confd.frr-ripngd.yang [new file with mode: 0644]
yang/frr-isisd.yang [new file with mode: 0644]
yang/frr-ripngd.yang [new file with mode: 0644]
yang/frr-test-module.yang
yang/subdir.am
zebra/kernel_socket.c
zebra/rib.h
zebra/rt_netlink.c
zebra/zebra_netns_notify.c
zebra/zebra_ns.c
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_router.c
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zserv.c
zebra/zserv.h

index cedca17729bfd1535614fc4242d062573c055cd0..62d3c2350ccf4c9b5ec5e60c8210e685f0bd1b18 100644 (file)
@@ -1,3 +1,12 @@
+# HOW TO GET YOUR ISSUE ADDRESSED FASTER
+
+* When reporting a crash provide a backtrace
+* When pasting configs, logs, shell output, backtraces, and other large chunks
+  of text [use Markdown code blocks](https://github.github.com/gfm/#fenced-code-blocks)
+* Include the FRR version; if you built from Git, please provide the commit
+  hash
+* Write your issue in English
+
 ### How to submit an issue
 Please use this text as a template and replace text in the sections or remove
 the entire section if it does not apply to your issue. For example in case of
index 42896c21a55795b4db21791d301676aa55a70d35..969b85f5240d52c6e14146a346dbed8ed7f6e184 100644 (file)
@@ -23,7 +23,7 @@ makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
 checkdepends="pytest py-setuptools"
 install="$pkgname.pre-install $pkgname.pre-deinstall $pkgname.post-deinstall"
 subpackages="$pkgname-dev $pkgname-doc $pkgname-dbg"
-source="$pkgname-$pkgver.tar.gz docker-start daemons daemons.conf"
+source="$pkgname-$pkgver.tar.gz docker-start daemons"
 
 builddir="$srcdir"/$pkgname-$pkgver
 
@@ -62,7 +62,6 @@ package() {
 
        install -Dm755 "$srcdir"/docker-start "$pkgdir"$_sbindir
        install -Dm644 "$srcdir"/daemons "$pkgdir"$_sysconfdir
-       install -Dm644 "$srcdir"/daemons.conf "$pkgdir"$_sysconfdir
        install -d "$pkgdir"/etc/init.d
        ln -s ${_sbindir}/frr "$pkgdir"/etc/init.d/frr
 }
diff --git a/bgpd/BGP4-MIB.txt b/bgpd/BGP4-MIB.txt
deleted file mode 100644 (file)
index c911316..0000000
+++ /dev/null
@@ -1,929 +0,0 @@
-    BGP4-MIB DEFINITIONS ::= BEGIN
-
-        IMPORTS
-            MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
-            IpAddress, Integer32, Counter32, Gauge32, mib-2
-                FROM SNMPv2-SMI
-            MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
-                FROM SNMPv2-CONF;
-
-        bgp MODULE-IDENTITY
-            LAST-UPDATED "9902100000Z"
-            ORGANIZATION "IETF IDR Working Group"
-            CONTACT-INFO "E-mail:  idr@merit.net
-
-                          Susan Hares  (Editor)
-                          Merit Network
-                          4251 Plymouth Road
-                          Suite C
-                          Ann Arbor, MI 48105-2785
-                          Tel: +1 734 936 2095
-                          Fax: +1 734 647 3185
-                          E-mail: skh@merit.edu
-
-                          Jeff Johnson (Editor)
-                          RedBack Networks, Inc.
-                          1389 Moffett Park Drive
-                          Sunnyvale, CA  94089-1134
-                          Tel: +1 408 548 3516
-                          Fax: +1 408 548 3599
-                          E-mail: jeff@redback.com"
-            DESCRIPTION
-                    "The MIB module for BGP-4."
-            REVISION    "9902100000Z"
-            DESCRIPTION
-                    "Corrected duplicate OBJECT IDENTIFIER
-                     assignment in the conformance information."
-            REVISION    "9601080000Z"
-            DESCRIPTION
-                    "1) Fixed the definitions of the traps to
-                     make them equivalent to their initial
-                     definition in RFC 1269.
-                     2) Added compliance and conformance info."
-            ::= { mib-2 15 }
-
-        bgpVersion OBJECT-TYPE
-            SYNTAX     OCTET STRING (SIZE (1..255))
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "Vector of supported BGP protocol version
-                    numbers.  Each peer negotiates the version
-                    from this vector.  Versions are identified
-                    via the string of bits contained within this
-                    object.  The first octet contains bits 0 to
-                    7, the second octet contains bits 8 to 15,
-                    and so on, with the most significant bit
-                    referring to the lowest bit number in the
-                    octet (e.g., the MSB of the first octet
-                    refers to bit 0).  If a bit, i, is present
-                    and set, then the version (i+1) of the BGP
-                    is supported."
-            ::= { bgp 1 }
-
-        bgpLocalAs OBJECT-TYPE
-            SYNTAX     INTEGER (0..65535)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The local autonomous system number."
-            ::= { bgp 2 }
-
-
-
-        -- BGP Peer table.  This table contains, one entry per BGP
-        -- peer, information about the BGP peer.
-
-        bgpPeerTable OBJECT-TYPE
-            SYNTAX     SEQUENCE OF BgpPeerEntry
-            MAX-ACCESS not-accessible
-            STATUS     current
-            DESCRIPTION
-                    "BGP peer table.  This table contains,
-                    one entry per BGP peer, information about the
-                    connections with BGP peers."
-            ::= { bgp 3 }
-
-        bgpPeerEntry OBJECT-TYPE
-            SYNTAX     BgpPeerEntry
-            MAX-ACCESS not-accessible
-            STATUS     current
-            DESCRIPTION
-                    "Entry containing information about the
-                    connection with a BGP peer."
-            INDEX { bgpPeerRemoteAddr }
-            ::= { bgpPeerTable 1 }
-
-        BgpPeerEntry ::= SEQUENCE {
-                bgpPeerIdentifier
-                    IpAddress,
-                bgpPeerState
-                    INTEGER,
-                bgpPeerAdminStatus
-                    INTEGER,
-                bgpPeerNegotiatedVersion
-                    Integer32,
-                bgpPeerLocalAddr
-                    IpAddress,
-                bgpPeerLocalPort
-                    INTEGER,
-                bgpPeerRemoteAddr
-                    IpAddress,
-                bgpPeerRemotePort
-                    INTEGER,
-                bgpPeerRemoteAs
-                    INTEGER,
-                bgpPeerInUpdates
-                    Counter32,
-                bgpPeerOutUpdates
-                    Counter32,
-                bgpPeerInTotalMessages
-                    Counter32,
-                bgpPeerOutTotalMessages
-                    Counter32,
-                bgpPeerLastError
-                    OCTET STRING,
-                bgpPeerFsmEstablishedTransitions
-                    Counter32,
-                bgpPeerFsmEstablishedTime
-                    Gauge32,
-                bgpPeerConnectRetryInterval
-                    INTEGER,
-                bgpPeerHoldTime
-                    INTEGER,
-                bgpPeerKeepAlive
-                    INTEGER,
-                bgpPeerHoldTimeConfigured
-                    INTEGER,
-                bgpPeerKeepAliveConfigured
-                    INTEGER,
-                bgpPeerMinASOriginationInterval
-                    INTEGER,
-                bgpPeerMinRouteAdvertisementInterval
-                    INTEGER,
-                bgpPeerInUpdateElapsedTime
-                    Gauge32
-                }
-
-        bgpPeerIdentifier OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The BGP Identifier of this entry's BGP peer."
-            ::= { bgpPeerEntry 1 }
-
-        bgpPeerState OBJECT-TYPE
-            SYNTAX     INTEGER {
-                                idle(1),
-                                connect(2),
-                                active(3),
-                                opensent(4),
-                                openconfirm(5),
-                                established(6)
-                       }
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The BGP peer connection state."
-            ::= { bgpPeerEntry 2 }
-
-        bgpPeerAdminStatus OBJECT-TYPE
-            SYNTAX     INTEGER {
-                                stop(1),
-                                start(2)
-                       }
-            MAX-ACCESS read-write
-            STATUS     current
-            DESCRIPTION
-                    "The desired state of the BGP connection.  A
-                    transition from 'stop' to 'start' will cause
-                    the BGP Start Event to be generated.  A
-                    transition from 'start' to 'stop' will cause
-                    the BGP Stop Event to be generated.  This
-                    parameter can be used to restart BGP peer
-                    connections.  Care should be used in providing
-                    write access to this object without adequate
-                    authentication."
-            ::= { bgpPeerEntry 3 }
-
-        bgpPeerNegotiatedVersion OBJECT-TYPE
-            SYNTAX     Integer32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The negotiated version of BGP running between
-                    the two peers."
-            ::= { bgpPeerEntry 4 }
-
-        bgpPeerLocalAddr OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The local IP address of this entry's BGP
-                    connection."
-            ::= { bgpPeerEntry 5 }
-
-        bgpPeerLocalPort OBJECT-TYPE
-            SYNTAX     INTEGER (0..65535)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The local port for the TCP connection between
-                    the BGP peers."
-            ::= { bgpPeerEntry 6 }
-
-        bgpPeerRemoteAddr OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The remote IP address of this entry's BGP
-                    peer."
-            ::= { bgpPeerEntry 7 }
-
-        bgpPeerRemotePort OBJECT-TYPE
-            SYNTAX     INTEGER (0..65535)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The remote port for the TCP connection between
-                    the BGP peers.  Note that the objects
-                    bgpPeerLocalAddr, bgpPeerLocalPort,
-                    bgpPeerRemoteAddr and bgpPeerRemotePort
-                    provide the appropriate reference to the
-                    standard MIB TCP connection table."
-            ::= { bgpPeerEntry 8 }
-
-        bgpPeerRemoteAs OBJECT-TYPE
-            SYNTAX     INTEGER (0..65535)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The remote autonomous system number."
-            ::= { bgpPeerEntry 9 }
-
-        bgpPeerInUpdates OBJECT-TYPE
-            SYNTAX     Counter32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The number of BGP UPDATE messages received on
-                    this connection.  This object should be
-                    initialized to zero (0) when the connection is
-                    established."
-            ::= { bgpPeerEntry 10 }
-
-        bgpPeerOutUpdates OBJECT-TYPE
-            SYNTAX     Counter32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The number of BGP UPDATE messages transmitted
-                    on this connection.  This object should be
-                    initialized to zero (0) when the connection is
-                    established."
-            ::= { bgpPeerEntry 11 }
-
-        bgpPeerInTotalMessages OBJECT-TYPE
-            SYNTAX     Counter32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The total number of messages received from the
-                    remote peer on this connection.  This object
-                    should be initialized to zero when the
-                    connection is established."
-            ::= { bgpPeerEntry 12 }
-
-        bgpPeerOutTotalMessages OBJECT-TYPE
-            SYNTAX     Counter32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The total number of messages transmitted to
-                    the remote peer on this connection.  This object
-                    should be initialized to zero when the
-                    connection is established."
-            ::= { bgpPeerEntry 13 }
-
-        bgpPeerLastError OBJECT-TYPE
-            SYNTAX     OCTET STRING (SIZE (2))
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The last error code and subcode seen by this
-                    peer on this connection.  If no error has
-                    occurred, this field is zero.  Otherwise, the
-                    first byte of this two byte OCTET STRING
-                    contains the error code, and the second byte
-                    contains the subcode."
-            ::= { bgpPeerEntry 14 }
-
-        bgpPeerFsmEstablishedTransitions OBJECT-TYPE
-            SYNTAX     Counter32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The total number of times the BGP FSM
-                    transitioned into the established state."
-            ::= { bgpPeerEntry 15 }
-
-        bgpPeerFsmEstablishedTime OBJECT-TYPE
-            SYNTAX     Gauge32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "This timer indicates how long (in seconds) this
-                    peer has been in the Established state or how long
-                    since this peer was last in the Established state.
-                    It is set to zero when a new peer is configured or
-                    the router is booted."
-            ::= { bgpPeerEntry 16 }
-
-        bgpPeerConnectRetryInterval OBJECT-TYPE
-            SYNTAX     INTEGER (1..65535)
-            MAX-ACCESS read-write
-            STATUS     current
-            DESCRIPTION
-                    "Time interval in seconds for the ConnectRetry
-                    timer.  The suggested value for this timer is
-                    120 seconds."
-            ::= { bgpPeerEntry 17 }
-
-        bgpPeerHoldTime OBJECT-TYPE
-            SYNTAX     INTEGER  ( 0 | 3..65535 )
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "Time interval in seconds for the Hold Timer
-                    established with the peer.  The value of this
-                    object is calculated by this BGP speaker by
-                    using the smaller of the value in
-                    bgpPeerHoldTimeConfigured and the Hold Time
-                    received in the OPEN message.  This value
-                    must be at lease three seconds if it is not
-                    zero (0) in which case the Hold Timer has
-                    not been established with the peer, or, the
-                    value of bgpPeerHoldTimeConfigured is zero (0)."
-            ::= { bgpPeerEntry 18 }
-
-        bgpPeerKeepAlive OBJECT-TYPE
-            SYNTAX     INTEGER ( 0 | 1..21845 )
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "Time interval in seconds for the KeepAlive
-                    timer established with the peer.  The value of
-                    this object is calculated by this BGP speaker
-                    such that, when compared with bgpPeerHoldTime,
-                    it has the same proportion as what
-                    bgpPeerKeepAliveConfigured has when compared
-                    with bgpPeerHoldTimeConfigured.  If the value
-                    of this object is zero (0), it indicates that
-                    the KeepAlive timer has not been established
-                    with the peer, or, the value of
-                    bgpPeerKeepAliveConfigured is zero (0)."
-            ::= { bgpPeerEntry 19 }
-
-        bgpPeerHoldTimeConfigured OBJECT-TYPE
-            SYNTAX     INTEGER ( 0 | 3..65535 )
-            MAX-ACCESS read-write
-            STATUS     current
-            DESCRIPTION
-                    "Time interval in seconds for the Hold Time
-                    configured for this BGP speaker with this peer.
-                    This value is placed in an OPEN message sent to
-                    this peer by this BGP speaker, and is compared
-                    with the Hold Time field in an OPEN message
-                    received from the peer when determining the Hold
-                    Time (bgpPeerHoldTime) with the peer.  This value
-                    must not be less than three seconds if it is not
-                    zero (0) in which case the Hold Time is NOT to be
-                    established with the peer.  The suggested value for
-                    this timer is 90 seconds."
-            ::= { bgpPeerEntry 20 }
-
-        bgpPeerKeepAliveConfigured OBJECT-TYPE
-            SYNTAX     INTEGER ( 0 | 1..21845 )
-            MAX-ACCESS read-write
-            STATUS     current
-            DESCRIPTION
-                    "Time interval in seconds for the KeepAlive timer
-                    configured for this BGP speaker with this peer.
-                    The value of this object will only determine the
-                    KEEPALIVE messages' frequency relative to the value
-                    specified in bgpPeerHoldTimeConfigured; the actual
-                    time interval for the KEEPALIVE messages is
-                    indicated by bgpPeerKeepAlive.  A reasonable
-                    maximum value for this timer would be configured to
-                    be one third of that of bgpPeerHoldTimeConfigured.
-                    If the value of this object is zero (0), no
-                    periodical KEEPALIVE messages are sent to the peer
-                    after the BGP connection has been established.  The
-                    suggested value for this timer is 30 seconds."
-            ::= { bgpPeerEntry 21 }
-
-        bgpPeerMinASOriginationInterval OBJECT-TYPE
-            SYNTAX     INTEGER (1..65535)
-            MAX-ACCESS read-write
-            STATUS     current
-            DESCRIPTION
-                    "Time interval in seconds for the
-                    MinASOriginationInterval timer.
-                    The suggested value for this timer is 15 seconds."
-            ::= { bgpPeerEntry 22 }
-
-        bgpPeerMinRouteAdvertisementInterval OBJECT-TYPE
-            SYNTAX     INTEGER (1..65535)
-            MAX-ACCESS read-write
-            STATUS     current
-            DESCRIPTION
-                    "Time interval in seconds for the
-                    MinRouteAdvertisementInterval timer.
-                    The suggested value for this timer is 30 seconds."
-            ::= { bgpPeerEntry 23 }
-
-        bgpPeerInUpdateElapsedTime OBJECT-TYPE
-            SYNTAX     Gauge32
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "Elapsed time in seconds since the last BGP
-                    UPDATE message was received from the peer.
-                    Each time bgpPeerInUpdates is incremented,
-                    the value of this object is set to zero (0)."
-            ::= { bgpPeerEntry 24 }
-
-
-
-        bgpIdentifier OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The BGP Identifier of local system."
-            ::= { bgp 4 }
-
-
-
-        -- Received Path Attribute Table.  This table contains,
-        -- one entry per path to a network, path attributes
-        -- received from all peers running BGP version 3 or less.
-        -- This table is obsolete, having been replaced in
-        -- functionality with the bgp4PathAttrTable.
-
-        bgpRcvdPathAttrTable OBJECT-TYPE
-            SYNTAX     SEQUENCE OF BgpPathAttrEntry
-            MAX-ACCESS not-accessible
-            STATUS     obsolete
-            DESCRIPTION
-                    "The BGP Received Path Attribute Table contains
-                    information about paths to destination networks
-                    received from all peers running BGP version 3 or
-                    less."
-            ::= { bgp 5 }
-
-        bgpPathAttrEntry OBJECT-TYPE
-            SYNTAX     BgpPathAttrEntry
-            MAX-ACCESS not-accessible
-            STATUS     obsolete
-            DESCRIPTION
-                    "Information about a path to a network."
-            INDEX { bgpPathAttrDestNetwork,
-                    bgpPathAttrPeer        }
-            ::= { bgpRcvdPathAttrTable 1 }
-
-        BgpPathAttrEntry ::= SEQUENCE {
-            bgpPathAttrPeer
-                 IpAddress,
-            bgpPathAttrDestNetwork
-                 IpAddress,
-            bgpPathAttrOrigin
-                 INTEGER,
-            bgpPathAttrASPath
-                 OCTET STRING,
-            bgpPathAttrNextHop
-                 IpAddress,
-            bgpPathAttrInterASMetric
-                 Integer32
-        }
-
-        bgpPathAttrPeer OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     obsolete
-            DESCRIPTION
-                    "The IP address of the peer where the path
-                    information was learned."
-            ::= { bgpPathAttrEntry 1 }
-
-        bgpPathAttrDestNetwork OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     obsolete
-            DESCRIPTION
-                    "The address of the destination network."
-            ::= { bgpPathAttrEntry 2 }
-
-        bgpPathAttrOrigin OBJECT-TYPE
-            SYNTAX     INTEGER {
-                           igp(1),-- networks are interior
-                           egp(2),-- networks learned via EGP
-                           incomplete(3) -- undetermined
-                       }
-            MAX-ACCESS read-only
-            STATUS     obsolete
-            DESCRIPTION
-                 "The ultimate origin of the path information."
-            ::= { bgpPathAttrEntry 3 }
-
-        bgpPathAttrASPath OBJECT-TYPE
-            SYNTAX     OCTET STRING (SIZE (2..255))
-            MAX-ACCESS read-only
-            STATUS     obsolete
-            DESCRIPTION
-                    "The set of ASs that must be traversed to reach
-                    the network.  This object is probably best
-                    represented as SEQUENCE OF INTEGER.  For SMI
-                    compatibility, though, it is represented as
-                    OCTET STRING.  Each AS is represented as a pair
-                    of octets according to the following algorithm:
-
-                        first-byte-of-pair = ASNumber / 256;
-                        second-byte-of-pair = ASNumber & 255;"
-            ::= { bgpPathAttrEntry 4 }
-
-        bgpPathAttrNextHop OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     obsolete
-            DESCRIPTION
-                    "The address of the border router that should
-                    be used for the destination network."
-            ::= { bgpPathAttrEntry 5 }
-
-        bgpPathAttrInterASMetric OBJECT-TYPE
-            SYNTAX     Integer32
-            MAX-ACCESS read-only
-            STATUS     obsolete
-            DESCRIPTION
-                    "The optional inter-AS metric.  If this
-                    attribute has not been provided for this route,
-                    the value for this object is 0."
-            ::= { bgpPathAttrEntry 6 }
-
-
-
-        -- BGP-4 Received Path Attribute Table.  This table contains,
-        -- one entry per path to a network, path attributes
-        -- received from all peers running BGP-4.
-
-        bgp4PathAttrTable OBJECT-TYPE
-            SYNTAX     SEQUENCE OF Bgp4PathAttrEntry
-            MAX-ACCESS not-accessible
-            STATUS     current
-            DESCRIPTION
-                    "The BGP-4 Received Path Attribute Table contains
-                    information about paths to destination networks
-                    received from all BGP4 peers."
-            ::= { bgp 6 }
-
-        bgp4PathAttrEntry OBJECT-TYPE
-            SYNTAX     Bgp4PathAttrEntry
-            MAX-ACCESS not-accessible
-            STATUS     current
-            DESCRIPTION
-                    "Information about a path to a network."
-            INDEX { bgp4PathAttrIpAddrPrefix,
-                    bgp4PathAttrIpAddrPrefixLen,
-                    bgp4PathAttrPeer            }
-            ::= { bgp4PathAttrTable 1 }
-
-        Bgp4PathAttrEntry ::= SEQUENCE {
-            bgp4PathAttrPeer
-                 IpAddress,
-            bgp4PathAttrIpAddrPrefixLen
-                 INTEGER,
-            bgp4PathAttrIpAddrPrefix
-                 IpAddress,
-            bgp4PathAttrOrigin
-                 INTEGER,
-            bgp4PathAttrASPathSegment
-                 OCTET STRING,
-            bgp4PathAttrNextHop
-                 IpAddress,
-            bgp4PathAttrMultiExitDisc
-                 INTEGER,
-            bgp4PathAttrLocalPref
-                 INTEGER,
-            bgp4PathAttrAtomicAggregate
-                 INTEGER,
-            bgp4PathAttrAggregatorAS
-                 INTEGER,
-            bgp4PathAttrAggregatorAddr
-                 IpAddress,
-            bgp4PathAttrCalcLocalPref
-                 INTEGER,
-            bgp4PathAttrBest
-                 INTEGER,
-            bgp4PathAttrUnknown
-                 OCTET STRING
-        }
-
-        bgp4PathAttrPeer OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The IP address of the peer where the path
-                    information was learned."
-            ::= { bgp4PathAttrEntry 1 }
-        bgp4PathAttrIpAddrPrefixLen OBJECT-TYPE
-            SYNTAX     INTEGER (0..32)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "Length in bits of the IP address prefix in the
-                    Network Layer Reachability Information field."
-            ::= { bgp4PathAttrEntry 2 }
-
-        bgp4PathAttrIpAddrPrefix OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "An IP address prefix in the Network Layer
-                    Reachability Information field.  This object
-                    is an IP address containing the prefix with
-                    length specified by bgp4PathAttrIpAddrPrefixLen.
-                    Any bits beyond the length specified by
-                    bgp4PathAttrIpAddrPrefixLen are zeroed."
-            ::= { bgp4PathAttrEntry 3 }
-
-        bgp4PathAttrOrigin OBJECT-TYPE
-            SYNTAX     INTEGER {
-                                 igp(1),-- networks are interior
-                                 egp(2),-- networks learned via EGP
-                                 incomplete(3) -- undetermined
-                               }
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The ultimate origin of the path information."
-            ::= { bgp4PathAttrEntry 4 }
-
-        bgp4PathAttrASPathSegment OBJECT-TYPE
-            SYNTAX     OCTET STRING (SIZE (2..255))
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The sequence of AS path segments.  Each AS
-                    path segment is represented by a triple
-                    <type, length, value>.
-
-                    The type is a 1-octet field which has two
-                    possible values:
-                         1      AS_SET: unordered set of ASs a
-                                     route in the UPDATE message
-                                     has traversed
-                         2      AS_SEQUENCE: ordered set of ASs
-                                     a route in the UPDATE message
-                                     has traversed.
-
-                    The length is a 1-octet field containing the
-                    number of ASs in the value field.
-
-                    The value field contains one or more AS
-                    numbers, each AS is represented in the octet
-                    string as a pair of octets according to the
-                    following algorithm:
-
-                        first-byte-of-pair = ASNumber / 256;
-                        second-byte-of-pair = ASNumber & 255;"
-            ::= { bgp4PathAttrEntry 5 }
-
-        bgp4PathAttrNextHop OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The address of the border router that should
-                    be used for the destination network."
-            ::= { bgp4PathAttrEntry 6 }
-
-        bgp4PathAttrMultiExitDisc OBJECT-TYPE
-            SYNTAX     INTEGER (-1..2147483647)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "This metric is used to discriminate between
-                    multiple exit points to an adjacent autonomous
-                    system.  A value of -1 indicates the absence of
-                    this attribute."
-            ::= { bgp4PathAttrEntry 7 }
-
-        bgp4PathAttrLocalPref OBJECT-TYPE
-            SYNTAX     INTEGER (-1..2147483647)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The originating BGP4 speaker's degree of
-                    preference for an advertised route.  A value of
-                    -1 indicates the absence of this attribute."
-            ::= { bgp4PathAttrEntry 8 }
-
-        bgp4PathAttrAtomicAggregate OBJECT-TYPE
-            SYNTAX     INTEGER {
-                           lessSpecificRrouteNotSelected(1),
-                           lessSpecificRouteSelected(2)
-                       }
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "Whether or not a system has selected
-                    a less specific route without selecting a
-                    more specific route."
-            ::= { bgp4PathAttrEntry 9 }
-
-        bgp4PathAttrAggregatorAS OBJECT-TYPE
-            SYNTAX     INTEGER (0..65535)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The AS number of the last BGP4 speaker that
-                    performed route aggregation.  A value of zero (0)
-                    indicates the absence of this attribute."
-            ::= { bgp4PathAttrEntry 10 }
-
-        bgp4PathAttrAggregatorAddr OBJECT-TYPE
-            SYNTAX     IpAddress
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The IP address of the last BGP4 speaker that
-                     performed route aggregation.  A value of
-                     0.0.0.0 indicates the absence of this attribute."
-            ::= { bgp4PathAttrEntry 11 }
-
-        bgp4PathAttrCalcLocalPref OBJECT-TYPE
-            SYNTAX     INTEGER (-1..2147483647)
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "The degree of preference calculated by the
-                    receiving BGP4 speaker for an advertised route.
-                    A value of -1 indicates the absence of this
-                    attribute."
-            ::= { bgp4PathAttrEntry 12 }
-
-        bgp4PathAttrBest OBJECT-TYPE
-            SYNTAX     INTEGER {
-                           false(1),-- not chosen as best route
-                           true(2) -- chosen as best route
-                       }
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "An indication of whether or not this route
-                    was chosen as the best BGP4 route."
-            ::= { bgp4PathAttrEntry 13 }
-
-        bgp4PathAttrUnknown OBJECT-TYPE
-            SYNTAX     OCTET STRING (SIZE(0..255))
-            MAX-ACCESS read-only
-            STATUS     current
-            DESCRIPTION
-                    "One or more path attributes not understood
-                     by this BGP4 speaker.  Size zero (0) indicates
-                     the absence of such attribute(s).  Octets
-                     beyond the maximum size, if any, are not
-                     recorded by this object."
-            ::= { bgp4PathAttrEntry 14 }
-
-
-        -- Traps.
-
-        -- note that in RFC 1657, bgpTraps was incorrectly
-        -- assigned a value of { bgp 7 }, and each of the
-        -- traps had the bgpPeerRemoteAddr object inappropriately
-        -- removed from their OBJECTS clause.  The following
-        -- definitions restore the semantics of the traps as
-        -- they were initially defined in RFC 1269.
-
-        -- { bgp 7 } is unused
-
-        bgpTraps          OBJECT IDENTIFIER ::= { bgp 0 }
-
-        bgpEstablished NOTIFICATION-TYPE
-            OBJECTS { bgpPeerRemoteAddr,
-                      bgpPeerLastError,
-                      bgpPeerState      }
-            STATUS  current
-            DESCRIPTION
-                    "The BGP Established event is generated when
-                    the BGP FSM enters the ESTABLISHED state."
-            ::= { bgpTraps 1 }
-
-        bgpBackwardTransition NOTIFICATION-TYPE
-            OBJECTS { bgpPeerRemoteAddr,
-                      bgpPeerLastError,
-                      bgpPeerState      }
-            STATUS  current
-            DESCRIPTION
-                    "The BGPBackwardTransition Event is generated
-                    when the BGP FSM moves from a higher numbered
-                    state to a lower numbered state."
-            ::= { bgpTraps 2 }
-
-        -- conformance information
-
-        bgpMIBConformance OBJECT IDENTIFIER ::= { bgp 8 }
-        bgpMIBCompliances OBJECT IDENTIFIER ::= { bgpMIBConformance 1 }
-        bgpMIBGroups      OBJECT IDENTIFIER ::= { bgpMIBConformance 2 }
-
-        -- compliance statements
-
-        bgpMIBCompliance MODULE-COMPLIANCE
-            STATUS  current
-            DESCRIPTION
-                    "The compliance statement for entities which
-                     implement the BGP4 mib."
-            MODULE  -- this module
-                MANDATORY-GROUPS { bgp4MIBGlobalsGroup,
-                                   bgp4MIBPeerGroup,
-                                   bgp4MIBPathAttrGroup,
-                                   bgp4MIBNotificationGroup }
-            ::= { bgpMIBCompliances 1 }
-
-        -- units of conformance
-
-        bgp4MIBGlobalsGroup OBJECT-GROUP
-            OBJECTS { bgpVersion,
-                      bgpLocalAs,
-                      bgpIdentifier }
-            STATUS  current
-            DESCRIPTION
-                    "A collection of objects providing information
-                     on global BGP state."
-            ::= { bgpMIBGroups 1 }
-
-        bgp4MIBPeerGroup OBJECT-GROUP
-            OBJECTS { bgpPeerIdentifier,
-                      bgpPeerState,
-                      bgpPeerAdminStatus,
-                      bgpPeerNegotiatedVersion,
-                      bgpPeerLocalAddr,
-                      bgpPeerLocalPort,
-                      bgpPeerRemoteAddr,
-                      bgpPeerRemotePort,
-                      bgpPeerRemoteAs,
-                      bgpPeerInUpdates,
-                      bgpPeerOutUpdates,
-                      bgpPeerInTotalMessages,
-                      bgpPeerOutTotalMessages,
-                      bgpPeerLastError,
-                      bgpPeerFsmEstablishedTransitions,
-                      bgpPeerFsmEstablishedTime,
-                      bgpPeerConnectRetryInterval,
-                      bgpPeerHoldTime,
-                      bgpPeerKeepAlive,
-                      bgpPeerHoldTimeConfigured,
-                      bgpPeerKeepAliveConfigured,
-                      bgpPeerMinASOriginationInterval,
-                      bgpPeerMinRouteAdvertisementInterval,
-                      bgpPeerInUpdateElapsedTime }
-            STATUS  current
-            DESCRIPTION
-                    "A collection of objects for managing
-                     BGP peers."
-            ::= { bgpMIBGroups 2 }
-
-        bgp4MIBRcvdPathAttrGroup OBJECT-GROUP
-            OBJECTS { bgpPathAttrPeer,
-                      bgpPathAttrDestNetwork,
-                      bgpPathAttrOrigin,
-                      bgpPathAttrASPath,
-                      bgpPathAttrNextHop,
-                      bgpPathAttrInterASMetric }
-            STATUS  obsolete
-            DESCRIPTION
-                    "A collection of objects for managing BGP
-                     path entries.
-
-                     This conformance group is obsolete,
-                     replaced by bgp4MIBPathAttrGroup."
-            ::= { bgpMIBGroups 3 }
-
-        bgp4MIBPathAttrGroup OBJECT-GROUP
-            OBJECTS { bgp4PathAttrPeer,
-                      bgp4PathAttrIpAddrPrefixLen,
-                      bgp4PathAttrIpAddrPrefix,
-                      bgp4PathAttrOrigin,
-                      bgp4PathAttrASPathSegment,
-                      bgp4PathAttrNextHop,
-                      bgp4PathAttrMultiExitDisc,
-                      bgp4PathAttrLocalPref,
-                      bgp4PathAttrAtomicAggregate,
-                      bgp4PathAttrAggregatorAS,
-                      bgp4PathAttrAggregatorAddr,
-                      bgp4PathAttrCalcLocalPref,
-                      bgp4PathAttrBest,
-                      bgp4PathAttrUnknown }
-            STATUS  current
-            DESCRIPTION
-                    "A collection of objects for managing
-                     BGP path entries."
-            ::= { bgpMIBGroups 4 }
-
-        bgp4MIBNotificationGroup NOTIFICATION-GROUP
-            NOTIFICATIONS { bgpEstablished,
-                            bgpBackwardTransition }
-            STATUS  current
-            DESCRIPTION
-                    "A collection of notifications for signaling
-                    changes in BGP peer relationships."
-            ::= { bgpMIBGroups 5 }
-
-    END
index 22401f0017735da5548484c548ee242ce3811121..55a86f99fc66467e4246c108474944df96ca9498 100644 (file)
@@ -193,7 +193,7 @@ static void bgp_addpath_flush_type(struct bgp *bgp, afi_t afi, safi_t safi,
                idalloc_drain_pool(
                        bgp->tx_addpath.id_allocators[afi][safi][addpath_type],
                        &(rn->tx_addpath.free_ids[addpath_type]));
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (pi->tx_addpath.addpath_tx_id[addpath_type]
                            != IDALLOC_INVALID) {
                                idalloc_free(
@@ -256,7 +256,7 @@ static void bgp_addpath_populate_type(struct bgp *bgp, afi_t afi, safi_t safi,
 
        for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
             rn = bgp_route_next(rn))
-               for (bi = rn->info; bi; bi = bi->next)
+               for (bi = bgp_node_get_bgp_path_info(rn); bi; bi = bi->next)
                        bgp_addpath_populate_path(allocator, bi, addpath_type);
 }
 
@@ -396,7 +396,7 @@ void bgp_addpath_update_ids(struct bgp *bgp, struct bgp_node *bn, afi_t afi,
                        continue;
 
                /* Free Unused IDs back to the pool.*/
-               for (pi = bn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(bn); pi; pi = pi->next) {
                        if (pi->tx_addpath.addpath_tx_id[i] != IDALLOC_INVALID
                            && !bgp_addpath_tx_path(i, pi)) {
                                idalloc_free_to_pool(pool_ptr,
@@ -407,7 +407,7 @@ void bgp_addpath_update_ids(struct bgp *bgp, struct bgp_node *bn, afi_t afi,
                }
 
                /* Give IDs to paths that need them (pulling from the pool) */
-               for (pi = bn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(bn); pi; pi = pi->next) {
                        if (pi->tx_addpath.addpath_tx_id[i] == IDALLOC_INVALID
                            && bgp_addpath_tx_path(i, pi)) {
                                pi->tx_addpath.addpath_tx_id[i] =
index 3d1880ca481f161443c59997c50d1c190e34ccc0..751140850a3303e18b8f309138331426484a55fb 100644 (file)
@@ -410,7 +410,7 @@ static unsigned int bgp_dump_routes_func(int afi, int first_run,
        table = bgp->rib[afi][SAFI_UNICAST];
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-               path = rn->info;
+               path = bgp_node_get_bgp_path_info(rn);
                while (path) {
                        path = bgp_dump_route_node_record(afi, rn, path, seq);
                        seq++;
index 93c0ac741a992e9752957defe5f42f6178c09160..7f6d34808f1f9eb26aabd833c70adba79f799b17 100644 (file)
@@ -1232,7 +1232,8 @@ static int evpn_route_is_def_gw(struct bgp *bgp, struct bgp_node *rn)
        struct bgp_path_info *local_pi = NULL;
 
        local_pi = NULL;
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1255,7 +1256,8 @@ static int evpn_route_is_sticky(struct bgp *bgp, struct bgp_node *rn)
        struct bgp_path_info *local_pi;
 
        local_pi = NULL;
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1292,7 +1294,8 @@ static int update_evpn_type4_route_entry(struct bgp *bgp, struct evpnes *es,
        evp = (struct prefix_evpn *)&rn->p;
 
        /* locate the local and remote entries if any */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1303,7 +1306,7 @@ static int update_evpn_type4_route_entry(struct bgp *bgp, struct evpnes *es,
                        remote_pi = tmp_pi;
        }
 
-       /* we don't expect to see a remote_pi at this point.
+       /* we don't expect to see a remote_ri at this point.
         * An ES route has esi + vtep_ip as the key,
         * We shouldn't see the same route from any other vtep.
         */
@@ -1449,7 +1452,8 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_def,
 
        *route_changed = 0;
        /* locate the local route entry if any */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp_def->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1587,7 +1591,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
 
        /* See if this is an update of an existing route, or a new add. */
        local_pi = NULL;
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1726,7 +1731,8 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
        bgp_path_info_reap(rn, local_pi);
 
        /* tell zebra to re-add the best remote path */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn);
+            tmp_pi; tmp_pi = tmp_pi->next) {
                if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_SELECTED)) {
                        curr_select = tmp_pi;
                        break;
@@ -1863,7 +1869,8 @@ static void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi,
        *pi = NULL;
 
        /* Now, find matching route. */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next)
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next)
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -2034,7 +2041,8 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
                        continue;
 
                /* Identify local route. */
-               for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+               for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+                    tmp_pi = tmp_pi->next) {
                        if (tmp_pi->peer == bgp->peer_self
                            && tmp_pi->type == ZEBRA_ROUTE_BGP
                            && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -2125,8 +2133,8 @@ static int delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
        safi = SAFI_EVPN;
 
        rdrn = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)&vpn->prd);
-       if (rdrn && rdrn->info) {
-               table = (struct bgp_table *)rdrn->info;
+       if (rdrn && bgp_node_has_bgp_path_info_data(rdrn)) {
+               table = bgp_node_get_bgp_table_info(rdrn);
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
                        struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
 
@@ -2195,8 +2203,8 @@ static int delete_all_es_routes(struct bgp *bgp, struct evpnes *es)
        /* Walk this ES's route table and delete all routes. */
        for (rn = bgp_table_top(es->route_table); rn;
             rn = bgp_route_next(rn)) {
-               for (pi = rn->info; (pi != NULL) && (nextpi = pi->next, 1);
-                    pi = nextpi) {
+               for (pi = bgp_node_get_bgp_path_info(rn);
+                    (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
                        bgp_path_info_delete(rn, pi);
                        bgp_path_info_reap(rn, pi);
                }
@@ -2216,8 +2224,8 @@ static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
        /* Walk this VNI's route table and delete all routes. */
        for (rn = bgp_table_top(vpn->route_table); rn;
             rn = bgp_route_next(rn)) {
-               for (pi = rn->info; (pi != NULL) && (nextpi = pi->next, 1);
-                    pi = nextpi) {
+               for (pi = bgp_node_get_bgp_path_info(rn);
+                    (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
                        bgp_path_info_delete(rn, pi);
                        bgp_path_info_reap(rn, pi);
                }
@@ -2353,7 +2361,7 @@ static int install_evpn_route_entry_in_es(struct bgp *bgp, struct evpnes *es,
        rn = bgp_node_get(es->route_table, (struct prefix *)p);
 
        /* Check if route entry is already present. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2454,7 +2462,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
 
        /* Check if route entry is already present. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2530,7 +2538,7 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
        rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
 
        /* Check if route entry is already present. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2602,7 +2610,7 @@ static int uninstall_evpn_route_entry_in_es(struct bgp *bgp, struct evpnes *es,
                return 0;
 
        /* Find matching route entry. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2667,7 +2675,7 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                return 0;
 
        /* Find matching route entry. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2708,7 +2716,7 @@ static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                return 0;
 
        /* Find matching route entry. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2901,14 +2909,15 @@ static int install_uninstall_routes_for_es(struct bgp *bgp,
         */
        for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
                        struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
                                /*
                                 * Consider "valid" remote routes applicable for
                                 * this ES.
@@ -2973,7 +2982,7 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
         */
        for (rd_rn = bgp_table_top(bgp_def->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
@@ -2991,7 +3000,8 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
                              || is_evpn_prefix_ipaddr_v6(evp)))
                                continue;
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
                                /* Consider "valid" remote routes applicable for
                                 * this VRF.
                                 */
@@ -3056,7 +3066,7 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp,
        /* EVPN routes are a 2-level table. */
        for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
@@ -3066,7 +3076,8 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp,
                        if (evp->prefix.route_type != rtype)
                                continue;
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
                                /* Consider "valid" remote routes applicable for
                                 * this VNI. */
                                if (!(CHECK_FLAG(pi->flags, BGP_PATH_VALID)
@@ -3501,7 +3512,7 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
                rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
                if (!rn) /* unexpected */
                        return 0;
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self &&
                            pi->type == ZEBRA_ROUTE_BGP
                            && pi->sub_type == BGP_ROUTE_STATIC)
@@ -3531,7 +3542,7 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
                if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
                        continue;
 
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self
                            && pi->type == ZEBRA_ROUTE_BGP
                            && pi->sub_type == BGP_ROUTE_STATIC)
@@ -4229,7 +4240,7 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
                /* Only care about "selected" routes - non-imported. */
                /* TODO: Support for AddPath for EVPN. */
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
                            && (!pi->extra || !pi->extra->parent)) {
                                bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p,
@@ -4301,7 +4312,7 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
                 * attribute. Also, we only consider "non-imported" routes.
                 * TODO: Support for AddPath for EVPN.
                 */
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
                            && (!pi->extra || !pi->extra->parent)) {
 
@@ -5263,13 +5274,14 @@ int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
        /* EVPN routes are a 2-level table. */
        for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
 
                                /* Consider "valid" remote routes applicable for
                                 * this VNI. */
index 43476372e568d285289b0e0b6293a7c16489b648..13f899e8806245f0159cd1997df73d23cc1deb55 100644 (file)
@@ -556,7 +556,8 @@ static void show_esi_routes(struct bgp *bgp,
                if (json)
                        json_prefix = json_object_new_object();
 
-               if (rn->info) {
+               pi = bgp_node_get_bgp_path_info(rn);
+               if (pi) {
                        /* Overall header/legend displayed once. */
                        if (header) {
                                bgp_evpn_show_route_header(vty, bgp,
@@ -573,7 +574,7 @@ static void show_esi_routes(struct bgp *bgp,
                /* For EVPN, the prefix is displayed for each path (to fit in
                 * with code that already exists).
                 */
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (; pi; pi = pi->next) {
                        json_object *json_path = NULL;
 
                        if (json)
@@ -643,7 +644,8 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
                if (json)
                        json_prefix = json_object_new_object();
 
-               if (rn->info) {
+               pi = bgp_node_get_bgp_path_info(rn);
+               if (pi) {
                        /* Overall header/legend displayed once. */
                        if (header) {
                                bgp_evpn_show_route_header(vty, bgp,
@@ -660,7 +662,7 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
                /* For EVPN, the prefix is displayed for each path (to fit in
                 * with code that already exists).
                 */
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (; pi; pi = pi->next) {
                        json_object *json_path = NULL;
 
                        if (vtep_ip.s_addr
@@ -1039,14 +1041,16 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
                if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
                        continue;
 
-               if ((table = rn->info) == NULL)
+               table = bgp_node_get_bgp_table_info(rn);
+               if (!table)
                        continue;
 
                rd_header = 1;
                tbl_ver = table->version;
 
                for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm))
-                       for (pi = rm->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rm); pi;
+                            pi = pi->next) {
                                total_count++;
                                if (type == bgp_show_type_neighbor) {
                                        union sockunion *su = output_arg;
@@ -2036,7 +2040,7 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
        /* See if route exists. */
        build_evpn_type3_prefix(&p, orig_ip);
        rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
-       if (!rn || !rn->info) {
+       if (!rn || !bgp_node_has_bgp_path_info_data(rn)) {
                if (!json)
                        vty_out(vty, "%% Network not in table\n");
                return;
@@ -2049,7 +2053,7 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
        route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
 
        /* Display each path for this prefix. */
-       for (pi = rn->info; pi; pi = pi->next) {
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                json_object *json_path = NULL;
 
                if (json)
@@ -2106,7 +2110,7 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
        /* See if route exists. Look for both non-sticky and sticky. */
        build_evpn_type2_prefix(&p, mac, ip);
        rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
-       if (!rn || !rn->info) {
+       if (!rn || !bgp_node_has_bgp_path_info_data(rn)) {
                if (!json)
                        vty_out(vty, "%% Network not in table\n");
                return;
@@ -2119,7 +2123,7 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
        route_vty_out_detail_header(vty, bgp, rn, NULL, afi, safi, json);
 
        /* Display each path for this prefix. */
-       for (pi = rn->info; pi; pi = pi->next) {
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                json_object *json_path = NULL;
 
                if (json)
@@ -2210,7 +2214,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
        build_evpn_type2_prefix(&p, mac, ip);
        rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
                                 (struct prefix *)&p, prd);
-       if (!rn || !rn->info) {
+       if (!rn || !bgp_node_has_bgp_path_info_data(rn)) {
                if (!json)
                        vty_out(vty, "%% Network not in table\n");
                return;
@@ -2226,7 +2230,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
                json_paths = json_object_new_array();
 
        /* Display each path for this prefix. */
-       for (pi = rn->info; pi; pi = pi->next) {
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                json_object *json_path = NULL;
 
                if (json)
@@ -2281,7 +2285,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
        if (!rd_rn)
                return;
 
-       table = (struct bgp_table *)rd_rn->info;
+       table = bgp_node_get_bgp_table_info(rd_rn);
        if (table == NULL)
                return;
 
@@ -2307,7 +2311,8 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
                if (json)
                        json_prefix = json_object_new_object();
 
-               if (rn->info) {
+               pi = bgp_node_get_bgp_path_info(rn);
+               if (pi) {
                        /* RD header and legend - once overall. */
                        if (rd_header && !json) {
                                vty_out(vty,
@@ -2330,7 +2335,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
                        json_paths = json_object_new_array();
 
                /* Display each path for this prefix. */
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (; pi; pi = pi->next) {
                        json_object *json_path = NULL;
 
                        if (json)
@@ -2404,7 +2409,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                int add_rd_to_json = 0;
                uint64_t tbl_ver;
 
-               table = (struct bgp_table *)rd_rn->info;
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (table == NULL)
                        continue;
 
@@ -2435,7 +2440,8 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                        if (type && evp->prefix.route_type != type)
                                continue;
 
-                       if (rn->info) {
+                       pi = bgp_node_get_bgp_path_info(rn);
+                       if (pi) {
                                /* Overall header/legend displayed once. */
                                if (header) {
                                        bgp_evpn_show_route_header(vty, bgp,
@@ -2467,7 +2473,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                         * fit in
                         * with code that already exists).
                         */
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (; pi; pi = pi->next) {
                                json_object *json_path = NULL;
                                path_cnt++;
                                add_prefix_to_json = 1;
index 9c230d1126045ca965db8dc68b0b4915a0773e63..26f0fffb377d15ab5018bfdd5b9a9f8c02a69598 100644 (file)
@@ -380,13 +380,14 @@ int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
                return CMD_SUCCESS;
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-               if (rn->info == NULL)
+               pi = bgp_node_get_bgp_path_info(rn);
+               if (pi == NULL)
                        continue;
                if (use_json) {
                        json_paths = json_object_new_array();
                        display = NLRI_STRING_FORMAT_JSON;
                }
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (; pi; pi = pi->next) {
                        total_count++;
                        route_vty_out_flowspec(vty, &rn->p, pi, display,
                                               json_paths);
@@ -543,11 +544,11 @@ extern int bgp_flowspec_display_match_per_ip(afi_t afi, struct bgp_table *rib,
                        continue;
 
                if (bgp_flowspec_contains_prefix(prefix, match, prefix_check)) {
-                       route_vty_out_flowspec(vty, &rn->p,
-                                              rn->info, use_json ?
-                                              NLRI_STRING_FORMAT_JSON :
-                                              NLRI_STRING_FORMAT_LARGE,
-                                              json_paths);
+                       route_vty_out_flowspec(
+                               vty, &rn->p, bgp_node_get_bgp_path_info(rn),
+                               use_json ? NLRI_STRING_FORMAT_JSON
+                                        : NLRI_STRING_FORMAT_LARGE,
+                               json_paths);
                        display++;
                }
        }
index d4204126e170476fa90d9ad1f6a2c4f932815e70..cf91faf964a9b93eda47effb2b57374a8913ae3d 100644 (file)
@@ -500,7 +500,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
        /*
         * match parent
         */
-       for (bpi = bn->info; bpi; bpi = bpi->next) {
+       for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
                if (bpi->extra && bpi->extra->parent == parent)
                        break;
        }
@@ -919,11 +919,13 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn,              /* to */
        bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
                              &(bgp_vrf->vpn_policy[afi].tovpn_rd));
 
+       if (!bn)
+               return;
        /*
         * vrf -> vpn
         * match original bpi imported from
         */
-       for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
+       for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
                if (bpi->extra && bpi->extra->parent == path_vrf) {
                        break;
                }
@@ -959,7 +961,7 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
                struct bgp_path_info *bpi;
 
                /* This is the per-RD table of prefixes */
-               table = prn->info;
+               table = bgp_node_get_bgp_table_info(prn);
 
                if (!table)
                        continue;
@@ -968,13 +970,14 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
 
                        char buf[PREFIX2STR_BUFFER];
 
-                       if (debug && bn->info) {
+                       bpi = bgp_node_get_bgp_path_info(bn);
+                       if (debug && bpi) {
                                zlog_debug(
                                        "%s: looking at prefix %s", __func__,
                                        prefix2str(&bn->p, buf, sizeof(buf)));
                        }
 
-                       for (bpi = bn->info; bpi; bpi = bpi->next) {
+                       for (; bpi; bpi = bpi->next) {
                                if (debug)
                                        zlog_debug("%s: type %d, sub_type %d",
                                                   __func__, bpi->type,
@@ -1017,7 +1020,8 @@ void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
                if (debug)
                        zlog_debug("%s: node=%p", __func__, bn);
 
-               for (bpi = bn->info; bpi; bpi = bpi->next) {
+               for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
+                    bpi = bpi->next) {
                        if (debug)
                                zlog_debug(
                                        "%s: calling vpn_leak_from_vrf_update",
@@ -1299,7 +1303,9 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn,            /* from */
                                   bgp->name_pretty);
 
                bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
-               for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
+
+               for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
+                    bpi = bpi->next) {
                        if (bpi->extra
                            && (struct bgp_path_info *)bpi->extra->parent
                                       == path_vpn) {
@@ -1335,7 +1341,8 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
        for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
             bn = bgp_route_next(bn)) {
 
-               for (bpi = bn->info; bpi; bpi = bpi->next) {
+               for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
+                    bpi = bpi->next) {
                        if (bpi->extra && bpi->extra->bgp_orig != bgp_vrf) {
 
                                /* delete route */
@@ -1374,14 +1381,15 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
                memcpy(prd.val, prn->p.u.val, 8);
 
                /* This is the per-RD table of prefixes */
-               table = prn->info;
+               table = bgp_node_get_bgp_table_info(prn);
 
                if (!table)
                        continue;
 
                for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
 
-                       for (bpi = bn->info; bpi; bpi = bpi->next) {
+                       for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
+                            bpi = bpi->next) {
 
                                if (bpi->extra
                                    && bpi->extra->bgp_orig == bgp_vrf)
index 1cb7e4c5e1b959b4af49bf1940c92733c34df98e..70d3d7b69c601934db29458ee7b8f81bc0c988d9 100644 (file)
@@ -44,8 +44,6 @@
 #include "bgpd/bgp_damp.h"
 #include "bgpd/bgp_fsm.h"
 #include "bgpd/bgp_vty.h"
-#include "zebra/rib.h"
-#include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
 
 DEFINE_MTYPE_STATIC(BGPD, MARTIAN_STRING, "BGP Martian Address Intf String");
 
@@ -83,7 +81,7 @@ static void bgp_nexthop_cache_reset(struct bgp_table *table)
        struct bgp_nexthop_cache *bnc;
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-               bnc = bgp_nexthop_get_node_info(rn);
+               bnc = bgp_node_get_bgp_nexthop_info(rn);
                if (!bnc)
                        continue;
 
@@ -94,7 +92,7 @@ static void bgp_nexthop_cache_reset(struct bgp_table *table)
                }
 
                bnc_free(bnc);
-               bgp_nexthop_set_node_info(rn, NULL);
+               bgp_node_set_bgp_nexthop_info(rn, NULL);
                bgp_unlock_node(rn);
        }
 }
@@ -351,14 +349,14 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc)
 
                rn = bgp_node_get(bgp->connected_table[AFI_IP],
                                  (struct prefix *)&p);
-               bc = bgp_connected_get_node_info(rn);
+               bc = bgp_node_get_bgp_connected_ref_info(rn);
                if (bc)
                        bc->refcnt++;
                else {
                        bc = XCALLOC(MTYPE_BGP_CONN,
                                     sizeof(struct bgp_connected_ref));
                        bc->refcnt = 1;
-                       bgp_connected_set_node_info(rn, bc);
+                       bgp_node_set_bgp_connected_ref_info(rn, bc);
                }
 
                for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
@@ -384,14 +382,14 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc)
                rn = bgp_node_get(bgp->connected_table[AFI_IP6],
                                  (struct prefix *)&p);
 
-               bc = bgp_connected_get_node_info(rn);
+               bc = bgp_node_get_bgp_connected_ref_info(rn);
                if (bc)
                        bc->refcnt++;
                else {
                        bc = XCALLOC(MTYPE_BGP_CONN,
                                     sizeof(struct bgp_connected_ref));
                        bc->refcnt = 1;
-                       bgp_connected_set_node_info(rn, bc);
+                       bgp_node_set_bgp_connected_ref_info(rn, bc);
                }
        }
 }
@@ -428,11 +426,11 @@ void bgp_connected_delete(struct bgp *bgp, struct connected *ifc)
        if (!rn)
                return;
 
-       bc = bgp_connected_get_node_info(rn);
+       bc = bgp_node_get_bgp_connected_ref_info(rn);
        bc->refcnt--;
        if (bc->refcnt == 0) {
                XFREE(MTYPE_BGP_CONN, bc);
-               bgp_connected_set_node_info(rn, NULL);
+               bgp_node_set_bgp_connected_ref_info(rn, NULL);
        }
        bgp_unlock_node(rn);
        bgp_unlock_node(rn);
@@ -444,14 +442,14 @@ static void bgp_connected_cleanup(struct route_table *table,
        struct bgp_connected_ref *bc;
        struct bgp_node *bn = bgp_node_from_rnode(rn);
 
-       bc = bgp_connected_get_node_info(bn);
+       bc = bgp_node_get_bgp_connected_ref_info(bn);
        if (!bc)
                return;
 
        bc->refcnt--;
        if (bc->refcnt == 0) {
                XFREE(MTYPE_BGP_CONN, bc);
-               bgp_connected_set_node_info(bn, NULL);
+               bgp_node_set_bgp_connected_ref_info(bn, NULL);
        }
 }
 
@@ -588,22 +586,30 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
                }
 }
 
-static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail)
+static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail,
+                            bool import_table)
 {
        struct bgp_node *rn;
        struct bgp_nexthop_cache *bnc;
        char buf[PREFIX2STR_BUFFER];
        time_t tbuf;
        afi_t afi;
+       struct bgp_table **table;
 
-       vty_out(vty, "Current BGP nexthop cache:\n");
+       if (import_table)
+               vty_out(vty, "Current BGP import check cache:\n");
+       else
+               vty_out(vty, "Current BGP nexthop cache:\n");
+       if (import_table)
+               table = bgp->import_check_table;
+       else
+               table = bgp->nexthop_cache_table;
        for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               if (!bgp->nexthop_cache_table[afi])
+               if (!table || !table[afi])
                        continue;
-
-               for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn;
+               for (rn = bgp_table_top(table[afi]); rn;
                     rn = bgp_route_next(rn)) {
-                       bnc = bgp_nexthop_get_node_info(rn);
+                       bnc = bgp_node_get_bgp_nexthop_info(rn);
                        if (!bnc)
                                continue;
 
@@ -640,7 +646,7 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail)
 }
 
 static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
-                                    int detail)
+                                    int detail, bool import_table)
 {
        struct bgp *bgp;
 
@@ -653,7 +659,7 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
                return CMD_WARNING;
        }
 
-       bgp_show_nexthops(vty, bgp, detail);
+       bgp_show_nexthops(vty, bgp, detail, import_table);
 
        return CMD_SUCCESS;
 }
@@ -668,7 +674,7 @@ static void bgp_show_all_instances_nexthops_vty(struct vty *vty)
                        (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
                                ? VRF_DEFAULT_NAME
                                : bgp->name);
-               bgp_show_nexthops(vty, bgp, 0);
+               bgp_show_nexthops(vty, bgp, 0, false);
        }
 }
 
@@ -689,7 +695,28 @@ DEFUN (show_ip_bgp_nexthop,
            || argv_find(argv, argc, "vrf", &idx))
                vrf = argv[++idx]->arg;
        int detail = argv_find(argv, argc, "detail", &idx) ? 1 : 0;
-       return show_ip_bgp_nexthop_table(vty, vrf, detail);
+
+       return show_ip_bgp_nexthop_table(vty, vrf, detail, false);
+}
+
+DEFUN (show_ip_bgp_import_check,
+       show_ip_bgp_import_check_cmd,
+       "show [ip] bgp [<view|vrf> VIEWVRFNAME] import-check-table [detail]",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       BGP_INSTANCE_HELP_STR
+       "BGP import check table\n"
+       "Show detailed information\n")
+{
+       int idx = 0;
+       char *vrf = NULL;
+
+       if (argv_find(argv, argc, "view", &idx)
+           || argv_find(argv, argc, "vrf", &idx))
+               vrf = argv[++idx]->arg;
+       int detail = argv_find(argv, argc, "detail", &idx) ? 1 : 0;
+       return show_ip_bgp_nexthop_table(vty, vrf, detail, true);
 }
 
 DEFUN (show_ip_bgp_instance_all_nexthop,
@@ -722,6 +749,7 @@ void bgp_scan_init(struct bgp *bgp)
 void bgp_scan_vty_init(void)
 {
        install_element(VIEW_NODE, &show_ip_bgp_nexthop_cmd);
+       install_element(VIEW_NODE, &show_ip_bgp_import_check_cmd);
        install_element(VIEW_NODE, &show_ip_bgp_instance_all_nexthop_cmd);
 }
 
index c5d12a570678febe0aa5bdce7fd7ebef85585db6..b6ef5a55c5377fde6590c93734412a03bef6d939 100644 (file)
@@ -95,7 +95,7 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
                }
                unregister_zebra_rnh(bnc,
                                     CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
-               bgp_nexthop_set_node_info(bnc->node, NULL);
+               bgp_node_set_bgp_nexthop_info(bnc->node, NULL);
                bgp_unlock_node(bnc->node);
                bnc->node = NULL;
                bnc_free(bnc);
@@ -126,7 +126,7 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer)
 
        rn = bgp_node_get(peer->bgp->nexthop_cache_table[afi], &p);
 
-       bnc = bgp_nexthop_get_node_info(rn);
+       bnc = bgp_node_get_bgp_nexthop_info(rn);
        if (!bnc)
                return;
 
@@ -183,10 +183,10 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
        else
                rn = bgp_node_get(bgp_nexthop->nexthop_cache_table[afi], &p);
 
-       bnc = bgp_nexthop_get_node_info(rn);
+       bnc = bgp_node_get_bgp_nexthop_info(rn);
        if (!bnc) {
                bnc = bnc_new();
-               bgp_nexthop_set_node_info(rn, bnc);
+               bgp_node_set_bgp_nexthop_info(rn, bnc);
                bnc->node = rn;
                bnc->bgp = bgp_nexthop;
                bgp_lock_node(rn);
@@ -293,7 +293,7 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
                return;
        }
 
-       bnc = bgp_nexthop_get_node_info(rn);
+       bnc = bgp_node_get_bgp_nexthop_info(rn);
        if (!bnc) {
                if (BGP_DEBUG(nht, NHT))
                        zlog_debug("Cannot find connected NHT node for peer %s on route_node as expected",
@@ -318,7 +318,7 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
                        zlog_debug("Freeing connected NHT node %p for peer %s",
                                   bnc, peer->host);
                unregister_zebra_rnh(bnc, 0);
-               bgp_nexthop_set_node_info(bnc->node, NULL);
+               bgp_node_set_bgp_nexthop_info(bnc->node, NULL);
                bgp_unlock_node(bnc->node);
                bnc_free(bnc);
        }
@@ -371,7 +371,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
                return;
        }
 
-       bnc = bgp_nexthop_get_node_info(rn);
+       bnc = bgp_node_get_bgp_nexthop_info(rn);
        if (!bnc) {
                if (BGP_DEBUG(nht, NHT)) {
                        char buf[PREFIX2STR_BUFFER];
@@ -510,7 +510,7 @@ void bgp_cleanup_nexthops(struct bgp *bgp)
 
                for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn;
                     rn = bgp_route_next(rn)) {
-                       bnc = bgp_nexthop_get_node_info(rn);
+                       bnc = bgp_node_get_bgp_nexthop_info(rn);
                        if (!bnc)
                                continue;
 
@@ -829,7 +829,7 @@ void bgp_nht_register_nexthops(struct bgp *bgp)
 
                for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn;
                     rn = bgp_route_next(rn)) {
-                       bnc = bgp_nexthop_get_node_info(rn);
+                       bnc = bgp_node_get_bgp_nexthop_info(rn);
 
                        if (!bnc)
                                continue;
@@ -869,7 +869,7 @@ void bgp_nht_register_enhe_capability_interfaces(struct peer *peer)
        if (!rn)
                return;
 
-       bnc = bgp_nexthop_get_node_info(rn);
+       bnc = bgp_node_get_bgp_nexthop_info(rn);
        if (!bnc)
                return;
 
index 8cefb3ff3988886a1c7f6f632c53b36b87e2914d..23002fb74ca842184fdb2a01ebbf788ba49b995d 100644 (file)
@@ -120,11 +120,12 @@ struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
            || (safi == SAFI_EVPN)) {
                prn = bgp_node_get(table, (struct prefix *)prd);
 
-               if (prn->info == NULL)
-                       prn->info = bgp_table_init(table->bgp, afi, safi);
+               if (!bgp_node_has_bgp_path_info_data(prn))
+                       bgp_node_set_bgp_table_info(
+                               prn, bgp_table_init(table->bgp, afi, safi));
                else
                        bgp_unlock_node(prn);
-               table = prn->info;
+               table = bgp_node_get_bgp_table_info(prn);
        }
 
        rn = bgp_node_get(table, p);
@@ -152,12 +153,12 @@ struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
                if (!prn)
                        return NULL;
 
-               if (prn->info == NULL) {
+               if (!bgp_node_has_bgp_path_info_data(prn)) {
                        bgp_unlock_node(prn);
                        return NULL;
                }
 
-               table = prn->info;
+               table = bgp_node_get_bgp_table_info(prn);
        }
 
        rn = bgp_node_lookup(table, p);
@@ -291,13 +292,13 @@ void bgp_path_info_add(struct bgp_node *rn, struct bgp_path_info *pi)
 {
        struct bgp_path_info *top;
 
-       top = rn->info;
+       top = bgp_node_get_bgp_path_info(rn);
 
-       pi->next = rn->info;
+       pi->next = top;
        pi->prev = NULL;
        if (top)
                top->prev = pi;
-       rn->info = pi;
+       bgp_node_set_bgp_path_info(rn, pi);
 
        bgp_path_info_lock(pi);
        bgp_lock_node(rn);
@@ -313,7 +314,7 @@ void bgp_path_info_reap(struct bgp_node *rn, struct bgp_path_info *pi)
        if (pi->prev)
                pi->prev->next = pi->next;
        else
-               rn->info = pi->next;
+               bgp_node_set_bgp_path_info(rn, pi->next);
 
        bgp_path_info_mpath_dequeue(pi);
        bgp_path_info_unlock(pi);
@@ -1895,11 +1896,13 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
        if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)) {
 
                /* Clear BGP_PATH_DMED_SELECTED for all paths */
-               for (pi1 = rn->info; pi1; pi1 = pi1->next)
+               for (pi1 = bgp_node_get_bgp_path_info(rn); pi1;
+                    pi1 = pi1->next)
                        bgp_path_info_unset_flag(rn, pi1,
                                                 BGP_PATH_DMED_SELECTED);
 
-               for (pi1 = rn->info; pi1; pi1 = pi1->next) {
+               for (pi1 = bgp_node_get_bgp_path_info(rn); pi1;
+                    pi1 = pi1->next) {
                        if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
                                continue;
                        if (BGP_PATH_HOLDDOWN(pi1))
@@ -1965,8 +1968,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
        /* Check old selected route and new selected route. */
        old_select = NULL;
        new_select = NULL;
-       for (pi = rn->info; (pi != NULL) && (nextpi = pi->next, 1);
-            pi = nextpi) {
+       for (pi = bgp_node_get_bgp_path_info(rn);
+            (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
                if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
                        old_select = pi;
 
@@ -2030,8 +2033,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
        }
 
        if (do_mpath && new_select) {
-               for (pi = rn->info; (pi != NULL) && (nextpi = pi->next, 1);
-                    pi = nextpi) {
+               for (pi = bgp_node_get_bgp_path_info(rn);
+                    (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
 
                        if (debug)
                                bgp_path_info_path_with_addpath_rx_str(
@@ -2151,7 +2154,7 @@ void bgp_zebra_clear_route_change_flags(struct bgp_node *rn)
 {
        struct bgp_path_info *pi;
 
-       for (pi = rn->info; pi; pi = pi->next) {
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                if (BGP_PATH_HOLDDOWN(pi))
                        continue;
                UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
@@ -2741,8 +2744,8 @@ static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_path_info *pi,
 
                prn = bgp_node_get(peer->bgp->rib[afi][safi],
                                   (struct prefix *)prd);
-               if (prn->info) {
-                       table = (struct bgp_table *)(prn->info);
+               if (bgp_node_has_bgp_path_info_data(prn)) {
+                       table = bgp_node_get_bgp_table_info(prn);
 
                        vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
                                peer->bgp, prd, table, &rn->p, pi);
@@ -2948,7 +2951,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                bgp_adj_in_set(rn, peer, attr, addpath_id);
 
        /* Check previously received route. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->peer == peer && pi->type == type
                    && pi->sub_type == sub_type
                    && pi->addpath_rx_id == addpath_id)
@@ -3172,8 +3175,8 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
 
                        prn = bgp_node_get(bgp->rib[afi][safi],
                                           (struct prefix *)prd);
-                       if (prn->info) {
-                               table = (struct bgp_table *)(prn->info);
+                       if (bgp_node_has_bgp_path_info_data(prn)) {
+                               table = bgp_node_get_bgp_table_info(prn);
 
                                vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
                                        bgp, prd, table, p, pi);
@@ -3322,8 +3325,8 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
 
                        prn = bgp_node_get(bgp->rib[afi][safi],
                                           (struct prefix *)prd);
-                       if (prn->info) {
-                               table = (struct bgp_table *)(prn->info);
+                       if (bgp_node_has_bgp_path_info_data(prn)) {
+                               table = bgp_node_get_bgp_table_info(prn);
 
                                vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
                                        bgp, prd, table, p, pi);
@@ -3459,8 +3462,8 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                struct bgp_table *table = NULL;
 
                prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
-               if (prn->info) {
-                       table = (struct bgp_table *)(prn->info);
+               if (bgp_node_has_bgp_path_info_data(prn)) {
+                       table = bgp_node_get_bgp_table_info(prn);
 
                        vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
                                bgp, prd, table, p, new);
@@ -3611,7 +3614,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                }
 
        /* Lookup withdrawn route. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->peer == peer && pi->type == type
                    && pi->sub_type == sub_type
                    && pi->addpath_rx_id == addpath_id)
@@ -3765,7 +3768,8 @@ static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
                        if (ain->peer != peer)
                                continue;
 
-                       struct bgp_path_info *pi = rn->info;
+                       struct bgp_path_info *pi =
+                               bgp_node_get_bgp_path_info(rn);
                        uint32_t num_labels = 0;
                        mpls_label_t *label_pnt = NULL;
 
@@ -3799,9 +3803,11 @@ void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
                bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
        else
                for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
-                    rn = bgp_route_next(rn))
-                       if ((table = rn->info) != NULL) {
+                    rn = bgp_route_next(rn)) {
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (table != NULL) {
                                struct prefix_rd prd;
+
                                prd.family = AF_UNSPEC;
                                prd.prefixlen = 64;
                                memcpy(&prd.val, rn->p.u.val, 8);
@@ -3809,6 +3815,7 @@ void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
                                bgp_soft_reconfig_table(peer, afi, safi, table,
                                                        &prd);
                        }
+               }
 }
 
 
@@ -3832,7 +3839,7 @@ static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
        /* It is possible that we have multiple paths for a prefix from a peer
         * if that peer is using AddPath.
         */
-       for (pi = rn->info; pi; pi = pi->next) {
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                if (pi->peer != peer)
                        continue;
 
@@ -3971,7 +3978,7 @@ static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
                        ain = ain_next;
                }
 
-               for (pi = rn->info; pi; pi = next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
                        next = pi->next;
                        if (pi->peer != peer)
                                continue;
@@ -4028,9 +4035,13 @@ void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
                bgp_clear_route_table(peer, afi, safi, NULL);
        else
                for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
-                    rn = bgp_route_next(rn))
-                       if ((table = rn->info) != NULL)
-                               bgp_clear_route_table(peer, afi, safi, table);
+                    rn = bgp_route_next(rn)) {
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (!table)
+                               continue;
+
+                       bgp_clear_route_table(peer, afi, safi, table);
+               }
 
        /* unlock if no nodes got added to the clear-node-queue. */
        if (!peer->clear_node_queue->thread)
@@ -4090,12 +4101,14 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
                        struct bgp_node *rm;
 
                        /* look for neighbor in tables */
-                       if ((table = rn->info) == NULL)
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (!table)
                                continue;
 
                        for (rm = bgp_table_top(table); rm;
                             rm = bgp_route_next(rm))
-                               for (pi = rm->info; pi; pi = pi->next) {
+                               for (pi = bgp_node_get_bgp_path_info(rm); pi;
+                                    pi = pi->next) {
                                        if (pi->peer != peer)
                                                continue;
                                        if (!CHECK_FLAG(pi->flags,
@@ -4109,7 +4122,8 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
        } else {
                for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
                     rn = bgp_route_next(rn))
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
                                if (pi->peer != peer)
                                        continue;
                                if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
@@ -4128,7 +4142,7 @@ static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
        struct bgp_path_info *next;
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
-               for (pi = rn->info; pi; pi = next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
                        next = pi->next;
                        if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
                            && pi->type == ZEBRA_ROUTE_BGP
@@ -4149,6 +4163,7 @@ void bgp_cleanup_routes(struct bgp *bgp)
 {
        afi_t afi;
        struct bgp_node *rn;
+       struct bgp_table *table;
 
        for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
                if (afi == AFI_L2VPN)
@@ -4163,26 +4178,22 @@ void bgp_cleanup_routes(struct bgp *bgp)
                        safi = SAFI_MPLS_VPN;
                        for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
                             rn = bgp_route_next(rn)) {
-                               if (rn->info) {
-                                       bgp_cleanup_table(bgp,
-                                               (struct bgp_table *)(rn->info),
-                                               safi);
-                                       bgp_table_finish((struct bgp_table **)&(
-                                               rn->info));
-                                       rn->info = NULL;
+                               table = bgp_node_get_bgp_table_info(rn);
+                               if (table != NULL) {
+                                       bgp_cleanup_table(bgp, table, safi);
+                                       bgp_table_finish(&table);
+                                       bgp_node_set_bgp_table_info(rn, NULL);
                                        bgp_unlock_node(rn);
                                }
                        }
                        safi = SAFI_ENCAP;
                        for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
                             rn = bgp_route_next(rn)) {
-                               if (rn->info) {
-                                       bgp_cleanup_table(bgp,
-                                               (struct bgp_table *)(rn->info),
-                                               safi);
-                                       bgp_table_finish((struct bgp_table **)&(
-                                               rn->info));
-                                       rn->info = NULL;
+                               table = bgp_node_get_bgp_table_info(rn);
+                               if (table != NULL) {
+                                       bgp_cleanup_table(bgp, table, safi);
+                                       bgp_table_finish(&table);
+                                       bgp_node_set_bgp_table_info(rn, NULL);
                                        bgp_unlock_node(rn);
                                }
                        }
@@ -4190,12 +4201,11 @@ void bgp_cleanup_routes(struct bgp *bgp)
        }
        for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
             rn = bgp_route_next(rn)) {
-               if (rn->info) {
-                       bgp_cleanup_table(bgp,
-                                         (struct bgp_table *)(rn->info),
-                                         SAFI_EVPN);
-                       bgp_table_finish((struct bgp_table **)&(rn->info));
-                       rn->info = NULL;
+               table = bgp_node_get_bgp_table_info(rn);
+               if (table != NULL) {
+                       bgp_cleanup_table(bgp, table, SAFI_EVPN);
+                       bgp_table_finish(&table);
+                       bgp_node_set_bgp_table_info(rn, NULL);
                        bgp_unlock_node(rn);
                }
        }
@@ -4458,7 +4468,7 @@ void bgp_static_update(struct bgp *bgp, struct prefix *p,
                attr_new = bgp_attr_intern(&attr);
        }
 
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
                    && pi->sub_type == BGP_ROUTE_STATIC)
                        break;
@@ -4626,7 +4636,7 @@ void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
        rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
 
        /* Check selected route and self inserted route. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
                    && pi->sub_type == BGP_ROUTE_STATIC)
                        break;
@@ -4661,7 +4671,7 @@ static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
        rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
 
        /* Check selected route and self inserted route. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
                    && pi->sub_type == BGP_ROUTE_STATIC)
                        break;
@@ -4771,7 +4781,7 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
                attr_new = bgp_attr_intern(&attr);
        }
 
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
                    && pi->sub_type == BGP_ROUTE_STATIC)
                        break;
@@ -4895,7 +4905,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                        return CMD_WARNING_CONFIG_FAILED;
                }
 
-               bgp_static = bgp_static_get_node_info(rn);
+               bgp_static = bgp_node_get_bgp_static_info(rn);
 
                if ((label_index != BGP_INVALID_LABEL_INDEX)
                    && (label_index != bgp_static->label_index)) {
@@ -4917,7 +4927,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
 
                /* Clear configuration. */
                bgp_static_free(bgp_static);
-               bgp_static_set_node_info(rn, NULL);
+               bgp_node_set_bgp_static_info(rn, NULL);
                bgp_unlock_node(rn);
                bgp_unlock_node(rn);
        } else {
@@ -4925,7 +4935,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                /* Set BGP static route configuration. */
                rn = bgp_node_get(bgp->route[afi][safi], &p);
 
-               bgp_static = bgp_static_get_node_info(rn);
+               bgp_static = bgp_node_get_bgp_static_info(rn);
                if (bgp_static) {
                        /* Configuration change. */
                        /* Label index cannot be changed. */
@@ -4976,7 +4986,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                                bgp_static->rmap.map =
                                        route_map_lookup_by_name(rmap);
                        }
-                       bgp_static_set_node_info(rn, bgp_static);
+                       bgp_node_set_bgp_static_info(rn, bgp_static);
                }
 
                bgp_static->valid = 1;
@@ -5002,25 +5012,27 @@ void bgp_static_add(struct bgp *bgp)
        FOREACH_AFI_SAFI (afi, safi)
                for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
                     rn = bgp_route_next(rn)) {
-                       if (rn->info == NULL)
+                       if (!bgp_node_has_bgp_path_info_data(rn))
                                continue;
 
                        if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
                            || (safi == SAFI_EVPN)) {
-                               table = rn->info;
+                               table = bgp_node_get_bgp_table_info(rn);
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
                                        bgp_static =
-                                               bgp_static_get_node_info(rm);
+                                               bgp_node_get_bgp_static_info(
+                                                       rm);
                                        bgp_static_update_safi(bgp, &rm->p,
                                                               bgp_static, afi,
                                                               safi);
                                }
                        } else {
-                               bgp_static_update(bgp, &rn->p,
-                                                 bgp_static_get_node_info(rn),
-                                                 afi, safi);
+                               bgp_static_update(
+                                       bgp, &rn->p,
+                                       bgp_node_get_bgp_static_info(rn), afi,
+                                       safi);
                        }
                }
 }
@@ -5039,29 +5051,30 @@ void bgp_static_delete(struct bgp *bgp)
        FOREACH_AFI_SAFI (afi, safi)
                for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
                     rn = bgp_route_next(rn)) {
-                       if (rn->info == NULL)
+                       if (!bgp_node_has_bgp_path_info_data(rn))
                                continue;
 
                        if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
                            || (safi == SAFI_EVPN)) {
-                               table = rn->info;
+                               table = bgp_node_get_bgp_table_info(rn);
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
                                        bgp_static =
-                                               bgp_static_get_node_info(rm);
+                                               bgp_node_get_bgp_static_info(
+                                                       rm);
                                        bgp_static_withdraw_safi(
                                                bgp, &rm->p, AFI_IP, safi,
                                                (struct prefix_rd *)&rn->p);
                                        bgp_static_free(bgp_static);
-                                       bgp_static_set_node_info(rn, NULL);
+                                       bgp_node_set_bgp_static_info(rn, NULL);
                                        bgp_unlock_node(rn);
                                }
                        } else {
-                               bgp_static = bgp_static_get_node_info(rn);
+                               bgp_static = bgp_node_get_bgp_static_info(rn);
                                bgp_static_withdraw(bgp, &rn->p, afi, safi);
                                bgp_static_free(bgp_static);
-                               bgp_static_set_node_info(rn, NULL);
+                               bgp_node_set_bgp_static_info(rn, NULL);
                                bgp_unlock_node(rn);
                        }
                }
@@ -5081,23 +5094,24 @@ void bgp_static_redo_import_check(struct bgp *bgp)
        FOREACH_AFI_SAFI (afi, safi) {
                for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
                     rn = bgp_route_next(rn)) {
-                       if (rn->info == NULL)
+                       if (!bgp_node_has_bgp_path_info_data(rn))
                                continue;
 
                        if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
                            || (safi == SAFI_EVPN)) {
-                               table = rn->info;
+                               table = bgp_node_get_bgp_table_info(rn);
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
                                        bgp_static =
-                                               bgp_static_get_node_info(rm);
+                                               bgp_node_get_bgp_static_info(
+                                                       rm);
                                        bgp_static_update_safi(bgp, &rm->p,
                                                               bgp_static, afi,
                                                               safi);
                                }
                        } else {
-                               bgp_static = bgp_static_get_node_info(rn);
+                               bgp_static = bgp_node_get_bgp_static_info(rn);
                                bgp_static_update(bgp, &rn->p, bgp_static, afi,
                                                  safi);
                        }
@@ -5115,7 +5129,7 @@ static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
 
        table = bgp->rib[afi][safi];
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (pi->peer == bgp->peer_self
                            && ((pi->type == ZEBRA_ROUTE_BGP
                                 && pi->sub_type == BGP_ROUTE_STATIC)
@@ -5222,15 +5236,16 @@ int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
                }
        }
        prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
-       if (prn->info == NULL)
-               prn->info = bgp_table_init(bgp, afi, safi);
+       if (!bgp_node_has_bgp_path_info_data(prn))
+               bgp_node_set_bgp_table_info(prn,
+                                           bgp_table_init(bgp, afi, safi));
        else
                bgp_unlock_node(prn);
-       table = prn->info;
+       table = bgp_node_get_bgp_table_info(prn);
 
        rn = bgp_node_get(table, &p);
 
-       if (rn->info) {
+       if (bgp_node_has_bgp_path_info_data(rn)) {
                vty_out(vty, "%% Same network configuration exists\n");
                bgp_unlock_node(rn);
        } else {
@@ -5269,7 +5284,7 @@ int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
                        if (gwip)
                                prefix_copy(&bgp_static->gatewayIp, &gw_ip);
                }
-               bgp_static_set_node_info(rn, bgp_static);
+               bgp_node_set_bgp_static_info(rn, bgp_static);
 
                bgp_static->valid = 1;
                bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
@@ -5320,20 +5335,21 @@ int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
        }
 
        prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
-       if (prn->info == NULL)
-               prn->info = bgp_table_init(bgp, afi, safi);
+       if (!bgp_node_has_bgp_path_info_data(prn))
+               bgp_node_set_bgp_table_info(prn,
+                                           bgp_table_init(bgp, afi, safi));
        else
                bgp_unlock_node(prn);
-       table = prn->info;
+       table = bgp_node_get_bgp_table_info(prn);
 
        rn = bgp_node_lookup(table, &p);
 
        if (rn) {
                bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
 
-               bgp_static = bgp_static_get_node_info(rn);
+               bgp_static = bgp_node_get_bgp_static_info(rn);
                bgp_static_free(bgp_static);
-               bgp_static_set_node_info(rn, NULL);
+               bgp_node_set_bgp_static_info(rn, NULL);
                bgp_unlock_node(rn);
                bgp_unlock_node(rn);
        } else
@@ -5553,13 +5569,13 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
 {
        struct bgp_node *rn;
        struct bgp_table *table;
-       struct bgp_path_info *pi, *new;
+       struct bgp_path_info *pi, *orig, *new;
 
        table = bgp->rib[afi][safi];
 
        rn = bgp_node_get(table, p);
 
-       for (pi = rn->info; pi; pi = pi->next)
+       for (orig = pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
                    && pi->sub_type == BGP_ROUTE_AGGREGATE)
                        break;
@@ -5569,7 +5585,7 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                 * If the aggregate information has not changed
                 * no need to re-install it again.
                 */
-               if (bgp_aggregate_info_same(rn->info, origin, aspath, community,
+               if (bgp_aggregate_info_same(orig, origin, aspath, community,
                                            ecommunity, lcommunity)) {
                        bgp_unlock_node(rn);
 
@@ -5604,7 +5620,7 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                bgp_path_info_add(rn, new);
                bgp_process(bgp, rn, afi, safi);
        } else {
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = orig; pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self
                            && pi->type == ZEBRA_ROUTE_BGP
                            && pi->sub_type == BGP_ROUTE_AGGREGATE)
@@ -5662,7 +5678,7 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
 
                match = 0;
 
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (BGP_PATH_HOLDDOWN(pi))
                                continue;
 
@@ -5854,7 +5870,7 @@ static void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
                        continue;
                match = 0;
 
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (BGP_PATH_HOLDDOWN(pi))
                                continue;
 
@@ -5904,7 +5920,7 @@ void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
 
        /* Aggregate address configuration check. */
        for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
-               aggregate = bgp_aggregate_get_node_info(rn);
+               aggregate = bgp_node_get_bgp_aggregate_info(rn);
                if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
                        bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
                        bgp_aggregate_route(bgp, &rn->p, pi, afi, safi, NULL,
@@ -5935,7 +5951,7 @@ void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
 
        /* Aggregate address configuration check. */
        for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
-               aggregate = bgp_aggregate_get_node_info(rn);
+               aggregate = bgp_node_get_bgp_aggregate_info(rn);
                if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
                        bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
                        bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
@@ -5974,13 +5990,13 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       aggregate = bgp_aggregate_get_node_info(rn);
+       aggregate = bgp_node_get_bgp_aggregate_info(rn);
        bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
        bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
                              NULL, NULL,  0, aggregate);
 
        /* Unlock aggregate address configuration. */
-       bgp_aggregate_set_node_info(rn, NULL);
+       bgp_node_set_bgp_aggregate_info(rn, NULL);
        bgp_aggregate_free(aggregate);
        bgp_unlock_node(rn);
        bgp_unlock_node(rn);
@@ -6015,7 +6031,7 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
        /* Old configuration check. */
        rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
 
-       if (rn->info) {
+       if (bgp_node_has_bgp_path_info_data(rn)) {
                vty_out(vty, "There is already same aggregate network.\n");
                /* try to remove the old entry */
                ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
@@ -6031,7 +6047,7 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
        aggregate->summary_only = summary_only;
        aggregate->as_set = as_set;
        aggregate->safi = safi;
-       bgp_aggregate_set_node_info(rn, aggregate);
+       bgp_node_set_bgp_aggregate_info(rn, aggregate);
 
        /* Aggregate address insert into BGP routing table. */
        bgp_aggregate_route(bgp, &p, NULL, afi, safi, NULL, aggregate);
@@ -6269,7 +6285,8 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
 
                new_attr = bgp_attr_intern(&attr_new);
 
-               for (bpi = bn->info; bpi; bpi = bpi->next)
+               for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
+                    bpi = bpi->next)
                        if (bpi->peer == bgp->peer_self
                            && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
                                break;
@@ -6351,7 +6368,7 @@ void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
                rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
                                      SAFI_UNICAST, p, NULL);
 
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self && pi->type == type)
                                break;
 
@@ -6381,7 +6398,7 @@ void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
        table = bgp->rib[afi][SAFI_UNICAST];
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self && pi->type == type
                            && pi->instance == instance)
                                break;
@@ -6564,7 +6581,7 @@ void route_vty_out(struct vty *vty, struct prefix *p,
                CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
        bool nexthop_othervrf = false;
        vrf_id_t nexthop_vrfid = VRF_DEFAULT;
-       const char *nexthop_vrfname = "Default";
+       const char *nexthop_vrfname = VRF_DEFAULT_NAME;
 
        if (json_paths)
                json_path = json_object_new_object();
@@ -7846,7 +7863,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
                                if (path->extra->bgp_orig->inst_type
                                    == BGP_INSTANCE_TYPE_DEFAULT)
 
-                                       vn = "Default";
+                                       vn = VRF_DEFAULT_NAME;
                                else
                                        vn = path->extra->bgp_orig->name;
 
@@ -8427,12 +8444,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
        if (use_json && !*json_header_depth) {
                vty_out(vty,
                        "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
-                       ",\n \"routerId\": \"%s\",\n \"routes\": { ",
+                       ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
+                       " \"localAS\": %u,\n \"routes\": { ",
                        bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
                        bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
                                                ? VRF_DEFAULT_NAME
                                                : bgp->name,
-                       table->version, inet_ntoa(bgp->router_id));
+                       table->version, inet_ntoa(bgp->router_id),
+                       bgp->default_local_pref, bgp->as);
                *json_header_depth = 2;
                if (rd) {
                        vty_out(vty, " \"routeDistinguishers\" : {");
@@ -8446,7 +8465,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
 
        /* Start processing of routes. */
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-               if (rn->info == NULL)
+               pi = bgp_node_get_bgp_path_info(rn);
+               if (pi == NULL)
                        continue;
 
                display = 0;
@@ -8455,7 +8475,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                else
                        json_paths = NULL;
 
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (; pi; pi = pi->next) {
                        total_count++;
                        if (type == bgp_show_type_flap_statistics
                            || type == bgp_show_type_flap_neighbor
@@ -8599,6 +8619,9 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                                else
                                        vty_out(vty, "%u", bgp->vrf_id);
                                vty_out(vty, "\n");
+                               vty_out(vty, "Default local pref %u, ",
+                                       bgp->default_local_pref);
+                               vty_out(vty, "local AS %u\n", bgp->as);
                                vty_out(vty, BGP_SHOW_SCODE_HEADER);
                                vty_out(vty, BGP_SHOW_NCODE_HEADER);
                                vty_out(vty, BGP_SHOW_OCODE_HEADER);
@@ -8715,6 +8738,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
        unsigned long output_cum = 0;
        unsigned long total_cum = 0;
        unsigned long json_header_depth = 0;
+       struct bgp_table *itable;
        bool show_msg;
 
        show_msg = (!use_json && type == bgp_show_type_normal);
@@ -8723,16 +8747,17 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
                next = bgp_route_next(rn);
                if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
                        continue;
-               if (rn->info != NULL) {
+
+               itable = bgp_node_get_bgp_table_info(rn);
+               if (itable != NULL) {
                        struct prefix_rd prd;
                        char rd[RD_ADDRSTRLEN];
 
                        memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
                        prefix_rd2str(&prd, rd, sizeof(rd));
-                       bgp_show_table(vty, bgp, safi, rn->info, type,
-                                      output_arg, use_json, rd, next == NULL,
-                                      &output_cum, &total_cum,
-                                      &json_header_depth);
+                       bgp_show_table(vty, bgp, safi, itable, type, output_arg,
+                                      use_json, rd, next == NULL, &output_cum,
+                                      &total_cum, &json_header_depth);
                        if (next == NULL)
                                show_msg = false;
                }
@@ -8897,7 +8922,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
                        vty_out(vty, "not allocated\n");
        }
 
-       for (pi = rn->info; pi; pi = pi->next) {
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                count++;
                if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
                        best = count;
@@ -9061,8 +9086,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
                for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
                        if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
                                continue;
-
-                       if ((table = rn->info) == NULL)
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (!table)
                                continue;
 
                        header = 1;
@@ -9076,7 +9101,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
                                continue;
                        }
 
-                       for (pi = rm->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rm); pi;
+                            pi = pi->next) {
                                if (header) {
                                        route_vty_out_detail_header(
                                                vty, bgp, rm,
@@ -9114,7 +9140,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
                if ((rn = bgp_node_match(rib, &match)) != NULL) {
                        if (!prefix_check
                            || rn->p.prefixlen == match.prefixlen) {
-                               for (pi = rn->info; pi; pi = pi->next) {
+                               for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                                    pi = pi->next) {
                                        if (header) {
                                                route_vty_out_detail_header(
                                                        vty, bgp, rn, NULL, afi,
@@ -9923,7 +9950,7 @@ static int bgp_table_stats_walker(struct thread *t)
                if (rn == top)
                        continue;
 
-               if (!rn->info)
+               if (!bgp_node_has_bgp_path_info_data(rn))
                        continue;
 
                ts->counts[BGP_STATS_PREFIXES]++;
@@ -9937,7 +9964,7 @@ static int bgp_table_stats_walker(struct thread *t)
 #endif
 
                /* check if the prefix is included by any other announcements */
-               while (prn && !prn->info)
+               while (prn && !bgp_node_has_bgp_path_info_data(prn))
                        prn = bgp_node_parent_nolock(prn);
 
                if (prn == NULL || prn == top) {
@@ -9946,10 +9973,10 @@ static int bgp_table_stats_walker(struct thread *t)
                        if (space)
                                ts->total_space +=
                                        pow(2.0, space - rn->p.prefixlen);
-               } else if (prn->info)
+               } else if (bgp_node_has_bgp_path_info_data(prn))
                        ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
 
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        pinum++;
                        ts->counts[BGP_STATS_RIB]++;
 
@@ -10132,7 +10159,8 @@ static int bgp_peer_count_walker(struct thread *t)
                        if (ain->peer == peer)
                                pc->count[PCOUNT_ADJ_IN]++;
 
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
+
                        if (pi->peer != peer)
                                continue;
 
@@ -10454,6 +10482,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                            table->version);
                        json_object_string_add(json, "bgpLocalRouterId",
                                               inet_ntoa(bgp->router_id));
+                       json_object_int_add(json, "defaultLocPrf",
+                                               bgp->default_local_pref);
+                       json_object_int_add(json, "localAS", bgp->as);
                        json_object_object_add(json, "bgpStatusCodes",
                                               json_scode);
                        json_object_object_add(json, "bgpOriginCodes",
@@ -10470,6 +10501,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                        else
                                vty_out(vty, "%u", bgp->vrf_id);
                        vty_out(vty, "\n");
+                       vty_out(vty, "Default local pref %u, ",
+                               bgp->default_local_pref);
+                       vty_out(vty, "local AS %u\n", bgp->as);
                        vty_out(vty, BGP_SHOW_SCODE_HEADER);
                        vty_out(vty, BGP_SHOW_NCODE_HEADER);
                        vty_out(vty, BGP_SHOW_OCODE_HEADER);
@@ -10497,6 +10531,11 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                                        "bgpLocalRouterId",
                                                        inet_ntoa(
                                                                bgp->router_id));
+                                               json_object_int_add(json,
+                                               "defaultLocPrf",
+                                               bgp->default_local_pref);
+                                               json_object_int_add(json,
+                                               "localAS", bgp->as);
                                                json_object_object_add(
                                                        json, "bgpStatusCodes",
                                                        json_scode);
@@ -10515,6 +10554,11 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                                        vty_out(vty, "%u",
                                                                bgp->vrf_id);
                                                vty_out(vty, "\n");
+                                               vty_out(vty,
+                                               "Default local pref %u, ",
+                                               bgp->default_local_pref);
+                                               vty_out(vty, "local AS %u\n",
+                                               bgp->as);
                                                vty_out(vty,
                                                        BGP_SHOW_SCODE_HEADER);
                                                vty_out(vty,
@@ -10576,6 +10620,13 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                                                "bgpLocalRouterId",
                                                                inet_ntoa(
                                                                        bgp->router_id));
+                                                       json_object_int_add(
+                                                       json, "defaultLocPrf",
+                                                       bgp->default_local_pref
+                                                       );
+                                                       json_object_int_add(
+                                                       json, "localAS",
+                                                       bgp->as);
                                                        json_object_object_add(
                                                                json,
                                                                "bgpStatusCodes",
@@ -10601,6 +10652,13 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                                                "%u",
                                                                bgp->vrf_id);
                                                        vty_out(vty, "\n");
+                                                       vty_out(vty,
+                                                       "Default local pref %u, ",
+                                                       bgp->default_local_pref
+                                                       );
+                                                       vty_out(vty,
+                                                       "local AS %u\n",
+                                                       bgp->as);
                                                        vty_out(vty,
                                                                BGP_SHOW_SCODE_HEADER);
                                                        vty_out(vty,
@@ -11033,12 +11091,12 @@ static int bgp_distance_set(struct vty *vty, const char *distance_str,
 
        /* Get BGP distance node. */
        rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
-       bdistance = bgp_distance_get_node(rn);
+       bdistance = bgp_node_get_bgp_distance_info(rn);
        if (bdistance)
                bgp_unlock_node(rn);
        else {
                bdistance = bgp_distance_new();
-               bgp_distance_set_node_info(rn, bdistance);
+               bgp_node_set_bgp_distance_info(rn, bdistance);
        }
 
        /* Set distance value. */
@@ -11083,7 +11141,7 @@ static int bgp_distance_unset(struct vty *vty, const char *distance_str,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       bdistance = bgp_distance_get_node(rn);
+       bdistance = bgp_node_get_bgp_distance_info(rn);
        distance = atoi(distance_str);
 
        if (bdistance->distance != distance) {
@@ -11095,7 +11153,7 @@ static int bgp_distance_unset(struct vty *vty, const char *distance_str,
                XFREE(MTYPE_AS_LIST, bdistance->access_list);
        bgp_distance_free(bdistance);
 
-       rn->info = NULL;
+       bgp_node_set_bgp_path_info(rn, NULL);
        bgp_unlock_node(rn);
        bgp_unlock_node(rn);
 
@@ -11122,7 +11180,7 @@ uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
        sockunion2hostprefix(&peer->su, &q);
        rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
        if (rn) {
-               bdistance = bgp_distance_get_node(rn);
+               bdistance = bgp_node_get_bgp_distance_info(rn);
                bgp_unlock_node(rn);
 
                if (bdistance->access_list) {
@@ -11137,7 +11195,7 @@ uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
        /* Backdoor check. */
        rn = bgp_node_lookup(bgp->route[afi][safi], p);
        if (rn) {
-               bgp_static = bgp_static_get_node_info(rn);
+               bgp_static = bgp_node_get_bgp_static_info(rn);
                bgp_unlock_node(rn);
 
                if (bgp_static->backdoor) {
@@ -11418,14 +11476,15 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
                     rn = bgp_route_next(rn)) {
                        if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
                                continue;
-                       if ((table = rn->info) == NULL)
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (!table)
                                continue;
                        if ((rm = bgp_node_match(table, &match)) == NULL)
                                continue;
 
                        if (!prefix_check
                            || rm->p.prefixlen == match.prefixlen) {
-                               pi = rm->info;
+                               pi = bgp_node_get_bgp_path_info(rm);
                                while (pi) {
                                        if (pi->extra && pi->extra->damp_info) {
                                                pi_temp = pi->next;
@@ -11445,7 +11504,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
                    != NULL) {
                        if (!prefix_check
                            || rn->p.prefixlen == match.prefixlen) {
-                               pi = rn->info;
+                               pi = bgp_node_get_bgp_path_info(rn);
                                while (pi) {
                                        if (pi->extra && pi->extra->damp_info) {
                                                pi_temp = pi->next;
@@ -11578,11 +11637,12 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
        /* Network configuration. */
        for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
             prn = bgp_route_next(prn)) {
-               if ((table = prn->info) == NULL)
+               table = bgp_node_get_bgp_table_info(prn);
+               if (!table)
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-                       bgp_static = bgp_static_get_node_info(rn);
+                       bgp_static = bgp_node_get_bgp_static_info(rn);
                        if (bgp_static == NULL)
                                continue;
 
@@ -11628,11 +11688,12 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
        /* Network configuration. */
        for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
             prn = bgp_route_next(prn)) {
-               if ((table = prn->info) == NULL)
+               table = bgp_node_get_bgp_table_info(prn);
+               if (!table)
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-                       bgp_static = bgp_static_get_node_info(rn);
+                       bgp_static = bgp_node_get_bgp_static_info(rn);
                        if (bgp_static == NULL)
                                continue;
 
@@ -11708,7 +11769,7 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
        /* Network configuration. */
        for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               bgp_static = bgp_static_get_node_info(rn);
+               bgp_static = bgp_node_get_bgp_static_info(rn);
                if (bgp_static == NULL)
                        continue;
 
@@ -11755,7 +11816,7 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
        /* Aggregate-address configuration. */
        for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               bgp_aggregate = bgp_aggregate_get_node_info(rn);
+               bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
                if (bgp_aggregate == NULL)
                        continue;
 
@@ -11807,7 +11868,7 @@ void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
 
        for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               bdistance = bgp_distance_get_node(rn);
+               bdistance = bgp_node_get_bgp_distance_info(rn);
                if (bdistance != NULL) {
                        char buf[PREFIX_STRLEN];
 
index fc27c546b464be1206d0405e27737013c131a10d..a308e8fec6e22f2e0fd64f3c673df634a0a61aa2 100644 (file)
@@ -3226,33 +3226,29 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
 
                /* For network route-map updates. */
                for (bn = bgp_table_top(bgp->route[afi][safi]); bn;
-                    bn = bgp_route_next(bn))
-                       if ((bgp_static = bn->info) != NULL) {
-                               if (bgp_static->rmap.name
-                                   && (strcmp(rmap_name, bgp_static->rmap.name)
-                                       == 0)) {
-                                       bgp_static->rmap.map = map;
-
-                                       if (route_update)
-                                               if (!bgp_static->backdoor) {
-                                                       if (bgp_debug_zebra(
-                                                                   &bn->p))
-                                                               zlog_debug(
-                                                                       "Processing route_map %s update on "
-                                                                       "static route %s",
-                                                                       rmap_name,
-                                                                       inet_ntop(
-                                                                               bn->p.family,
-                                                                               &bn->p.u.prefix,
-                                                                               buf,
-                                                                               INET6_ADDRSTRLEN));
-                                                       bgp_static_update(
-                                                               bgp, &bn->p,
-                                                               bgp_static, afi,
-                                                               safi);
-                                               }
-                               }
+                    bn = bgp_route_next(bn)) {
+                       bgp_static = bgp_node_get_bgp_static_info(bn);
+                       if (!bgp_static)
+                               continue;
+
+                       if (!bgp_static->rmap.name
+                           || (strcmp(rmap_name, bgp_static->rmap.name) != 0))
+                               continue;
+
+                       bgp_static->rmap.map = map;
+
+                       if (route_update && !bgp_static->backdoor) {
+                               if (bgp_debug_zebra(&bn->p))
+                                       zlog_debug(
+                                               "Processing route_map %s update on static route %s",
+                                               rmap_name,
+                                               inet_ntop(bn->p.family,
+                                                         &bn->p.u.prefix, buf,
+                                                         INET6_ADDRSTRLEN));
+                               bgp_static_update(bgp, &bn->p, bgp_static, afi,
+                                                 safi);
                        }
+               }
        }
 
        /* For redistribute route-map updates. */
@@ -3266,38 +3262,38 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
                                continue;
 
                        for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
-                               if (red->rmap.name
-                                   && (strcmp(rmap_name, red->rmap.name)
-                                       == 0)) {
-                                       red->rmap.map = map;
-
-                                       if (route_update) {
-                                               if (BGP_DEBUG(zebra, ZEBRA))
-                                                       zlog_debug(
-                                                               "Processing route_map %s update on "
-                                                               "redistributed routes",
-                                                               rmap_name);
-
-                                               bgp_redistribute_resend(
-                                                       bgp, afi, i,
+                               if (!red->rmap.name
+                                   || (strcmp(rmap_name, red->rmap.name) != 0))
+                                       continue;
+
+                               red->rmap.map = map;
+
+                               if (!route_update)
+                                       continue;
+
+                               if (BGP_DEBUG(zebra, ZEBRA))
+                                       zlog_debug(
+                                               "Processing route_map %s update on redistributed routes",
+                                               rmap_name);
+
+                               bgp_redistribute_resend(bgp, afi, i,
                                                        red->instance);
-                                       }
-                               }
                        }
                }
 
        /* for type5 command route-maps */
        FOREACH_AFI_SAFI (afi, safi) {
-               if (bgp->adv_cmd_rmap[afi][safi].name
-                   && strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name)
-                              == 0) {
-                       if (BGP_DEBUG(zebra, ZEBRA))
-                               zlog_debug(
-                                       "Processing route_map %s update on advertise type5 route command",
-                                       rmap_name);
-                       bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
-                       bgp_evpn_advertise_type5_routes(bgp, afi, safi);
-               }
+               if (!bgp->adv_cmd_rmap[afi][safi].name
+                   || strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name)
+                              != 0)
+                       continue;
+
+               if (BGP_DEBUG(zebra, ZEBRA))
+                       zlog_debug(
+                               "Processing route_map %s update on advertise type5 route command",
+                               rmap_name);
+               bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
+               bgp_evpn_advertise_type5_routes(bgp, afi, safi);
        }
 }
 
index c5d38f30093e51de41a8e4ae16db7c890f2a28c5..b614e87d23e3fb9111602389896a361c2cabf204 100644 (file)
@@ -418,7 +418,8 @@ static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
 
        for (ain = bgp_node->adj_in; ain; ain = ain->next) {
                int ret;
-               struct bgp_path_info *path = bgp_node->info;
+               struct bgp_path_info *path =
+                       bgp_node_get_bgp_path_info(bgp_node);
                mpls_label_t *label = NULL;
                uint32_t num_labels = 0;
 
index d539fad5107b5bfe32d9d0d17cd0b247219d1a15..c1321dd7dc106d84ec18e45a31d721ba7511cf0e 100644 (file)
@@ -715,7 +715,8 @@ static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[],
                if (rn) {
                        bgp_unlock_node(rn);
 
-                       for (path = rn->info; path; path = path->next)
+                       for (path = bgp_node_get_bgp_path_info(rn); path;
+                            path = path->next)
                                if (sockunion_same(&path->peer->su, &su))
                                        return path;
                }
@@ -762,7 +763,8 @@ static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[],
                do {
                        min = NULL;
 
-                       for (path = rn->info; path; path = path->next) {
+                       for (path = bgp_node_get_bgp_path_info(rn); path;
+                            path = path->next) {
                                if (path->peer->su.sin.sin_family == AF_INET
                                    && ntohl(paddr.s_addr)
                                               < ntohl(path->peer->su.sin
index 032141226365adc31670d60e722fba0c6f85d0ab..ecde71279d2deed6f5b6e96d49cea506afd5c5f2 100644 (file)
@@ -158,7 +158,8 @@ void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p,
 
        while (node && node->p.prefixlen <= p->prefixlen
               && prefix_match(&node->p, p)) {
-               if (node->info && node->p.prefixlen == p->prefixlen) {
+               if (bgp_node_has_bgp_path_info_data(node)
+                   && node->p.prefixlen == p->prefixlen) {
                        matched = node;
                        break;
                }
@@ -174,14 +175,14 @@ void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p,
        else if (matched == NULL)
                matched = node = bgp_node_from_rnode(node->parent);
 
-       if (matched->info) {
+       if (bgp_node_has_bgp_path_info_data(matched)) {
                bgp_lock_node(matched);
                listnode_add(matches, matched);
        }
 
        while ((node = bgp_route_next_until_maxlen(node, matched, maxlen))) {
                if (prefix_match(p, &node->p)) {
-                       if (node->info) {
+                       if (bgp_node_has_bgp_path_info_data(node)) {
                                bgp_lock_node(node);
                                listnode_add(matches, node);
                        }
index 4795ab741c576464009e5d7d3716a84eeafd6f44..040e83a8cd9e8a92ca278759f89cf27967137209 100644 (file)
@@ -61,9 +61,10 @@ struct bgp_node {
 
        STAILQ_ENTRY(bgp_node) pq;
 
+       uint64_t version;
+
        mpls_label_t local_label;
 
-       uint64_t version;
        uint8_t flags;
 #define BGP_NODE_PROCESS_SCHEDULED     (1 << 0)
 #define BGP_NODE_USER_CLEAR             (1 << 1)
@@ -319,61 +320,94 @@ void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p,
 
 
 static inline struct bgp_aggregate *
-bgp_aggregate_get_node_info(struct bgp_node *node)
+bgp_node_get_bgp_aggregate_info(struct bgp_node *node)
 {
        return node->info;
 }
 
-static inline void bgp_aggregate_set_node_info(struct bgp_node *node,
-                                              struct bgp_aggregate *aggregate)
+static inline void
+bgp_node_set_bgp_aggregate_info(struct bgp_node *node,
+                               struct bgp_aggregate *aggregate)
 {
        node->info = aggregate;
 }
 
-static inline struct bgp_distance *bgp_distance_get_node(struct bgp_node *node)
+static inline struct bgp_distance *
+bgp_node_get_bgp_distance_info(struct bgp_node *node)
 {
        return node->info;
 }
 
-static inline void bgp_distance_set_node_info(struct bgp_node *node,
-                                             struct bgp_distance *distance)
+static inline void bgp_node_set_bgp_distance_info(struct bgp_node *node,
+                                                 struct bgp_distance *distance)
 {
        node->info = distance;
 }
 
-static inline struct bgp_static *bgp_static_get_node_info(struct bgp_node *node)
+static inline struct bgp_static *
+bgp_node_get_bgp_static_info(struct bgp_node *node)
 {
        return node->info;
 }
 
-static inline void bgp_static_set_node_info(struct bgp_node *node,
-                                           struct bgp_static *bgp_static)
+static inline void bgp_node_set_bgp_static_info(struct bgp_node *node,
+                                               struct bgp_static *bgp_static)
 {
        node->info = bgp_static;
 }
 
 static inline struct bgp_connected_ref *
-bgp_connected_get_node_info(struct bgp_node *node)
+bgp_node_get_bgp_connected_ref_info(struct bgp_node *node)
 {
        return node->info;
 }
 
-static inline void bgp_connected_set_node_info(struct bgp_node *node,
-                                              struct bgp_connected_ref *bc)
+static inline void
+bgp_node_set_bgp_connected_ref_info(struct bgp_node *node,
+                                   struct bgp_connected_ref *bc)
 {
        node->info = bc;
 }
 
 static inline struct bgp_nexthop_cache *
-bgp_nexthop_get_node_info(struct bgp_node *node)
+bgp_node_get_bgp_nexthop_info(struct bgp_node *node)
 {
        return node->info;
 }
 
-static inline void bgp_nexthop_set_node_info(struct bgp_node *node,
+static inline void bgp_node_set_bgp_nexthop_info(struct bgp_node *node,
                                             struct bgp_nexthop_cache *bnc)
 {
        node->info = bnc;
 }
 
+static inline struct bgp_path_info *
+bgp_node_get_bgp_path_info(struct bgp_node *node)
+{
+       return node->info;
+}
+
+static inline void bgp_node_set_bgp_path_info(struct bgp_node *node,
+                                             struct bgp_path_info *bi)
+{
+       node->info = bi;
+}
+
+static inline struct bgp_table *
+bgp_node_get_bgp_table_info(struct bgp_node *node)
+{
+       return node->info;
+}
+
+static inline void bgp_node_set_bgp_table_info(struct bgp_node *node,
+                                              struct bgp_table *table)
+{
+       node->info = table;
+}
+
+static inline bool bgp_node_has_bgp_path_info_data(struct bgp_node *node)
+{
+       return !!node->info;
+}
+
 #endif /* _QUAGGA_BGP_TABLE_H */
index cefbf72b58ea8d95bc2209ebeba3fe02f5bb8275..3870df593f51a2278c1770167212aec5b8b59da7 100644 (file)
@@ -122,7 +122,8 @@ static void subgrp_withdraw_stale_addpath(struct updwalk_context *ctx,
        RB_FOREACH_SAFE (adj, bgp_adj_out_rb, &ctx->rn->adj_out, adj_next) {
 
                if (adj->subgroup == subgrp) {
-                       for (pi = ctx->rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(ctx->rn);
+                            pi; pi = pi->next) {
                                id = bgp_addpath_id_for_peer(peer, afi, safi,
                                        &pi->tx_addpath);
 
@@ -176,7 +177,8 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
                        if (addpath_capable) {
                                subgrp_withdraw_stale_addpath(ctx, subgrp);
 
-                               for (pi = ctx->rn->info; pi; pi = pi->next) {
+                               for (pi = bgp_node_get_bgp_path_info(ctx->rn);
+                                    pi; pi = pi->next) {
                                        /* Skip the bestpath for now */
                                        if (pi == ctx->pi)
                                                continue;
@@ -629,7 +631,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
                subgroup_default_originate(subgrp, 0);
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
-               for (ri = rn->info; ri; ri = ri->next)
+               for (ri = bgp_node_get_bgp_path_info(rn); ri; ri = ri->next)
 
                        if (CHECK_FLAG(ri->flags, BGP_PATH_SELECTED)
                            || (addpath_capable
@@ -695,9 +697,12 @@ void subgroup_announce_route(struct update_subgroup *subgrp)
                subgroup_announce_table(subgrp, NULL);
        else
                for (rn = bgp_table_top(update_subgroup_rib(subgrp)); rn;
-                    rn = bgp_route_next(rn))
-                       if ((table = (rn->info)) != NULL)
-                               subgroup_announce_table(subgrp, table);
+                    rn = bgp_route_next(rn)) {
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (!table)
+                               continue;
+                       subgroup_announce_table(subgrp, table);
+               }
 }
 
 void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
@@ -752,7 +757,8 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
                SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
                for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
                     rn = bgp_route_next(rn)) {
-                       for (ri = rn->info; ri; ri = ri->next) {
+                       for (ri = bgp_node_get_bgp_path_info(rn);
+                            ri; ri = ri->next) {
                                struct attr dummy_attr;
 
                                /* Provide dummy so the route-map can't modify
index 2b4477dddef4497b10d2456d974e5dc25b6d5aeb..54ca980cadb10b4e7e1bb1416af0c2a7bd87c0ff 100644 (file)
@@ -38,7 +38,7 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
        struct bgp_table *table;
        struct bgp_node *rn;
        struct bgp_node *rm;
-       struct attr *attr;
+       struct bgp_path_info *path;
        int rd_header;
        int header = 1;
        json_object *json = NULL;
@@ -79,170 +79,129 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
                if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
                        continue;
 
-               if ((table = rn->info) != NULL) {
-                       if (use_json)
-                               json_array = json_object_new_array();
-                       else
-                               json_array = NULL;
-
-                       rd_header = 1;
+               table = bgp_node_get_bgp_table_info(rn);
+               if (table == NULL)
+                       continue;
 
-                       for (rm = bgp_table_top(table); rm;
-                            rm = bgp_route_next(rm)) {
-                               if ((attr = rm->info) != NULL) {
-                                       if (header) {
-                                               if (use_json) {
-                                                       json_object_int_add(
-                                                               json,
-                                                               "bgpTableVersion",
-                                                               0);
-                                                       json_object_string_add(
-                                                               json,
-                                                               "bgpLocalRouterId",
-                                                               inet_ntoa(
-                                                                       bgp->router_id));
-                                                       json_object_object_add(
-                                                               json,
-                                                               "bgpStatusCodes",
-                                                               json_scode);
-                                                       json_object_object_add(
-                                                               json,
-                                                               "bgpOriginCodes",
-                                                               json_ocode);
-                                               } else {
-                                                       vty_out(vty,
-                                                               "BGP table version is 0, local router ID is %s\n",
-                                                               inet_ntoa(
-                                                                       bgp->router_id));
-                                                       vty_out(vty,
-                                                               "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
-                                                       vty_out(vty,
-                                                               "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
-                                                       vty_out(vty, V4_HEADER);
-                                               }
-                                               header = 0;
-                                       }
+               if (use_json)
+                       json_array = json_object_new_array();
+               else
+                       json_array = NULL;
+
+               rd_header = 1;
+
+               for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm)) {
+                       path = bgp_node_get_bgp_path_info(rm);
+                       if (path == NULL)
+                               continue;
+
+                       if (header) {
+                               if (use_json) {
+                                       json_object_int_add(
+                                               json, "bgpTableVersion", 0);
+                                       json_object_string_add(
+                                               json, "bgpLocalRouterId",
+                                               inet_ntoa(bgp->router_id));
+                                       json_object_object_add(json,
+                                                              "bgpStatusCodes",
+                                                              json_scode);
+                                       json_object_object_add(json,
+                                                              "bgpOriginCodes",
+                                                              json_ocode);
+                               } else {
+                                       vty_out(vty,
+                                               "BGP table version is 0, local router ID is %s\n",
+                                               inet_ntoa(bgp->router_id));
+                                       vty_out(vty,
+                                               "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
+                                       vty_out(vty,
+                                               "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
+                                       vty_out(vty, V4_HEADER);
+                               }
+                               header = 0;
+                       }
 
-                                       if (rd_header) {
-                                               uint16_t type;
-                                               struct rd_as rd_as = {0};
-                                               struct rd_ip rd_ip = {0};
+                       if (rd_header) {
+                               uint16_t type;
+                               struct rd_as rd_as = {0};
+                               struct rd_ip rd_ip = {0};
 #if ENABLE_BGP_VNC
-                                               struct rd_vnc_eth rd_vnc_eth = {
-                                                       0};
+                               struct rd_vnc_eth rd_vnc_eth = {0};
 #endif
-                                               uint8_t *pnt;
-
-                                               pnt = rn->p.u.val;
-
-                                               /* Decode RD type. */
-                                               type = decode_rd_type(pnt);
-                                               /* Decode RD value. */
-                                               if (type == RD_TYPE_AS)
-                                                       decode_rd_as(pnt + 2,
-                                                                    &rd_as);
-                                               else if (type == RD_TYPE_AS4)
-                                                       decode_rd_as4(pnt + 2,
-                                                                     &rd_as);
-                                               else if (type == RD_TYPE_IP)
-                                                       decode_rd_ip(pnt + 2,
-                                                                    &rd_ip);
+                               uint8_t *pnt;
+
+                               pnt = rn->p.u.val;
+
+                               /* Decode RD type. */
+                               type = decode_rd_type(pnt);
+                               /* Decode RD value. */
+                               if (type == RD_TYPE_AS)
+                                       decode_rd_as(pnt + 2, &rd_as);
+                               else if (type == RD_TYPE_AS4)
+                                       decode_rd_as4(pnt + 2, &rd_as);
+                               else if (type == RD_TYPE_IP)
+                                       decode_rd_ip(pnt + 2, &rd_ip);
 #if ENABLE_BGP_VNC
-                                               else if (type
-                                                        == RD_TYPE_VNC_ETH)
-                                                       decode_rd_vnc_eth(
-                                                               pnt,
-                                                               &rd_vnc_eth);
+                               else if (type == RD_TYPE_VNC_ETH)
+                                       decode_rd_vnc_eth(pnt, &rd_vnc_eth);
 #endif
-
-                                               if (use_json) {
-                                                       char buffer[BUFSIZ];
-                                                       if (type == RD_TYPE_AS
-                                                           || type == RD_TYPE_AS4)
-                                                               sprintf(buffer,
-                                                                       "%u:%d",
-                                                                       rd_as.as,
-                                                                       rd_as.val);
-                                                       else if (type
-                                                                == RD_TYPE_IP)
-                                                               sprintf(buffer,
-                                                                       "%s:%d",
-                                                                       inet_ntoa(
-                                                                               rd_ip.ip),
-                                                                       rd_ip.val);
-                                                       json_object_string_add(
-                                                               json_routes,
-                                                               "routeDistinguisher",
-                                                               buffer);
-                                               } else {
-                                                       vty_out(vty,
-                                                               "Route Distinguisher: ");
-
-                                                       if (type == RD_TYPE_AS
-                                                           || type == RD_TYPE_AS4)
-                                                               vty_out(vty,
-                                                                       "%u:%d",
-                                                                       rd_as.as,
-                                                                       rd_as.val);
-                                                       else if (type
-                                                                == RD_TYPE_IP)
-                                                               vty_out(vty,
-                                                                       "%s:%d",
-                                                                       inet_ntoa(
-                                                                               rd_ip.ip),
-                                                                       rd_ip.val);
+                               if (use_json) {
+                                       char buffer[BUFSIZ];
+                                       if (type == RD_TYPE_AS
+                                           || type == RD_TYPE_AS4)
+                                               sprintf(buffer, "%u:%d",
+                                                       rd_as.as, rd_as.val);
+                                       else if (type == RD_TYPE_IP)
+                                               sprintf(buffer, "%s:%d",
+                                                       inet_ntoa(rd_ip.ip),
+                                                       rd_ip.val);
+                                       json_object_string_add(
+                                               json_routes,
+                                               "routeDistinguisher", buffer);
+                               } else {
+                                       vty_out(vty, "Route Distinguisher: ");
+
+                                       if (type == RD_TYPE_AS
+                                           || type == RD_TYPE_AS4)
+                                               vty_out(vty, "%u:%d", rd_as.as,
+                                                       rd_as.val);
+                                       else if (type == RD_TYPE_IP)
+                                               vty_out(vty, "%s:%d",
+                                                       inet_ntoa(rd_ip.ip),
+                                                       rd_ip.val);
 #if ENABLE_BGP_VNC
-                                                       else if (
-                                                               type
-                                                               == RD_TYPE_VNC_ETH)
-                                                               vty_out(vty,
-                                                                       "%u:%02x:%02x:%02x:%02x:%02x:%02x",
-                                                                       rd_vnc_eth
-                                                                               .local_nve_id,
-                                                                       rd_vnc_eth
-                                                                               .macaddr
-                                                                               .octet[0],
-                                                                       rd_vnc_eth
-                                                                               .macaddr
-                                                                               .octet[1],
-                                                                       rd_vnc_eth
-                                                                               .macaddr
-                                                                               .octet[2],
-                                                                       rd_vnc_eth
-                                                                               .macaddr
-                                                                               .octet[3],
-                                                                       rd_vnc_eth
-                                                                               .macaddr
-                                                                               .octet[4],
-                                                                       rd_vnc_eth
-                                                                               .macaddr
-                                                                               .octet[5]);
+                                       else if (type == RD_TYPE_VNC_ETH)
+                                               vty_out(vty,
+                                                       "%u:%02x:%02x:%02x:%02x:%02x:%02x",
+                                                       rd_vnc_eth.local_nve_id,
+                                                       rd_vnc_eth.macaddr
+                                                               .octet[0],
+                                                       rd_vnc_eth.macaddr
+                                                               .octet[1],
+                                                       rd_vnc_eth.macaddr
+                                                               .octet[2],
+                                                       rd_vnc_eth.macaddr
+                                                               .octet[3],
+                                                       rd_vnc_eth.macaddr
+                                                               .octet[4],
+                                                       rd_vnc_eth.macaddr
+                                                               .octet[5]);
 #endif
 
-                                                       vty_out(vty, "\n");
-                                               }
-                                               rd_header = 0;
-                                       }
-                                       if (use_json) {
-                                               char buf_a[BUFSIZ];
-                                               char buf_b[BUFSIZ];
-
-                                               sprintf(buf_a, "%s/%d",
-                                                       inet_ntop(rm->p.family,
-                                                                 rm->p.u.val,
-                                                                 buf_b,
-                                                                 BUFSIZ),
-                                                       rm->p.prefixlen);
-                                               json_object_object_add(
-                                                       json_routes, buf_a,
-                                                       json_array);
-                                       } else {
-                                               route_vty_out_tmp(
-                                                       vty, &rm->p, attr,
-                                                       SAFI_MPLS_VPN, use_json,
-                                                       json_array);
-                                       }
+                                       vty_out(vty, "\n");
                                }
+                               rd_header = 0;
+                       }
+                       if (use_json) {
+                               char buf[BUFSIZ];
+
+                               prefix2str(&rm->p, buf, sizeof(buf));
+                               json_object_object_add(json_routes, buf,
+                                                      json_array);
+                       } else {
+                               route_vty_out_tmp(vty, &rm->p, path->attr,
+                                                 SAFI_MPLS_VPN, use_json,
+                                                 json_array);
                        }
                }
        }
index f83b146175e91716ffb0e582c9392474c5431601..2a4421aa54d30089d77699025c5100ec70f8075e 100644 (file)
@@ -7213,7 +7213,9 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
                        if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
                                continue;
 
-                       if ((table = rn->info) != NULL) {
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (table != NULL) {
+
                                if ((rm = bgp_node_match(table, &match))
                                    != NULL) {
                                        if (rm->p.prefixlen
@@ -10916,7 +10918,6 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
        if (use_json) {
                vty_out(vty, "%s\n", json_object_to_json_string_ext(
                                             json, JSON_C_TO_STRING_PRETTY));
-               json_object_free(json);
        } else {
                vty_out(vty, "\n");
        }
@@ -10991,8 +10992,10 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                }
        }
 
-       if (use_json)
+       if (use_json) {
                vty_out(vty, "}\n");
+               json_object_free(json);
+       }
        else if (!nbr_output)
                vty_out(vty, "%% BGP instance not found\n");
 }
index 1e0abaa29e94d8f99775beca0275d2d24bafd991..66d33337395b49b0dfe02537fc7cae9cfc4c7d10 100644 (file)
@@ -1482,7 +1482,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
                return;
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                        if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
 
                            (pi->type == ZEBRA_ROUTE_BGP
@@ -1694,7 +1694,7 @@ int bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
 
        for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn;
             rn = bgp_route_next(rn)) {
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE
                            && pi->type == type
                            && pi->instance == red->instance) {
index d6be3228feeebcadf4683fde7de0ca7944b584e0..7a3afbd18d543fa0bf99e30ba168e553c766c152 100644 (file)
@@ -1464,16 +1464,17 @@ static void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi,
                                               safi_t safi)
 {
        struct bgp_node *rn, *nrn;
+       struct bgp_table *table;
 
        for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               if (rn->info != NULL) {
+               table = bgp_node_get_bgp_table_info(rn);
+               if (table != NULL) {
                        /* Special handling for 2-level routing
                         * tables. */
                        if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                            || safi == SAFI_EVPN) {
-                               for (nrn = bgp_table_top(
-                                            (struct bgp_table *)(rn->info));
+                               for (nrn = bgp_table_top(table);
                                     nrn; nrn = bgp_route_next(nrn))
                                        bgp_process(bgp, nrn, afi, safi);
                        } else
@@ -3354,7 +3355,7 @@ void bgp_free(struct bgp *bgp)
                    || safi == SAFI_EVPN) {
                        for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
                             rn = bgp_route_next(rn)) {
-                               table = (struct bgp_table *)rn->info;
+                               table = bgp_node_get_bgp_table_info(rn);
                                bgp_table_finish(&table);
                        }
                }
@@ -7556,7 +7557,7 @@ int bgp_config_write(struct vty *vty)
 
                /* Confederation identifier*/
                if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
-                       vty_out(vty, " bgp confederation identifier %i\n",
+                       vty_out(vty, " bgp confederation identifier %u\n",
                                bgp->confed_id);
 
                /* Confederation peer */
index 6978dd145d88c88eca62c650dc9996ee2cf8efdd..a41473fa4ff8a6691306f8c2a5c24b997bda2239 100644 (file)
@@ -382,9 +382,10 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
        vnc_zlog_debug_verbose(
                "%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
                __func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)),
-               afi, safi, bn, (bn ? bn->info : NULL));
+               afi, safi, bn, (bn ? bgp_node_get_bgp_path_info(bn) : NULL));
 
-       for (bpi = (bn ? bn->info : NULL); bpi; bpi = bpi->next) {
+       for (bpi = (bn ? bgp_node_get_bgp_path_info(bn) : NULL); bpi;
+            bpi = bpi->next) {
 
                vnc_zlog_debug_verbose(
                        "%s: trying bpi=%p, bpi->peer=%p, bpi->type=%d, bpi->sub_type=%d, bpi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
@@ -471,12 +472,10 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
 
                        prn = bgp_node_get(bgp->rib[afi][safi],
                                           (struct prefix *)prd);
-                       if (prn->info) {
-                               table = (struct bgp_table *)(prn->info);
-
+                       table = bgp_node_get_bgp_table_info(prn);
+                       if (table)
                                vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
                                        bgp, prd, table, p, bpi);
-                       }
                        bgp_unlock_node(prn);
                }
 
@@ -945,7 +944,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
         *      ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr
         *  aspath: POINTS TO interned/refcounted hashed block
         */
-       for (bpi = bn->info; bpi; bpi = bpi->next) {
+       for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
                /* probably only need to check
                 * bpi->extra->vnc.export.rfapi_handle */
                if (bpi->peer == rfd->peer && bpi->type == type
@@ -1017,12 +1016,10 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
 
                                prn = bgp_node_get(bgp->rib[afi][safi],
                                                   (struct prefix *)prd);
-                               if (prn->info) {
-                                       table = (struct bgp_table *)(prn->info);
-
+                               table = bgp_node_get_bgp_table_info(prn);
+                               if (table)
                                        vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
                                                bgp, prd, table, p, bpi);
-                               }
                                bgp_unlock_node(prn);
                        }
 
@@ -1042,12 +1039,10 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
 
                                prn = bgp_node_get(bgp->rib[afi][safi],
                                                   (struct prefix *)prd);
-                               if (prn->info) {
-                                       table = (struct bgp_table *)(prn->info);
-
+                               table = bgp_node_get_bgp_table_info(prn);
+                               if (table)
                                        vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
                                                bgp, prd, table, p, bpi);
-                               }
                                bgp_unlock_node(prn);
                        }
 
@@ -1081,7 +1076,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
        /* debug */
 
        if (VNC_DEBUG(VERBOSE)) {
-               vnc_zlog_debug_verbose("%s: printing BI", __func__);
+               vnc_zlog_debug_verbose("%s: printing BPI", __func__);
                rfapiPrintBi(NULL, new);
        }
 
@@ -1093,12 +1088,10 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
                struct bgp_table *table = NULL;
 
                prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
-               if (prn->info) {
-                       table = (struct bgp_table *)(prn->info);
-
+               table = bgp_node_get_bgp_table_info(prn);
+               if (table)
                        vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
                                bgp, prd, table, p, new);
-               }
                bgp_unlock_node(prn);
                encode_label(label_val, &bn->local_label);
        }
@@ -3696,30 +3689,39 @@ static void rfapi_print_exported(struct bgp *bgp)
 
        for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rdn;
             rdn = bgp_route_next(rdn)) {
-               if (!rdn->info)
+               struct bgp_table *table;
+
+               table = bgp_node_get_bgp_table_info(rdn);
+               if (!table)
                        continue;
                fprintf(stderr, "%s: vpn rdn=%p\n", __func__, rdn);
-               for (rn = bgp_table_top(rdn->info); rn;
+               for (rn = bgp_table_top(table); rn;
                     rn = bgp_route_next(rn)) {
-                       if (!rn->info)
+                       bpi = bgp_node_get_bgp_path_info(rn);
+
+                       if (!bpi)
                                continue;
                        fprintf(stderr, "%s: rn=%p\n", __func__, rn);
-                       for (bpi = rn->info; bpi; bpi = bpi->next) {
+                       for (; bpi; bpi = bpi->next) {
                                rfapiPrintBi((void *)2, bpi); /* 2 => stderr */
                        }
                }
        }
        for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_ENCAP]); rdn;
             rdn = bgp_route_next(rdn)) {
-               if (!rdn->info)
+               struct bgp_table *table;
+
+               table = bgp_node_get_bgp_table_info(rdn);
+               if (!table)
                        continue;
                fprintf(stderr, "%s: encap rdn=%p\n", __func__, rdn);
-               for (rn = bgp_table_top(rdn->info); rn;
+               for (rn = bgp_table_top(table)); rn;
                     rn = bgp_route_next(rn)) {
-                       if (!rn->info)
+                       bpi = bgp_node_get_bgp_path_info(rn);
+                       if (!bpi)
                                continue;
                        fprintf(stderr, "%s: rn=%p\n", __func__, rn);
-                       for (bpi = rn->info; bpi; bpi = bpi->next) {
+                       for (; bpi; bpi = bpi->next) {
                                rfapiPrintBi((void *)2, bpi); /* 2 => stderr */
                        }
                }
index 6b2d5d3426ea0e75ef1794cd9d6b14787fef385b..904d43c65ad8137d1444104555117dbb30c1bd11 100644 (file)
@@ -4241,13 +4241,15 @@ static void rfapiBgpTableFilteredImport(struct bgp *bgp,
        for (rn1 = bgp_table_top(bgp->rib[afi][safi]); rn1;
             rn1 = bgp_route_next(rn1)) {
 
-               if (rn1->info) {
-                       for (rn2 = bgp_table_top(rn1->info); rn2;
+               if (bgp_node_has_bgp_path_info_data(rn1)) {
+
+                       for (rn2 = bgp_table_top(bgp_node_get_bgp_table_info(rn1)); rn2;
                             rn2 = bgp_route_next(rn2)) {
 
                                struct bgp_path_info *bpi;
 
-                               for (bpi = rn2->info; bpi; bpi = bpi->next) {
+                               for (bpi = bgp_node_get_bgp_path_info(rn2);
+                                    bpi; bpi = bpi->next) {
                                        uint32_t label = 0;
 
                                        if (CHECK_FLAG(bpi->flags,
index 1844839f25938eb2ac219ec351e850b1f67cd716..04ddff934dc04b450ef0249961969845e65aa449 100644 (file)
@@ -1570,7 +1570,7 @@ void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
 
        vty_out(vty, "  bn=%p%s", bn, HVTYNL);
 
-       for (bpi = bn->info; bpi; bpi = bpi->next) {
+       for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
                if (bpi->peer == rfd->peer && bpi->type == type
                    && bpi->sub_type == BGP_ROUTE_RFP && bpi->extra
                    && bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
index 212d394fdc22c5d857ada575c85fc29476f91974..3d8d5bccb0febfa42e6758985ce82c009d1faf7f 100644 (file)
@@ -256,7 +256,7 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
         */
        urn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST,
                               prefix, NULL);
-       for (ubpi = urn->info; ubpi; ubpi = ubpi->next) {
+       for (ubpi = bgp_node_get_bgp_path_info(urn); ubpi; ubpi = ubpi->next) {
                struct prefix unicast_nexthop;
 
                if (CHECK_FLAG(ubpi->flags, BGP_PATH_REMOVED))
@@ -483,7 +483,8 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)
                struct bgp_path_info *ri;
                struct bgp_path_info *next;
 
-               for (ri = rn->info, next = NULL; ri; ri = next) {
+               for (ri = bgp_node_get_bgp_path_info(rn), next = NULL;
+                    ri; ri = next) {
 
                        next = ri->next;
 
@@ -1846,7 +1847,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
                memcpy(prd.val, prn->p.u.val, 8);
 
                /* This is the per-RD table of prefixes */
-               table = prn->info;
+               table = bgp_node_get_bgp_table_info(prn);
 
                if (!table)
                        continue;
@@ -1856,7 +1857,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
                        /*
                         * skip prefix list check if no routes here
                         */
-                       if (!rn->info)
+                       if (!bgp_node_has_bgp_path_info_data(rn))
                                continue;
 
                        {
@@ -1883,7 +1884,8 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
                                }
                        }
 
-                       for (ri = rn->info; ri; ri = ri->next) {
+                       for (ri = bgp_node_get_bgp_path_info(rn);
+                            ri; ri = ri->next) {
 
                                vnc_zlog_debug_verbose("%s: ri->sub_type: %d",
                                                       __func__, ri->sub_type);
@@ -2003,7 +2005,7 @@ void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi)
                struct bgp_path_info *ri;
                struct bgp_path_info *next;
 
-               for (ri = rn->info, next = NULL; ri; ri = next) {
+               for (ri = bgp_node_get_bgp_path_info(rn), next = NULL; ri; ri = next) {
 
                        next = ri->next;
 
index 2f634f6f4093872df5e6bb9a2751261c7e2692f5..eb2d0fd8894666f3a7732a6e135ce8dcf0a8dc59 100644 (file)
@@ -545,8 +545,8 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_rd(
                return;
        }
 
-       /* Iterate over bgp_path_info items at this node */
-       for (bpi = bn->info; bpi; bpi = bpi->next) {
+       /* Iterate over bgp_info items at this node */
+       for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
 
                vnc_import_bgp_add_route_mode_resolve_nve_one_bi(
                        bgp, afi, bpi, /* VPN bpi */
@@ -676,7 +676,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve(
 
                struct bgp_table *table;
 
-               table = (struct bgp_table *)(bnp->info);
+               table = bgp_node_get_bgp_table_info(bnp);
 
                if (!table)
                        continue;
@@ -1305,8 +1305,8 @@ static void vnc_import_bgp_del_route_mode_resolve_nve_one_rd(
                return;
        }
 
-       /* Iterate over bgp_path_info items at this node */
-       for (bpi = bn->info; bpi; bpi = bpi->next) {
+       /* Iterate over bgp_info items at this node */
+       for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
 
                vnc_import_bgp_del_route_mode_resolve_nve_one_bi(
                        bgp, afi, bpi, /* VPN bpi */
@@ -1377,7 +1377,7 @@ vnc_import_bgp_del_route_mode_resolve_nve(struct bgp *bgp, afi_t afi,
 
                struct bgp_table *table;
 
-               table = (struct bgp_table *)(bnp->info);
+               table = bgp_node_get_bgp_table_info(bnp);
 
                if (!table)
                        continue;
@@ -2780,7 +2780,8 @@ void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi)
 
                struct bgp_path_info *bpi;
 
-               for (bpi = rn->info; bpi; bpi = bpi->next) {
+               for (bpi = bgp_node_get_bgp_path_info(rn); bpi;
+                    bpi = bpi->next) {
 
                        if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
                                continue;
@@ -2820,7 +2821,8 @@ void vnc_import_bgp_exterior_redist_enable(struct bgp *bgp, afi_t afi)
 
                struct bgp_path_info *bpi;
 
-               for (bpi = rn->info; bpi; bpi = bpi->next) {
+               for (bpi = bgp_node_get_bgp_path_info(rn); bpi;
+                    bpi = bpi->next) {
 
                        if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
                                continue;
@@ -2865,7 +2867,8 @@ void vnc_import_bgp_exterior_redist_enable_it(
 
                struct bgp_path_info *bpi;
 
-               for (bpi = rn->info; bpi; bpi = bpi->next) {
+               for (bpi = bgp_node_get_bgp_path_info(rn); bpi;
+                    bpi = bpi->next) {
 
                        if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
                                continue;
@@ -2902,14 +2905,17 @@ void vnc_import_bgp_redist_disable(struct bgp *bgp, afi_t afi)
        for (rn1 = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn1;
             rn1 = bgp_route_next(rn1)) {
 
-               if (rn1->info) {
-                       for (rn2 = bgp_table_top(rn1->info); rn2;
-                            rn2 = bgp_route_next(rn2)) {
+               if (bgp_node_has_bgp_path_info_data(rn1)) {
+
+                       for (rn2 = bgp_table_top(
+                                    bgp_node_get_bgp_table_info(rn1));
+                            rn2; rn2 = bgp_route_next(rn2)) {
 
                                struct bgp_path_info *bpi;
                                struct bgp_path_info *nextbpi;
 
-                               for (bpi = rn2->info; bpi; bpi = nextbpi) {
+                               for (bpi = bgp_node_get_bgp_path_info(rn2); bpi;
+                                    bpi = nextbpi) {
 
                                        nextbpi = bpi->next;
 
@@ -2999,7 +3005,8 @@ void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi)
 
                        struct bgp_path_info *bpi;
 
-                       for (bpi = rn->info; bpi; bpi = bpi->next) {
+                       for (bpi = bgp_node_get_bgp_path_info(rn); bpi;
+                            bpi = bpi->next) {
 
                                if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
                                        continue;
index a43cf1f6a98ccac4e8f182fab16b485b87e7d5eb..98f719969c0cb1ff6b1e7c921199f1f38370a400 100644 (file)
@@ -312,7 +312,7 @@ static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type)
                memcpy(prd.val, prn->p.u.val, 8);
 
                /* This is the per-RD table of prefixes */
-               table = prn->info;
+               table = bgp_node_get_bgp_table_info(prn);
                if (!table)
                        continue;
 
@@ -320,7 +320,8 @@ static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type)
 
                        struct bgp_path_info *ri;
 
-                       for (ri = rn->info; ri; ri = ri->next) {
+                       for (ri = bgp_node_get_bgp_path_info(rn); ri;
+                            ri = ri->next) {
                                if (ri->type
                                    == type) { /* has matching redist type */
                                        break;
index a13f058f744d4be14c788d25531de659f4edddc6..7d7d3ca189068c685bd797a5e52b0407068b71a6 100644 (file)
@@ -222,5 +222,3 @@ bgpd/bgp_debug.$(OBJEXT): bgpd/bgp_debug_clippy.c
 bgpd/bgp_rpki_clippy.c: $(CLIPPY_DEPS)
 $(AUTOMAKE_DUMMY)bgpd/bgpd_bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c
 $(AUTOMAKE_DUMMY)bgpd/bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c
-
-EXTRA_DIST += bgpd/BGP4-MIB.txt
index 09d57ab0f294fdcd6a19b406e4eb21f89bc87166..0d75f7d319976f8ec7dab61e7cd6f6cadb4227b9 100755 (executable)
@@ -13,7 +13,7 @@ AC_SUBST([PACKAGE_URL])
 PACKAGE_FULLNAME="FRRouting"
 AC_SUBST([PACKAGE_FULLNAME])
 
-CONFIG_ARGS="$ac_configure_args"
+CONFIG_ARGS="`echo $ac_configure_args | sed -e \"s% '[[A-Z]]*FLAGS=[[^']]\+'%%g\"`"
 AC_SUBST([CONFIG_ARGS])
 
 AC_CONFIG_SRCDIR([lib/zebra.h])
@@ -2180,6 +2180,9 @@ AC_CONFIG_FILES([
 
 AC_CONFIG_FILES([vtysh/extract.pl], [chmod +x vtysh/extract.pl])
 AC_CONFIG_FILES([tools/frr], [chmod +x tools/frr])
+AC_CONFIG_FILES([tools/watchfrr.sh], [chmod +x tools/watchfrr.sh])
+AC_CONFIG_FILES([tools/frrinit.sh], [chmod +x tools/frrinit.sh])
+AC_CONFIG_FILES([tools/frrcommon.sh])
 
 AC_CONFIG_COMMANDS([lib/route_types.h], [
        dst="${ac_abs_top_builddir}/lib/route_types.h"
index 1b048033667d48a42884784873cfc5d995b6cf11..cd7be5e801536beb4bd5657f70c19d6048c8a5d4 100644 (file)
@@ -83,7 +83,7 @@ into the kernel.
 =====================================================================
 
 If this message occurs the receive buffer should be increased by adding the
-following to /etc/sysctl.conf and "--nl-bufsize" to /etc/frr/daemons.conf.
+following to /etc/sysctl.conf and "--nl-bufsize" to /etc/frr/daemons.
 > net.core.rmem_default = 262144
 > net.core.rmem_max = 262144
 See message #4525 from 2005-05-09 in the quagga-users mailing list.
diff --git a/debianpkg/backports/ubuntu12.04/debian/control b/debianpkg/backports/ubuntu12.04/debian/control
deleted file mode 100644 (file)
index 9bae348..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-Source: frr
-Section: net
-Priority: optional
-Maintainer: Nobody <nobody@frrouting.org>
-Uploaders: Nobody <nobody@frrouting.org>
-XSBC-Original-Maintainer: <maintainers@frrouting.org>
-Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson0, libjson0-dev, pkg-config, python (>= 2.7), python-ipaddr
-Standards-Version: 3.9.6
-Homepage: http://www.frrouting.org/
-XS-Testsuite: autopkgtest
-
-Package: frr
-Architecture: any
-Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends}
-Pre-Depends: adduser
-Conflicts: zebra, zebra-pj, quagga
-Replaces: zebra, zebra-pj
-Suggests: snmpd
-Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga
- FRR is free software which manages TCP/IP based routing protocols.
- It supports BGP4, BGP4+, OSPFv2, OSPFv3, IS-IS, RIPv1, RIPv2, RIPng,
- PIM and LDP as well as the IPv6 versions of these.
- .
- FRR is a fork of Quagga with an open community model. The main git
- lives on https://github.com/frrouting/frr.git
-
-Package: frr-dbg
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, frr (= ${binary:Version})
-Priority: extra
-Section: debug
-Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (debug symbols)
- This package provides debugging symbols for all binary packages built 
- from frr source package. It's highly recommended to have this package
- installed before reporting any FRR crashes to either FRR developers or 
- Debian package maintainers.
-
-Package: frr-doc
-Section: net
-Architecture: all
-Depends: ${misc:Depends}
-Suggests: frr
-Description: documentation files for FRR
- This package includes info files for frr, a free software which manages
- TCP/IP based routing protocols.  It supports BGP4, BGP4+, OSPFv2, OSPFv3,
- IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
-
-Package: frr-pythontools
-Section: net
-Architecture: all
-Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr
-Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools)
- This package includes info files for frr, a free software which manages
- TCP/IP based routing protocols.  It supports BGP4, BGP4+, OSPFv2, OSPFv3,
- IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these.
-
diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.install b/debianpkg/backports/ubuntu12.04/debian/frr.install
deleted file mode 120000 (symlink)
index 83ecca5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../ubuntu14.04/debian/frr.install
\ No newline at end of file
diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postinst b/debianpkg/backports/ubuntu12.04/debian/frr.postinst
deleted file mode 120000 (symlink)
index eb98053..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../ubuntu14.04/debian/frr.postinst
\ No newline at end of file
diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postrm b/debianpkg/backports/ubuntu12.04/debian/frr.postrm
deleted file mode 120000 (symlink)
index 4f43808..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../ubuntu14.04/debian/frr.postrm
\ No newline at end of file
diff --git a/debianpkg/backports/ubuntu12.04/debian/rules b/debianpkg/backports/ubuntu12.04/debian/rules
deleted file mode 100755 (executable)
index 7495db8..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/make -f
-
-# FRRouting Configuration options
-######################################
-#
-#    WANT_xxxx   --> Set to 1 for enable, 0 for disable
-# The following are the defaults. They can be overridden by setting a 
-# env variable to a different value
-
-WANT_LDP ?= 1
-WANT_PIM ?= 1
-WANT_OSPFAPI ?= 1
-WANT_BGP_VNC ?= 1
-WANT_CUMULUS_MODE ?= 0
-WANT_MULTIPATH ?= 1
-WANT_SNMP ?= 0
-
-# NOTES:
-#
-# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here
-#    Please be aware that 0 is NOT disabled, but treated as unlimited
-
-MULTIPATH ?= 256
-
-# Set the following to the value required (or leave alone for the default below)
-# WANT_FRR_USER is used for the username and groupname of the FRR user account
-
-WANT_FRR_USER ?= frr
-WANT_FRR_VTY_GROUP ?= frrvty
-
-# Don't build PDF docs by default
-GENERATE_PDF ?= 0
-
-#
-####################################
-
-export DH_VERBOSE=1
-export DEB_BUILD_MAINT_OPTIONS = hardening=+all
-export DH_OPTIONS=-v
-
-ifeq ($(WANT_SNMP), 1)
-  USE_SNMP=--enable-snmp
-  $(warning "DEBIAN: SNMP enabled, sorry for your inconvenience")
-else
-  USE_SNMP=--disable-snmp
-  $(warning "DEBIAN: SNMP disabled, see README.Debian")
-endif
-
-ifeq ($(WANT_LDP), 1)
-  USE_LDP=--enable-ldpd
-else
-  USE_LDP=--disable-ldpd
-endif
-
-ifeq ($(WANT_PIM), 1)
-  USE_PIM=--enable-pimd
-else
-  USE_PIM=--disable-pimd
-endif
-
-ifeq ($(WANT_OSPFAPI), 1)
-  USE_OSPFAPI=--enable-ospfapi=yes
-else
-  USE_OSPFAPI=--enable-ospfapi=no
-endif
-
-ifeq ($(WANT_BGP_VNC), 1)
-  USE_BGP_VNC=--enable-bgp-vnc=yes
-else
-  USE_BGP_VNC=--enable-bgp-vnc=no
-endif
-
-USE_FRR_USER=--enable-user=$(WANT_FRR_USER)
-USE_FRR_GROUP=--enable-group=$(WANT_FRR_USER)
-USE_FRR_VTY_GROUP=--enable-vty-group=$(WANT_FRR_VTY_GROUP)
-
-ifeq ($(WANT_MULTIPATH), 1)
-  USE_MULTIPATH=--enable-multipath=$(MULTIPATH)
-else
-  USE_MULTIPATH=--disable-multipath
-endif
-
-ifeq ($(WANT_CUMULUS_MODE), 1)
-  USE_CUMULUS=--enable-cumulus=yes
-else
-  USE_CUMULUS=--enable-cumulus=no
-endif
-
-ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-  DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-endif
-
-ifdef DEBIAN_JOBS
-MAKEFLAGS += -j$(DEBIAN_JOBS)
-endif
-
-%:
-       dh $@ --with=autoreconf --parallel --dbg-package=frr-dbg --list-missing
-
-override_dh_auto_configure:
-       # Frr needs /proc to check some BSD vs Linux specific stuff.
-       # Else it fails with an obscure error message pointing out that
-       # IPCTL_FORWARDING is an undefined symbol which is not very helpful.
-       @if ! [ -d /proc/1 ]; then \
-               echo "./configure needs a mounted /proc"; \
-               exit 1; \
-       fi
-
-       if ! [ -e config.status ]; then \
-       dh_auto_configure -- \
-               --enable-exampledir=/usr/share/doc/frr/examples/ \
-               --localstatedir=/var/run/frr \
-               --sbindir=/usr/lib/frr \
-               --sysconfdir=/etc/frr \
-               $(USE_SNMP) \
-               $(USE_OSPFAPI) \
-               $(USE_MULTIPATH) \
-               $(USE_LDP) \
-               --enable-fpm \
-               $(USE_FRR_USER) $(USE_FRR_GROUP) \
-               $(USE_FRR_VTY_GROUP) \
-               --enable-configfile-mask=0640 \
-               --enable-logfile-mask=0640 \
-               --with-libpam \
-               --enable-systemd=no \
-               --enable-poll=yes \
-               $(USE_CUMULUS) \
-               $(USE_PIM) \
-               --disable-bfdd \
-               --enable-dependency-tracking \
-               $(USE_BGP_VNC) \
-               $(shell dpkg-buildflags --export=configure); \
-       fi
-
-override_dh_auto_build:
-ifeq ($(GENERATE_PDF), 1)
-       dh_auto_build -- -C doc pdf
-endif
-       rm -vf doc/user/_build/texinfo/frr.info
-       dh_auto_build -- -C doc info
-
-override_dh_auto_test:
-
-override_dh_auto_install:
-       dh_auto_install
-
-       # installed in frr-pythontools
-       rm debian/tmp/usr/lib/frr/frr-reload.py
-
-       # cleaning up the info dir
-       rm -f debian/tmp/usr/share/info/dir*
-
-       # install config files
-       mkdir -p debian/tmp/etc/frr/
-       perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
-
-       # leftover from previously shipping SMUX client OID MIB
-       mkdir -p debian/tmp/usr/share/snmp/mibs
-
-       # cleaning .la files
-       sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
-       sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la
diff --git a/debianpkg/backports/ubuntu12.04/debian/source/format b/debianpkg/backports/ubuntu12.04/debian/source/format
deleted file mode 100644 (file)
index 163aaf8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debianpkg/backports/ubuntu12.04/exclude b/debianpkg/backports/ubuntu12.04/exclude
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/debianpkg/backports/ubuntu12.04/versionext b/debianpkg/backports/ubuntu12.04/versionext
deleted file mode 100644 (file)
index 159e2e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
--1~ubuntu12.04+1
index 199d264f1aa25f2f77d891b2acdca24219435cf3..7fb81c44a005e3bc9b7afddefb169d7c34fb8a70 100644 (file)
@@ -3,7 +3,6 @@ usr/bin/vtysh
 usr/bin/mtracebis
 usr/include/frr/
 usr/lib/
-tools/frr etc/init.d/
 usr/share/doc/frr/
 usr/share/snmp/mibs/
 usr/share/yang/
diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postinst b/debianpkg/backports/ubuntu14.04/debian/frr.postinst
deleted file mode 100644 (file)
index 5a14e51..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash -e
-
-######################
-PASSWDFILE=/etc/passwd
-GROUPFILE=/etc/group
-
-frruid=`egrep "^frr:" $PASSWDFILE | awk -F ":" '{ print $3 }'`
-frrgid=`egrep "^frr:" $GROUPFILE | awk -F ":" '{ print $3 }'`
-frrvtygid=`egrep "^frrvty:" $GROUPFILE | awk -F ":" '{ print $3 }'`
-
-[ -n ${frruid} ]    || (echo "No uid for frr in ${PASSWDFILE}"   && /bin/false)
-[ -n ${frrgid} ]    || (echo "No gid for frr in ${GROUPFILE}"    && /bin/false)
-[ -n ${frrVTYgid} ] || (echo "No gid for frrvty in ${GROUPFILE}" && /bin/false)
-
-chown -R ${frruid}:${frrgid} /etc/frr
-touch /etc/frr/vtysh.conf
-chgrp ${frrvtygid} /etc/frr/vtysh*
-chmod 644 /etc/frr/*
-
-ENVIRONMENTFILE=/etc/environment
-if ! egrep --quiet '^VTYSH_PAGER=' ${ENVIRONMENTFILE}; then
-    echo "VTYSH_PAGER=/bin/cat"  >> ${ENVIRONMENTFILE}
-fi
-##################################################
-
-if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
-${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"}
-
-# This is most likely due to the answer "no" to the "really stop the server"
-# question in the prerm script.
-if [ "$1" = "abort-upgrade" ]; then
-  exit 0
-fi
-
-update-rc.d frr defaults > /dev/null
-
-#DEBHELPER#
-
diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postrm b/debianpkg/backports/ubuntu14.04/debian/frr.postrm
deleted file mode 100644 (file)
index 48c2332..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash -e
-
-if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
-${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"}
-# set -u       not because of debhelper
-
-update-rc.d -f frr remove >> /dev/null
-
-if [ "$1" = "purge" ]; then
-       rm -rf /etc/frr /var/run/frr /var/log/frr
-       userdel frr >/dev/null 2>&1 || true
-fi
-
-#DEBHELPER#
index 291233c147322a133fba42e78d76e87fa0e2a562..21b442d85a2fd5f43b53c3d8c9f28e42771e2879 100755 (executable)
@@ -178,6 +178,8 @@ override_dh_auto_test:
 override_dh_auto_install:
        dh_auto_install
 
+       cp tools/frrinit.sh debian/frr.init
+
        # installed in frr-pythontools
        rm debian/tmp/usr/lib/frr/frr-reload.py
 
index 7cdb8fbaf783ccbe9d83f2942d9d4361851c694c..12d6c3545c5694bd42028add0672235c77f52f5b 100755 (executable)
@@ -171,7 +171,7 @@ override_dh_systemd_enable:
 
 # backports
 SRCPKG = frr
-KNOWN_BACKPORTS = debian8 debian9 ubuntu12.04 ubuntu14.04 ubuntu16.04 ubuntu17.10 ubuntu18.04
+KNOWN_BACKPORTS = debian8 debian9 ubuntu14.04 ubuntu16.04 ubuntu17.10 ubuntu18.04
 DEBIAN_VERSION := $(shell dh_testdir && \
                dpkg-parsechangelog -c1 < debian/changelog | \
                sed -rn 's/^Version: ?//p')
index b6251962b7c94b7b0a4f4a670efacbccfe2d6092..af17e4642a45880654df8ec9f1b58af22cdc607b 100644 (file)
@@ -23,18 +23,8 @@ EXTRA_DIST += \
        debianpkg/backports/debian9/debian/source/format \
        debianpkg/backports/debian9/exclude \
        debianpkg/backports/debian9/versionext \
-       debianpkg/backports/ubuntu12.04/debian/control \
-       debianpkg/backports/ubuntu12.04/debian/frr.install \
-       debianpkg/backports/ubuntu12.04/debian/frr.postinst \
-       debianpkg/backports/ubuntu12.04/debian/frr.postrm \
-       debianpkg/backports/ubuntu12.04/debian/rules \
-       debianpkg/backports/ubuntu12.04/debian/source/format \
-       debianpkg/backports/ubuntu12.04/exclude \
-       debianpkg/backports/ubuntu12.04/versionext \
        debianpkg/backports/ubuntu14.04/debian/control \
        debianpkg/backports/ubuntu14.04/debian/frr.install \
-       debianpkg/backports/ubuntu14.04/debian/frr.postinst \
-       debianpkg/backports/ubuntu14.04/debian/frr.postrm \
        debianpkg/backports/ubuntu14.04/debian/rules \
        debianpkg/backports/ubuntu14.04/debian/source/format \
        debianpkg/backports/ubuntu14.04/exclude \
index d303784d4e50fde1e19db1f211a6d409cf7ef305..f88fc7bfdc007646ac21244473a9e0395c999236 100644 (file)
@@ -85,7 +85,6 @@ startup.  To configure by hand:
 
    docker exec -it frr /bin/sh
    vi /etc/frr/daemons
-   vi /etc/frr/daemons.conf
    cp /etc/frr/zebra.conf.sample /etc/frr/zebra.conf
    vi /etc/frr/zebra.conf
    /etc/init.d/frr start
index 9b2394f0182d9e0a43f81d0d17e44389677f31df..a2d58e225854cbf8d442548ddd31a1147430c34b 100644 (file)
@@ -158,7 +158,6 @@ Install the init.d service
 
     sudo install -m 755 tools/frr /etc/init.d/frr
     sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
     sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
 
 Enable daemons
index 81ca970469de788c2b7cbc14a7582fa9eac8b29f..7952cd682ae3e89785be183a9dd3df0ca0b94f4c 100644 (file)
@@ -112,7 +112,6 @@ Install the init.d service
 
     sudo install -m 755 tools/frr /etc/init.d/frr
     sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
     sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
 
 Enable daemons
index 9830b24dfca6a7d4efa59a7830c46c101dd499c6..f5329fef2c93e9de687ddd170a1e867aaa99f7c6 100644 (file)
@@ -139,9 +139,7 @@ Install the systemd service (if rebooted from last step, change directory back t
 ::
 
     sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
-    sudo install -m 644 tools/etc/default/frr /etc/default/frr
     sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
     sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
     sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
 
index e69ded8f73912d05b6574c4c17eff044b70e5663..110bc6a0ee4f9e19f41a87b4bf5e293925b6621c 100644 (file)
@@ -203,9 +203,7 @@ Install the systemd service
 ::
 
    sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
-   sudo install -m 644 tools/etc/default/frr /etc/default/frr
    sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-   sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
    sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
    sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
 
index 543dfdd3b994b301fcbc93998d2044edff7f2501..1bb0886fd58d94d085468ba8f9a175fd5dc0e61f 100644 (file)
@@ -216,6 +216,12 @@ License for Contributions
 FRR is under a “GPLv2 or later” license. Any code submitted must be released
 under the same license (preferred) or any license which allows redistribution
 under this GPLv2 license (eg MIT License).
+It is forbidden to push any code that prevents from using GPLv3 license. This
+becomes a community rule, as FRR produces binaries that links with Apache 2.0
+libraries. Apache 2.0 and GPLv2 license are incompatible, if put together.
+Please see `<http://www.apache.org/licenses/GPL-compatibility.html>`_ for
+more information. This rule guarantees the user to distribute FRR binary code
+without any licensing issues.
 
 Pre-submission Checklist
 ------------------------
index 8190415bf4c335739400baa68493b683a7ec3ae2..4c218c658028d1bb8cbee05832fcb8ef97dff2b2 100644 (file)
@@ -68,3 +68,23 @@ Appendix
    bugs
    packet-dumps
    glossary
+
+################
+Copyright notice
+################
+
+Copyright (c) 1996-2018 Kunihiro Ishiguro, et al.
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by Kunihiro Ishiguro.
index f48ff2e6bad65cba53a4dafa61e82a9d1a2595bf..295a26fda9f7a0ba2924dcfbae329a1efa09acb1 100644 (file)
@@ -67,17 +67,17 @@ Enabling RPKI
    to configure at least one reachable cache server. See section
    :ref:`configuring-rpki-rtr-cache-servers` for configuring a cache server.
 
-.. index:: RPKI and daemons.conf
+.. index:: RPKI and daemons
 
 When first installing FRR with RPKI support from the pre-packaged binaries.
 Remember to add ``-M rpki`` to the variable ``bgpd_options`` in
-:file:`/etc/frr/daemons.conf` , like so::
+:file:`/etc/frr/daemons` , like so::
 
-   bgpd_options="   --daemon -A 127.0.0.1 -M rpki"
+   bgpd_options="   -A 127.0.0.1 -M rpki"
 
 instead of the default setting::
 
-   bgpd_options="   --daemon -A 127.0.0.1"
+   bgpd_options="   -A 127.0.0.1"
 
 Otherwise you will encounter an error when trying to enter RPKI
 configuration mode due to the ``rpki`` module not being loaded when the BGP
index 8a76a61e787a29704603d3b7554e4fb9837a8511..3a09c50309409767a36a370ff304b01835b3ddf2 100644 (file)
@@ -41,7 +41,7 @@ Daemons Configuration File
 --------------------------
 There is another file that controls the default options passed to daemons when
 starting FRR as a service. This file is located in your configuration
-directory, usually at :file:`/etc/frr/daemons.conf`.
+directory, usually at :file:`/etc/frr/daemons`.
 
 This file has several parts. Here is an example:
 
diff --git a/eigrpd/EIGRP-MIB.txt b/eigrpd/EIGRP-MIB.txt
deleted file mode 100644 (file)
index f6ea298..0000000
+++ /dev/null
@@ -1,1321 +0,0 @@
-CISCO-EIGRP-MIB DEFINITIONS ::= BEGIN
-
-    IMPORTS
-        MODULE-IDENTITY,
-        OBJECT-TYPE,
-        NOTIFICATION-TYPE,
-        Unsigned32,
-        Gauge32,
-        Counter32,
-        Counter64
-            FROM SNMPv2-SMI
-        TruthValue,
-        TEXTUAL-CONVENTION
-            FROM SNMPv2-TC
-        SnmpAdminString
-            FROM SNMP-FRAMEWORK-MIB
-        MODULE-COMPLIANCE,
-        OBJECT-GROUP,
-        NOTIFICATION-GROUP
-            FROM SNMPv2-CONF
-        ciscoMgmt
-            FROM CISCO-SMI
-        InterfaceIndexOrZero,
-        ifIndex
-            FROM IF-MIB
-        InetAddressType,
-        InetAddress,
-        InetAddressPrefixLength
-            FROM INET-ADDRESS-MIB;
-
-ciscoEigrpMIB MODULE-IDENTITY
-    LAST-UPDATED        "200411160000Z"
-    ORGANIZATION        "Cisco Systems, Inc."
-    CONTACT-INFO        "Cisco Systems
-                         Customer Service
-
-                         Postal: 170 W Tasman Drive
-                                 San Jose, CA  95134
-                                 USA
-
-                         Tel: +1 800 553-NETS
-
-                         E-mail: cs-eigrp@cisco.com"
-    DESCRIPTION
-        "Enhanced Interior Gateway Protocol (EIGRP) is a Cisco
-         proprietary distance vector routing protocol.   It is based on
-         the Diffusing Update Algorithm (DUAL), which is a method of
-         finding loop-free paths through a network.   Directly
-         connected routers running EIGRP form neighbor adjacencies in
-         order to propagate best-path and alternate-path routing
-         information for configured and learned routes.
-
-         The tables defined within the MIB are closely aligned with how
-         the router command-line interface for EIGRP displays
-         information on EIGRP configurations, i.e., the topology table
-         contains objects associated with the EIGRP topology commands,
-         and the peer table contains objects associated withe EIGRP
-         neighbor commands, etc.
-
-         There are five main tables within this mib:
-
-            EIGRP VPN table
-               Contains information regarding which virtual private
-               networks (VPN) are configured with EIGRP.
-
-            EIGRP traffic statistics table
-               Contains counter & statistcs regarding specific types of
-               EIGRP packets sent and related collective information
-               per VPN and per autonomous system (AS).
-
-            EIGRP topology table
-               Contains information regarding EIGRP routes received in
-               updates and originated locally.   EIGRP sends and
-               receives routing updates from adjacent routers running
-               EIGRP with which it formed a peer relationship.
-
-            EIGRP peer (neighbor) table
-               Contains information about neighbor EIGRP routers with
-               which peer adjacencies have been established.   EIGRP
-               uses a Hello protocol to form neighbor relationships
-               with directly connected routers also running EIGRP.
-
-            EIGRP interfaces table
-               Contains information and statistics on each of the
-               interfaces on the router over which EIGRP has been
-               configured to run."
-
-
-    REVISION    "200411160000Z"
-    DESCRIPTION
-                "Initial version of the MIB module."
-    ::= { ciscoMgmt 449 }
-
---
--- Textual Conventions
---
-
-    EigrpUpTimeString ::= TEXTUAL-CONVENTION
-        DISPLAY-HINT "8a"
-        STATUS       current
-        DESCRIPTION
-            "Specifies a timer value in days, hours, minutes,
-             and seconds in ASCII format.
-
-             If the up time is less than 24 hours, the number
-             of days will not be reflected and the string will
-             be formatted like this: 'hh:mm:ss', reflecting
-             hours, minutes, and seconds.
-
-             If the up time is greater than 24 hours, EIGRP is
-             less precise and the minutes and seconds are not
-             reflected.  Instead only the days and hours are shown
-             and the string will be formatted like this: 'xxxdxxh'." 
-        SYNTAX       OCTET STRING (SIZE (0..8))
-
-    EigrpVersionString ::= TEXTUAL-CONVENTION 
-        DISPLAY-HINT "1d.1d/1d.1d"
-        STATUS     current
-        DESCRIPTION
-            "Specifies an ASCII string representing the IOS major
-             and minor version followed by the EIGRP major and minor
-             version."
-        SYNTAX       OCTET STRING (SIZE (0..9))
-
---
--- Objects
---
-
-    cEigrpMIBNotifications OBJECT IDENTIFIER ::= { ciscoEigrpMIB 0 }
-    cEigrpMIBObjects       OBJECT IDENTIFIER ::= { ciscoEigrpMIB 1 }
-    cEigrpMIBConformance   OBJECT IDENTIFIER ::= { ciscoEigrpMIB 2 }
-    cEigrpVpnInfo          OBJECT IDENTIFIER ::= { cEigrpMIBObjects 1 }
-    cEigrpAsInfo           OBJECT IDENTIFIER ::= { cEigrpMIBObjects 2 }
-    cEigrpTopologyInfo     OBJECT IDENTIFIER ::= { cEigrpMIBObjects 3 }
-    cEigrpPeerInfo         OBJECT IDENTIFIER ::= { cEigrpMIBObjects 4 }
-    cEigrpInterfaceInfo    OBJECT IDENTIFIER ::= { cEigrpMIBObjects 5 }
-
-    -- EIGRP VPN Base Table definition
-
-    cEigrpVpnTable OBJECT-TYPE
-        SYNTAX     SEQUENCE OF CEigrpVpnEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "This table contains information on those VPN's configured
-             to run EIGRP.  The VPN creation on a router is independent
-             of the routing protocol to be used over it.   A VPN is
-             given a name and has a dedicated routing table associated
-             with it.  This routing table is identified internally
-             by a unique integer value."
-        ::= { cEigrpVpnInfo 1 }
-
-    cEigrpVpnEntry OBJECT-TYPE
-        SYNTAX     CEigrpVpnEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "Information relating to a single VPN which is configured
-             to run EIGRP."
-        INDEX { cEigrpVpnId }
-        ::= { cEigrpVpnTable 1 }
-
-   CEigrpVpnEntry ::=
-       SEQUENCE {
-           cEigrpVpnId  Unsigned32,
-           cEigrpVpnName SnmpAdminString
-       }
-
-    cEigrpVpnId  OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The unique VPN identifier.  This is a unique integer
-             relative to all other VPN's defined on the router.  It
-             also identifies internally the routing table instance."
-        ::= { cEigrpVpnEntry 1 }
-
-    cEigrpVpnName  OBJECT-TYPE
-        SYNTAX     SnmpAdminString
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The name given to the VPN."
-        ::= { cEigrpVpnEntry 2 }
-
-    --  EIGRP Traffic Stats table definition
-
-    cEigrpTraffStatsTable OBJECT-TYPE
-        SYNTAX     SEQUENCE OF CEigrpTraffStatsEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "Table of EIGRP traffic statistics and information
-             associated with all EIGRP autonomous systems."
-        ::= { cEigrpAsInfo 1 }
-
-    cEigrpTraffStatsEntry OBJECT-TYPE
-        SYNTAX     CEigrpTraffStatsEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The set of statistics and information for a single EIGRP
-             Autonomous System."
-        INDEX { cEigrpVpnId, cEigrpAsNumber }
-        ::= { cEigrpTraffStatsTable 1 }
-
-    CEigrpTraffStatsEntry ::=
-        SEQUENCE {
-            cEigrpAsNumber        Unsigned32,
-            cEigrpNbrCount        Unsigned32,
-            cEigrpHellosSent      Counter32,
-            cEigrpHellosRcvd      Counter32,
-            cEigrpUpdatesSent     Counter32,
-            cEigrpUpdatesRcvd     Counter32,
-            cEigrpQueriesSent     Counter32,
-            cEigrpQueriesRcvd     Counter32,
-            cEigrpRepliesSent     Counter32,
-            cEigrpRepliesRcvd     Counter32,
-            cEigrpAcksSent        Counter32,
-            cEigrpAcksRcvd        Counter32,
-            cEigrpInputQHighMark  Unsigned32,
-            cEigrpInputQDrops     Counter32,
-            cEigrpSiaQueriesSent  Counter32,
-            cEigrpSiaQueriesRcvd  Counter32,
-            cEigrpAsRouterIdType  InetAddressType,
-            cEigrpAsRouterId      InetAddress,
-            cEigrpTopoRoutes      Counter32,
-            cEigrpHeadSerial      Counter64,
-            cEigrpNextSerial      Counter64,
-            cEigrpXmitPendReplies Unsigned32,
-            cEigrpXmitDummies     Unsigned32
-        }
-
-    cEigrpAsNumber  OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The Autonomous System number which is unique integer
-             per VPN."
-        ::= { cEigrpTraffStatsEntry 1 }
-
-    cEigrpNbrCount  OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number of live EIGRP neighbors formed on all
-           interfaces whose IP addresses fall under networks configured
-           in the EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 2 }
-
-    cEigrpHellosSent  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number Hello packets that have been sent to all
-           EIGRP neighbors formed on all interfaces whose IP addresses
-           fall under networks configured for the EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 3 }
-
-    cEigrpHellosRcvd  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number Hello packets that have been received
-           from all EIGRP neighbors formed on all interfaces whose IP
-           addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 4 }
-
-    cEigrpUpdatesSent  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number routing update packets that have been
-           sent to all EIGRP neighbors formed on all interfaces whose
-           IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 5 }
-
-    cEigrpUpdatesRcvd  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number routing update packets that have been
-           received from all EIGRP neighbors formed on all interfaces
-           whose IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 6 }
-
-    cEigrpQueriesSent  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number alternate route query packets that have
-           been sent to all EIGRP neighbors formed on all interfaces
-           whose IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 7 }
-
-    cEigrpQueriesRcvd  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number alternate route query packets that
-           have been received from all EIGRP neighbors formed on
-           all interfaces whose IP addresses fall under networks
-           configured for the EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 8 }
-
-    cEigrpRepliesSent  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number query reply packets that have been sent
-           to all EIGRP neighbors formed on all interfaces whose IP
-           addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 9 }
-
-    cEigrpRepliesRcvd  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number query reply packets that have been
-           received from all EIGRP neighbors formed on all interfaces
-           whose IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 10 }
-
-    cEigrpAcksSent  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number packet acknowledgements that have been
-           sent to all EIGRP neighbors formed on all interfaces whose
-           IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 11 }
-
-    cEigrpAcksRcvd  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number packet acknowledgements that have been
-           received from all EIGRP neighbors formed on all interfaces
-           whose IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 12 }
-
-    cEigrpInputQHighMark  OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The highest number of EIGRP packets in the input queue
-             waiting to be processed internally addressed to this
-             AS."
-        ::= { cEigrpTraffStatsEntry 13 }
-
-    cEigrpInputQDrops  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The number of EIGRP packets dropped from the input
-           queue due to it being full within the AS."
-        ::= { cEigrpTraffStatsEntry 14 }
-
-    cEigrpSiaQueriesSent  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number of Stuck-In-Active (SIA) query packets
-           sent to all EIGRP neighbors formed on all interfaces whose
-           IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 15 }
-
-    cEigrpSiaQueriesRcvd  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number of Stuck-In-Active (SIA) query packets
-           received from all EIGRP neighbors formed on all interfaces
-           whose IP addresses fall under networks configured for the
-           EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 16 }
-
-    cEigrpAsRouterIdType  OBJECT-TYPE
-        SYNTAX     InetAddressType
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The format of the router-id configured or automatically
-           selected for the EIGRP AS."
-        ::= { cEigrpTraffStatsEntry 17 }
-
-    cEigrpAsRouterId  OBJECT-TYPE
-        SYNTAX     InetAddress
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The router-id configured or automatically selected for the
-           EIGRP AS.   Each EIGRP routing process has a unique
-           router-id selected from each autonomous system configured.
-           The format is governed by object cEigrpAsRouterIdType."
-        ::= { cEigrpTraffStatsEntry 18 }
-
-    cEigrpTopoRoutes  OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "The total number of EIGRP derived routes currently existing
-           in the topology table for the AS."
-        ::= { cEigrpTraffStatsEntry 19 }
-
-    cEigrpHeadSerial  OBJECT-TYPE
-        SYNTAX     Counter64
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "Routes in a topology table for an AS are assigned serial
-             numbers and are sequenced internally as they are inserted
-             and deleted.   The serial number of the first route in
-             that internal sequence is called the head serial number.
-             Each AS has its own topology table, and its own serial
-             number space, each of which begins with the value 1.
-             A serial number of zero implies that there are no routes
-             in the topology."
-        ::= { cEigrpTraffStatsEntry 20 }
-
-    cEigrpNextSerial  OBJECT-TYPE
-        SYNTAX     Counter64
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The serial number that would be assigned to the next new
-             or changed route in the topology table for the AS."
-        ::= { cEigrpTraffStatsEntry 21 }
-
-    cEigrpXmitPendReplies  OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-           "When alternate route query packets are sent to adjacent
-           EIGRP peers in an AS, replies are expected.   This object
-           is the total number of outstanding replies expected to
-           queries that have been sent to peers in the current AS.
-           It remains at zero most of the time until an EIGRP route
-           becomes active."
-        ::= { cEigrpTraffStatsEntry 22 }
-
-    cEigrpXmitDummies  OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "A dummy is a temporary internal entity used as a place
-             holder in the topology table for an AS. They are not
-             transmitted in routing updates.  This is the total
-             number currently in existence associated with the AS."
-        ::= { cEigrpTraffStatsEntry 23 }
-
-    --  EIGRP topology table definition
-
-    cEigrpTopoTable OBJECT-TYPE
-        SYNTAX     SEQUENCE OF CEigrpTopoEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The table of EIGRP routes and their associated
-             attributes for an Autonomous System (AS) configured
-             in a VPN is called a topology table.  All route entries in
-             the topology table will be indexed by IP network type,
-             IP network number and network mask (prefix) size."
-        ::= { cEigrpTopologyInfo 1 }
-
-    cEigrpTopoEntry OBJECT-TYPE
-        SYNTAX     CEigrpTopoEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The entry for a single EIGRP topology table in the given
-             AS."
-        INDEX { cEigrpVpnId, cEigrpAsNumber, cEigrpDestNetType,
-                cEigrpDestNet, cEigrpDestNetPrefixLen }
-        ::= { cEigrpTopoTable 1 }
-
-    CEigrpTopoEntry ::=
-        SEQUENCE {
-            cEigrpDestNetType             InetAddressType,
-            cEigrpDestNet                 InetAddress,
-            cEigrpDestNetPrefixLen        InetAddressPrefixLength,
-            cEigrpActive                  TruthValue,
-            cEigrpStuckInActive           TruthValue,
-            cEigrpDestSuccessors          Unsigned32,
-            cEigrpFdistance               Unsigned32,
-            cEigrpRouteOriginType         SnmpAdminString,
-            cEigrpRouteOriginAddrType     InetAddressType,
-            cEigrpRouteOriginAddr         InetAddress,
-            cEigrpNextHopAddressType      InetAddressType,
-            cEigrpNextHopAddress          InetAddress,
-            cEigrpNextHopInterface        SnmpAdminString,
-            cEigrpDistance                Unsigned32,
-            cEigrpReportDistance          Unsigned32
-        }
-
-    cEigrpDestNetType OBJECT-TYPE
-        SYNTAX     InetAddressType
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The format of the destination IP network number for
-             a single route in the topology table in the AS specified
-             in cEigrpDestNet."
-        ::= { cEigrpTopoEntry 1 }
-
-    cEigrpDestNet OBJECT-TYPE
-        SYNTAX     InetAddress
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The destination IP network number for a single route in
-             the topology table in the AS.  The format is governed
-             by object cEigrpDestNetType."
-        ::= { cEigrpTopoEntry 2 }
-
-    cEigrpDestNetPrefixLen OBJECT-TYPE
-        SYNTAX     InetAddressPrefixLength
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The prefix length associated with the destination IP
-             network address for a single route in the topology
-             table in the AS.  The format is governed by the object
-             cEigrpDestNetType."
-        ::= { cEigrpTopoEntry 4 }
-
-    cEigrpActive OBJECT-TYPE
-        SYNTAX     TruthValue
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "A value of true(1) indicates the route to the
-             destination network has failed and an active (query)
-             search for an alternative path is in progress.  A value
-             of false(2) indicates the route is stable (passive)."
-        ::= { cEigrpTopoEntry 5 }
-
-    cEigrpStuckInActive OBJECT-TYPE
-        SYNTAX     TruthValue
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "A value of true(1) indicates that that this route which is
-             in active state (cEigrpActive = true(1)) has not received
-             any replies to queries for alternate paths, and a second
-             EIGRP route query, called a stuck-in-active query, has
-             now been sent."
-        ::= { cEigrpTopoEntry 6 }
-
-    cEigrpDestSuccessors OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "A successor is the next routing hop for a path to the
-             destination IP network number for a single route in the
-             topology table in the AS.  There can be several
-             potential successors if there are multiple paths to the
-             destination.   This is the total number of successors for
-             a topology entry."
-        ::= { cEigrpTopoEntry 7 }
-
-    cEigrpFdistance OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "The feasibility (best) distance is the minimum distance
-             from this router to the destination IP network in
-             this topology entry.  The feasibility distance is
-             used in determining the best successor for a path to the
-             destination network."
-        ::= { cEigrpTopoEntry 8 }
-
-     cEigrpRouteOriginType OBJECT-TYPE
-        SYNTAX     SnmpAdminString
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "This is a text string describing the internal origin
-              of the EIGRP route represented by the topology entry."
-        ::= { cEigrpTopoEntry 9 }
-
-     cEigrpRouteOriginAddrType OBJECT-TYPE
-        SYNTAX     InetAddressType
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "The format of the IP address defined as the origin of
-             this topology route entry."
-        ::= { cEigrpTopoEntry 10 }
-
-     cEigrpRouteOriginAddr OBJECT-TYPE
-        SYNTAX     InetAddress
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "If the origin of the topology route entry is external
-              to this router, then this object is the IP address
-              of the router from which it originated.  The format 
-              is governed by object cEigrpRouteOriginAddrType."
-        ::= { cEigrpTopoEntry 11 }
-
-     cEigrpNextHopAddressType OBJECT-TYPE
-        SYNTAX     InetAddressType
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "The format of the next hop IP address for the route
-              represented by the topology entry."
-        ::= { cEigrpTopoEntry 12 }
-
-     cEigrpNextHopAddress OBJECT-TYPE
-        SYNTAX     InetAddress
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "This is the next hop IP address for the route represented
-              by the topology entry.   The next hop is where
-              network traffic will be routed to in order to reach
-              the destination network for this topology entry.  The
-              format is governed by cEigrpNextHopAddressType."
-        ::= { cEigrpTopoEntry 13 }
-
-     cEigrpNextHopInterface OBJECT-TYPE
-        SYNTAX     SnmpAdminString
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "The interface through which the next hop IP address
-              is reached to send network traffic to the destination
-              network represented by the topology entry."
-        ::= { cEigrpTopoEntry 14 }
-
-     cEigrpDistance OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "The computed distance to the destination network entry
-             from this router."
-        ::= { cEigrpTopoEntry 15 }
-
-     cEigrpReportDistance OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-             "The computed distance to the destination network in the
-              topology entry reported to this router by the originator
-              of this route."
-        ::= { cEigrpTopoEntry 16 }
-
-    --  EIGRP Peer table per VPN and AS (expansion table)
-
-    cEigrpPeerTable OBJECT-TYPE
-        SYNTAX     SEQUENCE OF CEigrpPeerEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The table of established EIGRP peers (neighbors) in the
-             selected autonomous system.   Peers are indexed by their
-             unique internal handle id, as well as the AS number and
-             VPN id.   The peer entry is removed from the table if
-             the peer is declared down."
-    ::= { cEigrpPeerInfo 1 }
-
-    cEigrpPeerEntry OBJECT-TYPE
-        SYNTAX     CEigrpPeerEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "Statistics and operational parameters for a single peer
-             in the AS."
-        INDEX { cEigrpVpnId, cEigrpAsNumber, cEigrpHandle }
-        ::= { cEigrpPeerTable 1 }
-
-    CEigrpPeerEntry ::=
-        SEQUENCE {
-            cEigrpHandle        Unsigned32,
-            cEigrpPeerAddrType  InetAddressType,
-            cEigrpPeerAddr      InetAddress,
-            cEigrpPeerIfIndex   InterfaceIndexOrZero,
-            cEigrpHoldTime      Unsigned32,
-            cEigrpUpTime        EigrpUpTimeString,
-            cEigrpSrtt          Unsigned32,
-            cEigrpRto           Unsigned32,
-            cEigrpPktsEnqueued  Unsigned32,
-            cEigrpLastSeq       Unsigned32,
-            cEigrpVersion       EigrpVersionString,
-            cEigrpRetrans       Counter32,
-            cEigrpRetries       Unsigned32
-        }
-
-    cEigrpHandle OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The unique internal identifier for the peer in the AS.
-             This is a unique value among peer entries in a selected
-             table."
-        ::= { cEigrpPeerEntry 1 }
-
-    cEigrpPeerAddrType OBJECT-TYPE
-        SYNTAX     InetAddressType
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The format of the remote source IP address used by the
-             peer to establish the EIGRP adjacency with this router."
-        ::= { cEigrpPeerEntry 2 }
-
-    cEigrpPeerAddr OBJECT-TYPE
-        SYNTAX     InetAddress
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The source IP address used by the peer to establish the
-             EIGRP adjacency with this router.  The format is
-             governed by object cEigrpPeerAddrType."
-        ::= { cEigrpPeerEntry 3 }
-
-    cEigrpPeerIfIndex OBJECT-TYPE
-        SYNTAX     InterfaceIndexOrZero
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The ifIndex of the interface on this router through
-             which this peer can be reached."
-        ::= { cEigrpPeerEntry 4 }
-
-    cEigrpHoldTime OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "seconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The count-down timer indicating how much time must
-             pass without receiving a hello packet from this
-             EIGRP peer before this router declares the peer down.
-             A peer declared as down is removed from the table and
-             is no longer visible."
-        ::= { cEigrpPeerEntry 5 }
-
-    cEigrpUpTime OBJECT-TYPE
-        SYNTAX       EigrpUpTimeString
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-            "The elapsed time since the EIGRP adjacency was first
-             established with the peer."
-        ::= { cEigrpPeerEntry 6 }
-
-    cEigrpSrtt OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "milliseconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The computed smooth round trip time for packets to and
-             from the peer."
-        ::= { cEigrpPeerEntry 7 }
-
-    cEigrpRto OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "milliseconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The computed retransmission timeout for the peer.
-             This value is computed over time as packets are sent to
-             the peer and acknowledgements are received from it,
-             and is the amount of time to wait before resending
-             a packet from the retransmission queue to the peer
-             when an expected acknowledgement has not been received."
-        ::= { cEigrpPeerEntry 8 }
-
-    cEigrpPktsEnqueued OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The number of any EIGRP packets currently enqueued
-             waiting to be sent to this peer."
-        ::= { cEigrpPeerEntry 9 }
-
-    cEigrpLastSeq OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "All transmitted EIGRP packets have a sequence number
-             assigned. This is the sequence number of the last EIGRP
-             packet sent to this peer."
-        ::= { cEigrpPeerEntry 10 }
-
-    cEigrpVersion OBJECT-TYPE
-        SYNTAX     EigrpVersionString
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The EIGRP version information reported by the remote
-             peer."
-        ::= { cEigrpPeerEntry 11 }
-
-    cEigrpRetrans OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The cumulative number of retransmissions to this peer
-             during the period that the peer adjacency has remained
-             up."
-        ::= { cEigrpPeerEntry 12 }
-
-    cEigrpRetries OBJECT-TYPE
-        SYNTAX     Unsigned32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The number of times the current unacknowledged packet
-             has been retried, i.e. resent to this peer to be
-             acknowledged."
-        ::= { cEigrpPeerEntry 13 }
-
-    --  EIGRP Interfaces table per VPN and AS
-
-    cEigrpInterfaceTable OBJECT-TYPE
-        SYNTAX     SEQUENCE OF CEigrpInterfaceEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "The table of interfaces over which EIGRP is running, and
-             their associated statistics.   This table is independent
-             of whether any peer adjacencies have been formed over
-             the interfaces or not.   Interfaces running EIGRP are
-             determined by whether their assigned IP addresses fall
-             within configured EIGRP network statements."
-        ::= { cEigrpInterfaceInfo 1 }
-
-    cEigrpInterfaceEntry OBJECT-TYPE
-        SYNTAX     CEigrpInterfaceEntry
-        MAX-ACCESS not-accessible
-        STATUS     current
-        DESCRIPTION
-            "Information for a single interface running EIGRP in the
-             AS and VPN."
-        INDEX { cEigrpVpnId, cEigrpAsNumber, ifIndex }
-        ::= { cEigrpInterfaceTable 1 }
-
-    CEigrpInterfaceEntry ::=
-        SEQUENCE {
-            cEigrpPeerCount        Gauge32,
-            cEigrpXmitReliableQ    Gauge32,
-            cEigrpXmitUnreliableQ  Gauge32,
-            cEigrpMeanSrtt         Unsigned32,
-            cEigrpPacingReliable   Unsigned32,
-            cEigrpPacingUnreliable Unsigned32,
-            cEigrpMFlowTimer       Unsigned32,
-            cEigrpPendingRoutes    Gauge32,
-            cEigrpHelloInterval    Unsigned32,
-            cEigrpXmitNextSerial   Counter64,
-            cEigrpUMcasts          Counter32,
-            cEigrpRMcasts          Counter32,
-            cEigrpUUcasts          Counter32,
-            cEigrpRUcasts          Counter32,
-            cEigrpMcastExcepts     Counter32,
-            cEigrpCRpkts           Counter32,
-            cEigrpAcksSuppressed   Counter32,
-            cEigrpRetransSent       Counter32,
-            cEigrpOOSrcvd          Counter32,
-            cEigrpAuthMode         INTEGER,
-            cEigrpAuthKeyChain    SnmpAdminString
-         }
-
-    cEigrpPeerCount OBJECT-TYPE
-        SYNTAX     Gauge32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The number of EIGRP adjacencies currently formed with
-             peers reached through this interface."
-        ::= { cEigrpInterfaceEntry 3 }
-
-    cEigrpXmitReliableQ OBJECT-TYPE
-        SYNTAX     Gauge32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The number of EIGRP packets currently waiting in the
-             reliable transport (acknowledgement-required) 
-             transmission queue to be sent to a peer."
-        ::= { cEigrpInterfaceEntry 4 }
-
-    cEigrpXmitUnreliableQ OBJECT-TYPE
-        SYNTAX     Gauge32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The number EIGRP of packets currently waiting in
-             the unreliable transport (no acknowledgement required)
-             transmission queue."
-        ::= { cEigrpInterfaceEntry 5 }
-
-    cEigrpMeanSrtt OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "milliseconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The average of all the computed smooth round trip time
-             values for a packet to and from all peers established on
-             this interface."
-        ::= { cEigrpInterfaceEntry 6 }
-
-    cEigrpPacingReliable OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "milliseconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The configured time interval between EIGRP packet
-             transmissions on the interface when the reliable transport
-             method is used."
-        ::= { cEigrpInterfaceEntry 7 }
-
-    cEigrpPacingUnreliable OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "milliseconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The configured time interval between EIGRP packet
-             transmissions on the interface when the unreliable
-             transport method is used."
-        ::= { cEigrpInterfaceEntry 8 }
-
-    cEigrpMFlowTimer OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "milliseconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The configured multicast flow control timer value for
-             this interface."
-        ::= { cEigrpInterfaceEntry 9 }
-
-    cEigrpPendingRoutes OBJECT-TYPE
-        SYNTAX     Gauge32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The number of queued EIGRP routing updates awaiting
-             transmission on this interface."
-        ::= { cEigrpInterfaceEntry 10 }
-
-    cEigrpHelloInterval OBJECT-TYPE
-        SYNTAX     Unsigned32
-        UNITS      "seconds"
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The configured time interval between Hello packet
-             transmissions for this interface."
-        ::= { cEigrpInterfaceEntry 11 }
-
-    cEigrpXmitNextSerial OBJECT-TYPE
-        SYNTAX     Counter64
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The serial number of the next EIGRP packet that is to
-             be queued for transmission on this interface."
-        ::= { cEigrpInterfaceEntry 12 }
-
-    cEigrpUMcasts OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number of unreliable (no acknowledgement
-             required) EIGRP multicast packets sent on this
-             interface."
-        ::= { cEigrpInterfaceEntry 13 }
-
-    cEigrpRMcasts OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number of reliable (acknowledgement required)
-             EIGRP multicast packets sent on this interface."
-        ::= { cEigrpInterfaceEntry 14 }
-
-    cEigrpUUcasts OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number of unreliable (no acknowledgement
-             required) EIGRP unicast packets sent on this
-             interface."
-        ::= { cEigrpInterfaceEntry 15 }
-
-    cEigrpRUcasts OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number of reliable (acknowledgement required)
-             unicast packets sent on this interface."
-        ::= { cEigrpInterfaceEntry 16 }
-
-    cEigrpMcastExcepts OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number of EIGRP multicast exception
-             transmissions that have occurred on this interface."
-        ::= { cEigrpInterfaceEntry 17 }
-
-    cEigrpCRpkts OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number EIGRP Conditional-Receive packets sent on
-             this interface."
-        ::= { cEigrpInterfaceEntry 18 }
-
-    cEigrpAcksSuppressed OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number of individual EIGRP acknowledgement
-             packets that have been suppressed and combined in
-             an already enqueued outbound reliable packet on this
-             interface."
-        ::= { cEigrpInterfaceEntry 19 }
-
-    cEigrpRetransSent OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number EIGRP packet retransmissions sent on
-             the interface."
-        ::= { cEigrpInterfaceEntry 20 }
-
-    cEigrpOOSrcvd OBJECT-TYPE
-        SYNTAX     Counter32
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The total number of out-of-sequence EIGRP packets
-             received."
-        ::= { cEigrpInterfaceEntry 21 }
-
-    cEigrpAuthMode OBJECT-TYPE
-        SYNTAX     INTEGER {
-                       none(1),
-                       md5(2)
-                   }
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The EIGRP authentication mode of the interface.
-            none  :  no authentication enabled on the interface
-            md5   :  MD5 authentication enabled on the interface"
-        ::= { cEigrpInterfaceEntry 22 }
-
-    cEigrpAuthKeyChain OBJECT-TYPE
-        SYNTAX     SnmpAdminString
-        MAX-ACCESS read-only
-        STATUS     current
-        DESCRIPTION
-            "The name of the authentication key-chain configured
-             on this interface.   The key-chain is a reference to
-             which set of secret keys are to be accessed in order
-             to determine which secret key string to use.  The key
-             chain name is not the secret key string password and
-             can also be used in other routing protocols, such
-             as RIP and ISIS."
-        ::= { cEigrpInterfaceEntry 23 }
-
-    -- Notifications
-
-    cEigrpAuthFailureEvent NOTIFICATION-TYPE
-        OBJECTS { cEigrpPeerAddrType, cEigrpPeerAddr }
-        STATUS     current
-        DESCRIPTION
-            "This notification is sent when EIGRP MD5 authentication
-             is enabled on any interface and peer adjacencies are
-             formed, and any adjacencies go down as a result of an
-             authentication failure."
-        ::=  { cEigrpMIBNotifications 1 }
-
-    cEigrpRouteStuckInActive NOTIFICATION-TYPE
-        OBJECTS { cEigrpPeerAddrType, cEigrpPeerAddr,
-                  cEigrpStuckInActive }
-        STATUS     current
-        DESCRIPTION
-            "This notification is sent when a route in the topology
-             table is stuck in an active state.  During the query
-             phase for a new route to a destination network, a route
-             is described as being in the active state if when an
-             alternate path is actively being sought, no replies are
-             received to normal queries or stuck-in-active queries."
-        ::=  { cEigrpMIBNotifications 2 }
-
-    -- Conformance
-
-    cEigrpMIBCompliances
-        OBJECT IDENTIFIER ::= { cEigrpMIBConformance 1 }
-
-    cEigrpMIBGroups
-        OBJECT IDENTIFIER ::= { cEigrpMIBConformance 2 }
-
-    -- Compliance
-
-    cEigrpMIBCompliance MODULE-COMPLIANCE
-        STATUS     current
-        DESCRIPTION
-            "The compliance statement for entities which implement
-             the Cisco EIGRP Management MIB."
-        MODULE
-            MANDATORY-GROUPS {
-                cEigrpVpnDataGroup,
-                cEigrpTrafficStatsGroup,
-                cEigrpInterfaceDataGroup,
-                cEigrpPeerDataGroup,
-                cEigrpTopoDataGroup,
-                cEigrpNotificationsGroup
-            }
-
-            OBJECT cEigrpAsRouterIdType
-            SYNTAX INTEGER { ipv4(1) }
-            DESCRIPTION
-                "An implementation is only required to support
-                 IPv4 address type."
-
-            OBJECT cEigrpRouteOriginAddrType
-            SYNTAX INTEGER { ipv4(1) }
-            DESCRIPTION
-                "An implementation is only required to support
-                 IPv4 address type."
-
-            OBJECT cEigrpNextHopAddressType
-            SYNTAX INTEGER { ipv4(1) }
-            DESCRIPTION
-                "An implementation is only required to support
-                 IPv4 address type."
-
-            OBJECT cEigrpPeerAddrType
-            SYNTAX INTEGER { ipv4(1) }
-            DESCRIPTION
-                "An implementation is only required to support
-                 IPv4 address type."
-        ::= { cEigrpMIBCompliances 1 }
-
-    -- Units of Conformance
-
-    cEigrpVpnDataGroup OBJECT-GROUP
-        OBJECTS {
-            cEigrpVpnName
-        }
-        STATUS     current
-        DESCRIPTION
-            "The collection of VPN names which have been configured
-             with one or more EIGRP autonmous systems."
-        ::= { cEigrpMIBGroups 1 }
-
-    cEigrpTrafficStatsGroup OBJECT-GROUP
-        OBJECTS {
-            cEigrpHellosSent,
-            cEigrpHellosRcvd,
-            cEigrpUpdatesSent,
-            cEigrpUpdatesRcvd,
-            cEigrpQueriesSent,
-            cEigrpQueriesRcvd,
-            cEigrpRepliesSent,
-            cEigrpRepliesRcvd,
-            cEigrpAcksSent,
-            cEigrpAcksRcvd,
-            cEigrpInputQHighMark,
-            cEigrpInputQDrops,
-            cEigrpSiaQueriesSent,
-            cEigrpSiaQueriesRcvd
-        }
-        STATUS     current
-        DESCRIPTION
-            "A collection of objects providing management information
-             regarding collective EIGRP packet statistics for all EIGRP
-             autonomous systems configured."
-        ::= { cEigrpMIBGroups 2 }
-
-    cEigrpInterfaceDataGroup OBJECT-GROUP
-        OBJECTS {
-            cEigrpPeerCount,
-            cEigrpXmitReliableQ,
-            cEigrpXmitUnreliableQ,
-            cEigrpMeanSrtt,
-            cEigrpPacingReliable,
-            cEigrpPacingUnreliable,
-            cEigrpMFlowTimer,
-            cEigrpPendingRoutes,
-            cEigrpHelloInterval,
-            cEigrpXmitNextSerial,
-            cEigrpUMcasts,
-            cEigrpRMcasts,
-            cEigrpUUcasts,
-            cEigrpRUcasts,
-            cEigrpMcastExcepts,
-            cEigrpCRpkts,
-            cEigrpAcksSuppressed,
-            cEigrpRetransSent,
-            cEigrpOOSrcvd,
-            cEigrpAuthMode,
-            cEigrpAuthKeyChain
-        }
-        STATUS     current
-        DESCRIPTION
-            "A collection of objects providing management information
-             for interfaces over which EIGRP is configured and
-             running."
-        ::= { cEigrpMIBGroups 3 }
-
-    cEigrpPeerDataGroup OBJECT-GROUP
-        OBJECTS {
-            cEigrpNbrCount,
-            cEigrpPeerAddrType,
-            cEigrpPeerAddr,
-            cEigrpPeerIfIndex,
-            cEigrpHoldTime,
-            cEigrpUpTime,
-            cEigrpSrtt,
-            cEigrpRto,
-            cEigrpPktsEnqueued,
-            cEigrpLastSeq,
-            cEigrpVersion,
-            cEigrpRetrans,
-            cEigrpRetries
-        }
-        STATUS     current
-        DESCRIPTION
-            "A collection of objects providing management information
-             for EIGRP peer adjacencies formed in the EIGRP
-             autonoumous systems."
-        ::= { cEigrpMIBGroups 4 }
-
-    cEigrpTopoDataGroup OBJECT-GROUP
-        OBJECTS {
-            cEigrpAsRouterId,
-            cEigrpAsRouterIdType,
-            cEigrpTopoRoutes,
-            cEigrpHeadSerial,
-            cEigrpNextSerial,
-            cEigrpXmitPendReplies,
-            cEigrpXmitDummies,
-            cEigrpActive,
-            cEigrpStuckInActive,
-            cEigrpDestSuccessors,
-            cEigrpFdistance,
-            cEigrpRouteOriginType,
-            cEigrpRouteOriginAddrType,
-            cEigrpRouteOriginAddr,
-            cEigrpNextHopAddressType,
-            cEigrpNextHopAddress,
-            cEigrpNextHopInterface,
-            cEigrpDistance,
-            cEigrpReportDistance
-        }
-        STATUS     current
-        DESCRIPTION
-            "A collection of objects providing management information
-             for EIGRP topology routes derived within autonomous
-             systems and received in updates from EIGRP neighbors."
-        ::= { cEigrpMIBGroups 5 }
-
-    cEigrpNotificationsGroup NOTIFICATION-GROUP
-        NOTIFICATIONS {
-            cEigrpAuthFailureEvent,
-            cEigrpRouteStuckInActive
-        }
-        STATUS     current
-        DESCRIPTION
-            "Group of notifications on EIGRP routers."
-        ::= { cEigrpMIBGroups 6 }
-END
\ No newline at end of file
index 86061b3ae35013a9d4e0429288e9695b563a93d8..d532afbbe632de5abe746de981923d40dc6aaa04 100644 (file)
@@ -66,5 +66,3 @@ noinst_HEADERS += \
 
 eigrpd_eigrpd_SOURCES = eigrpd/eigrp_main.c
 eigrpd_eigrpd_LDADD = eigrpd/libeigrp.a lib/libfrr.la @LIBCAP@
-
-EXTRA_DIST += eigrpd/EIGRP-MIB.txt
index 05cec5a5282484ab4b4790c231aadccdd6e1f4cf..a0fa3d274f27436b28bcd86c50e71924140d0692 100644 (file)
@@ -1,6 +1,8 @@
 if FPM
+if HAVE_PROTOBUF
 lib_LTLIBRARIES += fpm/libfrrfpm_pb.la
 endif
+endif
 
 fpm_libfrrfpm_pb_la_LDFLAGS = -version-info 0:0:0
 fpm_libfrrfpm_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS)
@@ -10,11 +12,9 @@ fpm_libfrrfpm_pb_la_SOURCES = \
        fpm/fpm_pb.c \
        # end
 
-if HAVE_PROTOBUF
 nodist_fpm_libfrrfpm_pb_la_SOURCES = \
        fpm/fpm.pb-c.c \
        # end
-endif
 
 CLEANFILES += \
        fpm/fpm.pb-c.c \
index 2b3116b1ff19fd107d4f69c31b7cf1db1903f7a4..e8b729c779cb21286f4b4ba2e4fa0a91f5af8bad 100644 (file)
 #include "isisd/isis_lsp.h"
 #include "isisd/isis_spf_private.h"
 #include "isisd/isis_tx_queue.h"
+#include "isisd/isis_csm.h"
 
 DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric")
 DEFINE_MTYPE_STATIC(ISISD, FABRICD_NEIGHBOR, "ISIS OpenFabric Neighbor Entry")
+DEFINE_MTYPE_STATIC(ISISD, FABRICD_FLOODING_INFO, "ISIS OpenFabric Flooding Log")
 
 /* Tracks initial synchronization as per section 2.4
  *
@@ -63,20 +65,28 @@ struct fabricd {
        uint8_t tier_pending;
        struct thread *tier_calculation_timer;
        struct thread *tier_set_timer;
+
+       int csnp_delay;
+       bool always_send_csnp;
 };
 
 /* Code related to maintaining the neighbor lists */
 
 struct neighbor_entry {
-       struct isis_vertex *vertex;
+       uint8_t id[ISIS_SYS_ID_LEN];
+       struct isis_adjacency *adj;
        bool present;
 };
 
-static struct neighbor_entry *neighbor_entry_new(struct isis_vertex *vertex)
+static struct neighbor_entry *neighbor_entry_new(const uint8_t *id,
+                                                struct isis_adjacency *adj)
 {
-       struct neighbor_entry *rv = XMALLOC(MTYPE_FABRICD_NEIGHBOR, sizeof(*rv));
+       struct neighbor_entry *rv = XMALLOC(MTYPE_FABRICD_NEIGHBOR,
+                                           sizeof(*rv));
+
+       memcpy(rv->id, id, sizeof(rv->id));
+       rv->adj = adj;
 
-       rv->vertex = vertex;
        return rv;
 }
 
@@ -102,32 +112,29 @@ static unsigned neighbor_entry_hash_key(void *np)
 {
        struct neighbor_entry *n = np;
 
-       return jhash(n->vertex->N.id, ISIS_SYS_ID_LEN, 0x55aa5a5a);
+       return jhash(n->id, sizeof(n->id), 0x55aa5a5a);
 }
 
 static bool neighbor_entry_hash_cmp(const void *a, const void *b)
 {
        const struct neighbor_entry *na = a, *nb = b;
 
-       return memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN) == 0;
+       return memcmp(na->id, nb->id, sizeof(na->id)) == 0;
 }
 
 static int neighbor_entry_list_cmp(void *a, void *b)
 {
        struct neighbor_entry *na = a, *nb = b;
 
-       return -memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN);
+       return -memcmp(na->id, nb->id, sizeof(na->id));
 }
 
 static struct neighbor_entry *neighbor_entry_lookup_list(struct skiplist *list,
                                                         const uint8_t *id)
 {
-       struct isis_vertex querier;
-       isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS);
+       struct neighbor_entry n = { {0} };
 
-       struct neighbor_entry n = {
-               .vertex = &querier
-       };
+       memcpy(n.id, id, sizeof(n.id));
 
        struct neighbor_entry *rv;
 
@@ -143,12 +150,9 @@ static struct neighbor_entry *neighbor_entry_lookup_list(struct skiplist *list,
 static struct neighbor_entry *neighbor_entry_lookup_hash(struct hash *hash,
                                                         const uint8_t *id)
 {
-       struct isis_vertex querier;
-       isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS);
+       struct neighbor_entry n = {{0}};
 
-       struct neighbor_entry n = {
-               .vertex = &querier
-       };
+       memcpy(n.id, id, sizeof(n.id));
 
        struct neighbor_entry *rv = hash_lookup(hash, &n);
 
@@ -158,28 +162,55 @@ static struct neighbor_entry *neighbor_entry_lookup_hash(struct hash *hash,
        return rv;
 }
 
-static void neighbor_lists_update(struct fabricd *f)
+static int fabricd_handle_adj_state_change(struct isis_adjacency *arg)
 {
-       neighbor_lists_clear(f);
+       struct fabricd *f = arg->circuit->area->fabricd;
+
+       if (!f)
+               return 0;
+
+       while (!skiplist_empty(f->neighbors))
+               skiplist_delete_first(f->neighbors);
+
+       struct listnode *node;
+       struct isis_circuit *circuit;
+
+       for (ALL_LIST_ELEMENTS_RO(f->area->circuit_list, node, circuit)) {
+               if (circuit->state != C_STATE_UP)
+                       continue;
+
+               struct isis_adjacency *adj = circuit->u.p2p.neighbor;
+
+               if (!adj || adj->adj_state != ISIS_ADJ_UP)
+                       continue;
+
+               struct neighbor_entry *n = neighbor_entry_new(adj->sysid, adj);
+
+               skiplist_insert(f->neighbors, n, n);
+       }
+
+       return 0;
+}
+
+static void neighbors_neighbors_update(struct fabricd *f)
+{
+       hash_clean(f->neighbors_neighbors, neighbor_entry_del_void);
 
        struct listnode *node;
        struct isis_vertex *v;
 
        for (ALL_QUEUE_ELEMENTS_RO(&f->spftree->paths, node, v)) {
-               if (!v->d_N || !VTYPE_IS(v->type))
+               if (v->d_N < 2 || !VTYPE_IS(v->type))
                        continue;
 
                if (v->d_N > 2)
                        break;
 
-               struct neighbor_entry *n = neighbor_entry_new(v);
-               if (v->d_N == 1) {
-                       skiplist_insert(f->neighbors, n, n);
-               } else {
-                       struct neighbor_entry *inserted;
-                       inserted = hash_get(f->neighbors_neighbors, n, hash_alloc_intern);
-                       assert(inserted == n);
-               }
+               struct neighbor_entry *n = neighbor_entry_new(v->N.id, NULL);
+               struct neighbor_entry *inserted;
+               inserted = hash_get(f->neighbors_neighbors, n,
+                                   hash_alloc_intern);
+               assert(inserted == n);
        }
 }
 
@@ -198,6 +229,8 @@ struct fabricd *fabricd_new(struct isis_area *area)
                                              "Fabricd Neighbors");
 
        rv->tier = rv->tier_config = ISIS_TIER_UNDEFINED;
+
+       rv->csnp_delay = FABRICD_DEFAULT_CSNP_DELAY;
        return rv;
 };
 
@@ -445,7 +478,7 @@ void fabricd_run_spf(struct isis_area *area)
                return;
 
        isis_run_hopcount_spf(area, isis->sysid, f->spftree);
-       neighbor_lists_update(f);
+       neighbors_neighbors_update(f);
        fabricd_bump_tier_calculation_timer(f);
 }
 
@@ -493,43 +526,37 @@ int fabricd_write_settings(struct isis_area *area, struct vty *vty)
                written++;
        }
 
+       if (f->csnp_delay != FABRICD_DEFAULT_CSNP_DELAY
+           || f->always_send_csnp) {
+               vty_out(vty, " triggered-csnp-delay %d%s\n", f->csnp_delay,
+                       f->always_send_csnp ? " always" : "");
+       }
+
        return written;
 }
 
-static void move_to_dnr(struct isis_lsp *lsp, struct neighbor_entry *n)
+static void move_to_queue(struct isis_lsp *lsp, struct neighbor_entry *n,
+                         enum isis_tx_type type, struct isis_circuit *circuit)
 {
-       struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N);
-
        n->present = false;
 
-       if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-               char buff[PREFIX2STR_BUFFER];
-               zlog_debug("OpenFabric: Adding %s to DNR",
-                          vid2string(n->vertex, buff, sizeof(buff)));
-       }
+       if (n->adj && n->adj->circuit == circuit)
+               return;
 
-       if (adj) {
-               isis_tx_queue_add(adj->circuit->tx_queue, lsp,
-                                 TX_LSP_CIRCUIT_SCOPED);
+       if (isis->debugs & DEBUG_FLOODING) {
+               zlog_debug("OpenFabric: Adding %s to %s",
+                          print_sys_hostname(n->id),
+                          (type == TX_LSP_NORMAL) ? "RF" : "DNR");
        }
-}
 
-static void move_to_rf(struct isis_lsp *lsp, struct neighbor_entry *n)
-{
-       struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N);
+       if (n->adj)
+               isis_tx_queue_add(n->adj->circuit->tx_queue, lsp, type);
 
-       n->present = false;
-
-       if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-               char buff[PREFIX2STR_BUFFER];
-               zlog_debug("OpenFabric: Adding %s to RF",
-                          vid2string(n->vertex, buff, sizeof(buff)));
-       }
+       uint8_t *neighbor_id = XMALLOC(MTYPE_FABRICD_FLOODING_INFO,
+                                      sizeof(n->id));
 
-       if (adj) {
-               isis_tx_queue_add(adj->circuit->tx_queue, lsp,
-                                 TX_LSP_NORMAL);
-       }
+       memcpy(neighbor_id, n->id, sizeof(n->id));
+       listnode_add(lsp->flooding_neighbors[type], neighbor_id);
 }
 
 static void mark_neighbor_as_present(struct hash_backet *backet, void *arg)
@@ -549,66 +576,89 @@ static void handle_firsthops(struct hash_backet *backet, void *arg)
 
        n = neighbor_entry_lookup_list(f->neighbors, vertex->N.id);
        if (n) {
-               if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-                       char buff[PREFIX2STR_BUFFER];
+               if (isis->debugs & DEBUG_FLOODING) {
                        zlog_debug("Removing %s from NL as its in the reverse path",
-                                  vid2string(vertex, buff, sizeof(buff)));
+                                  print_sys_hostname(n->id));
                }
                n->present = false;
        }
 
        n = neighbor_entry_lookup_hash(f->neighbors_neighbors, vertex->N.id);
        if (n) {
-               if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-                       char buff[PREFIX2STR_BUFFER];
+               if (isis->debugs & DEBUG_FLOODING) {
                        zlog_debug("Removing %s from NN as its in the reverse path",
-                                  vid2string(vertex, buff, sizeof(buff)));
+                                  print_sys_hostname(n->id));
                }
                n->present = false;
        }
 }
 
-void fabricd_lsp_flood(struct isis_lsp *lsp)
+static struct isis_lsp *lsp_for_neighbor(struct fabricd *f,
+                                        struct neighbor_entry *n)
 {
-       struct fabricd *f = lsp->area->fabricd;
-       assert(f);
+       uint8_t id[ISIS_SYS_ID_LEN + 1] = {0};
 
-       void *cursor = NULL;
-       struct neighbor_entry *n;
+       memcpy(id, n->id, sizeof(n->id));
 
-       if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-               zlog_debug("OpenFabric: Flooding LSP %s",
-                          rawlspid_print(lsp->hdr.lsp_id));
-       }
+       struct isis_vertex vertex = {0};
 
-       /* Mark all elements in NL as present and move T0s into DNR */
-       while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) {
-               n->present = true;
+       isis_vertex_id_init(&vertex, id, VTYPE_NONPSEUDO_TE_IS);
 
-               struct isis_lsp *node_lsp = lsp_for_vertex(f->spftree,
-                                                          n->vertex);
-               if (!node_lsp
-                   || !node_lsp->tlvs
-                   || !node_lsp->tlvs->spine_leaf
-                   || !node_lsp->tlvs->spine_leaf->has_tier
-                   || node_lsp->tlvs->spine_leaf->tier != 0) {
+       return lsp_for_vertex(f->spftree, &vertex);
+}
+
+static void fabricd_free_lsp_flooding_info(void *val)
+{
+       XFREE(MTYPE_FABRICD_FLOODING_INFO, val);
+}
+
+static void fabricd_lsp_reset_flooding_info(struct isis_lsp *lsp,
+                                           struct isis_circuit *circuit)
+{
+       lsp->flooding_time = time(NULL);
+
+       XFREE(MTYPE_FABRICD_FLOODING_INFO, lsp->flooding_interface);
+       for (enum isis_tx_type type = TX_LSP_NORMAL;
+            type <= TX_LSP_CIRCUIT_SCOPED; type++) {
+               if (lsp->flooding_neighbors[type]) {
+                       list_delete_all_node(lsp->flooding_neighbors[type]);
                        continue;
                }
 
-               if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-                       zlog_debug("Moving %s to DNR because it's T0",
-                                  rawlspid_print(node_lsp->hdr.lsp_id));
-               }
+               lsp->flooding_neighbors[type] = list_new();
+               lsp->flooding_neighbors[type]->del =
+                       fabricd_free_lsp_flooding_info;
+       }
 
-               move_to_dnr(lsp, n);
+       if (circuit) {
+               lsp->flooding_interface = XSTRDUP(MTYPE_FABRICD_FLOODING_INFO,
+                                                 circuit->interface->name);
        }
 
+       lsp->flooding_circuit_scoped = false;
+}
+
+void fabricd_lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
+{
+       struct fabricd *f = lsp->area->fabricd;
+       assert(f);
+
+       fabricd_lsp_reset_flooding_info(lsp, circuit);
+
+       void *cursor = NULL;
+       struct neighbor_entry *n;
+
+       /* Mark all elements in NL as present */
+       while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor))
+               n->present = true;
+
        /* Mark all elements in NN as present */
        hash_iterate(f->neighbors_neighbors, mark_neighbor_as_present, NULL);
 
-       struct isis_vertex *originator = isis_find_vertex(&f->spftree->paths,
-                                                         lsp->hdr.lsp_id,
-                                                         VTYPE_NONPSEUDO_TE_IS);
+       struct isis_vertex *originator =
+               isis_find_vertex(&f->spftree->paths,
+                                lsp->hdr.lsp_id,
+                                VTYPE_NONPSEUDO_TE_IS);
 
        /* Remove all IS from NL and NN in the shortest path
         * to the IS that originated the LSP */
@@ -621,22 +671,20 @@ void fabricd_lsp_flood(struct isis_lsp *lsp)
                if (!n->present)
                        continue;
 
-               struct isis_lsp *nlsp = lsp_for_vertex(f->spftree, n->vertex);
+               struct isis_lsp *nlsp = lsp_for_neighbor(f, n);
                if (!nlsp || !nlsp->tlvs) {
-                       if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-                               char buff[PREFIX2STR_BUFFER];
+                       if (isis->debugs & DEBUG_FLOODING) {
                                zlog_debug("Moving %s to DNR as it has no LSP",
-                                          vid2string(n->vertex, buff, sizeof(buff)));
+                                          print_sys_hostname(n->id));
                        }
 
-                       move_to_dnr(lsp, n);
+                       move_to_queue(lsp, n, TX_LSP_CIRCUIT_SCOPED, circuit);
                        continue;
                }
 
-               if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-                       char buff[PREFIX2STR_BUFFER];
+               if (isis->debugs & DEBUG_FLOODING) {
                        zlog_debug("Considering %s from NL...",
-                                  vid2string(n->vertex, buff, sizeof(buff)));
+                                  print_sys_hostname(n->id));
                }
 
                /* For all neighbors of the NL IS check whether they are present
@@ -651,10 +699,9 @@ void fabricd_lsp_flood(struct isis_lsp *lsp)
                                                        er->id);
 
                        if (nn) {
-                               if (isis->debugs & DEBUG_FABRICD_FLOODING) {
-                                       char buff[PREFIX2STR_BUFFER];
+                               if (isis->debugs & DEBUG_FLOODING) {
                                        zlog_debug("Found neighbor %s in NN, removing it from NN and setting reflood.",
-                                                  vid2string(nn->vertex, buff, sizeof(buff)));
+                                                  print_sys_hostname(nn->id));
                                }
 
                                nn->present = false;
@@ -662,24 +709,26 @@ void fabricd_lsp_flood(struct isis_lsp *lsp)
                        }
                }
 
-               if (need_reflood)
-                       move_to_rf(lsp, n);
-               else
-                       move_to_dnr(lsp, n);
+               move_to_queue(lsp, n, need_reflood ?
+                             TX_LSP_NORMAL : TX_LSP_CIRCUIT_SCOPED,
+                             circuit);
        }
 
-       if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+       if (isis->debugs & DEBUG_FLOODING) {
                zlog_debug("OpenFabric: Flooding algorithm complete.");
        }
 }
 
-void fabricd_trigger_csnp(struct isis_area *area)
+void fabricd_trigger_csnp(struct isis_area *area, bool circuit_scoped)
 {
        struct fabricd *f = area->fabricd;
 
        if (!f)
                return;
 
+       if (!circuit_scoped && !f->always_send_csnp)
+               return;
+
        struct listnode *node;
        struct isis_circuit *circuit;
 
@@ -689,7 +738,7 @@ void fabricd_trigger_csnp(struct isis_area *area)
 
                thread_cancel(circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
                thread_add_timer_msec(master, send_l2_csnp, circuit,
-                                     isis_jitter(500, CSNP_JITTER),
+                                     isis_jitter(f->csnp_delay, CSNP_JITTER),
                                      &circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
        }
 }
@@ -717,3 +766,43 @@ struct list *fabricd_ip_addrs(struct isis_circuit *circuit)
 
        return NULL;
 }
+
+void fabricd_lsp_free(struct isis_lsp *lsp)
+{
+       XFREE(MTYPE_FABRICD_FLOODING_INFO, lsp->flooding_interface);
+       for (enum isis_tx_type type = TX_LSP_NORMAL;
+            type <= TX_LSP_CIRCUIT_SCOPED; type++) {
+               if (!lsp->flooding_neighbors[type])
+                       continue;
+
+               list_delete(&lsp->flooding_neighbors[type]);
+       }
+}
+
+void fabricd_update_lsp_no_flood(struct isis_lsp *lsp,
+                                struct isis_circuit *circuit)
+{
+       if (!fabricd)
+               return;
+
+       fabricd_lsp_reset_flooding_info(lsp, circuit);
+       lsp->flooding_circuit_scoped = true;
+}
+
+void fabricd_configure_triggered_csnp(struct isis_area *area, int delay,
+                                     bool always_send_csnp)
+{
+       struct fabricd *f = area->fabricd;
+
+       if (!f)
+               return;
+
+       f->csnp_delay = delay;
+       f->always_send_csnp = always_send_csnp;
+}
+
+void fabricd_init(void)
+{
+       hook_register(isis_adj_state_change_hook,
+                     fabricd_handle_adj_state_change);
+}
index 76c182f2d27816e1b1fc5cb71ccc8584fbb80ba6..315cfba3f08e8f54820f0b51a028ddc2f9e59ce6 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef FABRICD_H
 #define FABRICD_H
 
+#define FABRICD_DEFAULT_CSNP_DELAY 500
+
 struct fabricd;
 
 struct isis_circuit;
@@ -42,8 +44,13 @@ struct isis_spftree *fabricd_spftree(struct isis_area *area);
 void fabricd_configure_tier(struct isis_area *area, uint8_t tier);
 uint8_t fabricd_tier(struct isis_area *area);
 int fabricd_write_settings(struct isis_area *area, struct vty *vty);
-void fabricd_lsp_flood(struct isis_lsp *lsp);
-void fabricd_trigger_csnp(struct isis_area *area);
+void fabricd_lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit);
+void fabricd_trigger_csnp(struct isis_area *area, bool circuit_scoped);
 struct list *fabricd_ip_addrs(struct isis_circuit *circuit);
-
+void fabricd_lsp_free(struct isis_lsp *lsp);
+void fabricd_update_lsp_no_flood(struct isis_lsp *lsp,
+                                struct isis_circuit *circuit);
+void fabricd_configure_triggered_csnp(struct isis_area *area, int delay,
+                                     bool always_send_csnp);
+void fabricd_init(void);
 #endif
index b0f2947ec6bbac2baa2506fc64701a83cfc2856f..e1cdfc30ea0abbde1d51e4992f1e491cab498e27 100644 (file)
@@ -258,6 +258,11 @@ void isis_adj_state_change(struct isis_adjacency *adj,
                        reason ? reason : "unspecified");
        }
 
+#ifndef FABRICD
+       /* send northbound notification */
+       isis_notif_adj_state_change(adj, new_state, reason);
+#endif /* ifndef FABRICD */
+
        if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
                del = false;
                for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
index 06385a4e1f5d7e47d112f988a4e1f2393b936abe..81b4b397ecb0eda77620eddc650fac68b0e02360 100644 (file)
@@ -38,6 +38,7 @@
 #include "prefix.h"
 #include "stream.h"
 #include "qobj.h"
+#include "lib/northbound_cli.h"
 
 #include "isisd/dict.h"
 #include "isisd/isis_constants.h"
@@ -78,6 +79,47 @@ struct isis_circuit *isis_circuit_new()
        /*
         * Default values
         */
+#ifndef FABRICD
+       circuit->is_type = yang_get_default_enum(
+               "/frr-interface:lib/interface/frr-isisd:isis/circuit-type");
+       circuit->flags = 0;
+
+       circuit->pad_hellos = yang_get_default_bool(
+               "/frr-interface:lib/interface/frr-isisd:isis/hello/padding");
+       circuit->hello_interval[0] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1");
+       circuit->hello_interval[1] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2");
+       circuit->hello_multiplier[0] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1");
+       circuit->hello_multiplier[1] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2");
+       circuit->csnp_interval[0] = yang_get_default_uint16(
+               "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1");
+       circuit->csnp_interval[1] = yang_get_default_uint16(
+               "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2");
+       circuit->psnp_interval[0] = yang_get_default_uint16(
+               "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1");
+       circuit->psnp_interval[1] = yang_get_default_uint16(
+               "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2");
+       circuit->priority[0] = yang_get_default_uint8(
+               "/frr-interface:lib/interface/frr-isisd:isis/priority/level-1");
+       circuit->priority[1] = yang_get_default_uint8(
+               "/frr-interface:lib/interface/frr-isisd:isis/priority/level-2");
+       circuit->metric[0] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1");
+       circuit->metric[1] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2");
+       circuit->te_metric[0] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1");
+       circuit->te_metric[1] = yang_get_default_uint32(
+               "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2");
+
+       for (i = 0; i < 2; i++) {
+               circuit->level_arg[i].level = i + 1;
+               circuit->level_arg[i].circuit = circuit;
+       }
+#else
        circuit->is_type = IS_LEVEL_1_AND_2;
        circuit->flags = 0;
        circuit->pad_hellos = 1;
@@ -92,6 +134,7 @@ struct isis_circuit *isis_circuit_new()
                circuit->level_arg[i].level = i + 1;
                circuit->level_arg[i].circuit = circuit;
        }
+#endif /* ifndef FABRICD */
 
        circuit->mtc = mpls_te_circuit_new();
 
@@ -666,11 +709,21 @@ int isis_circuit_up(struct isis_circuit *circuit)
 
        circuit->tx_queue = isis_tx_queue_new(circuit, send_lsp);
 
+#ifndef FABRICD
+       /* send northbound notification */
+       isis_notif_if_state_change(circuit, false);
+#endif /* ifndef FABRICD */
+
        return ISIS_OK;
 }
 
 void isis_circuit_down(struct isis_circuit *circuit)
 {
+#ifndef FABRICD
+       /* send northbound notification */
+       isis_notif_if_state_change(circuit, true);
+#endif /* ifndef FABRICD */
+
        /* Clear the flags for all the lsps of the circuit. */
        isis_circuit_update_all_srmflags(circuit, 0);
 
@@ -729,7 +782,6 @@ void isis_circuit_down(struct isis_circuit *circuit)
        THREAD_TIMER_OFF(circuit->t_send_csnp[1]);
        THREAD_TIMER_OFF(circuit->t_send_psnp[0]);
        THREAD_TIMER_OFF(circuit->t_send_psnp[1]);
-       THREAD_OFF(circuit->t_send_lsp);
        THREAD_OFF(circuit->t_read);
 
        if (circuit->tx_queue) {
@@ -920,6 +972,7 @@ DEFINE_HOOK(isis_circuit_config_write,
            (struct isis_circuit *circuit, struct vty *vty),
            (circuit, vty))
 
+#ifdef FABRICD
 int isis_interface_config_write(struct vty *vty)
 {
        struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
@@ -1142,6 +1195,33 @@ int isis_interface_config_write(struct vty *vty)
 
        return write;
 }
+#else
+int isis_interface_config_write(struct vty *vty)
+{
+       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+       int write = 0;
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+       struct lyd_node *dnode;
+
+       FOR_ALL_INTERFACES (vrf, ifp) {
+               dnode = yang_dnode_get(
+                       running_config->dnode,
+                       "/frr-interface:lib/interface[name='%s'][vrf='%s']",
+                       ifp->name, vrf->name);
+               if (dnode == NULL)
+                       continue;
+
+               write++;
+               nb_cli_show_dnode_cmds(vty, dnode, false);
+               circuit = circuit_scan_by_ifp(ifp);
+               if (circuit)
+                       write += hook_call(isis_circuit_config_write, circuit,
+                                          vty);
+       }
+       return write;
+}
+#endif /* ifdef FABRICD */
 
 struct isis_circuit *isis_circuit_create(struct isis_area *area,
                                         struct interface *ifp)
@@ -1262,35 +1342,22 @@ struct cmd_node interface_node = {
        INTERFACE_NODE, "%s(config-if)# ", 1,
 };
 
-ferr_r isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type)
+void isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type)
 {
        if (circuit->circ_type == circ_type)
-               return ferr_ok();
-
-       /* Changing the network type to/of loopback or unknown interfaces
-        * is not supported. */
-       if (circ_type == CIRCUIT_T_UNKNOWN || circ_type == CIRCUIT_T_LOOPBACK
-           || circuit->circ_type == CIRCUIT_T_LOOPBACK) {
-               return ferr_cfg_invalid(
-                       "cannot change network type on unknown interface");
-       }
+               return;
 
        if (circuit->state != C_STATE_UP) {
                circuit->circ_type = circ_type;
                circuit->circ_type_config = circ_type;
        } else {
                struct isis_area *area = circuit->area;
-               if (circ_type == CIRCUIT_T_BROADCAST
-                   && !if_is_broadcast(circuit->interface))
-                       return ferr_cfg_reality(
-                               "cannot configure non-broadcast interface for broadcast operation");
 
                isis_csm_state_change(ISIS_DISABLE, circuit, area);
                circuit->circ_type = circ_type;
                circuit->circ_type_config = circ_type;
                isis_csm_state_change(ISIS_ENABLE, circuit, area);
        }
-       return ferr_ok();
 }
 
 int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid,
index 7d7b25b92fd863b5456b7ed07b290c692a72f885..73ead8f7dab34abb0bf0aae7e69b086cfe1b2916 100644 (file)
@@ -86,7 +86,6 @@ struct isis_circuit {
        struct thread *t_read;
        struct thread *t_send_csnp[2];
        struct thread *t_send_psnp[2];
-       struct thread *t_send_lsp;
        struct isis_tx_queue *tx_queue;
        struct isis_circuit_arg level_arg[2]; /* used as argument for threads */
 
@@ -185,7 +184,7 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
                         bool ipv6_router);
 ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive);
 void isis_circuit_is_type_set(struct isis_circuit *circuit, int is_type);
-ferr_r isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type);
+void isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type);
 
 ferr_r isis_circuit_metric_set(struct isis_circuit *circuit, int level,
                               int metric);
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
new file mode 100644 (file)
index 0000000..c68f49f
--- /dev/null
@@ -0,0 +1,2024 @@
+/*
+ * Copyright (C) 2001,2002   Sampo Saaristo
+ *                           Tampere University of Technology
+ *                           Institute of Communications Engineering
+ * Copyright (C) 2018        Volta Networks
+ *                           Emanuele Di Pascale
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "if.h"
+#include "vrf.h"
+#include "log.h"
+#include "prefix.h"
+#include "command.h"
+#include "northbound_cli.h"
+#include "libfrr.h"
+#include "yang.h"
+#include "lib/linklist.h"
+#include "isisd/isisd.h"
+#include "isisd/isis_cli.h"
+#include "isisd/isis_misc.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_csm.h"
+
+#ifndef VTYSH_EXTRACT_PL
+#include "isisd/isis_cli_clippy.c"
+#endif
+
+#ifndef FABRICD
+
+/*
+ * XPath: /frr-isisd:isis/instance
+ */
+DEFPY_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag",
+          ROUTER_STR
+          "ISO IS-IS\n"
+          "ISO Routing area tag\n")
+{
+       int ret;
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, XPATH_MAXLEN,
+                "/frr-isisd:isis/instance[area-tag='%s']", tag);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       /* default value in yang for is-type is level-1, but in FRR
+        * the first instance is assigned is-type level-1-2. We
+        * need to make sure to set it in the yang model so that it
+        * is consistent with what FRR sees.
+        */
+       if (listcount(isis->area_list) == 0)
+               nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY,
+                                     "level-1-2");
+       ret = nb_cli_apply_changes(vty, base_xpath);
+       if (ret == CMD_SUCCESS)
+               VTY_PUSH_XPATH(ISIS_NODE, base_xpath);
+
+       return ret;
+}
+
+DEFPY(no_router_isis, no_router_isis_cmd, "no router isis WORD$tag",
+      NO_STR ROUTER_STR
+      "ISO IS-IS\n"
+      "ISO Routing area tag\n")
+{
+       char temp_xpath[XPATH_MAXLEN];
+       struct listnode *node, *nnode;
+       struct isis_circuit *circuit = NULL;
+       struct isis_area *area = NULL;
+
+       if (!yang_dnode_exists(vty->candidate_config->dnode,
+                              "/frr-isisd:isis/instance[area-tag='%s']",
+                              tag)) {
+               vty_out(vty, "ISIS area %s not found.\n", tag);
+               return CMD_ERR_NOTHING_TODO;
+       }
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+       area = isis_area_lookup(tag);
+       if (area && area->circuit_list && listcount(area->circuit_list)) {
+               for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
+                                      circuit)) {
+                       /* add callbacks to delete each of the circuits listed
+                        */
+                       const char *vrf_name =
+                               vrf_lookup_by_id(circuit->interface->vrf_id)
+                                       ->name;
+                       snprintf(
+                               temp_xpath, XPATH_MAXLEN,
+                               "/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis",
+                               circuit->interface->name, vrf_name);
+                       nb_cli_enqueue_change(vty, temp_xpath, NB_OP_DELETE,
+                                             NULL);
+               }
+       }
+
+       return nb_cli_apply_changes(
+               vty, "/frr-isisd:isis/instance[area-tag='%s']", tag);
+}
+
+void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
+                         bool show_defaults)
+{
+       vty_out(vty, "!\n");
+       vty_out(vty, "router isis %s\n",
+               yang_dnode_get_string(dnode, "./area-tag"));
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
+ * XPath: /frr-isisd:isis/instance
+ */
+DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag",
+      "Interface Internet Protocol config commands\n"
+      "IP router interface commands\n"
+      "IS-IS routing protocol\n"
+      "Routing process tag\n")
+{
+       char temp_xpath[XPATH_MAXLEN];
+       const char *circ_type;
+       struct isis_area *area;
+       struct interface *ifp;
+       const struct lyd_node *dnode =
+               yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
+
+       /* area will be created if it is not present. make sure the yang model
+        * is synced with FRR and call the appropriate NB cb.
+        */
+       area = isis_area_lookup(tag);
+       if (!area) {
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']", tag);
+               nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']/is-type",
+                        tag);
+               nb_cli_enqueue_change(
+                       vty, temp_xpath, NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
+                                     NB_OP_MODIFY, "true");
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2"
+                                                       : "level-1");
+       } else {
+               /* area exists, circuit type defaults to its area's is_type */
+               switch (area->is_type) {
+               case IS_LEVEL_1:
+                       circ_type = "level-1";
+                       break;
+               case IS_LEVEL_2:
+                       circ_type = "level-2";
+                       break;
+               case IS_LEVEL_1_AND_2:
+                       circ_type = "level-1-2";
+                       break;
+               default:
+                       /* just to silence compiler warnings */
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
+                                     NB_OP_MODIFY, "true");
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
+                                     NB_OP_MODIFY, circ_type);
+       }
+
+       /* check if the interface is a loopback and if so set it as passive */
+       ifp = yang_dnode_get_entry(dnode, false);
+       if (ifp && if_is_loopback(ifp))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
+                                     NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag",
+      "Interface Internet Protocol config commands\n"
+      "IP router interface commands\n"
+      "IS-IS routing protocol\n"
+      "Routing process tag\n")
+{
+       char temp_xpath[XPATH_MAXLEN];
+       const char *circ_type;
+       struct isis_area *area;
+       struct interface *ifp;
+       const struct lyd_node *dnode =
+               yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
+
+       /* area will be created if it is not present. make sure the yang model
+        * is synced with FRR and call the appropriate NB cb.
+        */
+       area = isis_area_lookup(tag);
+       if (!area) {
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']", tag);
+               nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']/is-type",
+                        tag);
+               nb_cli_enqueue_change(
+                       vty, temp_xpath, NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
+                                     NB_OP_MODIFY, "true");
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2"
+                                                       : "level-1");
+       } else {
+               /* area exists, circuit type defaults to its area's is_type */
+               switch (area->is_type) {
+               case IS_LEVEL_1:
+                       circ_type = "level-1";
+                       break;
+               case IS_LEVEL_2:
+                       circ_type = "level-2";
+                       break;
+               case IS_LEVEL_1_AND_2:
+                       circ_type = "level-1-2";
+                       break;
+               default:
+                       /* just to silence compiler warnings */
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
+                                     NB_OP_MODIFY, "true");
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
+                                     NB_OP_MODIFY, circ_type);
+       }
+
+       /* check if the interface is a loopback and if so set it as passive */
+       ifp = yang_dnode_get_entry(dnode, false);
+       if (ifp && if_is_loopback(ifp))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
+                                     NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_ip_router_isis, no_ip_router_isis_cmd,
+      "no <ip|ipv6>$ip router isis [WORD]$tag",
+      NO_STR
+      "Interface Internet Protocol config commands\n"
+      "IP router interface commands\n"
+      "IP router interface commands\n"
+      "IS-IS routing protocol\n"
+      "Routing process tag\n")
+{
+       const struct lyd_node *dnode =
+               yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
+
+       /* if both ipv4 and ipv6 are off delete the interface isis container too
+        */
+       if (!strncmp(ip, "ipv6", strlen("ipv6"))) {
+               if (dnode
+                   && !yang_dnode_get_bool(dnode,
+                                           "./frr-isisd:isis/ipv4-routing"))
+                       nb_cli_enqueue_change(vty, "./frr-isisd:isis",
+                                             NB_OP_DELETE, NULL);
+               else
+                       nb_cli_enqueue_change(vty,
+                                             "./frr-isisd:isis/ipv6-routing",
+                                             NB_OP_MODIFY, "false");
+       } else { /* no ipv4  */
+               if (dnode
+                   && !yang_dnode_get_bool(dnode,
+                                           "./frr-isisd:isis/ipv6-routing"))
+                       nb_cli_enqueue_change(vty, "./frr-isisd:isis",
+                                             NB_OP_DELETE, NULL);
+               else
+                       nb_cli_enqueue_change(vty,
+                                             "./frr-isisd:isis/ipv4-routing",
+                                             NB_OP_MODIFY, "false");
+       }
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " ip router isis %s\n",
+               yang_dnode_get_string(dnode, "../area-tag"));
+}
+
+void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " ipv6 router isis %s\n",
+               yang_dnode_get_string(dnode, "../area-tag"));
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/area-address
+ */
+DEFPY(net, net_cmd, "[no] net WORD",
+      "Remove an existing Network Entity Title for this process\n"
+      "A Network Entity Title for this process (OSI only)\n"
+      "XX.XXXX. ... .XXX.XX  Network entity title (NET)\n")
+{
+       nb_cli_enqueue_change(vty, "./area-address",
+                             no ? NB_OP_DELETE : NB_OP_CREATE, net);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       vty_out(vty, " net %s\n", yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/is-type
+ */
+DEFPY(is_type, is_type_cmd, "is-type <level-1|level-1-2|level-2-only>$level",
+      "IS Level for this routing process (OSI only)\n"
+      "Act as a station router only\n"
+      "Act as both a station router and an area router\n"
+      "Act as an area router only\n")
+{
+       nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY,
+                             strmatch(level, "level-2-only") ? "level-2"
+                                                             : level);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_is_type, no_is_type_cmd,
+      "no is-type [<level-1|level-1-2|level-2-only>]",
+      NO_STR
+      "IS Level for this routing process (OSI only)\n"
+      "Act as a station router only\n"
+      "Act as both a station router and an area router\n"
+      "Act as an area router only\n")
+{
+       const char *value = NULL;
+       const struct lyd_node *dnode =
+               yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
+       struct isis_area *area = yang_dnode_get_entry(dnode, false);
+
+       /*
+        * Put the is-type back to defaults:
+        * - level-1-2 on first area
+        * - level-1 for the rest
+        */
+       if (area && listgetdata(listhead(isis->area_list)) == area)
+               value = "level-1-2";
+       else
+               value = NULL;
+       nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, value);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_is_type(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       int is_type = yang_dnode_get_enum(dnode, NULL);
+
+       switch (is_type) {
+       case IS_LEVEL_1:
+               vty_out(vty, " is-type level-1\n");
+               break;
+       case IS_LEVEL_2:
+               vty_out(vty, " is-type level-2-only\n");
+               break;
+       case IS_LEVEL_1_AND_2:
+               vty_out(vty, " is-type level-1-2\n");
+               break;
+       }
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/dynamic-hostname
+ */
+DEFPY(dynamic_hostname, dynamic_hostname_cmd, "[no] hostname dynamic",
+      NO_STR
+      "Dynamic hostname for IS-IS\n"
+      "Dynamic hostname\n")
+{
+       nb_cli_enqueue_change(vty, "./dynamic-hostname", NB_OP_MODIFY,
+                             no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+
+       vty_out(vty, " hostname dynamic\n");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/overload
+ */
+DEFPY(set_overload_bit, set_overload_bit_cmd, "[no] set-overload-bit",
+      "Reset overload bit to accept transit traffic\n"
+      "Set overload bit to avoid any transit traffic\n")
+{
+       nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY,
+                             no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " set-overload-bit\n");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/attached
+ */
+DEFPY(set_attached_bit, set_attached_bit_cmd, "[no] set-attached-bit",
+      "Reset attached bit\n"
+      "Set attached bit to identify as L1/L2 router for inter-area traffic\n")
+{
+       nb_cli_enqueue_change(vty, "./attached", NB_OP_MODIFY,
+                             no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " set-attached-bit\n");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/metric-style
+ */
+DEFPY(metric_style, metric_style_cmd,
+      "metric-style <narrow|transition|wide>$style",
+      "Use old-style (ISO 10589) or new-style packet formats\n"
+      "Use old style of TLVs with narrow metric\n"
+      "Send and accept both styles of TLVs during transition\n"
+      "Use new style of TLVs to carry wider metric\n")
+{
+       nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, style);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_metric_style, no_metric_style_cmd,
+      "no metric-style [narrow|transition|wide]",
+      NO_STR
+      "Use old-style (ISO 10589) or new-style packet formats\n"
+      "Use old style of TLVs with narrow metric\n"
+      "Send and accept both styles of TLVs during transition\n"
+      "Use new style of TLVs to carry wider metric\n")
+{
+       nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, "narrow");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       int metric = yang_dnode_get_enum(dnode, NULL);
+
+       switch (metric) {
+       case ISIS_NARROW_METRIC:
+               vty_out(vty, " metric-style narrow\n");
+               break;
+       case ISIS_WIDE_METRIC:
+               vty_out(vty, " metric-style wide\n");
+               break;
+       case ISIS_TRANSITION_METRIC:
+               vty_out(vty, " metric-style transition\n");
+               break;
+       }
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/area-password
+ */
+DEFPY(area_passwd, area_passwd_cmd,
+      "area-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]",
+      "Configure the authentication password for an area\n"
+      "Clear-text authentication type\n"
+      "MD5 authentication type\n"
+      "Level-wide password\n"
+      "Authentication\n"
+      "SNP PDUs\n"
+      "Send but do not check PDUs on receiving\n"
+      "Send and check PDUs on receiving\n")
+{
+       nb_cli_enqueue_change(vty, "./area-password", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./area-password/password", NB_OP_MODIFY,
+                             pwd);
+       nb_cli_enqueue_change(vty, "./area-password/password-type",
+                             NB_OP_MODIFY, pwd_type);
+       nb_cli_enqueue_change(vty, "./area-password/authenticate-snp",
+                             NB_OP_MODIFY, snp ? snp : "none");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_area_pwd(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults)
+{
+       const char *snp;
+
+       vty_out(vty, " area-password %s %s",
+               yang_dnode_get_string(dnode, "./password-type"),
+               yang_dnode_get_string(dnode, "./password"));
+       snp = yang_dnode_get_string(dnode, "./authenticate-snp");
+       if (!strmatch("none", snp))
+               vty_out(vty, " authenticate snp %s", snp);
+       vty_out(vty, "\n");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/domain-password
+ */
+DEFPY(domain_passwd, domain_passwd_cmd,
+      "domain-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]",
+      "Set the authentication password for a routing domain\n"
+      "Clear-text authentication type\n"
+      "MD5 authentication type\n"
+      "Level-wide password\n"
+      "Authentication\n"
+      "SNP PDUs\n"
+      "Send but do not check PDUs on receiving\n"
+      "Send and check PDUs on receiving\n")
+{
+       nb_cli_enqueue_change(vty, "./domain-password", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./domain-password/password", NB_OP_MODIFY,
+                             pwd);
+       nb_cli_enqueue_change(vty, "./domain-password/password-type",
+                             NB_OP_MODIFY, pwd_type);
+       nb_cli_enqueue_change(vty, "./domain-password/authenticate-snp",
+                             NB_OP_MODIFY, snp ? snp : "none");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_area_passwd, no_area_passwd_cmd,
+      "no <area-password|domain-password>$cmd",
+      NO_STR
+      "Configure the authentication password for an area\n"
+      "Set the authentication password for a routing domain\n")
+{
+       nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+
+       return nb_cli_apply_changes(vty, "./%s", cmd);
+}
+
+void cli_show_isis_domain_pwd(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults)
+{
+       const char *snp;
+
+       vty_out(vty, " domain-password %s %s",
+               yang_dnode_get_string(dnode, "./password-type"),
+               yang_dnode_get_string(dnode, "./password"));
+       snp = yang_dnode_get_string(dnode, "./authenticate-snp");
+       if (!strmatch("none", snp))
+               vty_out(vty, " authenticate snp %s", snp);
+       vty_out(vty, "\n");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/generation-interval
+ */
+DEFPY(lsp_gen_interval, lsp_gen_interval_cmd,
+      "lsp-gen-interval [level-1|level-2]$level (1-120)$val",
+      "Minimum interval between regenerating same LSP\n"
+      "Set interval for level 1 only\n"
+      "Set interval for level 2 only\n"
+      "Minimum interval in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-1",
+                                     NB_OP_MODIFY, val_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-2",
+                                     NB_OP_MODIFY, val_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_lsp_gen_interval, no_lsp_gen_interval_cmd,
+      "no lsp-gen-interval [level-1|level-2]$level [(1-120)]",
+      NO_STR
+      "Minimum interval between regenerating same LSP\n"
+      "Set interval for level 1 only\n"
+      "Set interval for level 2 only\n"
+      "Minimum interval in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_lsp_gen_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " lsp-gen-interval %s\n", l1);
+       else {
+               vty_out(vty, " lsp-gen-interval level-1 %s\n", l1);
+               vty_out(vty, " lsp-gen-interval level-2 %s\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/refresh-interval
+ */
+DEFPY(lsp_refresh_interval, lsp_refresh_interval_cmd,
+      "lsp-refresh-interval [level-1|level-2]$level (1-65235)$val",
+      "LSP refresh interval\n"
+      "LSP refresh interval for Level 1 only\n"
+      "LSP refresh interval for Level 2 only\n"
+      "LSP refresh interval in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-1",
+                                     NB_OP_MODIFY, val_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-2",
+                                     NB_OP_MODIFY, val_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_lsp_refresh_interval, no_lsp_refresh_interval_cmd,
+      "no lsp-refresh-interval [level-1|level-2]$level [(1-65235)]",
+      NO_STR
+      "LSP refresh interval\n"
+      "LSP refresh interval for Level 1 only\n"
+      "LSP refresh interval for Level 2 only\n"
+      "LSP refresh interval in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_lsp_ref_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " lsp-refresh-interval %s\n", l1);
+       else {
+               vty_out(vty, " lsp-refresh-interval level-1 %s\n", l1);
+               vty_out(vty, " lsp-refresh-interval level-2 %s\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime
+ */
+DEFPY(max_lsp_lifetime, max_lsp_lifetime_cmd,
+      "max-lsp-lifetime [level-1|level-2]$level (350-65535)$val",
+      "Maximum LSP lifetime\n"
+      "Maximum LSP lifetime for Level 1 only\n"
+      "Maximum LSP lifetime for Level 2 only\n"
+      "LSP lifetime in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-1",
+                                     NB_OP_MODIFY, val_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-2",
+                                     NB_OP_MODIFY, val_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_max_lsp_lifetime, no_max_lsp_lifetime_cmd,
+      "no max-lsp-lifetime [level-1|level-2]$level [(350-65535)]",
+      NO_STR
+      "Maximum LSP lifetime\n"
+      "Maximum LSP lifetime for Level 1 only\n"
+      "Maximum LSP lifetime for Level 2 only\n"
+      "LSP lifetime in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_lsp_max_lifetime(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " max-lsp-lifetime %s\n", l1);
+       else {
+               vty_out(vty, " max-lsp-lifetime level-1 %s\n", l1);
+               vty_out(vty, " max-lsp-lifetime level-2 %s\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/mtu
+ */
+DEFPY(area_lsp_mtu, area_lsp_mtu_cmd, "lsp-mtu (128-4352)$val",
+      "Configure the maximum size of generated LSPs\n"
+      "Maximum size of generated LSPs\n")
+{
+       nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, val_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_area_lsp_mtu, no_area_lsp_mtu_cmd, "no lsp-mtu [(128-4352)]",
+      NO_STR
+      "Configure the maximum size of generated LSPs\n"
+      "Maximum size of generated LSPs\n")
+{
+       nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_lsp_mtu(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       vty_out(vty, " lsp-mtu %s\n", yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/minimum-interval
+ */
+DEFPY(spf_interval, spf_interval_cmd,
+      "spf-interval [level-1|level-2]$level (1-120)$val",
+      "Minimum interval between SPF calculations\n"
+      "Set interval for level 1 only\n"
+      "Set interval for level 2 only\n"
+      "Minimum interval between consecutive SPFs in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1",
+                                     NB_OP_MODIFY, val_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2",
+                                     NB_OP_MODIFY, val_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_spf_interval, no_spf_interval_cmd,
+      "no spf-interval [level-1|level-2]$level [(1-120)]",
+      NO_STR
+      "Minimum interval between SPF calculations\n"
+      "Set interval for level 1 only\n"
+      "Set interval for level 2 only\n"
+      "Minimum interval between consecutive SPFs in seconds\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_spf_min_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " spf-interval %s\n", l1);
+       else {
+               vty_out(vty, " spf-interval level-1 %s\n", l1);
+               vty_out(vty, " spf-interval level-2 %s\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
+ */
+DEFPY(spf_delay_ietf, spf_delay_ietf_cmd,
+      "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)",
+      "IETF SPF delay algorithm\n"
+      "Delay used while in QUIET state\n"
+      "Delay used while in QUIET state in milliseconds\n"
+      "Delay used while in SHORT_WAIT state\n"
+      "Delay used while in SHORT_WAIT state in milliseconds\n"
+      "Delay used while in LONG_WAIT\n"
+      "Delay used while in LONG_WAIT state in milliseconds\n"
+      "Time with no received IGP events before considering IGP stable\n"
+      "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
+      "Maximum duration needed to learn all the events related to a single failure\n"
+      "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
+{
+       nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_CREATE,
+                             NULL);
+       nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/init-delay",
+                             NB_OP_MODIFY, init_delay_str);
+       nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/short-delay",
+                             NB_OP_MODIFY, short_delay_str);
+       nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/long-delay",
+                             NB_OP_MODIFY, long_delay_str);
+       nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/hold-down",
+                             NB_OP_MODIFY, holddown_str);
+       nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/time-to-learn",
+                             NB_OP_MODIFY, time_to_learn_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_spf_delay_ietf, no_spf_delay_ietf_cmd,
+      "no spf-delay-ietf [init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)]",
+      NO_STR
+      "IETF SPF delay algorithm\n"
+      "Delay used while in QUIET state\n"
+      "Delay used while in QUIET state in milliseconds\n"
+      "Delay used while in SHORT_WAIT state\n"
+      "Delay used while in SHORT_WAIT state in milliseconds\n"
+      "Delay used while in LONG_WAIT\n"
+      "Delay used while in LONG_WAIT state in milliseconds\n"
+      "Time with no received IGP events before considering IGP stable\n"
+      "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
+      "Maximum duration needed to learn all the events related to a single failure\n"
+      "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
+{
+       nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_DELETE,
+                             NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_spf_ietf_backoff(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       vty_out(vty,
+               " spf-delay-ietf init-delay %s short-delay %s long-delay %s holddown %s time-to-learn %s\n",
+               yang_dnode_get_string(dnode, "./init-delay"),
+               yang_dnode_get_string(dnode, "./short-delay"),
+               yang_dnode_get_string(dnode, "./long-delay"),
+               yang_dnode_get_string(dnode, "./hold-down"),
+               yang_dnode_get_string(dnode, "./time-to-learn"));
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/purge-originator
+ */
+DEFPY(area_purge_originator, area_purge_originator_cmd, "[no] purge-originator",
+      NO_STR "Use the RFC 6232 purge-originator\n")
+{
+       nb_cli_enqueue_change(vty, "./purge-originator", NB_OP_MODIFY,
+                             no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_purge_origin(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " purge-originator\n");
+}
+
+/*
+ * XPath: /frr-isisd:isis/mpls-te
+ */
+DEFPY(isis_mpls_te_on, isis_mpls_te_on_cmd, "mpls-te on",
+      MPLS_TE_STR "Enable the MPLS-TE functionality\n")
+{
+       nb_cli_enqueue_change(vty, "/frr-isisd:isis/mpls-te", NB_OP_CREATE,
+                             NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_isis_mpls_te_on, no_isis_mpls_te_on_cmd, "no mpls-te [on]",
+      NO_STR
+      "Disable the MPLS-TE functionality\n"
+      "Enable the MPLS-TE functionality\n")
+{
+       nb_cli_enqueue_change(vty, "/frr-isisd:isis/mpls-te", NB_OP_DELETE,
+                             NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       vty_out(vty, "  mpls-te on\n");
+}
+
+/*
+ * XPath: /frr-isisd:isis/mpls-te/router-address
+ */
+DEFPY(isis_mpls_te_router_addr, isis_mpls_te_router_addr_cmd,
+      "mpls-te router-address A.B.C.D",
+      MPLS_TE_STR
+      "Stable IP address of the advertising router\n"
+      "MPLS-TE router address in IPv4 address format\n")
+{
+       nb_cli_enqueue_change(vty, "/frr-isisd:isis/mpls-te/router-address",
+                             NB_OP_MODIFY, router_address_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode,
+                                      bool show_defaults)
+{
+       vty_out(vty, "  mpls-te router-address %s\n",
+               yang_dnode_get_string(dnode, NULL));
+}
+
+DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd,
+      "[no] mpls-te inter-as [level-1|level-1-2|level-2-only]",
+      NO_STR MPLS_TE_STR
+      "Configure MPLS-TE Inter-AS support\n"
+      "AREA native mode self originate INTER-AS LSP with L1 only flooding scope\n"
+      "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope\n"
+      "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n")
+{
+       vty_out(vty, "MPLS-TE Inter-AS is not yet supported.");
+       return CMD_SUCCESS;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate
+ */
+DEFPY(isis_default_originate, isis_default_originate_cmd,
+      "[no] default-information originate <ipv4|ipv6>$ip"
+      " <level-1|level-2>$level [always]$always"
+      " [<metric (0-16777215)$metric|route-map WORD$rmap>]",
+      NO_STR
+      "Control distribution of default information\n"
+      "Distribute a default route\n"
+      "Distribute default route for IPv4\n"
+      "Distribute default route for IPv6\n"
+      "Distribute default route into level-1\n"
+      "Distribute default route into level-2\n"
+      "Always advertise default route\n"
+      "Metric for default route\n"
+      "ISIS default metric\n"
+      "Route map reference\n"
+      "Pointer to route-map entries\n")
+{
+       if (no)
+               nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+       else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./always", NB_OP_MODIFY,
+                                     always ? "true" : "false");
+               nb_cli_enqueue_change(vty, "./route-map",
+                                     rmap ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     rmap ? rmap : NULL);
+               nb_cli_enqueue_change(vty, "./metric",
+                                     metric ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     metric ? metric_str : NULL);
+               if (strmatch(ip, "ipv6") && !always) {
+                       vty_out(vty,
+                               "Zebra doesn't implement default-originate for IPv6 yet\n");
+                       vty_out(vty,
+                               "so use with care or use default-originate always.\n");
+               }
+       }
+
+       return nb_cli_apply_changes(
+               vty, "./default-information-originate/%s[level='%s']", ip,
+               level);
+}
+
+static void vty_print_def_origin(struct vty *vty, struct lyd_node *dnode,
+                                const char *family, const char *level,
+                                bool show_defaults)
+{
+       const char *metric;
+
+       vty_out(vty, " default-information originate %s %s", family, level);
+       if (yang_dnode_get_bool(dnode, "./always"))
+               vty_out(vty, " always");
+
+       if (yang_dnode_exists(dnode, "./route-map"))
+               vty_out(vty, " route-map %s",
+                       yang_dnode_get_string(dnode, "./route-map"));
+       else if (yang_dnode_exists(dnode, "./metric")) {
+               metric = yang_dnode_get_string(dnode, "./metric");
+               if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
+                       vty_out(vty, " metric %s", metric);
+       }
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       const char *level = yang_dnode_get_string(dnode, "./level");
+
+       vty_print_def_origin(vty, dnode, "ipv4", level, show_defaults);
+}
+
+void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       const char *level = yang_dnode_get_string(dnode, "./level");
+
+       vty_print_def_origin(vty, dnode, "ipv6", level, show_defaults);
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute
+ */
+DEFPY(isis_redistribute, isis_redistribute_cmd,
+      "[no] redistribute <ipv4|ipv6>$ip " PROTO_REDIST_STR
+      "$proto"
+      " <level-1|level-2>$level"
+      " [<metric (0-16777215)|route-map WORD>]",
+      NO_STR REDIST_STR
+      "Redistribute IPv4 routes\n"
+      "Redistribute IPv6 routes\n" PROTO_REDIST_HELP
+      "Redistribute into level-1\n"
+      "Redistribute into level-2\n"
+      "Metric for redistributed routes\n"
+      "ISIS default metric\n"
+      "Route map reference\n"
+      "Pointer to route-map entries\n")
+{
+       if (no)
+               nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+       else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./route-map",
+                                     route_map ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     route_map ? route_map : NULL);
+               nb_cli_enqueue_change(vty, "./metric",
+                                     metric ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     metric ? metric_str : NULL);
+       }
+
+       return nb_cli_apply_changes(
+               vty, "./redistribute/%s[protocol='%s'][level='%s']", ip, proto,
+               level);
+}
+
+static void vty_print_redistribute(struct vty *vty, struct lyd_node *dnode,
+                                  const char *family)
+{
+       const char *level = yang_dnode_get_string(dnode, "./level");
+       const char *protocol = yang_dnode_get_string(dnode, "./protocol");
+
+       vty_out(vty, " redistribute %s %s %s", family, protocol, level);
+       if (yang_dnode_exists(dnode, "./metric"))
+               vty_out(vty, " metric %s",
+                       yang_dnode_get_string(dnode, "./metric"));
+       else if (yang_dnode_exists(dnode, "./route-map"))
+               vty_out(vty, " route-map %s",
+                       yang_dnode_get_string(dnode, "./route-map"));
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults)
+{
+       vty_print_redistribute(vty, dnode, "ipv4");
+}
+void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults)
+{
+       vty_print_redistribute(vty, dnode, "ipv6");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology
+ */
+DEFPY(isis_topology, isis_topology_cmd,
+      "[no] topology "
+      "<ipv4-unicast"
+      "|ipv4-mgmt"
+      "|ipv6-unicast"
+      "|ipv4-multicast"
+      "|ipv6-multicast"
+      "|ipv6-mgmt"
+      "|ipv6-dstsrc>$topology "
+      "[overload]$overload",
+      NO_STR
+      "Configure IS-IS topologies\n"
+      "IPv4 unicast topology\n"
+      "IPv4 management topology\n"
+      "IPv6 unicast topology\n"
+      "IPv4 multicast topology\n"
+      "IPv6 multicast topology\n"
+      "IPv6 management topology\n"
+      "IPv6 dst-src topology\n"
+      "Set overload bit for topology\n")
+{
+       char base_xpath[XPATH_MAXLEN];
+
+       /* Since IPv4-unicast is not configurable it is not present in the
+        * YANG model, so we need to validate it here
+        */
+       if (strmatch(topology, "ipv4-unicast")) {
+               vty_out(vty, "Cannot configure IPv4 unicast topology\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (strmatch(topology, "ipv4-mgmt"))
+               snprintf(base_xpath, XPATH_MAXLEN,
+                        "./multi-topology/ipv4-management");
+       else if (strmatch(topology, "ipv6-mgmt"))
+               snprintf(base_xpath, XPATH_MAXLEN,
+                        "./multi-topology/ipv6-management");
+       else
+               snprintf(base_xpath, XPATH_MAXLEN, "./multi-topology/%s",
+                        topology);
+
+       if (no)
+               nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+       else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY,
+                                     overload ? "true" : "false");
+       }
+
+       return nb_cli_apply_changes(vty, base_xpath);
+}
+
+void cli_show_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults)
+{
+       vty_out(vty, " topology ipv4-multicast");
+       if (yang_dnode_get_bool(dnode, "./overload"))
+               vty_out(vty, " overload");
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       vty_out(vty, " topology ipv4-mgmt");
+       if (yang_dnode_get_bool(dnode, "./overload"))
+               vty_out(vty, " overload");
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       vty_out(vty, " topology ipv6-unicast");
+       if (yang_dnode_get_bool(dnode, "./overload"))
+               vty_out(vty, " overload");
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults)
+{
+       vty_out(vty, " topology ipv6-multicast");
+       if (yang_dnode_get_bool(dnode, "./overload"))
+               vty_out(vty, " overload");
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       vty_out(vty, " topology ipv6-mgmt");
+       if (yang_dnode_get_bool(dnode, "./overload"))
+               vty_out(vty, " overload");
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults)
+{
+       vty_out(vty, " topology ipv6-dstsrc");
+       if (yang_dnode_get_bool(dnode, "./overload"))
+               vty_out(vty, " overload");
+       vty_out(vty, "\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
+ */
+DEFPY(isis_passive, isis_passive_cmd, "[no] isis passive",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Configure the passive mode for interface\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive", NB_OP_MODIFY,
+                             no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_passive(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis passive\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
+ */
+
+DEFPY(isis_passwd, isis_passwd_cmd, "isis password <md5|clear>$type WORD$pwd",
+      "IS-IS routing protocol\n"
+      "Configure the authentication password for a circuit\n"
+      "HMAC-MD5 authentication\n"
+      "Cleartext password\n"
+      "Circuit password\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_CREATE,
+                             NULL);
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password",
+                             NB_OP_MODIFY, pwd);
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password-type",
+                             NB_OP_MODIFY, type);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_isis_passwd, no_isis_passwd_cmd, "no isis password [<md5|clear> WORD]",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Configure the authentication password for a circuit\n"
+      "HMAC-MD5 authentication\n"
+      "Cleartext password\n"
+      "Circuit password\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_DELETE,
+                             NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_password(struct vty *vty, struct lyd_node *dnode,
+                              bool show_defaults)
+{
+       vty_out(vty, " isis password %s %s\n",
+               yang_dnode_get_string(dnode, "./password-type"),
+               yang_dnode_get_string(dnode, "./password"));
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric
+ */
+DEFPY(isis_metric, isis_metric_cmd,
+      "isis metric [level-1|level-2]$level (0-16777215)$met",
+      "IS-IS routing protocol\n"
+      "Set default metric for circuit\n"
+      "Specify metric for level-1 routing\n"
+      "Specify metric for level-2 routing\n"
+      "Default metric value\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1",
+                                     NB_OP_MODIFY, met_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2",
+                                     NB_OP_MODIFY, met_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_isis_metric, no_isis_metric_cmd,
+      "no isis metric [level-1|level-2]$level [(0-16777215)]",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Set default metric for circuit\n"
+      "Specify metric for level-1 routing\n"
+      "Specify metric for level-2 routing\n"
+      "Default metric value\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_metric(struct vty *vty, struct lyd_node *dnode,
+                            bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " isis metric %s\n", l1);
+       else {
+               vty_out(vty, " isis metric %s level-1\n", l1);
+               vty_out(vty, " isis metric %s level-2\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval
+ */
+DEFPY(isis_hello_interval, isis_hello_interval_cmd,
+      "isis hello-interval [level-1|level-2]$level (1-600)$intv",
+      "IS-IS routing protocol\n"
+      "Set Hello interval\n"
+      "Specify hello-interval for level-1 IIHs\n"
+      "Specify hello-interval for level-2 IIHs\n"
+      "Holdtime 1 seconds, interval depends on multiplier\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/hello/interval/level-1",
+                                     NB_OP_MODIFY, intv_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/hello/interval/level-2",
+                                     NB_OP_MODIFY, intv_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_isis_hello_interval, no_isis_hello_interval_cmd,
+      "no isis hello-interval [level-1|level-2]$level [(1-600)]",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Set Hello interval\n"
+      "Specify hello-interval for level-1 IIHs\n"
+      "Specify hello-interval for level-2 IIHs\n"
+      "Holdtime 1 second, interval depends on multiplier\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/hello/interval/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/hello/interval/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_hello_interval(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " isis hello-interval %s\n", l1);
+       else {
+               vty_out(vty, " isis hello-interval %s level-1\n", l1);
+               vty_out(vty, " isis hello-interval %s level-2\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier
+ */
+DEFPY(isis_hello_multiplier, isis_hello_multiplier_cmd,
+      "isis hello-multiplier [level-1|level-2]$level (2-100)$mult",
+      "IS-IS routing protocol\n"
+      "Set multiplier for Hello holding time\n"
+      "Specify hello multiplier for level-1 IIHs\n"
+      "Specify hello multiplier for level-2 IIHs\n"
+      "Hello multiplier value\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/hello/multiplier/level-1",
+                       NB_OP_MODIFY, mult_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/hello/multiplier/level-2",
+                       NB_OP_MODIFY, mult_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_isis_hello_multiplier, no_isis_hello_multiplier_cmd,
+      "no isis hello-multiplier [level-1|level-2]$level [(2-100)]",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Set multiplier for Hello holding time\n"
+      "Specify hello multiplier for level-1 IIHs\n"
+      "Specify hello multiplier for level-2 IIHs\n"
+      "Hello multiplier value\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/hello/multiplier/level-1",
+                       NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/hello/multiplier/level-2",
+                       NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_hello_multi(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " isis hello-multiplier %s\n", l1);
+       else {
+               vty_out(vty, " isis hello-multiplier %s level-1\n", l1);
+               vty_out(vty, " isis hello-multiplier %s level-2\n", l2);
+       }
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
+ */
+DEFPY(isis_threeway_adj, isis_threeway_adj_cmd, "[no] isis three-way-handshake",
+      NO_STR
+      "IS-IS commands\n"
+      "Enable/Disable three-way handshake\n")
+{
+       nb_cli_enqueue_change(vty,
+                             "./frr-isisd:isis/disable-three-way-handshake",
+                             NB_OP_MODIFY, no ? "true" : "false");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_threeway_shake(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis three-way-handshake\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
+ */
+DEFPY(isis_hello_padding, isis_hello_padding_cmd, "[no] isis hello padding",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Add padding to IS-IS hello packets\n"
+      "Pad hello packets\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/hello/padding",
+                             NB_OP_MODIFY, no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_hello_padding(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+
+       vty_out(vty, " isis hello padding\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval
+ */
+DEFPY(csnp_interval, csnp_interval_cmd,
+      "isis csnp-interval (1-600)$intv [level-1|level-2]$level",
+      "IS-IS routing protocol\n"
+      "Set CSNP interval in seconds\n"
+      "CSNP interval value\n"
+      "Specify interval for level-1 CSNPs\n"
+      "Specify interval for level-2 CSNPs\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/csnp-interval/level-1",
+                                     NB_OP_MODIFY, intv_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/csnp-interval/level-2",
+                                     NB_OP_MODIFY, intv_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_csnp_interval, no_csnp_interval_cmd,
+      "no isis csnp-interval [(1-600)] [level-1|level-2]$level",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Set CSNP interval in seconds\n"
+      "CSNP interval value\n"
+      "Specify interval for level-1 CSNPs\n"
+      "Specify interval for level-2 CSNPs\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/csnp-interval/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/csnp-interval/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_csnp_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " isis csnp-interval %s\n", l1);
+       else {
+               vty_out(vty, " isis csnp-interval %s level-1\n", l1);
+               vty_out(vty, " isis csnp-interval %s level-2\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval
+ */
+DEFPY(psnp_interval, psnp_interval_cmd,
+      "isis psnp-interval (1-120)$intv [level-1|level-2]$level",
+      "IS-IS routing protocol\n"
+      "Set PSNP interval in seconds\n"
+      "PSNP interval value\n"
+      "Specify interval for level-1 PSNPs\n"
+      "Specify interval for level-2 PSNPs\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/psnp-interval/level-1",
+                                     NB_OP_MODIFY, intv_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/psnp-interval/level-2",
+                                     NB_OP_MODIFY, intv_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_psnp_interval, no_psnp_interval_cmd,
+      "no isis psnp-interval [(1-120)] [level-1|level-2]$level",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Set PSNP interval in seconds\n"
+      "PSNP interval value\n"
+      "Specify interval for level-1 PSNPs\n"
+      "Specify interval for level-2 PSNPs\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/psnp-interval/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty,
+                                     "./frr-isisd:isis/psnp-interval/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_psnp_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " isis psnp-interval %s\n", l1);
+       else {
+               vty_out(vty, " isis psnp-interval %s level-1\n", l1);
+               vty_out(vty, " isis psnp-interval %s level-2\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology
+ */
+DEFPY(circuit_topology, circuit_topology_cmd,
+      "[no] isis topology"
+      "<ipv4-unicast"
+      "|ipv4-mgmt"
+      "|ipv6-unicast"
+      "|ipv4-multicast"
+      "|ipv6-multicast"
+      "|ipv6-mgmt"
+      "|ipv6-dstsrc"
+      ">$topology",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Configure interface IS-IS topologies\n"
+      "IPv4 unicast topology\n"
+      "IPv4 management topology\n"
+      "IPv6 unicast topology\n"
+      "IPv4 multicast topology\n"
+      "IPv6 multicast topology\n"
+      "IPv6 management topology\n"
+      "IPv6 dst-src topology\n")
+{
+       nb_cli_enqueue_change(vty, ".", NB_OP_MODIFY, no ? "false" : "true");
+
+       if (strmatch(topology, "ipv4-mgmt"))
+               return nb_cli_apply_changes(
+                       vty, "./frr-isisd:isis/multi-topology/ipv4-management");
+       else if (strmatch(topology, "ipv6-mgmt"))
+               return nb_cli_apply_changes(
+                       vty, "./frr-isisd:isis/multi-topology/ipv6-management");
+       else
+               return nb_cli_apply_changes(
+                       vty, "./frr-isisd:isis/multi-topology/%s", topology);
+}
+
+void cli_show_ip_isis_mt_ipv4_unicast(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis topology ipv4-unicast\n");
+}
+
+void cli_show_ip_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode,
+                                       bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis topology ipv4-multicast\n");
+}
+
+void cli_show_ip_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis topology ipv4-mgmt\n");
+}
+
+void cli_show_ip_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis topology ipv6-unicast\n");
+}
+
+void cli_show_ip_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode,
+                                       bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis topology ipv6-multicast\n");
+}
+
+void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis topology ipv6-mgmt\n");
+}
+
+void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " isis topology ipv6-dstsrc\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
+ */
+DEFPY(isis_circuit_type, isis_circuit_type_cmd,
+      "isis circuit-type <level-1|level-1-2|level-2-only>$type",
+      "IS-IS routing protocol\n"
+      "Configure circuit type for interface\n"
+      "Level-1 only adjacencies are formed\n"
+      "Level-1-2 adjacencies are formed\n"
+      "Level-2 only adjacencies are formed\n")
+{
+       nb_cli_enqueue_change(
+               vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
+               strmatch(type, "level-2-only") ? "level-2" : type);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_isis_circuit_type, no_isis_circuit_type_cmd,
+      "no isis circuit-type [level-1|level-1-2|level-2-only]",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Configure circuit type for interface\n"
+      "Level-1 only adjacencies are formed\n"
+      "Level-1-2 adjacencies are formed\n"
+      "Level-2 only adjacencies are formed\n")
+{
+       const struct lyd_node *dnode;
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+       int is_type;
+       const char *circ_type;
+
+       /*
+        * Default value depends on whether the circuit is part of an area,
+        * and the is-type of the area if there is one. So we need to do this
+        * here.
+        */
+       dnode = yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
+       ifp = yang_dnode_get_entry(dnode, false);
+       if (!ifp)
+               goto def_val;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               goto def_val;
+
+       if (circuit->state == C_STATE_UP)
+               is_type = circuit->area->is_type;
+       else
+               goto def_val;
+
+       switch (is_type) {
+       case IS_LEVEL_1:
+               circ_type = "level-1";
+               break;
+       case IS_LEVEL_2:
+               circ_type = "level-2";
+               break;
+       case IS_LEVEL_1_AND_2:
+               circ_type = "level-1-2";
+               break;
+       default:
+               return CMD_ERR_NO_MATCH;
+       }
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
+                             NB_OP_MODIFY, circ_type);
+
+       return nb_cli_apply_changes(vty, NULL);
+
+def_val:
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
+                             NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       int level = yang_dnode_get_enum(dnode, NULL);
+
+       switch (level) {
+       case IS_LEVEL_1:
+               vty_out(vty, " isis circuit-type level-1\n");
+               break;
+       case IS_LEVEL_2:
+               vty_out(vty, " isis circuit-type level-2-only\n");
+               break;
+       case IS_LEVEL_1_AND_2:
+               vty_out(vty, " isis circuit-type level-1-2\n");
+               break;
+       }
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
+ */
+DEFPY(isis_network, isis_network_cmd, "[no] isis network point-to-point",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Set network type\n"
+      "point-to-point network type\n")
+{
+       nb_cli_enqueue_change(vty, "./frr-isisd:isis/network-type",
+                             NB_OP_MODIFY,
+                             no ? "broadcast" : "point-to-point");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       if (yang_dnode_get_enum(dnode, NULL) != CIRCUIT_T_P2P)
+               vty_out(vty, " no");
+
+       vty_out(vty, " isis network point-to-point\n");
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority
+ */
+DEFPY(isis_priority, isis_priority_cmd,
+      "isis priority (0-127)$prio [level-1|level-2]$level",
+      "IS-IS routing protocol\n"
+      "Set priority for Designated Router election\n"
+      "Priority value\n"
+      "Specify priority for level-1 routing\n"
+      "Specify priority for level-2 routing\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1",
+                                     NB_OP_MODIFY, prio_str);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2",
+                                     NB_OP_MODIFY, prio_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_isis_priority, no_isis_priority_cmd,
+      "no isis priority [(0-127)] [level-1|level-2]$level",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Set priority for Designated Router election\n"
+      "Priority value\n"
+      "Specify priority for level-1 routing\n"
+      "Specify priority for level-2 routing\n")
+{
+       if (!level || strmatch(level, "level-1"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1",
+                                     NB_OP_MODIFY, NULL);
+       if (!level || strmatch(level, "level-2"))
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2",
+                                     NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode,
+                              bool show_defaults)
+{
+       const char *l1 = yang_dnode_get_string(dnode, "./level-1");
+       const char *l2 = yang_dnode_get_string(dnode, "./level-2");
+
+       if (strmatch(l1, l2))
+               vty_out(vty, " isis priority %s\n", l1);
+       else {
+               vty_out(vty, " isis priority %s level-1\n", l1);
+               vty_out(vty, " isis priority %s level-2\n", l2);
+       }
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/log-adjacency-changes
+ */
+DEFPY(log_adj_changes, log_adj_changes_cmd, "[no] log-adjacency-changes",
+      NO_STR "Log changes in adjacency state\n")
+{
+       nb_cli_enqueue_change(vty, "./log-adjacency-changes", NB_OP_MODIFY,
+                             no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_log_adjacency(struct vty *vty, struct lyd_node *dnode,
+                                bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+       vty_out(vty, " log-adjacency-changes\n");
+}
+
+void isis_cli_init(void)
+{
+       install_element(CONFIG_NODE, &router_isis_cmd);
+       install_element(CONFIG_NODE, &no_router_isis_cmd);
+
+       install_element(INTERFACE_NODE, &ip_router_isis_cmd);
+       install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
+       install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
+
+       install_element(ISIS_NODE, &net_cmd);
+
+       install_element(ISIS_NODE, &is_type_cmd);
+       install_element(ISIS_NODE, &no_is_type_cmd);
+
+       install_element(ISIS_NODE, &dynamic_hostname_cmd);
+
+       install_element(ISIS_NODE, &set_overload_bit_cmd);
+       install_element(ISIS_NODE, &set_attached_bit_cmd);
+
+       install_element(ISIS_NODE, &metric_style_cmd);
+       install_element(ISIS_NODE, &no_metric_style_cmd);
+
+       install_element(ISIS_NODE, &area_passwd_cmd);
+       install_element(ISIS_NODE, &domain_passwd_cmd);
+       install_element(ISIS_NODE, &no_area_passwd_cmd);
+
+       install_element(ISIS_NODE, &lsp_gen_interval_cmd);
+       install_element(ISIS_NODE, &no_lsp_gen_interval_cmd);
+       install_element(ISIS_NODE, &lsp_refresh_interval_cmd);
+       install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd);
+       install_element(ISIS_NODE, &max_lsp_lifetime_cmd);
+       install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd);
+       install_element(ISIS_NODE, &area_lsp_mtu_cmd);
+       install_element(ISIS_NODE, &no_area_lsp_mtu_cmd);
+
+       install_element(ISIS_NODE, &spf_interval_cmd);
+       install_element(ISIS_NODE, &no_spf_interval_cmd);
+       install_element(ISIS_NODE, &spf_delay_ietf_cmd);
+       install_element(ISIS_NODE, &no_spf_delay_ietf_cmd);
+
+       install_element(ISIS_NODE, &area_purge_originator_cmd);
+
+       install_element(ISIS_NODE, &isis_mpls_te_on_cmd);
+       install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd);
+       install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd);
+       install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd);
+
+       install_element(ISIS_NODE, &isis_default_originate_cmd);
+       install_element(ISIS_NODE, &isis_redistribute_cmd);
+
+       install_element(ISIS_NODE, &isis_topology_cmd);
+
+       install_element(INTERFACE_NODE, &isis_passive_cmd);
+
+       install_element(INTERFACE_NODE, &isis_passwd_cmd);
+       install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
+
+       install_element(INTERFACE_NODE, &isis_metric_cmd);
+       install_element(INTERFACE_NODE, &no_isis_metric_cmd);
+
+       install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
+       install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
+
+       install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
+       install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
+
+       install_element(INTERFACE_NODE, &isis_threeway_adj_cmd);
+
+       install_element(INTERFACE_NODE, &isis_hello_padding_cmd);
+
+       install_element(INTERFACE_NODE, &csnp_interval_cmd);
+       install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
+
+       install_element(INTERFACE_NODE, &psnp_interval_cmd);
+       install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
+
+       install_element(INTERFACE_NODE, &circuit_topology_cmd);
+
+       install_element(INTERFACE_NODE, &isis_circuit_type_cmd);
+       install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd);
+
+       install_element(INTERFACE_NODE, &isis_network_cmd);
+
+       install_element(INTERFACE_NODE, &isis_priority_cmd);
+       install_element(INTERFACE_NODE, &no_isis_priority_cmd);
+
+       install_element(ISIS_NODE, &log_adj_changes_cmd);
+}
+
+#endif /* ifndef FABRICD */
diff --git a/isisd/isis_cli.h b/isisd/isis_cli.h
new file mode 100644 (file)
index 0000000..8dadf60
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2018       Volta Networks
+ *                          Emanuele Di Pascale
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef ISISD_ISIS_CLI_H_
+#define ISISD_ISIS_CLI_H_
+
+/* add cli_show declarations here as externs */
+void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
+                         bool show_defaults);
+void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults);
+void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults);
+void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults);
+void cli_show_isis_is_type(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults);
+void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults);
+void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults);
+void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults);
+void cli_show_isis_area_pwd(struct vty *vty, struct lyd_node *dnode,
+                           bool show_defaults);
+void cli_show_isis_domain_pwd(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults);
+void cli_show_isis_lsp_gen_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_isis_lsp_ref_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_isis_lsp_max_lifetime(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_isis_lsp_mtu(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults);
+void cli_show_isis_spf_min_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_isis_spf_ietf_backoff(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_isis_purge_origin(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults);
+void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults);
+void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode,
+                                      bool show_defaults);
+void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+void cli_show_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults);
+void cli_show_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+void cli_show_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults);
+void cli_show_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults);
+void cli_show_ip_isis_passive(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults);
+void cli_show_ip_isis_password(struct vty *vty, struct lyd_node *dnode,
+                              bool show_defaults);
+void cli_show_ip_isis_metric(struct vty *vty, struct lyd_node *dnode,
+                            bool show_defaults);
+void cli_show_ip_isis_hello_interval(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+void cli_show_ip_isis_hello_multi(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults);
+void cli_show_ip_isis_threeway_shake(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+void cli_show_ip_isis_hello_padding(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_ip_isis_csnp_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_ip_isis_psnp_interval(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_ip_isis_mt_ipv4_unicast(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults);
+void cli_show_ip_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode,
+                                       bool show_defaults);
+void cli_show_ip_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_ip_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults);
+void cli_show_ip_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode,
+                                       bool show_defaults);
+void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
+void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults);
+void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode,
+                              bool show_defaults);
+void cli_show_isis_log_adjacency(struct vty *vty, struct lyd_node *dnode,
+                                bool show_defaults);
+
+#endif /* ISISD_ISIS_CLI_H_ */
index 9a57d0d0ac2f522cba654e01bb40e9ac10873257..658624370b9ed0a3af7b5768779051ef03aa3866 100644 (file)
@@ -143,6 +143,8 @@ static void lsp_destroy(struct isis_lsp *lsp)
 
        if (lsp->pdu)
                stream_free(lsp->pdu);
+
+       fabricd_lsp_free(lsp);
        XFREE(MTYPE_ISIS_LSP, lsp);
 }
 
@@ -353,6 +355,15 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno)
        else
                newseq = seqno + 1;
 
+#ifndef FABRICD
+       /* check for overflow */
+       if (newseq < lsp->hdr.seqno) {
+               /* send northbound notification */
+               isis_notif_lsp_exceed_max(lsp->area,
+                                         rawlspid_print(lsp->hdr.lsp_id));
+       }
+#endif /* ifndef FABRICD */
+
        lsp->hdr.seqno = newseq;
 
        lsp_pack_pdu(lsp);
@@ -384,6 +395,7 @@ static void lsp_purge(struct isis_lsp *lsp, int level,
        lsp->hdr.rem_lifetime = 0;
        lsp->level = level;
        lsp->age_out = lsp->area->max_lsp_lifetime[level - 1];
+       lsp->area->lsp_purge_count[level - 1]++;
 
        lsp_purge_add_poi(lsp, sender);
 
@@ -611,7 +623,7 @@ static void lsp_set_time(struct isis_lsp *lsp)
                stream_putw_at(lsp->pdu, 10, lsp->hdr.rem_lifetime);
 }
 
-static void lspid_print(uint8_t *lsp_id, uint8_t *trg, char dynhost, char frag)
+void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag)
 {
        struct isis_dynhn *dyn = NULL;
        uint8_t id[SYSID_STRLEN];
@@ -628,10 +640,10 @@ static void lspid_print(uint8_t *lsp_id, uint8_t *trg, char dynhost, char frag)
        else
                memcpy(id, sysid_print(lsp_id), 15);
        if (frag)
-               sprintf((char *)trg, "%s.%02x-%02x", id, LSP_PSEUDO_ID(lsp_id),
+               sprintf(dest, "%s.%02x-%02x", id, LSP_PSEUDO_ID(lsp_id),
                        LSP_FRAGMENT(lsp_id));
        else
-               sprintf((char *)trg, "%s.%02x", id, LSP_PSEUDO_ID(lsp_id));
+               sprintf(dest, "%s.%02x", id, LSP_PSEUDO_ID(lsp_id));
 }
 
 /* Convert the lsp attribute bits to attribute string */
@@ -660,7 +672,7 @@ static const char *lsp_bits2string(uint8_t lsp_bits, char *buf, size_t buf_size)
 /* this function prints the lsp on show isis database */
 void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost)
 {
-       uint8_t LSPid[255];
+       char LSPid[255];
        char age_out[8];
        char b[200];
 
@@ -1238,6 +1250,7 @@ int lsp_generate(struct isis_area *area, int level)
        lsp_seqno_update(newlsp);
        newlsp->last_generated = time(NULL);
        lsp_flood(newlsp, NULL);
+       area->lsp_gen_count[level - 1]++;
 
        refresh_time = lsp_refresh_time(newlsp, rem_lifetime);
 
@@ -1261,6 +1274,12 @@ int lsp_generate(struct isis_area *area, int level)
                "ISIS (%s): Built L%d LSP. Set triggered regenerate to non-pending.",
                area->area_tag, level);
 
+#ifndef FABRICD
+       /* send northbound notification */
+       isis_notif_lsp_gen(area, rawlspid_print(newlsp->hdr.lsp_id),
+                          newlsp->hdr.seqno, newlsp->last_generated);
+#endif /* ifndef FABRICD */
+
        return ISIS_OK;
 }
 
@@ -1298,6 +1317,7 @@ static int lsp_regenerate(struct isis_area *area, int level)
        lsp->hdr.rem_lifetime = rem_lifetime;
        lsp->last_generated = time(NULL);
        lsp_flood(lsp, NULL);
+       area->lsp_gen_count[level - 1]++;
        for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
                if (!frag->tlvs) {
                        /* Updating and flooding should only affect fragments
@@ -1962,6 +1982,7 @@ void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
        lsp->level = level;
        lsp_adjust_stream(lsp);
        lsp->age_out = ZERO_AGE_LIFETIME;
+       lsp->area->lsp_purge_count[level - 1]++;
 
        memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr));
        lsp->hdr.rem_lifetime = 0;
@@ -1997,12 +2018,21 @@ void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set)
        }
 }
 
-void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
+void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit,
+               const char *func, const char *file, int line)
 {
+       if (isis->debugs & DEBUG_FLOODING) {
+               zlog_debug("Flooding LSP %s%s%s (From %s %s:%d)",
+                          rawlspid_print(lsp->hdr.lsp_id),
+                          circuit ? " except on " : "",
+                          circuit ? circuit->interface->name : "",
+                          func, file, line);
+       }
+
        if (!fabricd)
                lsp_set_all_srmflags(lsp, true);
        else
-               fabricd_lsp_flood(lsp);
+               fabricd_lsp_flood(lsp, circuit);
 
        if (circuit)
                isis_tx_queue_del(circuit->tx_queue, lsp);
index 2b45e6994ce1179887156cc90233e90876a0e531..e6ea0b4eda7f47b3849a73b93c7e003b7f81e0cc 100644 (file)
@@ -47,6 +47,11 @@ struct isis_lsp {
        int age_out;
        struct isis_area *area;
        struct isis_tlvs *tlvs;
+
+       time_t flooding_time;
+       struct list *flooding_neighbors[TX_LSP_CIRCUIT_SCOPED + 1];
+       char *flooding_interface;
+       bool flooding_circuit_scoped;
 };
 
 dict_t *lsp_db_init(void);
@@ -100,12 +105,17 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
                struct isis_tlvs *tlvs, struct stream *stream,
                struct isis_area *area, int level, bool confusion);
 void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno);
+void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag);
 void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost);
 void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost);
 int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost);
 /* sets SRMflags for all active circuits of an lsp */
 void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);
-void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit);
+
+#define lsp_flood(lsp, circuit) \
+       _lsp_flood((lsp), (circuit), __func__, __FILE__, __LINE__)
+void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit,
+               const char *func, const char *file, int line);
 void lsp_init(void);
 
 #endif /* ISIS_LSP */
index 2d540348e450fbfb689d569be48bf7060b04bb34..9126e40d4233a0fd0d1dbbe47975cbc929812ecd 100644 (file)
@@ -58,6 +58,7 @@
 #include "isisd/isis_bfd.h"
 #include "isisd/isis_lsp.h"
 #include "isisd/isis_mt.h"
+#include "isisd/fabricd.h"
 
 /* Default configuration file name */
 #define ISISD_DEFAULT_CONFIG "isisd.conf"
@@ -106,12 +107,23 @@ static __attribute__((__noreturn__)) void terminate(int i)
 /*
  * Signal handlers
  */
-
+#ifdef FABRICD
 void sighup(void)
 {
-       zlog_notice("SIGHUP/reload is not implemented for isisd");
+       zlog_notice("SIGHUP/reload is not implemented for fabricd");
        return;
 }
+#else
+static struct frr_daemon_info isisd_di;
+void sighup(void)
+{
+       zlog_info("SIGHUP received");
+
+       /* Reload config file. */
+       vty_read_config(NULL, isisd_di.config_file, config_default);
+}
+
+#endif
 
 __attribute__((__noreturn__)) void sigint(void)
 {
@@ -150,8 +162,12 @@ struct quagga_signal_t isisd_signals[] = {
        },
 };
 
+
 static const struct frr_yang_module_info *isisd_yang_modules[] = {
        &frr_interface_info,
+#ifndef FABRICD
+       &frr_isisd_info,
+#endif /* ifndef FABRICD */
 };
 
 #ifdef FABRICD
@@ -216,6 +232,9 @@ int main(int argc, char **argv, char **envp)
        isis_init();
        isis_circuit_init();
        isis_vty_init();
+#ifndef FABRICD
+       isis_cli_init();
+#endif /* ifdef FABRICD */
        isis_spf_cmds_init();
        isis_redist_init();
        isis_route_map_init();
@@ -228,6 +247,7 @@ int main(int argc, char **argv, char **envp)
 
        isis_zebra_init(master);
        isis_bfd_init();
+       fabricd_init();
 
        frr_config_fork();
        frr_run(master);
diff --git a/isisd/isis_northbound.c b/isisd/isis_northbound.c
new file mode 100644 (file)
index 0000000..a467282
--- /dev/null
@@ -0,0 +1,3233 @@
+/*
+ * Copyright (C) 2001,2002   Sampo Saaristo
+ *                           Tampere University of Technology
+ *                           Institute of Communications Engineering
+ * Copyright (C) 2018        Volta Networks
+ *                           Emanuele Di Pascale
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+#include "northbound.h"
+#include "libfrr.h"
+#include "linklist.h"
+#include "log.h"
+#include "isisd/dict.h"
+#include "isisd/isis_constants.h"
+#include "isisd/isis_common.h"
+#include "isisd/isis_flags.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isisd.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_pdu.h"
+#include "isisd/isis_dynhn.h"
+#include "isisd/isis_misc.h"
+#include "isisd/isis_csm.h"
+#include "isisd/isis_adjacency.h"
+#include "isisd/isis_spf.h"
+#include "isisd/isis_te.h"
+#include "isisd/isis_memory.h"
+#include "isisd/isis_mt.h"
+#include "isisd/isis_cli.h"
+#include "isisd/isis_redist.h"
+#include "lib/spf_backoff.h"
+#include "lib/lib_errors.h"
+#include "lib/vrf.h"
+
+/*
+ * XPath: /frr-isisd:isis/instance
+ */
+static int isis_instance_create(enum nb_event event,
+                               const struct lyd_node *dnode,
+                               union nb_resource *resource)
+{
+       struct isis_area *area;
+       const char *area_tag;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area_tag = yang_dnode_get_string(dnode, "./area-tag");
+       area = isis_area_lookup(area_tag);
+       if (area)
+               return NB_ERR_INCONSISTENCY;
+
+       area = isis_area_create(area_tag);
+       /* save area in dnode to avoid looking it up all the time */
+       yang_dnode_set_entry(dnode, area);
+
+       return NB_OK;
+}
+
+static int isis_instance_delete(enum nb_event event,
+                               const struct lyd_node *dnode)
+{
+       const char *area_tag;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area_tag = yang_dnode_get_string(dnode, "./area-tag");
+       isis_area_destroy(area_tag);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/is-type
+ */
+static int isis_instance_is_type_modify(enum nb_event event,
+                                       const struct lyd_node *dnode,
+                                       union nb_resource *resource)
+{
+       struct isis_area *area;
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       type = yang_dnode_get_enum(dnode, NULL);
+       isis_area_is_type_set(area, type);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/area-address
+ */
+static int isis_instance_area_address_create(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       struct isis_area *area;
+       struct area_addr addr, *addrr = NULL, *addrp = NULL;
+       struct listnode *node;
+       uint8_t buff[255];
+       const char *net_title = yang_dnode_get_string(dnode, NULL);
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               addr.addr_len = dotformat2buff(buff, net_title);
+               memcpy(addr.area_addr, buff, addr.addr_len);
+               if (addr.area_addr[addr.addr_len - 1] != 0) {
+                       flog_warn(
+                               EC_LIB_NB_CB_CONFIG_VALIDATE,
+                               "nsel byte (last byte) in area address must be 0");
+                       return NB_ERR_VALIDATION;
+               }
+               if (isis->sysid_set) {
+                       /* Check that the SystemID portions match */
+                       if (memcmp(isis->sysid, GETSYSID((&addr)),
+                                  ISIS_SYS_ID_LEN)) {
+                               flog_warn(
+                                       EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                       "System ID must not change when defining additional area addresses");
+                               return NB_ERR_VALIDATION;
+                       }
+               }
+               break;
+       case NB_EV_PREPARE:
+               addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
+               addrr->addr_len = dotformat2buff(buff, net_title);
+               memcpy(addrr->area_addr, buff, addrr->addr_len);
+               resource->ptr = addrr;
+               break;
+       case NB_EV_ABORT:
+               XFREE(MTYPE_ISIS_AREA_ADDR, resource->ptr);
+               break;
+       case NB_EV_APPLY:
+               area = yang_dnode_get_entry(dnode, true);
+               addrr = resource->ptr;
+
+               if (isis->sysid_set == 0) {
+                       /*
+                        * First area address - get the SystemID for this router
+                        */
+                       memcpy(isis->sysid, GETSYSID(addrr), ISIS_SYS_ID_LEN);
+                       isis->sysid_set = 1;
+               } else {
+                       /* check that we don't already have this address */
+                       for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node,
+                                                 addrp)) {
+                               if ((addrp->addr_len + ISIS_SYS_ID_LEN
+                                    + ISIS_NSEL_LEN)
+                                   != (addrr->addr_len))
+                                       continue;
+                               if (!memcmp(addrp->area_addr, addrr->area_addr,
+                                           addrr->addr_len)) {
+                                       XFREE(MTYPE_ISIS_AREA_ADDR, addrr);
+                                       return NB_OK; /* silent fail */
+                               }
+                       }
+               }
+
+               /*Forget the systemID part of the address */
+               addrr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN);
+               assert(area->area_addrs); /* to silence scan-build sillyness */
+               listnode_add(area->area_addrs, addrr);
+
+               /* only now we can safely generate our LSPs for this area */
+               if (listcount(area->area_addrs) > 0) {
+                       if (area->is_type & IS_LEVEL_1)
+                               lsp_generate(area, IS_LEVEL_1);
+                       if (area->is_type & IS_LEVEL_2)
+                               lsp_generate(area, IS_LEVEL_2);
+               }
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int isis_instance_area_address_delete(enum nb_event event,
+                                            const struct lyd_node *dnode)
+{
+       struct area_addr addr, *addrp = NULL;
+       struct listnode *node;
+       uint8_t buff[255];
+       struct isis_area *area;
+       const char *net_title;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       net_title = yang_dnode_get_string(dnode, NULL);
+       addr.addr_len = dotformat2buff(buff, net_title);
+       memcpy(addr.area_addr, buff, (int)addr.addr_len);
+       area = yang_dnode_get_entry(dnode, true);
+       for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
+               if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
+                   && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
+                       break;
+       }
+       if (!addrp)
+               return NB_ERR_INCONSISTENCY;
+
+       listnode_delete(area->area_addrs, addrp);
+       XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
+       /*
+        * Last area address - reset the SystemID for this router
+        */
+       if (listcount(area->area_addrs) == 0) {
+               memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
+               isis->sysid_set = 0;
+               if (isis->debugs & DEBUG_EVENTS)
+                       zlog_debug("Router has no SystemID");
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/dynamic-hostname
+ */
+static int isis_instance_dynamic_hostname_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       isis_area_dynhostname_set(area, yang_dnode_get_bool(dnode, NULL));
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/attached
+ */
+static int isis_instance_attached_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct isis_area *area;
+       bool attached;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       attached = yang_dnode_get_bool(dnode, NULL);
+       isis_area_attached_bit_set(area, attached);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/overload
+ */
+static int isis_instance_overload_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct isis_area *area;
+       bool overload;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       overload = yang_dnode_get_bool(dnode, NULL);
+       isis_area_overload_bit_set(area, overload);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/metric-style
+ */
+static int isis_instance_metric_style_modify(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       struct isis_area *area;
+       bool old_metric, new_metric;
+       enum isis_metric_style metric_style = yang_dnode_get_enum(dnode, NULL);
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       old_metric = (metric_style == ISIS_WIDE_METRIC) ? false : true;
+       new_metric = (metric_style == ISIS_NARROW_METRIC) ? false : true;
+       isis_area_metricstyle_set(area, old_metric, new_metric);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/purge-originator
+ */
+static int isis_instance_purge_originator_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       area->purge_originator = yang_dnode_get_bool(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/mtu
+ */
+static int isis_instance_lsp_mtu_modify(enum nb_event event,
+                                       const struct lyd_node *dnode,
+                                       union nb_resource *resource)
+{
+       struct listnode *node;
+       struct isis_circuit *circuit;
+       uint16_t lsp_mtu = yang_dnode_get_uint16(dnode, NULL);
+       struct isis_area *area;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               area = yang_dnode_get_entry(dnode, false);
+               if (!area)
+                       break;
+               for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
+                       if (circuit->state != C_STATE_INIT
+                           && circuit->state != C_STATE_UP)
+                               continue;
+                       if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
+                               flog_warn(
+                                       EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                       "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
+                                       circuit->interface->name,
+                                       isis_circuit_pdu_size(circuit));
+                               return NB_ERR_VALIDATION;
+                       }
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               area = yang_dnode_get_entry(dnode, true);
+               isis_area_lsp_mtu_set(area, lsp_mtu);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-1
+ */
+static int
+isis_instance_lsp_refresh_interval_level_1_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       struct isis_area *area;
+       uint16_t refr_int;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       refr_int = yang_dnode_get_uint16(dnode, NULL);
+       area = yang_dnode_get_entry(dnode, true);
+       isis_area_lsp_refresh_set(area, IS_LEVEL_1, refr_int);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/refresh-interval/level-2
+ */
+static int
+isis_instance_lsp_refresh_interval_level_2_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       struct isis_area *area;
+       uint16_t refr_int;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       refr_int = yang_dnode_get_uint16(dnode, NULL);
+       area = yang_dnode_get_entry(dnode, true);
+       isis_area_lsp_refresh_set(area, IS_LEVEL_2, refr_int);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-1
+ */
+static int
+isis_instance_lsp_maximum_lifetime_level_1_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       struct isis_area *area;
+       uint16_t max_lt;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       max_lt = yang_dnode_get_uint16(dnode, NULL);
+       area = yang_dnode_get_entry(dnode, true);
+       isis_area_max_lsp_lifetime_set(area, IS_LEVEL_1, max_lt);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime/level-2
+ */
+static int
+isis_instance_lsp_maximum_lifetime_level_2_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       struct isis_area *area;
+       uint16_t max_lt;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       max_lt = yang_dnode_get_uint16(dnode, NULL);
+       area = yang_dnode_get_entry(dnode, true);
+       isis_area_max_lsp_lifetime_set(area, IS_LEVEL_2, max_lt);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-1
+ */
+static int isis_instance_lsp_generation_interval_level_1_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       struct isis_area *area;
+       uint16_t gen_int;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       gen_int = yang_dnode_get_uint16(dnode, NULL);
+       area = yang_dnode_get_entry(dnode, true);
+       area->lsp_gen_interval[0] = gen_int;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/lsp/generation-interval/level-2
+ */
+static int isis_instance_lsp_generation_interval_level_2_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       struct isis_area *area;
+       uint16_t gen_int;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       gen_int = yang_dnode_get_uint16(dnode, NULL);
+       area = yang_dnode_get_entry(dnode, true);
+       area->lsp_gen_interval[1] = gen_int;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay
+ */
+static void ietf_backoff_delay_apply_finish(const struct lyd_node *dnode)
+{
+       long init_delay = yang_dnode_get_uint16(dnode, "./init-delay");
+       long short_delay = yang_dnode_get_uint16(dnode, "./short-delay");
+       long long_delay = yang_dnode_get_uint16(dnode, "./long-delay");
+       long holddown = yang_dnode_get_uint16(dnode, "./hold-down");
+       long timetolearn = yang_dnode_get_uint16(dnode, "./time-to-learn");
+       struct isis_area *area = yang_dnode_get_entry(dnode, true);
+       size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS  Lx");
+       char *buf = XCALLOC(MTYPE_TMP, bufsiz);
+
+       snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
+       spf_backoff_free(area->spf_delay_ietf[0]);
+       area->spf_delay_ietf[0] =
+               spf_backoff_new(master, buf, init_delay, short_delay,
+                               long_delay, holddown, timetolearn);
+
+       snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
+       spf_backoff_free(area->spf_delay_ietf[1]);
+       area->spf_delay_ietf[1] =
+               spf_backoff_new(master, buf, init_delay, short_delay,
+                               long_delay, holddown, timetolearn);
+
+       XFREE(MTYPE_TMP, buf);
+}
+
+static int
+isis_instance_spf_ietf_backoff_delay_create(enum nb_event event,
+                                           const struct lyd_node *dnode,
+                                           union nb_resource *resource)
+{
+       /* All the work is done in the apply_finish */
+       return NB_OK;
+}
+
+static int
+isis_instance_spf_ietf_backoff_delay_delete(enum nb_event event,
+                                           const struct lyd_node *dnode)
+{
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       spf_backoff_free(area->spf_delay_ietf[0]);
+       spf_backoff_free(area->spf_delay_ietf[1]);
+       area->spf_delay_ietf[0] = NULL;
+       area->spf_delay_ietf[1] = NULL;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay
+ */
+static int isis_instance_spf_ietf_backoff_delay_init_delay_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* All the work is done in the apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay
+ */
+static int isis_instance_spf_ietf_backoff_delay_short_delay_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* All the work is done in the apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay
+ */
+static int isis_instance_spf_ietf_backoff_delay_long_delay_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* All the work is done in the apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down
+ */
+static int isis_instance_spf_ietf_backoff_delay_hold_down_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* All the work is done in the apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn
+ */
+static int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* All the work is done in the apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-1
+ */
+static int
+isis_instance_spf_minimum_interval_level_1_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       area->min_spf_interval[0] = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-2
+ */
+static int
+isis_instance_spf_minimum_interval_level_2_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       area->min_spf_interval[1] = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/area-password
+ */
+static void area_password_apply_finish(const struct lyd_node *dnode)
+{
+       const char *password = yang_dnode_get_string(dnode, "./password");
+       struct isis_area *area = yang_dnode_get_entry(dnode, true);
+       int pass_type = yang_dnode_get_enum(dnode, "./password-type");
+       uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp");
+
+       switch (pass_type) {
+       case ISIS_PASSWD_TYPE_CLEARTXT:
+               isis_area_passwd_cleartext_set(area, IS_LEVEL_1, password,
+                                              snp_auth);
+               break;
+       case ISIS_PASSWD_TYPE_HMAC_MD5:
+               isis_area_passwd_hmac_md5_set(area, IS_LEVEL_1, password,
+                                             snp_auth);
+               break;
+       }
+}
+
+static int isis_instance_area_password_create(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_area_password_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       isis_area_passwd_unset(area, IS_LEVEL_1);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/area-password/password
+ */
+static int
+isis_instance_area_password_password_modify(enum nb_event event,
+                                           const struct lyd_node *dnode,
+                                           union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/area-password/password-type
+ */
+static int
+isis_instance_area_password_password_type_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/area-password/authenticate-snp
+ */
+static int isis_instance_area_password_authenticate_snp_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/domain-password
+ */
+static void domain_password_apply_finish(const struct lyd_node *dnode)
+{
+       const char *password = yang_dnode_get_string(dnode, "./password");
+       struct isis_area *area = yang_dnode_get_entry(dnode, true);
+       int pass_type = yang_dnode_get_enum(dnode, "./password-type");
+       uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp");
+
+       switch (pass_type) {
+       case ISIS_PASSWD_TYPE_CLEARTXT:
+               isis_area_passwd_cleartext_set(area, IS_LEVEL_2, password,
+                                              snp_auth);
+               break;
+       case ISIS_PASSWD_TYPE_HMAC_MD5:
+               isis_area_passwd_hmac_md5_set(area, IS_LEVEL_2, password,
+                                             snp_auth);
+               break;
+       }
+}
+
+static int isis_instance_domain_password_create(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_domain_password_delete(enum nb_event event,
+                                               const struct lyd_node *dnode)
+{
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       isis_area_passwd_unset(area, IS_LEVEL_2);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/domain-password/password
+ */
+static int
+isis_instance_domain_password_password_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/domain-password/password-type
+ */
+static int
+isis_instance_domain_password_password_type_modify(enum nb_event event,
+                                                  const struct lyd_node *dnode,
+                                                  union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/domain-password/authenticate-snp
+ */
+static int isis_instance_domain_password_authenticate_snp_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* actual setting is done in apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
+ */
+static void default_info_origin_apply_finish(const struct lyd_node *dnode,
+                                            int family)
+{
+       int originate_type = DEFAULT_ORIGINATE;
+       unsigned long metric = 0;
+       const char *routemap = NULL;
+       struct isis_area *area = yang_dnode_get_entry(dnode, true);
+       int level = yang_dnode_get_enum(dnode, "./level");
+
+       if (yang_dnode_get_bool(dnode, "./always")) {
+               originate_type = DEFAULT_ORIGINATE_ALWAYS;
+       } else if (family == AF_INET6) {
+               zlog_warn(
+                       "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
+                       __func__);
+       }
+
+       if (yang_dnode_exists(dnode, "./metric"))
+               metric = yang_dnode_get_uint32(dnode, "./metric");
+       else if (yang_dnode_exists(dnode, "./route-map"))
+               routemap = yang_dnode_get_string(dnode, "./route-map");
+
+       isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
+                       originate_type);
+}
+
+static void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode)
+{
+       default_info_origin_apply_finish(dnode, AF_INET);
+}
+
+static void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode)
+{
+       default_info_origin_apply_finish(dnode, AF_INET6);
+}
+
+static int isis_instance_default_information_originate_ipv4_create(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_default_information_originate_ipv4_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       struct isis_area *area;
+       int level;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       level = yang_dnode_get_enum(dnode, "./level");
+       isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always
+ */
+static int isis_instance_default_information_originate_ipv4_always_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map
+ */
+static int isis_instance_default_information_originate_ipv4_route_map_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_default_information_originate_ipv4_route_map_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/metric
+ */
+static int isis_instance_default_information_originate_ipv4_metric_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_default_information_originate_ipv4_metric_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6
+ */
+static int isis_instance_default_information_originate_ipv6_create(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_default_information_originate_ipv6_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       struct isis_area *area;
+       int level;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       level = yang_dnode_get_enum(dnode, "./level");
+       isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always
+ */
+static int isis_instance_default_information_originate_ipv6_always_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map
+ */
+static int isis_instance_default_information_originate_ipv6_route_map_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_default_information_originate_ipv6_route_map_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/metric
+ */
+static int isis_instance_default_information_originate_ipv6_metric_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_default_information_originate_ipv6_metric_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       /* It's all done by default_info_origin_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute/ipv4
+ */
+static void redistribute_apply_finish(const struct lyd_node *dnode, int family)
+{
+       assert(family == AF_INET || family == AF_INET6);
+       int type, level;
+       unsigned long metric = 0;
+       const char *routemap = NULL;
+       struct isis_area *area;
+
+       type = yang_dnode_get_enum(dnode, "./protocol");
+       level = yang_dnode_get_enum(dnode, "./level");
+       area = yang_dnode_get_entry(dnode, true);
+
+       if (yang_dnode_exists(dnode, "./metric"))
+               metric = yang_dnode_get_uint32(dnode, "./metric");
+       else if (yang_dnode_exists(dnode, "./route-map"))
+               routemap = yang_dnode_get_string(dnode, "./route-map");
+
+       isis_redist_set(area, level, family, type, metric, routemap, 0);
+}
+
+static void redistribute_ipv4_apply_finish(const struct lyd_node *dnode)
+{
+       redistribute_apply_finish(dnode, AF_INET);
+}
+
+static void redistribute_ipv6_apply_finish(const struct lyd_node *dnode)
+{
+       redistribute_apply_finish(dnode, AF_INET6);
+}
+
+static int isis_instance_redistribute_ipv4_create(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_redistribute_ipv4_delete(enum nb_event event,
+                                                 const struct lyd_node *dnode)
+{
+       struct isis_area *area;
+       int level, type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       level = yang_dnode_get_enum(dnode, "./level");
+       type = yang_dnode_get_enum(dnode, "./protocol");
+       isis_redist_unset(area, level, AF_INET, type);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map
+ */
+static int
+isis_instance_redistribute_ipv4_route_map_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+static int
+isis_instance_redistribute_ipv4_route_map_delete(enum nb_event event,
+                                                const struct lyd_node *dnode)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric
+ */
+static int
+isis_instance_redistribute_ipv4_metric_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+static int
+isis_instance_redistribute_ipv4_metric_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute/ipv6
+ */
+static int isis_instance_redistribute_ipv6_create(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+static int isis_instance_redistribute_ipv6_delete(enum nb_event event,
+                                                 const struct lyd_node *dnode)
+{
+       struct isis_area *area;
+       int level, type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       level = yang_dnode_get_enum(dnode, "./level");
+       type = yang_dnode_get_enum(dnode, "./protocol");
+       isis_redist_unset(area, level, AF_INET6, type);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute/ipv6/route-map
+ */
+static int
+isis_instance_redistribute_ipv6_route_map_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+static int
+isis_instance_redistribute_ipv6_route_map_delete(enum nb_event event,
+                                                const struct lyd_node *dnode)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute/ipv6/metric
+ */
+static int
+isis_instance_redistribute_ipv6_metric_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+static int
+isis_instance_redistribute_ipv6_metric_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       /* It's all done by redistribute_apply_finish */
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
+ */
+static int isis_multi_topology_common(enum nb_event event,
+                                     const struct lyd_node *dnode,
+                                     const char *topology, bool create)
+{
+       struct isis_area *area;
+       struct isis_area_mt_setting *setting;
+       uint16_t mtid = isis_str2mtid(topology);
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               if (mtid == (uint16_t)-1) {
+                       flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                 "Unknown topology %s", topology);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               area = yang_dnode_get_entry(dnode, true);
+               setting = area_get_mt_setting(area, mtid);
+               setting->enabled = create;
+               lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int isis_multi_topology_overload_common(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              const char *topology)
+{
+       struct isis_area *area;
+       struct isis_area_mt_setting *setting;
+       uint16_t mtid = isis_str2mtid(topology);
+
+       /* validation is done in isis_multi_topology_common */
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       setting = area_get_mt_setting(area, mtid);
+       setting->overload = yang_dnode_get_bool(dnode, NULL);
+       if (setting->enabled)
+               lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
+
+       return NB_OK;
+}
+
+static int
+isis_instance_multi_topology_ipv4_multicast_create(enum nb_event event,
+                                                  const struct lyd_node *dnode,
+                                                  union nb_resource *resource)
+{
+       return isis_multi_topology_common(event, dnode, "ipv4-multicast", true);
+}
+
+static int
+isis_instance_multi_topology_ipv4_multicast_delete(enum nb_event event,
+                                                  const struct lyd_node *dnode)
+{
+       return isis_multi_topology_common(event, dnode, "ipv4-multicast",
+                                         false);
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload
+ */
+static int isis_instance_multi_topology_ipv4_multicast_overload_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_overload_common(event, dnode,
+                                                  "ipv4-multicast");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management
+ */
+static int isis_instance_multi_topology_ipv4_management_create(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_common(event, dnode, "ipv4-mgmt", true);
+}
+
+static int isis_instance_multi_topology_ipv4_management_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       return isis_multi_topology_common(event, dnode, "ipv4-mgmt", false);
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload
+ */
+static int isis_instance_multi_topology_ipv4_management_overload_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_overload_common(event, dnode, "ipv4-mgmt");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast
+ */
+static int
+isis_instance_multi_topology_ipv6_unicast_create(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-unicast", true);
+}
+
+static int
+isis_instance_multi_topology_ipv6_unicast_delete(enum nb_event event,
+                                                const struct lyd_node *dnode)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-unicast", false);
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload
+ */
+static int isis_instance_multi_topology_ipv6_unicast_overload_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_overload_common(event, dnode,
+                                                  "ipv6-unicast");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast
+ */
+static int
+isis_instance_multi_topology_ipv6_multicast_create(enum nb_event event,
+                                                  const struct lyd_node *dnode,
+                                                  union nb_resource *resource)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-multicast", true);
+}
+
+static int
+isis_instance_multi_topology_ipv6_multicast_delete(enum nb_event event,
+                                                  const struct lyd_node *dnode)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-multicast",
+                                         false);
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload
+ */
+static int isis_instance_multi_topology_ipv6_multicast_overload_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_overload_common(event, dnode,
+                                                  "ipv6-multicast");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management
+ */
+static int isis_instance_multi_topology_ipv6_management_create(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-mgmt", true);
+}
+
+static int isis_instance_multi_topology_ipv6_management_delete(
+       enum nb_event event, const struct lyd_node *dnode)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-mgmt", false);
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload
+ */
+static int isis_instance_multi_topology_ipv6_management_overload_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_overload_common(event, dnode, "ipv6-mgmt");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc
+ */
+static int
+isis_instance_multi_topology_ipv6_dstsrc_create(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", true);
+}
+
+static int
+isis_instance_multi_topology_ipv6_dstsrc_delete(enum nb_event event,
+                                               const struct lyd_node *dnode)
+{
+       return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", false);
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload
+ */
+static int isis_instance_multi_topology_ipv6_dstsrc_overload_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return isis_multi_topology_overload_common(event, dnode, "ipv6-dstsrc");
+}
+
+/*
+ * XPath: /frr-isisd:isis/instance/log-adjacency-changes
+ */
+static int
+isis_instance_log_adjacency_changes_modify(enum nb_event event,
+                                          const struct lyd_node *dnode,
+                                          union nb_resource *resource)
+{
+       struct isis_area *area;
+       bool log = yang_dnode_get_bool(dnode, NULL);
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       area->log_adj_changes = log ? 1 : 0;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/mpls-te
+ */
+static int isis_mpls_te_create(enum nb_event event,
+                              const struct lyd_node *dnode,
+                              union nb_resource *resource)
+{
+       struct listnode *node;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       isisMplsTE.status = enable;
+
+       /*
+        * Following code is intended to handle two cases;
+        *
+        * 1) MPLS-TE was disabled at startup time, but now become enabled.
+        * In this case, we must enable MPLS-TE Circuit regarding interface
+        * MPLS_TE flag
+        * 2) MPLS-TE was once enabled then disabled, and now enabled again.
+        */
+       for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) {
+               if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type))
+                       continue;
+
+               if ((circuit->mtc->status == disable)
+                   && HAS_LINK_PARAMS(circuit->interface))
+                       circuit->mtc->status = enable;
+               else
+                       continue;
+
+               /* Reoriginate STD_TE & GMPLS circuits */
+               if (circuit->area)
+                       lsp_regenerate_schedule(circuit->area, circuit->is_type,
+                                               0);
+       }
+
+       return NB_OK;
+}
+
+static int isis_mpls_te_delete(enum nb_event event,
+                              const struct lyd_node *dnode)
+{
+       struct listnode *node;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       isisMplsTE.status = disable;
+
+       /* Flush LSP if circuit engage */
+       for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) {
+               if (circuit->mtc == NULL || (circuit->mtc->status == disable))
+                       continue;
+
+               /* disable MPLS_TE Circuit */
+               circuit->mtc->status = disable;
+
+               /* Re-originate circuit without STD_TE & GMPLS parameters */
+               if (circuit->area)
+                       lsp_regenerate_schedule(circuit->area, circuit->is_type,
+                                               0);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-isisd:isis/mpls-te/router-address
+ */
+static int isis_mpls_te_router_address_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       struct in_addr value;
+       struct listnode *node;
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv4(&value, dnode, NULL);
+       isisMplsTE.router_id.s_addr = value.s_addr;
+       /* only proceed if MPLS-TE is enabled */
+       if (isisMplsTE.status == disable)
+               return NB_OK;
+
+       /* Update main Router ID in isis global structure */
+       isis->router_id = value.s_addr;
+       /* And re-schedule LSP update */
+       for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
+               if (listcount(area->area_addrs) > 0)
+                       lsp_regenerate_schedule(area, area->is_type, 0);
+
+       return NB_OK;
+}
+
+static int isis_mpls_te_router_address_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       struct listnode *node;
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       isisMplsTE.router_id.s_addr = INADDR_ANY;
+       /* only proceed if MPLS-TE is enabled */
+       if (isisMplsTE.status == disable)
+               return NB_OK;
+
+       /* Update main Router ID in isis global structure */
+       isis->router_id = 0;
+       /* And re-schedule LSP update */
+       for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
+               if (listcount(area->area_addrs) > 0)
+                       lsp_regenerate_schedule(area, area->is_type, 0);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis
+ */
+static int lib_interface_isis_create(enum nb_event event,
+                                    const struct lyd_node *dnode,
+                                    union nb_resource *resource)
+{
+       struct isis_area *area;
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+       const char *area_tag = yang_dnode_get_string(dnode, "./area-tag");
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = isis_area_lookup(area_tag);
+       /* The area should have already be created. We are
+        * setting the priority of the global isis area creation
+        * slightly lower, so it should be executed first, but I
+        * cannot rely on that so here I have to check.
+        */
+       if (!area) {
+               flog_err(
+                       EC_LIB_NB_CB_CONFIG_APPLY,
+                       "%s: attempt to create circuit for area %s before the area has been created",
+                       __func__, area_tag);
+               abort();
+       }
+
+       ifp = yang_dnode_get_entry(dnode, true);
+       circuit = isis_circuit_create(area, ifp);
+       assert(circuit->state == C_STATE_CONF || circuit->state == C_STATE_UP);
+       yang_dnode_set_entry(dnode, circuit);
+
+       return NB_OK;
+}
+
+static int lib_interface_isis_delete(enum nb_event event,
+                                    const struct lyd_node *dnode)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       if (!circuit)
+               return NB_ERR_INCONSISTENCY;
+       /* delete circuit through csm changes */
+       switch (circuit->state) {
+       case C_STATE_UP:
+               isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
+                                     circuit->interface);
+               isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
+               break;
+       case C_STATE_CONF:
+               isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
+               break;
+       case C_STATE_INIT:
+               isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
+                                     circuit->interface);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag
+ */
+static int lib_interface_isis_area_tag_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       struct interface *ifp;
+       struct vrf *vrf;
+       const char *area_tag, *ifname, *vrfname;
+
+       if (event == NB_EV_VALIDATE) {
+               /* libyang doesn't like relative paths across module boundaries
+                */
+               ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
+               vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
+               vrf = vrf_lookup_by_name(vrfname);
+               assert(vrf);
+               ifp = if_lookup_by_name(ifname, vrf->vrf_id);
+               if (!ifp)
+                       return NB_OK;
+               circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+               area_tag = yang_dnode_get_string(dnode, NULL);
+               if (circuit && circuit->area && circuit->area->area_tag
+                   && strcmp(circuit->area->area_tag, area_tag)) {
+                       flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                 "ISIS circuit is already defined on %s",
+                                 circuit->area->area_tag);
+                       return NB_ERR_VALIDATION;
+               }
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
+ */
+static int lib_interface_isis_circuit_type_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       int circ_type = yang_dnode_get_enum(dnode, NULL);
+       struct isis_circuit *circuit;
+       struct interface *ifp;
+       struct vrf *vrf;
+       const char *ifname, *vrfname;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* libyang doesn't like relative paths across module boundaries
+                */
+               ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
+               vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
+               vrf = vrf_lookup_by_name(vrfname);
+               assert(vrf);
+               ifp = if_lookup_by_name(ifname, vrf->vrf_id);
+               if (!ifp)
+                       break;
+               circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+               if (circuit && circuit->state == C_STATE_UP
+                   && circuit->area->is_type != IS_LEVEL_1_AND_2
+                   && circuit->area->is_type != circ_type) {
+                       flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                 "Invalid circuit level for area %s",
+                                 circuit->area->area_tag);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               circuit = yang_dnode_get_entry(dnode, true);
+               isis_circuit_is_type_set(circuit, circ_type);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
+ */
+static int lib_interface_isis_ipv4_routing_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       bool ipv4, ipv6;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       ipv4 = yang_dnode_get_bool(dnode, NULL);
+       ipv6 = yang_dnode_get_bool(dnode, "../ipv6-routing");
+       isis_circuit_af_set(circuit, ipv4, ipv6);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
+ */
+static int lib_interface_isis_ipv6_routing_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       bool ipv4, ipv6;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
+       ipv6 = yang_dnode_get_bool(dnode, NULL);
+       isis_circuit_af_set(circuit, ipv4, ipv6);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1
+ */
+static int
+lib_interface_isis_csnp_interval_level_1_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->csnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2
+ */
+static int
+lib_interface_isis_csnp_interval_level_2_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->csnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1
+ */
+static int
+lib_interface_isis_psnp_interval_level_1_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->psnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2
+ */
+static int
+lib_interface_isis_psnp_interval_level_2_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->psnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding
+ */
+static int lib_interface_isis_hello_padding_modify(enum nb_event event,
+                                                  const struct lyd_node *dnode,
+                                                  union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->pad_hellos = yang_dnode_get_bool(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1
+ */
+static int
+lib_interface_isis_hello_interval_level_1_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       uint32_t interval;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       interval = yang_dnode_get_uint32(dnode, NULL);
+       circuit->hello_interval[0] = interval;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2
+ */
+static int
+lib_interface_isis_hello_interval_level_2_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       uint32_t interval;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       interval = yang_dnode_get_uint32(dnode, NULL);
+       circuit->hello_interval[1] = interval;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1
+ */
+static int
+lib_interface_isis_hello_multiplier_level_1_modify(enum nb_event event,
+                                                  const struct lyd_node *dnode,
+                                                  union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       uint16_t multi;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       multi = yang_dnode_get_uint16(dnode, NULL);
+       circuit->hello_multiplier[0] = multi;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2
+ */
+static int
+lib_interface_isis_hello_multiplier_level_2_modify(enum nb_event event,
+                                                  const struct lyd_node *dnode,
+                                                  union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       uint16_t multi;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       multi = yang_dnode_get_uint16(dnode, NULL);
+       circuit->hello_multiplier[1] = multi;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1
+ */
+static int
+lib_interface_isis_metric_level_1_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       unsigned int met;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       met = yang_dnode_get_uint32(dnode, NULL);
+       isis_circuit_metric_set(circuit, IS_LEVEL_1, met);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2
+ */
+static int
+lib_interface_isis_metric_level_2_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       unsigned int met;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       met = yang_dnode_get_uint32(dnode, NULL);
+       isis_circuit_metric_set(circuit, IS_LEVEL_2, met);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1
+ */
+static int
+lib_interface_isis_priority_level_1_modify(enum nb_event event,
+                                          const struct lyd_node *dnode,
+                                          union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->priority[0] = yang_dnode_get_uint8(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2
+ */
+static int
+lib_interface_isis_priority_level_2_modify(enum nb_event event,
+                                          const struct lyd_node *dnode,
+                                          union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->priority[1] = yang_dnode_get_uint8(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type
+ */
+static int lib_interface_isis_network_type_modify(enum nb_event event,
+                                                 const struct lyd_node *dnode,
+                                                 union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       int net_type = yang_dnode_get_enum(dnode, NULL);
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               circuit = yang_dnode_get_entry(dnode, false);
+               if (!circuit)
+                       break;
+               if (circuit->circ_type == CIRCUIT_T_LOOPBACK
+                   || circuit->circ_type == CIRCUIT_T_UNKNOWN) {
+                       flog_warn(
+                               EC_LIB_NB_CB_CONFIG_VALIDATE,
+                               "Cannot change network type on unknown or loopback interface");
+                       return NB_ERR_VALIDATION;
+               }
+               if (net_type == CIRCUIT_T_BROADCAST
+                   && circuit->state == C_STATE_UP
+                   && !if_is_broadcast(circuit->interface)) {
+                       flog_warn(
+                               EC_LIB_NB_CB_CONFIG_VALIDATE,
+                               "Cannot configure non-broadcast interface for broadcast operation");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               circuit = yang_dnode_get_entry(dnode, true);
+               isis_circuit_circ_type_set(circuit, net_type);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
+ */
+static int lib_interface_isis_passive_modify(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       struct isis_area *area;
+       struct interface *ifp;
+       bool passive = yang_dnode_get_bool(dnode, NULL);
+
+       /* validation only applies if we are setting passive to false */
+       if (!passive && event == NB_EV_VALIDATE) {
+               circuit = yang_dnode_get_entry(dnode, false);
+               if (!circuit)
+                       return NB_OK;
+               ifp = circuit->interface;
+               if (!ifp)
+                       return NB_OK;
+               if (if_is_loopback(ifp)) {
+                       flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                 "Loopback is always passive");
+                       return NB_ERR_VALIDATION;
+               }
+       }
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       if (circuit->state != C_STATE_UP) {
+               circuit->is_passive = passive;
+       } else {
+               area = circuit->area;
+               isis_csm_state_change(ISIS_DISABLE, circuit, area);
+               circuit->is_passive = passive;
+               isis_csm_state_change(ISIS_ENABLE, circuit, area);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/password
+ */
+static int lib_interface_isis_password_create(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       return NB_OK;
+}
+
+static int lib_interface_isis_password_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       isis_circuit_passwd_unset(circuit);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password
+ */
+static int
+lib_interface_isis_password_password_modify(enum nb_event event,
+                                           const struct lyd_node *dnode,
+                                           union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       const char *password;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       password = yang_dnode_get_string(dnode, NULL);
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->passwd.len = strlen(password);
+       strncpy((char *)circuit->passwd.passwd, password, 255);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type
+ */
+static int
+lib_interface_isis_password_password_type_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+       uint8_t pass_type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       pass_type = yang_dnode_get_enum(dnode, NULL);
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->passwd.type = pass_type;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
+ */
+static int lib_interface_isis_disable_three_way_handshake_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->disable_threeway_adj = yang_dnode_get_bool(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
+ */
+static int lib_interface_isis_multi_topology_common(
+       enum nb_event event, const struct lyd_node *dnode, uint16_t mtid)
+{
+       struct isis_circuit *circuit;
+       bool value;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               circuit = yang_dnode_get_entry(dnode, false);
+               if (circuit && circuit->area && circuit->area->oldmetric) {
+                       flog_warn(
+                               EC_LIB_NB_CB_CONFIG_VALIDATE,
+                               "Multi topology IS-IS can only be used with wide metrics");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               circuit = yang_dnode_get_entry(dnode, true);
+               value = yang_dnode_get_bool(dnode, NULL);
+               isis_circuit_mt_enabled_set(circuit, mtid, value);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int lib_interface_isis_multi_topology_ipv4_unicast_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV4_UNICAST);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast
+ */
+static int lib_interface_isis_multi_topology_ipv4_multicast_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV4_MULTICAST);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management
+ */
+static int lib_interface_isis_multi_topology_ipv4_management_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV4_MGMT);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast
+ */
+static int lib_interface_isis_multi_topology_ipv6_unicast_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV6_UNICAST);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast
+ */
+static int lib_interface_isis_multi_topology_ipv6_multicast_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV6_MULTICAST);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management
+ */
+static int lib_interface_isis_multi_topology_ipv6_management_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV6_MGMT);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc
+ */
+static int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV6_DSTSRC);
+}
+
+/*
+ * NOTIFICATIONS
+ */
+static void notif_prep_instance_hdr(const char *xpath,
+                                   const struct isis_area *area,
+                                   const char *routing_instance,
+                                   struct list *args)
+{
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-instance", xpath);
+       data = yang_data_new_string(xpath_arg, routing_instance);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-protocol-name",
+                xpath);
+       data = yang_data_new_string(xpath_arg, area->area_tag);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/isis-level", xpath);
+       data = yang_data_new_enum(xpath_arg, area->is_type);
+       listnode_add(args, data);
+}
+
+static void notif_prepr_iface_hdr(const char *xpath,
+                                 const struct isis_circuit *circuit,
+                                 struct list *args)
+{
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
+       data = yang_data_new_string(xpath_arg, circuit->interface->name);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-level", xpath);
+       data = yang_data_new_enum(xpath_arg, circuit->is_type);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/extended-circuit-id", xpath);
+       /* we do not seem to have the extended version of the circuit_id */
+       data = yang_data_new_uint32(xpath_arg, (uint32_t)circuit->circuit_id);
+       listnode_add(args, data);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:database-overload
+ */
+void isis_notif_db_overload(const struct isis_area *area, bool overload)
+{
+       const char *xpath = "/frr-isisd:database-overload";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/overload", xpath);
+       data = yang_data_new_enum(xpath_arg, !!overload);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:lsp-too-large
+ */
+void isis_notif_lsp_too_large(const struct isis_circuit *circuit,
+                             uint32_t pdu_size, const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:lsp-too-large";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/pdu-size", xpath);
+       data = yang_data_new_uint32(xpath_arg, pdu_size);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:if-state-change
+ */
+void isis_notif_if_state_change(const struct isis_circuit *circuit, bool down)
+{
+       const char *xpath = "/frr-isisd:if-state-change";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
+       data = yang_data_new_enum(xpath_arg, !!down);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:corrupted-lsp-detected
+ */
+void isis_notif_corrupted_lsp(const struct isis_area *area, const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:corrupted-lsp-detected";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:attempt-to-exceed-max-sequence
+ */
+void isis_notif_lsp_exceed_max(const struct isis_area *area, const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:attempt-to-exceed-max-sequence";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:max-area-addresses-mismatch
+ */
+void isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
+                                      uint8_t max_area_addrs,
+                                      const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:max-area-addresses-mismatch";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/max-area-addresses", xpath);
+       data = yang_data_new_uint8(xpath_arg, max_area_addrs);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:authentication-type-failure
+ */
+void isis_notif_authentication_type_failure(const struct isis_circuit *circuit,
+                                           const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:authentication-type-failure";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:authentication-failure
+ */
+void isis_notif_authentication_failure(const struct isis_circuit *circuit,
+                                      const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:authentication-failure";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:adjacency-state-change
+ */
+void isis_notif_adj_state_change(const struct isis_adjacency *adj,
+                                int new_state, const char *reason)
+{
+       const char *xpath = "/frr-isisd:adjacency-state-change";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_circuit *circuit = adj->circuit;
+       struct isis_area *area = circuit->area;
+       struct isis_dynhn *dyn = dynhn_find_by_id(adj->sysid);
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       if (dyn) {
+               snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor", xpath);
+               data = yang_data_new_string(xpath_arg, dyn->hostname);
+               listnode_add(arguments, data);
+       }
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
+       data = yang_data_new_string(xpath_arg, sysid_print(adj->sysid));
+       listnode_add(arguments, data);
+
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
+       switch (new_state) {
+       case ISIS_ADJ_DOWN:
+               data = yang_data_new_string(xpath_arg, "down");
+               break;
+       case ISIS_ADJ_UP:
+               data = yang_data_new_string(xpath_arg, "up");
+               break;
+       case ISIS_ADJ_INITIALIZING:
+               data = yang_data_new_string(xpath_arg, "init");
+               break;
+       default:
+               data = yang_data_new_string(xpath_arg, "failed");
+       }
+       listnode_add(arguments, data);
+       if (new_state == ISIS_ADJ_DOWN) {
+               snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
+               data = yang_data_new_string(xpath_arg, reason);
+               listnode_add(arguments, data);
+       }
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:rejected-adjacency
+ */
+void isis_notif_reject_adjacency(const struct isis_circuit *circuit,
+                                const char *reason, const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:rejected-adjacency";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
+       data = yang_data_new_string(xpath_arg, reason);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:area-mismatch
+ */
+void isis_notif_area_mismatch(const struct isis_circuit *circuit,
+                             const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:area-mismatch";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:lsp-received
+ */
+void isis_notif_lsp_received(const struct isis_circuit *circuit,
+                            const char *lsp_id, uint32_t seqno,
+                            uint32_t timestamp, const char *sys_id)
+{
+       const char *xpath = "/frr-isisd:lsp-received";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
+       data = yang_data_new_uint32(xpath_arg, seqno);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/received-timestamp", xpath);
+       data = yang_data_new_uint32(xpath_arg, timestamp);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
+       data = yang_data_new_string(xpath_arg, sys_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:lsp-generation
+ */
+void isis_notif_lsp_gen(const struct isis_area *area, const char *lsp_id,
+                       uint32_t seqno, uint32_t timestamp)
+{
+       const char *xpath = "/frr-isisd:lsp-generation";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
+       data = yang_data_new_uint32(xpath_arg, seqno);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/send-timestamp", xpath);
+       data = yang_data_new_uint32(xpath_arg, timestamp);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:id-len-mismatch
+ */
+void isis_notif_id_len_mismatch(const struct isis_circuit *circuit,
+                               uint8_t rcv_id_len, const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:id-len-mismatch";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/pdu-field-len", xpath);
+       data = yang_data_new_uint8(xpath_arg, rcv_id_len);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:version-skew
+ */
+void isis_notif_version_skew(const struct isis_circuit *circuit,
+                            uint8_t version, const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:version-skew";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/protocol-version", xpath);
+       data = yang_data_new_uint8(xpath_arg, version);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:lsp-error-detected
+ */
+void isis_notif_lsp_error(const struct isis_circuit *circuit,
+                         const char *lsp_id, const char *raw_pdu,
+                         __attribute__((unused)) uint32_t offset,
+                         __attribute__((unused)) uint8_t tlv_type)
+{
+       const char *xpath = "/frr-isisd:lsp-error-detected";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+       /* ignore offset and tlv_type which cannot be set properly */
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:sequence-number-skipped
+ */
+void isis_notif_seqno_skipped(const struct isis_circuit *circuit,
+                             const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:sequence-number-skipped";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:own-lsp-purge
+ */
+void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,
+                             const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:own-lsp-purge";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/* clang-format off */
+const struct frr_yang_module_info frr_isisd_info = {
+       .name = "frr-isisd",
+       .nodes = {
+               {
+                       .xpath = "/frr-isisd:isis/instance",
+                       .cbs.create = isis_instance_create,
+                       .cbs.delete = isis_instance_delete,
+                       .cbs.cli_show = cli_show_router_isis,
+                       .priority = NB_DFLT_PRIORITY - 1,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/is-type",
+                       .cbs.modify = isis_instance_is_type_modify,
+                       .cbs.cli_show = cli_show_isis_is_type,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/area-address",
+                       .cbs.create = isis_instance_area_address_create,
+                       .cbs.delete = isis_instance_area_address_delete,
+                       .cbs.cli_show = cli_show_isis_area_address,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/dynamic-hostname",
+                       .cbs.modify = isis_instance_dynamic_hostname_modify,
+                       .cbs.cli_show = cli_show_isis_dynamic_hostname,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/attached",
+                       .cbs.modify = isis_instance_attached_modify,
+                       .cbs.cli_show = cli_show_isis_attached,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/overload",
+                       .cbs.modify = isis_instance_overload_modify,
+                       .cbs.cli_show = cli_show_isis_overload,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/metric-style",
+                       .cbs.modify = isis_instance_metric_style_modify,
+                       .cbs.cli_show = cli_show_isis_metric_style,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/purge-originator",
+                       .cbs.modify = isis_instance_purge_originator_modify,
+                       .cbs.cli_show = cli_show_isis_purge_origin,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/mtu",
+                       .cbs.modify = isis_instance_lsp_mtu_modify,
+                       .cbs.cli_show = cli_show_isis_lsp_mtu,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval",
+                       .cbs.cli_show = cli_show_isis_lsp_ref_interval,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-1",
+                       .cbs.modify = isis_instance_lsp_refresh_interval_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/refresh-interval/level-2",
+                       .cbs.modify = isis_instance_lsp_refresh_interval_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime",
+                       .cbs.cli_show = cli_show_isis_lsp_max_lifetime,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-1",
+                       .cbs.modify = isis_instance_lsp_maximum_lifetime_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-2",
+                       .cbs.modify = isis_instance_lsp_maximum_lifetime_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/generation-interval",
+                       .cbs.cli_show = cli_show_isis_lsp_gen_interval,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-1",
+                       .cbs.modify = isis_instance_lsp_generation_interval_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/lsp/generation-interval/level-2",
+                       .cbs.modify = isis_instance_lsp_generation_interval_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay",
+                       .cbs.create = isis_instance_spf_ietf_backoff_delay_create,
+                       .cbs.delete = isis_instance_spf_ietf_backoff_delay_delete,
+                       .cbs.apply_finish = ietf_backoff_delay_apply_finish,
+                       .cbs.cli_show = cli_show_isis_spf_ietf_backoff,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay",
+                       .cbs.modify = isis_instance_spf_ietf_backoff_delay_init_delay_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay",
+                       .cbs.modify = isis_instance_spf_ietf_backoff_delay_short_delay_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay",
+                       .cbs.modify = isis_instance_spf_ietf_backoff_delay_long_delay_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down",
+                       .cbs.modify = isis_instance_spf_ietf_backoff_delay_hold_down_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn",
+                       .cbs.modify = isis_instance_spf_ietf_backoff_delay_time_to_learn_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/minimum-interval",
+                       .cbs.cli_show = cli_show_isis_spf_min_interval,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-1",
+                       .cbs.modify = isis_instance_spf_minimum_interval_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/spf/minimum-interval/level-2",
+                       .cbs.modify = isis_instance_spf_minimum_interval_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/area-password",
+                       .cbs.create = isis_instance_area_password_create,
+                       .cbs.delete = isis_instance_area_password_delete,
+                       .cbs.apply_finish = area_password_apply_finish,
+                       .cbs.cli_show = cli_show_isis_area_pwd,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/area-password/password",
+                       .cbs.modify = isis_instance_area_password_password_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/area-password/password-type",
+                       .cbs.modify = isis_instance_area_password_password_type_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/area-password/authenticate-snp",
+                       .cbs.modify = isis_instance_area_password_authenticate_snp_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/domain-password",
+                       .cbs.create = isis_instance_domain_password_create,
+                       .cbs.delete = isis_instance_domain_password_delete,
+                       .cbs.apply_finish = domain_password_apply_finish,
+                       .cbs.cli_show = cli_show_isis_domain_pwd,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/domain-password/password",
+                       .cbs.modify = isis_instance_domain_password_password_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/domain-password/password-type",
+                       .cbs.modify = isis_instance_domain_password_password_type_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/domain-password/authenticate-snp",
+                       .cbs.modify = isis_instance_domain_password_authenticate_snp_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4",
+                       .cbs.create = isis_instance_default_information_originate_ipv4_create,
+                       .cbs.delete = isis_instance_default_information_originate_ipv4_delete,
+                       .cbs.apply_finish = default_info_origin_ipv4_apply_finish,
+                       .cbs.cli_show = cli_show_isis_def_origin_ipv4,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always",
+                       .cbs.modify = isis_instance_default_information_originate_ipv4_always_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/route-map",
+                       .cbs.modify = isis_instance_default_information_originate_ipv4_route_map_modify,
+                       .cbs.delete = isis_instance_default_information_originate_ipv4_route_map_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/metric",
+                       .cbs.modify = isis_instance_default_information_originate_ipv4_metric_modify,
+                       .cbs.delete = isis_instance_default_information_originate_ipv4_metric_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6",
+                       .cbs.create = isis_instance_default_information_originate_ipv6_create,
+                       .cbs.delete = isis_instance_default_information_originate_ipv6_delete,
+                       .cbs.apply_finish = default_info_origin_ipv6_apply_finish,
+                       .cbs.cli_show = cli_show_isis_def_origin_ipv6,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always",
+                       .cbs.modify = isis_instance_default_information_originate_ipv6_always_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/route-map",
+                       .cbs.modify = isis_instance_default_information_originate_ipv6_route_map_modify,
+                       .cbs.delete = isis_instance_default_information_originate_ipv6_route_map_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/metric",
+                       .cbs.modify = isis_instance_default_information_originate_ipv6_metric_modify,
+                       .cbs.delete = isis_instance_default_information_originate_ipv6_metric_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/redistribute/ipv4",
+                       .cbs.create = isis_instance_redistribute_ipv4_create,
+                       .cbs.delete = isis_instance_redistribute_ipv4_delete,
+                       .cbs.apply_finish = redistribute_ipv4_apply_finish,
+                       .cbs.cli_show = cli_show_isis_redistribute_ipv4,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/route-map",
+                       .cbs.modify = isis_instance_redistribute_ipv4_route_map_modify,
+                       .cbs.delete = isis_instance_redistribute_ipv4_route_map_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/metric",
+                       .cbs.modify = isis_instance_redistribute_ipv4_metric_modify,
+                       .cbs.delete = isis_instance_redistribute_ipv4_metric_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/redistribute/ipv6",
+                       .cbs.create = isis_instance_redistribute_ipv6_create,
+                       .cbs.delete = isis_instance_redistribute_ipv6_delete,
+                       .cbs.apply_finish = redistribute_ipv6_apply_finish,
+                       .cbs.cli_show = cli_show_isis_redistribute_ipv6,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/route-map",
+                       .cbs.modify = isis_instance_redistribute_ipv6_route_map_modify,
+                       .cbs.delete = isis_instance_redistribute_ipv6_route_map_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/metric",
+                       .cbs.modify = isis_instance_redistribute_ipv6_metric_modify,
+                       .cbs.delete = isis_instance_redistribute_ipv6_metric_delete,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast",
+                       .cbs.create = isis_instance_multi_topology_ipv4_multicast_create,
+                       .cbs.delete = isis_instance_multi_topology_ipv4_multicast_delete,
+                       .cbs.cli_show = cli_show_isis_mt_ipv4_multicast,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload",
+                       .cbs.modify = isis_instance_multi_topology_ipv4_multicast_overload_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management",
+                       .cbs.create = isis_instance_multi_topology_ipv4_management_create,
+                       .cbs.delete = isis_instance_multi_topology_ipv4_management_delete,
+                       .cbs.cli_show = cli_show_isis_mt_ipv4_mgmt,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management/overload",
+                       .cbs.modify = isis_instance_multi_topology_ipv4_management_overload_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast",
+                       .cbs.create = isis_instance_multi_topology_ipv6_unicast_create,
+                       .cbs.delete = isis_instance_multi_topology_ipv6_unicast_delete,
+                       .cbs.cli_show = cli_show_isis_mt_ipv6_unicast,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload",
+                       .cbs.modify = isis_instance_multi_topology_ipv6_unicast_overload_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast",
+                       .cbs.create = isis_instance_multi_topology_ipv6_multicast_create,
+                       .cbs.delete = isis_instance_multi_topology_ipv6_multicast_delete,
+                       .cbs.cli_show = cli_show_isis_mt_ipv6_multicast,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload",
+                       .cbs.modify = isis_instance_multi_topology_ipv6_multicast_overload_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management",
+                       .cbs.create = isis_instance_multi_topology_ipv6_management_create,
+                       .cbs.delete = isis_instance_multi_topology_ipv6_management_delete,
+                       .cbs.cli_show = cli_show_isis_mt_ipv6_mgmt,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management/overload",
+                       .cbs.modify = isis_instance_multi_topology_ipv6_management_overload_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc",
+                       .cbs.create = isis_instance_multi_topology_ipv6_dstsrc_create,
+                       .cbs.delete = isis_instance_multi_topology_ipv6_dstsrc_delete,
+                       .cbs.cli_show = cli_show_isis_mt_ipv6_dstsrc,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload",
+                       .cbs.modify = isis_instance_multi_topology_ipv6_dstsrc_overload_modify,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/instance/log-adjacency-changes",
+                       .cbs.modify = isis_instance_log_adjacency_changes_modify,
+                       .cbs.cli_show = cli_show_isis_log_adjacency,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/mpls-te",
+                       .cbs.create = isis_mpls_te_create,
+                       .cbs.delete = isis_mpls_te_delete,
+                       .cbs.cli_show = cli_show_isis_mpls_te,
+               },
+               {
+                       .xpath = "/frr-isisd:isis/mpls-te/router-address",
+                       .cbs.modify = isis_mpls_te_router_address_modify,
+                       .cbs.delete = isis_mpls_te_router_address_delete,
+                       .cbs.cli_show = cli_show_isis_mpls_te_router_addr,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis",
+                       .cbs.create = lib_interface_isis_create,
+                       .cbs.delete = lib_interface_isis_delete,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/area-tag",
+                       .cbs.modify = lib_interface_isis_area_tag_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/circuit-type",
+                       .cbs.modify = lib_interface_isis_circuit_type_modify,
+                       .cbs.cli_show = cli_show_ip_isis_circ_type,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv4-routing",
+                       .cbs.modify = lib_interface_isis_ipv4_routing_modify,
+                       .cbs.cli_show = cli_show_ip_isis_ipv4,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv6-routing",
+                       .cbs.modify = lib_interface_isis_ipv6_routing_modify,
+                       .cbs.cli_show = cli_show_ip_isis_ipv6,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval",
+                       .cbs.cli_show = cli_show_ip_isis_csnp_interval,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1",
+                       .cbs.modify = lib_interface_isis_csnp_interval_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2",
+                       .cbs.modify = lib_interface_isis_csnp_interval_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval",
+                       .cbs.cli_show = cli_show_ip_isis_psnp_interval,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1",
+                       .cbs.modify = lib_interface_isis_psnp_interval_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2",
+                       .cbs.modify = lib_interface_isis_psnp_interval_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/padding",
+                       .cbs.modify = lib_interface_isis_hello_padding_modify,
+                       .cbs.cli_show = cli_show_ip_isis_hello_padding,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval",
+                       .cbs.cli_show = cli_show_ip_isis_hello_interval,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1",
+                       .cbs.modify = lib_interface_isis_hello_interval_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2",
+                       .cbs.modify = lib_interface_isis_hello_interval_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier",
+                       .cbs.cli_show = cli_show_ip_isis_hello_multi,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1",
+                       .cbs.modify = lib_interface_isis_hello_multiplier_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2",
+                       .cbs.modify = lib_interface_isis_hello_multiplier_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric",
+                       .cbs.cli_show = cli_show_ip_isis_metric,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1",
+                       .cbs.modify = lib_interface_isis_metric_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2",
+                       .cbs.modify = lib_interface_isis_metric_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority",
+                       .cbs.cli_show = cli_show_ip_isis_priority,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-1",
+                       .cbs.modify = lib_interface_isis_priority_level_1_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-2",
+                       .cbs.modify = lib_interface_isis_priority_level_2_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/network-type",
+                       .cbs.modify = lib_interface_isis_network_type_modify,
+                       .cbs.cli_show = cli_show_ip_isis_network_type,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/passive",
+                       .cbs.modify = lib_interface_isis_passive_modify,
+                       .cbs.cli_show = cli_show_ip_isis_passive,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password",
+                       .cbs.create = lib_interface_isis_password_create,
+                       .cbs.delete = lib_interface_isis_password_delete,
+                       .cbs.cli_show = cli_show_ip_isis_password,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password",
+                       .cbs.modify = lib_interface_isis_password_password_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/password/password-type",
+                       .cbs.modify = lib_interface_isis_password_password_type_modify,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake",
+                       .cbs.modify = lib_interface_isis_disable_three_way_handshake_modify,
+                       .cbs.cli_show = cli_show_ip_isis_threeway_shake,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast",
+                       .cbs.modify = lib_interface_isis_multi_topology_ipv4_unicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv4_unicast,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast",
+                       .cbs.modify = lib_interface_isis_multi_topology_ipv4_multicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv4_multicast,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management",
+                       .cbs.modify = lib_interface_isis_multi_topology_ipv4_management_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv4_mgmt,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast",
+                       .cbs.modify = lib_interface_isis_multi_topology_ipv6_unicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_unicast,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast",
+                       .cbs.modify = lib_interface_isis_multi_topology_ipv6_multicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_multicast,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management",
+                       .cbs.modify = lib_interface_isis_multi_topology_ipv6_management_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_mgmt,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc",
+                       .cbs.modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_dstsrc,
+               },
+               {
+                       .xpath = NULL,
+               },
+       }
+};
index 900ce9f922e9a6dd5bd08f92b3797a83929053f7..330da9b216b62a5c760200dacf64f6bb0b3adf57 100644 (file)
@@ -58,6 +58,7 @@
 #include "isisd/isis_errors.h"
 #include "isisd/fabricd.h"
 #include "isisd/isis_tx_queue.h"
+#include "isisd/isis_pdu_counter.h"
 
 static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
                   int level)
@@ -88,6 +89,7 @@ static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
        /* Update PDU length */
        stream_putw_at(circuit->snd_stream, lenp, length);
 
+       pdu_counter_count(circuit->area->pdu_tx_counters, pdu_type);
        retval = circuit->tx(circuit, level);
        if (retval != ISIS_OK)
                flog_err(EC_ISIS_PACKET,
@@ -551,6 +553,10 @@ static int pdu_len_validate(uint16_t pdu_len, struct isis_circuit *circuit)
 static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                         uint8_t *ssnpa)
 {
+       /* keep a copy of the raw pdu for NB notifications */
+       size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+       size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+       char raw_pdu[pdu_end - pdu_start];
        bool p2p_hello = (pdu_type == P2P_HELLO);
        int level = p2p_hello ? 0
                              : (pdu_type == L1_LAN_HELLO) ? ISIS_LEVEL1
@@ -560,6 +566,9 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                        ? "P2P IIH"
                        : (level == ISIS_LEVEL1) ? "L1 LAN IIH" : "L2 LAN IIH";
 
+
+       stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+                       pdu_end - pdu_start);
        if (isis->debugs & DEBUG_ADJ_PACKETS) {
                zlog_debug("ISIS-Adj (%s): Rcvd %s on %s, cirType %s, cirID %u",
                           circuit->area->area_tag, pdu_name,
@@ -574,11 +583,21 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
        if (p2p_hello) {
                if (circuit->circ_type != CIRCUIT_T_P2P) {
                        zlog_warn("p2p hello on non p2p circuit");
+#ifndef FABRICD
+                       isis_notif_reject_adjacency(
+                               circuit, "p2p hello on non p2p circuit",
+                               raw_pdu);
+#endif /* ifndef FABRICD */
                        return ISIS_WARNING;
                }
        } else {
                if (circuit->circ_type != CIRCUIT_T_BROADCAST) {
                        zlog_warn("lan hello on non broadcast circuit");
+#ifndef FABRICD
+                       isis_notif_reject_adjacency(
+                               circuit, "lan hello on non broadcast circuit",
+                               raw_pdu);
+#endif /* ifndef FABRICD */
                        return ISIS_WARNING;
                }
 
@@ -586,6 +605,12 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                        zlog_debug(
                                "level %d LAN Hello received over circuit with externalDomain = true",
                                level);
+#ifndef FABRICD
+                       isis_notif_reject_adjacency(
+                               circuit,
+                               "LAN Hello received over circuit with externalDomain = true",
+                               raw_pdu);
+#endif /* ifndef FABRICD */
                        return ISIS_WARNING;
                }
 
@@ -596,6 +621,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                                        circuit->area->area_tag,
                                        circuit->interface->name);
                        }
+#ifndef FABRICD
+                       isis_notif_reject_adjacency(
+                               circuit, "Interface level mismatch", raw_pdu);
+#endif /* ifndef FABRICD */
                        return ISIS_WARNING;
                }
        }
@@ -621,6 +650,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                        "ISIS-Adj (%s): Rcvd %s from (%s) with invalid pdu length %" PRIu16,
                        circuit->area->area_tag, pdu_name,
                        circuit->interface->name, iih.pdu_len);
+#ifndef FABRICD
+               isis_notif_reject_adjacency(circuit, "Invalid PDU length",
+                                           raw_pdu);
+#endif /* ifndef FABRICD */
                return ISIS_WARNING;
        }
 
@@ -628,6 +661,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                flog_err(EC_ISIS_PACKET,
                         "Level %d LAN Hello with Circuit Type %d", level,
                         iih.circ_type);
+#ifndef FABRICD
+               isis_notif_reject_adjacency(
+                       circuit, "LAN Hello with wrong IS-level", raw_pdu);
+#endif /* ifndef FABRICD */
                return ISIS_ERROR;
        }
 
@@ -637,24 +674,47 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
        if (isis_unpack_tlvs(STREAM_READABLE(circuit->rcv_stream),
                             circuit->rcv_stream, &iih.tlvs, &error_log)) {
                zlog_warn("isis_unpack_tlvs() failed: %s", error_log);
+#ifndef FABRICD
+               isis_notif_reject_adjacency(circuit, "Failed to unpack TLVs",
+                                           raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
        if (!iih.tlvs->area_addresses.count) {
                zlog_warn("No Area addresses TLV in %s", pdu_name);
+#ifndef FABRICD
+               /* send northbound notification */
+               isis_notif_area_mismatch(circuit, raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
        if (!iih.tlvs->protocols_supported.count) {
                zlog_warn("No supported protocols TLV in %s", pdu_name);
+#ifndef FABRICD
+               isis_notif_reject_adjacency(
+                       circuit, "No supported protocols TLV", raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
-       if (!isis_tlvs_auth_is_valid(iih.tlvs, &circuit->passwd,
-                                    circuit->rcv_stream, false)) {
+       int auth_code = isis_tlvs_auth_is_valid(iih.tlvs, &circuit->passwd,
+                                               circuit->rcv_stream, false);
+       if (auth_code != ISIS_AUTH_OK) {
                isis_event_auth_failure(circuit->area->area_tag,
                                        "IIH authentication failure",
                                        iih.sys_id);
+#ifndef FABRICD
+               /* send northbound notification */
+               stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+                               pdu_end - pdu_start);
+               if (auth_code == ISIS_AUTH_FAILURE)
+                       isis_notif_authentication_failure(circuit, raw_pdu);
+               else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+                       isis_notif_authentication_type_failure(circuit,
+                                                              raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
@@ -662,6 +722,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                zlog_warn(
                        "ISIS-Adj (%s): Received IIH with own sysid - discard",
                        circuit->area->area_tag);
+#ifndef FABRICD
+               isis_notif_reject_adjacency(
+                       circuit, "Received IIH with our own sysid", raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
@@ -676,6 +740,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                                circuit->area->area_tag, level,
                                circuit->interface->name);
                }
+#ifndef FABRICD
+               /* send northbound notification */
+               isis_notif_area_mismatch(circuit, raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
@@ -691,7 +759,11 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                                "ISIS-Adj (%s): Neither IPv4 nor IPv6 considered usable. Ignoring IIH",
                                circuit->area->area_tag);
                }
-
+#ifndef FABRICD
+               isis_notif_reject_adjacency(
+                       circuit, "Neither IPv4 not IPv6 considered usable",
+                       raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
@@ -702,6 +774,16 @@ out:
        return retval;
 }
 
+static void lsp_flood_or_update(struct isis_lsp *lsp,
+                               struct isis_circuit *circuit,
+                               bool circuit_scoped)
+{
+       if (!circuit_scoped)
+               lsp_flood(lsp, circuit);
+       else
+               fabricd_update_lsp_no_flood(lsp, circuit);
+}
+
 /*
  * Process Level 1/2 Link State
  * ISO - 10589
@@ -712,6 +794,12 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
 {
        int level;
        bool circuit_scoped;
+       size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+       size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+       char raw_pdu[pdu_end - pdu_start];
+
+       stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+                       pdu_end - pdu_start);
 
        if (pdu_type == FS_LINK_STATE) {
                if (!fabricd)
@@ -756,6 +844,12 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
        hdr.checksum = stream_getw(circuit->rcv_stream);
        hdr.lsp_bits = stream_getc(circuit->rcv_stream);
 
+#ifndef FABRICD
+       /* send northbound notification */
+       isis_notif_lsp_received(circuit, rawlspid_print(hdr.lsp_id), hdr.seqno,
+                               time(NULL), sysid_print(hdr.lsp_id));
+#endif /* ifndef FABRICD */
+
        if (pdu_len_validate(hdr.pdu_len, circuit)) {
                zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %" PRIu16,
                           circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
@@ -822,6 +916,17 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
                             circuit->rcv_stream, &tlvs, &error_log)) {
                zlog_warn("Something went wrong unpacking the LSP: %s",
                          error_log);
+#ifndef FABRICD
+               /* send northbound notification. Note that the tlv-type and
+                * offset cannot correctly be set here as they are not returned
+                * by isis_unpack_tlvs, but in there I cannot fire a
+                * notification because I have no circuit information. So until
+                * we change the code above to return those extra fields, we
+                * will send dummy values which are ignored in the callback
+                */
+               isis_notif_lsp_error(circuit, rawlspid_print(hdr.lsp_id),
+                                    raw_pdu, 0, 0);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
@@ -834,10 +939,20 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
        struct isis_passwd *passwd = (level == ISIS_LEVEL1)
                                             ? &circuit->area->area_passwd
                                             : &circuit->area->domain_passwd;
-       if (!isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream, true)) {
+       int auth_code = isis_tlvs_auth_is_valid(tlvs, passwd,
+                                               circuit->rcv_stream, true);
+       if (auth_code != ISIS_AUTH_OK) {
                isis_event_auth_failure(circuit->area->area_tag,
                                        "LSP authentication failure",
                                        hdr.lsp_id);
+#ifndef FABRICD
+               /* send northbound notification */
+               if (auth_code == ISIS_AUTH_FAILURE)
+                       isis_notif_authentication_failure(circuit, raw_pdu);
+               else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+                       isis_notif_authentication_type_failure(circuit,
+                                                              raw_pdu);
+#endif /* ifndef FABRICD */
                goto out;
        }
 
@@ -931,8 +1046,8 @@ dontcheckadj:
                                                   lsp_confusion);
                                        tlvs = NULL;
                                        /* ii */
-                                       if (!circuit_scoped)
-                                               lsp_flood(lsp, NULL);
+                                       lsp_flood_or_update(lsp, NULL,
+                                                           circuit_scoped);
                                        /* v */
                                        ISIS_FLAGS_CLEAR_ALL(
                                                lsp->SSNflags); /* FIXME:
@@ -976,9 +1091,19 @@ dontcheckadj:
                        } else if (lsp->hdr.rem_lifetime != 0) {
                                /* our own LSP -> 7.3.16.4 c) */
                                if (comp == LSP_NEWER) {
+#ifndef FABRICD
+                                       if (lsp->hdr.seqno < hdr.seqno) {
+                                               /* send northbound
+                                                * notification */
+                                               isis_notif_seqno_skipped(
+                                                       circuit,
+                                                       rawlspid_print(
+                                                               hdr.lsp_id));
+                                       }
+#endif /* ifndef FABRICD */
                                        lsp_inc_seqno(lsp, hdr.seqno);
-                                       if (!circuit_scoped)
-                                               lsp_flood(lsp, NULL);
+                                       lsp_flood_or_update(lsp, NULL,
+                                                           circuit_scoped);
                                } else {
                                        isis_tx_queue_add(circuit->tx_queue,
                                                          lsp, TX_LSP_NORMAL);
@@ -986,10 +1111,19 @@ dontcheckadj:
                                }
                                if (isis->debugs & DEBUG_UPDATE_PACKETS)
                                        zlog_debug(
-                                               "ISIS-Upd (%s): (1) re-originating LSP %s new seq 0x%08" PRIx32,
+                                               "ISIS-Upd (%s): (1) "
+                                               "re-originating LSP %s new seq "
+                                               "0x%08" PRIx32,
                                                circuit->area->area_tag,
                                                rawlspid_print(hdr.lsp_id),
                                                lsp->hdr.seqno);
+                       } else {
+                               /* our own LSP with 0 remaining life time */
+#ifndef FABRICD
+                               /* send northbound notification */
+                               isis_notif_own_lsp_purge(
+                                       circuit, rawlspid_print(hdr.lsp_id));
+#endif /* ifndef FABRICD */
                        }
                }
                goto out;
@@ -1014,6 +1148,11 @@ dontcheckadj:
                if (comp == LSP_NEWER) {
                        /* 7.3.16.1  */
                        lsp_inc_seqno(lsp, hdr.seqno);
+#ifndef FABRICD
+                       /* send northbound notification */
+                       isis_notif_seqno_skipped(circuit,
+                                                rawlspid_print(hdr.lsp_id));
+#endif /* ifndef FABRICD */
                        if (isis->debugs & DEBUG_UPDATE_PACKETS) {
                                zlog_debug(
                                        "ISIS-Upd (%s): (2) re-originating LSP %s new seq 0x%08" PRIx32,
@@ -1068,8 +1207,7 @@ dontcheckadj:
                                           circuit->area, level, false);
                                tlvs = NULL;
                        }
-                       if (!circuit_scoped)
-                               lsp_flood(lsp, circuit);
+                       lsp_flood_or_update(lsp, circuit, circuit_scoped);
 
                        /* iv */
                        if (circuit->circ_type != CIRCUIT_T_BROADCAST)
@@ -1096,9 +1234,7 @@ dontcheckadj:
        retval = ISIS_OK;
 
 out:
-       if (circuit_scoped) {
-               fabricd_trigger_csnp(circuit->area);
-       }
+       fabricd_trigger_csnp(circuit->area, circuit_scoped);
 
        isis_free_tlvs(tlvs);
        return retval;
@@ -1113,6 +1249,12 @@ out:
 static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
                       const uint8_t *ssnpa)
 {
+#ifndef FABRICD
+       size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+       size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+       char raw_pdu[pdu_end - pdu_start];
+#endif /* ifndef FABRICD */
+
        bool is_csnp = (pdu_type == L1_COMPLETE_SEQ_NUM
                        || pdu_type == L2_COMPLETE_SEQ_NUM);
        char typechar = is_csnp ? 'C' : 'P';
@@ -1123,6 +1265,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
 
        uint16_t pdu_len = stream_getw(circuit->rcv_stream);
        uint8_t rem_sys_id[ISIS_SYS_ID_LEN];
+
        stream_get(rem_sys_id, circuit->rcv_stream, ISIS_SYS_ID_LEN);
        stream_forward_getp(circuit->rcv_stream, 1); /* Circuit ID - unused */
 
@@ -1226,13 +1369,26 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
        struct isis_passwd *passwd = (level == IS_LEVEL_1)
                                             ? &circuit->area->area_passwd
                                             : &circuit->area->domain_passwd;
-       if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)
-           && !isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream,
-                                       false)) {
-               isis_event_auth_failure(circuit->area->area_tag,
-                                       "SNP authentication failure",
-                                       rem_sys_id);
-               goto out;
+       if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)) {
+               int auth_code = isis_tlvs_auth_is_valid(
+                       tlvs, passwd, circuit->rcv_stream, false);
+               if (auth_code != ISIS_AUTH_OK) {
+                       isis_event_auth_failure(circuit->area->area_tag,
+                                               "SNP authentication failure",
+                                               rem_sys_id);
+#ifndef FABRICD
+                       /* send northbound notification */
+                       stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+                                       pdu_end - pdu_start);
+                       if (auth_code == ISIS_AUTH_FAILURE)
+                               isis_notif_authentication_failure(circuit,
+                                                                 raw_pdu);
+                       else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+                               isis_notif_authentication_type_failure(circuit,
+                                                                      raw_pdu);
+#endif /* ifndef FABRICD */
+                       goto out;
+               }
        }
 
        struct isis_lsp_entry *entry_head =
@@ -1412,6 +1568,12 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size)
 int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
 {
        int retval = ISIS_OK;
+       size_t pdu_start = stream_get_getp(circuit->rcv_stream);
+       size_t pdu_end = stream_get_endp(circuit->rcv_stream);
+       char raw_pdu[pdu_end - pdu_start];
+
+       stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
+                       pdu_end - pdu_start);
 
        /* Verify that at least the 8 bytes fixed header have been received */
        if (stream_get_endp(circuit->rcv_stream) < ISIS_FIXED_HDR_LEN) {
@@ -1426,9 +1588,12 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
        uint8_t pdu_type = stream_getc(circuit->rcv_stream)
                           & 0x1f; /* bits 6-8 are reserved */
        uint8_t version2 = stream_getc(circuit->rcv_stream);
+
        stream_forward_getp(circuit->rcv_stream, 1); /* reserved */
        uint8_t max_area_addrs = stream_getc(circuit->rcv_stream);
 
+       pdu_counter_count(circuit->area->pdu_rx_counters, pdu_type);
+
        if (idrp == ISO9542_ESIS) {
                flog_err(EC_LIB_DEVELOPMENT,
                         "No support for ES-IS packet IDRP=%" PRIx8, idrp);
@@ -1443,6 +1608,10 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
 
        if (version1 != 1) {
                zlog_warn("Unsupported ISIS version %" PRIu8, version1);
+#ifndef FABRICD
+               /* send northbound notification */
+               isis_notif_version_skew(circuit, version1, raw_pdu);
+#endif /* ifndef FABRICD */
                return ISIS_WARNING;
        }
 
@@ -1452,6 +1621,10 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
                        "IDFieldLengthMismatch: ID Length field in a received PDU  %" PRIu8
                        ", while the parameter for this IS is %u",
                        id_len, ISIS_SYS_ID_LEN);
+#ifndef FABRICD
+               /* send northbound notification */
+               isis_notif_id_len_mismatch(circuit, id_len, raw_pdu);
+#endif /* ifndef FABRICD */
                return ISIS_ERROR;
        }
 
@@ -1478,6 +1651,10 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
 
        if (version2 != 1) {
                zlog_warn("Unsupported ISIS PDU version %" PRIu8, version2);
+#ifndef FABRICD
+               /* send northbound notification */
+               isis_notif_version_skew(circuit, version2, raw_pdu);
+#endif /* ifndef FABRICD */
                return ISIS_WARNING;
        }
 
@@ -1496,6 +1673,11 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
                        "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8
                        " while the parameter for this IS is %u",
                        max_area_addrs, isis->max_area_addrs);
+#ifndef FABRICD
+               /* send northbound notification */
+               isis_notif_max_area_addr_mismatch(circuit, max_area_addrs,
+                                                 raw_pdu);
+#endif /* ifndef FABRICD */
                return ISIS_ERROR;
        }
 
@@ -1581,15 +1763,18 @@ void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream)
        stream_putc(stream, 0); /* Max Area Addresses 0 => 3 */
 }
 
-static void put_hello_hdr(struct isis_circuit *circuit, int level,
-                         size_t *len_pointer)
+static uint8_t hello_pdu_type(struct isis_circuit *circuit, int level)
 {
-       uint8_t pdu_type;
-
        if (circuit->circ_type == CIRCUIT_T_BROADCAST)
-               pdu_type = (level == IS_LEVEL_1) ? L1_LAN_HELLO : L2_LAN_HELLO;
+               return (level == IS_LEVEL_1) ? L1_LAN_HELLO : L2_LAN_HELLO;
        else
-               pdu_type = P2P_HELLO;
+               return P2P_HELLO;
+}
+
+static void put_hello_hdr(struct isis_circuit *circuit, int level,
+                         size_t *len_pointer)
+{
+       uint8_t pdu_type = hello_pdu_type(circuit, level);
 
        isis_circuit_stream(circuit, &circuit->snd_stream);
        fill_fixed_hdr(pdu_type, circuit->snd_stream);
@@ -1732,6 +1917,8 @@ int send_hello(struct isis_circuit *circuit, int level)
 
        isis_free_tlvs(tlvs);
 
+       pdu_counter_count(circuit->area->pdu_tx_counters,
+                         hello_pdu_type(circuit, level));
        retval = circuit->tx(circuit, level);
        if (retval != ISIS_OK)
                flog_err(EC_ISIS_PACKET,
@@ -1745,9 +1932,8 @@ int send_hello(struct isis_circuit *circuit, int level)
 static int send_hello_cb(struct thread *thread)
 {
        struct isis_circuit_arg *arg = THREAD_ARG(thread);
-       
        assert(arg);
-       
+
        struct isis_circuit *circuit = arg->circuit;
        int level = arg->level;
 
@@ -1858,10 +2044,11 @@ int send_csnp(struct isis_circuit *circuit, int level)
            || dict_count(circuit->area->lspdb[level - 1]) == 0)
                return ISIS_OK;
 
+       uint8_t pdu_type = (level == ISIS_LEVEL1) ? L1_COMPLETE_SEQ_NUM
+                                                 : L2_COMPLETE_SEQ_NUM;
+
        isis_circuit_stream(circuit, &circuit->snd_stream);
-       fill_fixed_hdr((level == ISIS_LEVEL1) ? L1_COMPLETE_SEQ_NUM
-                                             : L2_COMPLETE_SEQ_NUM,
-                      circuit->snd_stream);
+       fill_fixed_hdr(pdu_type, circuit->snd_stream);
 
        size_t len_pointer = stream_get_endp(circuit->snd_stream);
        stream_putw(circuit->snd_stream, 0);
@@ -1943,6 +2130,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
                                        stream_get_endp(circuit->snd_stream));
                }
 
+               pdu_counter_count(circuit->area->pdu_tx_counters, pdu_type);
                int retval = circuit->tx(circuit, level);
                if (retval != ISIS_OK) {
                        flog_err(EC_ISIS_PACKET,
@@ -2036,10 +2224,11 @@ static int send_psnp(int level, struct isis_circuit *circuit)
        if (!circuit->snd_stream)
                return ISIS_ERROR;
 
+       uint8_t pdu_type = (level == ISIS_LEVEL1) ? L1_PARTIAL_SEQ_NUM
+                                                 : L2_PARTIAL_SEQ_NUM;
+
        isis_circuit_stream(circuit, &circuit->snd_stream);
-       fill_fixed_hdr((level == ISIS_LEVEL1) ? L1_PARTIAL_SEQ_NUM
-                                             : L2_PARTIAL_SEQ_NUM,
-                      circuit->snd_stream);
+       fill_fixed_hdr(pdu_type, circuit->snd_stream);
 
        size_t len_pointer = stream_get_endp(circuit->snd_stream);
        stream_putw(circuit->snd_stream, 0); /* length is filled in later */
@@ -2110,6 +2299,7 @@ static int send_psnp(int level, struct isis_circuit *circuit)
                                        stream_get_endp(circuit->snd_stream));
                }
 
+               pdu_counter_count(circuit->area->pdu_tx_counters, pdu_type);
                int retval = circuit->tx(circuit, level);
                if (retval != ISIS_OK) {
                        flog_err(EC_ISIS_PACKET,
@@ -2182,9 +2372,9 @@ int send_l2_psnp(struct thread *thread)
 /*
  * ISO 10589 - 7.3.14.3
  */
-void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type)
+void send_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp,
+             enum isis_tx_type tx_type)
 {
-       struct isis_circuit *circuit = arg;
        int clear_srm = 1;
        int retval = ISIS_OK;
 
@@ -2217,6 +2407,11 @@ void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type)
                        lsp->hdr.checksum, lsp->hdr.rem_lifetime,
                        circuit->interface->name, stream_get_endp(lsp->pdu),
                        stream_get_size(circuit->snd_stream));
+#ifndef FABRICD
+               /* send a northbound notification */
+               isis_notif_lsp_too_large(circuit, stream_get_endp(lsp->pdu),
+                                        rawlspid_print(lsp->hdr.lsp_id));
+#endif /* ifndef FABRICD */
                if (isis->debugs & DEBUG_PACKET_DUMP)
                        zlog_dump_data(STREAM_DATA(lsp->pdu),
                                       stream_get_endp(lsp->pdu));
@@ -2229,14 +2424,18 @@ void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type)
 
        if (tx_type == TX_LSP_CIRCUIT_SCOPED) {
                stream_putc_at(circuit->snd_stream, 4, FS_LINK_STATE);
-               stream_putc_at(circuit->snd_stream, 7, L2_CIRCUIT_FLOODING_SCOPE);
+               stream_putc_at(circuit->snd_stream, 7,
+                              L2_CIRCUIT_FLOODING_SCOPE);
        }
 
        if (isis->debugs & DEBUG_UPDATE_PACKETS) {
-               zlog_debug("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08" PRIx32
+               zlog_debug("ISIS-Upd (%s): Sending %sL%d LSP %s, seq 0x%08" PRIx32
                           ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
                           "s on %s",
-                          circuit->area->area_tag, lsp->level,
+                          circuit->area->area_tag,
+                          (tx_type == TX_LSP_CIRCUIT_SCOPED)
+                               ? "Circuit scoped " : "",
+                          lsp->level,
                           rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.seqno,
                           lsp->hdr.checksum, lsp->hdr.rem_lifetime,
                           circuit->interface->name);
@@ -2245,7 +2444,12 @@ void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type)
                                       stream_get_endp(circuit->snd_stream));
        }
 
+       uint8_t pdu_type = (tx_type == TX_LSP_CIRCUIT_SCOPED) ? FS_LINK_STATE
+                        : (lsp->level == ISIS_LEVEL1) ? L1_LINK_STATE
+                                                      : L2_LINK_STATE;
+
        clear_srm = 0;
+       pdu_counter_count(circuit->area->pdu_tx_counters, pdu_type);
        retval = circuit->tx(circuit, lsp->level);
        if (retval != ISIS_OK) {
                flog_err(EC_ISIS_PACKET,
index 0fa3b2c7ab06a40a83faaaa76aa5551746739dca..1e70a42f132121e0a9baa66ea1a20fb49a64379e 100644 (file)
@@ -214,7 +214,8 @@ int send_l1_csnp(struct thread *thread);
 int send_l2_csnp(struct thread *thread);
 int send_l1_psnp(struct thread *thread);
 int send_l2_psnp(struct thread *thread);
-void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type);
+void send_lsp(struct isis_circuit *circuit,
+             struct isis_lsp *lsp, enum isis_tx_type tx_type);
 void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
 int send_hello(struct isis_circuit *circuit, int level);
 int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa);
diff --git a/isisd/isis_pdu_counter.c b/isisd/isis_pdu_counter.c
new file mode 100644 (file)
index 0000000..ec2a0c2
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * IS-IS Routing protocol - isis_pdu_counter.c
+ * Copyright (C) 2018 Christian Franke, for NetDEF Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "vty.h"
+
+#include "isisd/isis_pdu_counter.h"
+#include "isisd/isisd.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_pdu.h"
+
+static int pdu_type_to_counter_index(uint8_t pdu_type)
+{
+       switch (pdu_type) {
+       case L1_LAN_HELLO:
+               return L1_LAN_HELLO_INDEX;
+       case L2_LAN_HELLO:
+               return L2_LAN_HELLO_INDEX;
+       case P2P_HELLO:
+               return P2P_HELLO_INDEX;
+       case L1_LINK_STATE:
+               return L1_LINK_STATE_INDEX;
+       case L2_LINK_STATE:
+               return L2_LINK_STATE_INDEX;
+       case FS_LINK_STATE:
+               return FS_LINK_STATE_INDEX;
+       case L1_COMPLETE_SEQ_NUM:
+               return L1_COMPLETE_SEQ_NUM_INDEX;
+       case L2_COMPLETE_SEQ_NUM:
+               return L2_COMPLETE_SEQ_NUM_INDEX;
+       case L1_PARTIAL_SEQ_NUM:
+               return L1_PARTIAL_SEQ_NUM_INDEX;
+       case L2_PARTIAL_SEQ_NUM:
+               return L2_PARTIAL_SEQ_NUM_INDEX;
+       default:
+               return -1;
+       }
+}
+
+static const char *pdu_counter_index_to_name(enum pdu_counter_index index)
+{
+       switch (index) {
+       case L1_LAN_HELLO_INDEX:
+               return " L1 IIH";
+       case L2_LAN_HELLO_INDEX:
+               return " L2 IIH";
+       case P2P_HELLO_INDEX:
+               return "P2P IIH";
+       case L1_LINK_STATE_INDEX:
+               return " L1 LSP";
+       case L2_LINK_STATE_INDEX:
+               return " L2 LSP";
+       case FS_LINK_STATE_INDEX:
+               return " FS LSP";
+       case L1_COMPLETE_SEQ_NUM_INDEX:
+               return "L1 CSNP";
+       case L2_COMPLETE_SEQ_NUM_INDEX:
+               return "L2 CSNP";
+       case L1_PARTIAL_SEQ_NUM_INDEX:
+               return "L1 PSNP";
+       case L2_PARTIAL_SEQ_NUM_INDEX:
+               return "L2 PSNP";
+       default:
+               return "???????";
+       }
+}
+
+void pdu_counter_count(pdu_counter_t counter, uint8_t pdu_type)
+{
+       int index = pdu_type_to_counter_index(pdu_type);
+
+       if (index < 0)
+               return;
+
+       counter[index]++;
+}
+
+void pdu_counter_print(struct vty *vty, const char *prefix,
+                      pdu_counter_t counter)
+{
+       for (int i = 0; i < PDU_COUNTER_SIZE; i++) {
+               if (!counter[i])
+                       continue;
+               vty_out(vty, "%s%s: %" PRIu64 "\n", prefix,
+                       pdu_counter_index_to_name(i), counter[i]);
+       }
+}
diff --git a/isisd/isis_pdu_counter.h b/isisd/isis_pdu_counter.h
new file mode 100644 (file)
index 0000000..7f07adf
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * IS-IS Routing protocol - isis_pdu_counter.c
+ * Copyright (C) 2018 Christian Franke, for NetDEF Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef ISIS_PDU_COUNTER_H
+#define ISIS_PDU_COUNTER_H
+
+enum pdu_counter_index {
+       L1_LAN_HELLO_INDEX = 0,
+       L2_LAN_HELLO_INDEX,
+       P2P_HELLO_INDEX,
+       L1_LINK_STATE_INDEX,
+       L2_LINK_STATE_INDEX,
+       FS_LINK_STATE_INDEX,
+       L1_COMPLETE_SEQ_NUM_INDEX,
+       L2_COMPLETE_SEQ_NUM_INDEX,
+       L1_PARTIAL_SEQ_NUM_INDEX,
+       L2_PARTIAL_SEQ_NUM_INDEX,
+       PDU_COUNTER_SIZE
+};
+typedef uint64_t pdu_counter_t[PDU_COUNTER_SIZE];
+
+void pdu_counter_print(struct vty *vty, const char *prefix,
+                      pdu_counter_t counter);
+void pdu_counter_count(pdu_counter_t counter, uint8_t pdu_type);
+
+#endif
index 6564149a43d99480d9bb241e288ad66abd900839..815de513fc592e70366efd6bc61178cf60ea6815 100644 (file)
@@ -388,9 +388,8 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis)
                }
 }
 
-static void isis_redist_set(struct isis_area *area, int level, int family,
-                           int type, uint32_t metric, const char *routemap,
-                           int originate_type)
+void isis_redist_set(struct isis_area *area, int level, int family, int type,
+                    uint32_t metric, const char *routemap, int originate_type)
 {
        int protocol = redist_protocol(family);
        struct isis_redist *redist =
@@ -445,8 +444,7 @@ static void isis_redist_set(struct isis_area *area, int level, int family,
        }
 }
 
-static void isis_redist_unset(struct isis_area *area, int level, int family,
-                             int type)
+void isis_redist_unset(struct isis_area *area, int level, int family, int type)
 {
        struct isis_redist *redist =
                get_redist_settings(area, family, type, level);
@@ -513,21 +511,15 @@ void isis_redist_area_finish(struct isis_area *area)
        isis_redist_update_zebra_subscriptions(area->isis);
 }
 
+#ifdef FABRICD
 DEFUN (isis_redistribute,
        isis_redistribute_cmd,
        "redistribute <ipv4|ipv6> " PROTO_REDIST_STR
-#ifndef FABRICD
-       " <level-1|level-2>"
-#endif
        " [<metric (0-16777215)|route-map WORD>]",
        REDIST_STR
        "Redistribute IPv4 routes\n"
        "Redistribute IPv6 routes\n"
        PROTO_REDIST_HELP
-#ifndef FABRICD
-       "Redistribute into level-1\n"
-       "Redistribute into level-2\n"
-#endif
        "Metric for redistributed routes\n"
        "ISIS default metric\n"
        "Route map reference\n"
@@ -535,7 +527,6 @@ DEFUN (isis_redistribute,
 {
        int idx_afi = 1;
        int idx_protocol = 2;
-       int idx_level = 3;
        int idx_metric_rmap = fabricd ? 3 : 4;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int family;
@@ -557,14 +548,7 @@ DEFUN (isis_redistribute,
        if (type < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (fabricd)
-               level = 2;
-       else if (!strcmp("level-1", argv[idx_level]->arg))
-               level = 1;
-       else if (!strcmp("level-2", argv[idx_level]->arg))
-               level = 2;
-       else
-               return CMD_WARNING_CONFIG_FAILED;
+       level = 2;
 
        if ((area->is_type & level) != level) {
                vty_out(vty, "Node is not a level-%d IS\n", level);
@@ -593,24 +577,15 @@ DEFUN (isis_redistribute,
 
 DEFUN (no_isis_redistribute,
        no_isis_redistribute_cmd,
-       "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR
-#ifndef FABRICD
-       " <level-1|level-2>"
-#endif
-       , NO_STR
+       "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR,
+       NO_STR
        REDIST_STR
        "Redistribute IPv4 routes\n"
        "Redistribute IPv6 routes\n"
-       PROTO_REDIST_HELP
-#ifndef FABRICD
-       "Redistribute into level-1\n"
-       "Redistribute into level-2\n"
-#endif
-       )
+       PROTO_REDIST_HELP)
 {
        int idx_afi = 2;
        int idx_protocol = 3;
-       int idx_level = 4;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int type;
        int level;
@@ -629,10 +604,7 @@ DEFUN (no_isis_redistribute,
        if (type < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (fabricd)
-               level = 2;
-       else
-               level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
+       level = 2;
 
        isis_redist_unset(area, level, family, type);
        return 0;
@@ -641,18 +613,11 @@ DEFUN (no_isis_redistribute,
 DEFUN (isis_default_originate,
        isis_default_originate_cmd,
        "default-information originate <ipv4|ipv6>"
-#ifndef FABRICD
-       " <level-1|level-2>"
-#endif
        " [always] [<metric (0-16777215)|route-map WORD>]",
        "Control distribution of default information\n"
        "Distribute a default route\n"
        "Distribute default route for IPv4\n"
        "Distribute default route for IPv6\n"
-#ifndef FABRICD
-       "Distribute default route into level-1\n"
-       "Distribute default route into level-2\n"
-#endif
        "Always advertise default route\n"
        "Metric for default route\n"
        "ISIS default metric\n"
@@ -660,7 +625,6 @@ DEFUN (isis_default_originate,
        "Pointer to route-map entries\n")
 {
        int idx_afi = 2;
-       int idx_level = 3;
        int idx_always = fabricd ? 3 : 4;
        int idx_metric_rmap = fabricd ? 3 : 4;
        VTY_DECLVAR_CONTEXT(isis_area, area);
@@ -674,10 +638,7 @@ DEFUN (isis_default_originate,
        if (family < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (fabricd)
-               level = 2;
-       else
-               level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
+       level = 2;
 
        if ((area->is_type & level) != level) {
                vty_out(vty, "Node is not a level-%d IS\n", level);
@@ -711,23 +672,14 @@ DEFUN (isis_default_originate,
 
 DEFUN (no_isis_default_originate,
        no_isis_default_originate_cmd,
-       "no default-information originate <ipv4|ipv6>"
-#ifndef FABRICD
-       " <level-1|level-2>"
-#endif
-       , NO_STR
+       "no default-information originate <ipv4|ipv6>",
+       NO_STR
        "Control distribution of default information\n"
        "Distribute a default route\n"
        "Distribute default route for IPv4\n"
-       "Distribute default route for IPv6\n"
-#ifndef FABRICD
-       "Distribute default route into level-1\n"
-       "Distribute default route into level-2\n"
-#endif
-       )
+       "Distribute default route for IPv6\n")
 {
        int idx_afi = 3;
-       int idx_level = 4;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int family;
        int level;
@@ -736,18 +688,12 @@ DEFUN (no_isis_default_originate,
        if (family < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (fabricd)
-               level = 2;
-       else if (strmatch("level-1", argv[idx_level]->text))
-               level = 1;
-       else if (strmatch("level-2", argv[idx_level]->text))
-               level = 2;
-       else
-               return CMD_WARNING_CONFIG_FAILED;
+       level = 2;
 
        isis_redist_unset(area, level, family, DEFAULT_ROUTE);
        return 0;
 }
+#endif /* ifdef FABRICD */
 
 int isis_redist_config_write(struct vty *vty, struct isis_area *area,
                             int family)
@@ -810,8 +756,11 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
 
 void isis_redist_init(void)
 {
+#ifdef FABRICD
        install_element(ROUTER_NODE, &isis_redistribute_cmd);
        install_element(ROUTER_NODE, &no_isis_redistribute_cmd);
+
        install_element(ROUTER_NODE, &isis_default_originate_cmd);
        install_element(ROUTER_NODE, &no_isis_default_originate_cmd);
+#endif /* ifdef FABRICD */
 }
index 95f06f71ec9a343f88e71e4fa4f88867d77797f9..9c37c310eae8e61dfa00c8a7fd9d0b639a590629 100644 (file)
@@ -55,4 +55,8 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
 void isis_redist_init(void);
 void isis_redist_area_finish(struct isis_area *area);
 
+void isis_redist_set(struct isis_area *area, int level, int family, int type,
+                    uint32_t metric, const char *routemap, int originate_type);
+void isis_redist_unset(struct isis_area *area, int level, int family, int type);
+
 #endif
index 08b905c65032fd89ca22169329ac76cc45151d62..a69c95cadf8ce9073661cf07e5f00a68e39fa7bf 100644 (file)
@@ -1087,141 +1087,6 @@ static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp)
        return circuit->mtc;
 }
 
-DEFUN (isis_mpls_te_on,
-       isis_mpls_te_on_cmd,
-       "mpls-te on",
-       MPLS_TE_STR
-       "Enable MPLS-TE functionality\n")
-{
-       struct listnode *node;
-       struct isis_circuit *circuit;
-
-       if (IS_MPLS_TE(isisMplsTE))
-               return CMD_SUCCESS;
-
-       if (IS_DEBUG_ISIS(DEBUG_TE))
-               zlog_debug("ISIS MPLS-TE: OFF -> ON");
-
-       isisMplsTE.status = enable;
-
-       /*
-        * Following code is intended to handle two cases;
-        *
-        * 1) MPLS-TE was disabled at startup time, but now become enabled.
-        * In this case, we must enable MPLS-TE Circuit regarding interface
-        * MPLS_TE flag
-        * 2) MPLS-TE was once enabled then disabled, and now enabled again.
-        */
-       for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) {
-               if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type))
-                       continue;
-
-               if ((circuit->mtc->status == disable)
-                   && HAS_LINK_PARAMS(circuit->interface))
-                       circuit->mtc->status = enable;
-               else
-                       continue;
-
-               /* Reoriginate STD_TE & GMPLS circuits */
-               if (circuit->area)
-                       lsp_regenerate_schedule(circuit->area, circuit->is_type,
-                                               0);
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_mpls_te_on,
-       no_isis_mpls_te_on_cmd,
-       "no mpls-te",
-       NO_STR
-       "Disable the MPLS-TE functionality\n")
-{
-       struct listnode *node;
-       struct isis_circuit *circuit;
-
-       if (isisMplsTE.status == disable)
-               return CMD_SUCCESS;
-
-       if (IS_DEBUG_ISIS(DEBUG_TE))
-               zlog_debug("ISIS MPLS-TE: ON -> OFF");
-
-       isisMplsTE.status = disable;
-
-       /* Flush LSP if circuit engage */
-       for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) {
-               if (circuit->mtc == NULL || (circuit->mtc->status == disable))
-                       continue;
-
-               /* disable MPLS_TE Circuit */
-               circuit->mtc->status = disable;
-
-               /* Re-originate circuit without STD_TE & GMPLS parameters */
-               if (circuit->area)
-                       lsp_regenerate_schedule(circuit->area, circuit->is_type,
-                                               0);
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_mpls_te_router_addr,
-       isis_mpls_te_router_addr_cmd,
-       "mpls-te router-address A.B.C.D",
-       MPLS_TE_STR
-       "Stable IP address of the advertising router\n"
-       "MPLS-TE router address in IPv4 address format\n")
-{
-       int idx_ipv4 = 2;
-       struct in_addr value;
-       struct listnode *node;
-       struct isis_area *area;
-
-       if (!inet_aton(argv[idx_ipv4]->arg, &value)) {
-               vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       isisMplsTE.router_id.s_addr = value.s_addr;
-
-       if (isisMplsTE.status == disable)
-               return CMD_SUCCESS;
-
-       /* Update main Router ID in isis global structure */
-       isis->router_id = value.s_addr;
-       /* And re-schedule LSP update */
-       for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
-               if (listcount(area->area_addrs) > 0)
-                       lsp_regenerate_schedule(area, area->is_type, 0);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_mpls_te_inter_as,
-       isis_mpls_te_inter_as_cmd,
-       "mpls-te inter-as <level-1|level-1-2|level-2-only>",
-       MPLS_TE_STR
-       "Configure MPLS-TE Inter-AS support\n"
-       "AREA native mode self originate INTER-AS LSP with L1 only flooding scope)\n"
-       "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope)\n"
-       "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n")
-{
-       vty_out(vty, "Not yet supported\n");
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_mpls_te_inter_as,
-       no_isis_mpls_te_inter_as_cmd,
-       "no mpls-te inter-as",
-       NO_STR
-       "Disable the MPLS-TE functionality\n"
-       "Disable MPLS-TE Inter-AS support\n")
-{
-
-       vty_out(vty, "Not yet supported\n");
-       return CMD_SUCCESS;
-}
-
 DEFUN (show_isis_mpls_te_router,
        show_isis_mpls_te_router_cmd,
        "show " PROTO_NAME " mpls-te router",
@@ -1363,12 +1228,6 @@ void isis_mpls_te_init(void)
        /* Register new VTY commands */
        install_element(VIEW_NODE, &show_isis_mpls_te_router_cmd);
        install_element(VIEW_NODE, &show_isis_mpls_te_interface_cmd);
-
-       install_element(ROUTER_NODE, &isis_mpls_te_on_cmd);
-       install_element(ROUTER_NODE, &no_isis_mpls_te_on_cmd);
-       install_element(ROUTER_NODE, &isis_mpls_te_router_addr_cmd);
-       install_element(ROUTER_NODE, &isis_mpls_te_inter_as_cmd);
-       install_element(ROUTER_NODE, &no_isis_mpls_te_inter_as_cmd);
 #endif
 
        return;
index 87d827335068c3903eaa2d06a0b66df5d82f80f9..5a6c7bc3003718a36561f59771a09a5239482c21 100644 (file)
@@ -3304,17 +3304,17 @@ static const auth_validator_func auth_validators[] = {
                [ISIS_PASSWD_TYPE_HMAC_MD5] = auth_validator_hmac_md5,
 };
 
-bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
-                            struct stream *stream, bool is_lsp)
+int isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
+                           struct stream *stream, bool is_lsp)
 {
        /* If no auth is set, always pass authentication */
        if (!passwd->type)
-               return true;
+               return ISIS_AUTH_OK;
 
        /* If we don't known how to validate the auth, return invalid */
        if (passwd->type >= array_size(auth_validators)
            || !auth_validators[passwd->type])
-               return false;
+               return ISIS_AUTH_NO_VALIDATOR;
 
        struct isis_auth *auth_head = (struct isis_auth *)tlvs->isis_auth.head;
        struct isis_auth *auth;
@@ -3325,10 +3325,14 @@ bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
 
        /* If matching auth TLV could not be found, return invalid */
        if (!auth)
-               return false;
+               return ISIS_AUTH_TYPE_FAILURE;
+
 
        /* Perform validation and return result */
-       return auth_validators[passwd->type](passwd, stream, auth, is_lsp);
+       if (auth_validators[passwd->type](passwd, stream, auth, is_lsp))
+               return ISIS_AUTH_OK;
+       else
+               return ISIS_AUTH_FAILURE;
 }
 
 bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs,
index 4144809fa3aeaaf4a55317dfe522679906ae3705..fce30d4ee7756c6c218e40088d1ac8b46749d577 100644 (file)
@@ -196,6 +196,13 @@ struct isis_purge_originator {
        uint8_t sender[6];
 };
 
+enum isis_auth_result {
+       ISIS_AUTH_OK = 0,
+       ISIS_AUTH_TYPE_FAILURE,
+       ISIS_AUTH_FAILURE,
+       ISIS_AUTH_NO_VALIDATOR,
+};
+
 RB_HEAD(isis_mt_item_list, isis_item_list);
 
 struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m,
@@ -337,8 +344,8 @@ void isis_tlvs_add_ipv4_addresses(struct isis_tlvs *tlvs,
                                  struct list *addresses);
 void isis_tlvs_add_ipv6_addresses(struct isis_tlvs *tlvs,
                                  struct list *addresses);
-bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
-                            struct stream *stream, bool is_lsp);
+int isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
+                           struct stream *stream, bool is_lsp);
 bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs,
                                    struct list *addresses);
 struct isis_adjacency;
index fe67a3f4d19794b6c5d5871301d6f1b0efa87ce4..270dcae7d0a07b734fc110433aebce8e8bc22606 100644 (file)
 #include "dict.h"
 #include "isisd/isis_circuit.h"
 #include "isisd/isis_lsp.h"
+#include "isisd/isis_misc.h"
 #include "isisd/isis_tx_queue.h"
 
 DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE, "ISIS TX Queue")
 DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE_ENTRY, "ISIS TX Queue Entry")
 
 struct isis_tx_queue {
-       void *arg;
-       void (*send_event)(void *arg, struct isis_lsp *, enum isis_tx_type);
+       struct isis_circuit *circuit;
+       void (*send_event)(struct isis_circuit *circuit,
+                          struct isis_lsp *, enum isis_tx_type);
        struct hash *hash;
 };
 
 struct isis_tx_queue_entry {
        struct isis_lsp *lsp;
        enum isis_tx_type type;
+       bool is_retry;
        struct thread *retry;
        struct isis_tx_queue *queue;
 };
@@ -72,14 +75,15 @@ static bool tx_queue_hash_cmp(const void *a, const void *b)
        return true;
 }
 
-struct isis_tx_queue *isis_tx_queue_new(void *arg,
-                                       void(*send_event)(void *arg,
-                                                         struct isis_lsp *,
-                                                         enum isis_tx_type))
+struct isis_tx_queue *isis_tx_queue_new(
+               struct isis_circuit *circuit,
+               void(*send_event)(struct isis_circuit *circuit,
+                                 struct isis_lsp *,
+                                 enum isis_tx_type))
 {
        struct isis_tx_queue *rv = XCALLOC(MTYPE_TX_QUEUE, sizeof(*rv));
 
-       rv->arg = arg;
+       rv->circuit = circuit;
        rv->send_event = send_event;
 
        rv->hash = hash_create(tx_queue_hash_key, tx_queue_hash_cmp, NULL);
@@ -121,19 +125,35 @@ static int tx_queue_send_event(struct thread *thread)
        e->retry = NULL;
        thread_add_timer(master, tx_queue_send_event, e, 5, &e->retry);
 
-       queue->send_event(queue->arg, e->lsp, e->type);
+       if (e->is_retry)
+               queue->circuit->area->lsp_rxmt_count++;
+       else
+               e->is_retry = true;
+
+       queue->send_event(queue->circuit, e->lsp, e->type);
        /* Don't access e here anymore, send_event might have destroyed it */
 
        return 0;
 }
 
-void isis_tx_queue_add(struct isis_tx_queue *queue,
-                      struct isis_lsp *lsp,
-                      enum isis_tx_type type)
+void _isis_tx_queue_add(struct isis_tx_queue *queue,
+                       struct isis_lsp *lsp,
+                       enum isis_tx_type type,
+                       const char *func, const char *file,
+                       int line)
 {
        if (!queue)
                return;
 
+       if (isis->debugs & DEBUG_TX_QUEUE) {
+               zlog_debug("Add LSP %s to %s queue as %s LSP. (From %s %s:%d)",
+                          rawlspid_print(lsp->hdr.lsp_id),
+                          queue->circuit->interface->name,
+                          (type == TX_LSP_CIRCUIT_SCOPED) ?
+                          "circuit scoped" : "regular",
+                          func, file, line);
+       }
+
        struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp);
        if (!e) {
                e = XCALLOC(MTYPE_TX_QUEUE_ENTRY, sizeof(*e));
@@ -150,9 +170,12 @@ void isis_tx_queue_add(struct isis_tx_queue *queue,
        if (e->retry)
                thread_cancel(e->retry);
        thread_add_event(master, tx_queue_send_event, e, 0, &e->retry);
+
+       e->is_retry = false;
 }
 
-void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp)
+void _isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp,
+                       const char *func, const char *file, int line)
 {
        if (!queue)
                return;
@@ -161,6 +184,13 @@ void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp)
        if (!e)
                return;
 
+       if (isis->debugs & DEBUG_TX_QUEUE) {
+               zlog_debug("Remove LSP %s from %s queue. (From %s %s:%d)",
+                          rawlspid_print(lsp->hdr.lsp_id),
+                          queue->circuit->interface->name,
+                          func, file, line);
+       }
+
        if (e->retry)
                thread_cancel(e->retry);
 
index ddecdf1e4f5589ec46c070daba53a78bc8472f21..c2beda45b72953513aa951bc9d6388534cff3bbf 100644 (file)
@@ -29,18 +29,26 @@ enum isis_tx_type {
 
 struct isis_tx_queue;
 
-struct isis_tx_queue *isis_tx_queue_new(void *arg,
-                                       void(*send_event)(void *arg,
-                                                         struct isis_lsp *,
-                                                         enum isis_tx_type));
+struct isis_tx_queue *isis_tx_queue_new(
+               struct isis_circuit *circuit,
+               void(*send_event)(struct isis_circuit *circuit,
+                                 struct isis_lsp *,
+                                 enum isis_tx_type)
+);
 
 void isis_tx_queue_free(struct isis_tx_queue *queue);
 
-void isis_tx_queue_add(struct isis_tx_queue *queue,
-                      struct isis_lsp *lsp,
-                      enum isis_tx_type type);
-
-void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp);
+#define isis_tx_queue_add(queue, lsp, type) \
+       _isis_tx_queue_add((queue), (lsp), (type), \
+                          __func__, __FILE__, __LINE__)
+void _isis_tx_queue_add(struct isis_tx_queue *queue, struct isis_lsp *lsp,
+                       enum isis_tx_type type, const char *func,
+                       const char *file, int line);
+
+#define isis_tx_queue_del(queue, lsp) \
+       _isis_tx_queue_del((queue), (lsp), __func__, __FILE__, __LINE__)
+void _isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp,
+                       const char *func, const char *file, int line);
 
 unsigned long isis_tx_queue_len(struct isis_tx_queue *queue);
 
index c211763042821b8f2664b5bcf4a5e2df1eb59a87..06432db0b25c022ad89b679252a0f2fe6fc8e4df 100644 (file)
 #include <zebra.h>
 
 #include "command.h"
-#include "spf_backoff.h"
 #include "bfd.h"
 
 #include "isis_circuit.h"
 #include "isis_csm.h"
 #include "isis_misc.h"
-#include "isis_mt.h"
 #include "isisd.h"
 #include "isis_bfd.h"
 #include "isis_vty_common.h"
@@ -57,449 +55,6 @@ struct isis_circuit *isis_circuit_lookup(struct vty *vty)
        return circuit;
 }
 
-DEFUN (ip_router_isis,
-       ip_router_isis_cmd,
-       "ip router " PROTO_NAME " WORD",
-       "Interface Internet Protocol config commands\n"
-       "IP router interface commands\n"
-       PROTO_HELP
-       "Routing process tag\n")
-{
-       int idx_afi = 0;
-       int idx_word = 3;
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct isis_circuit *circuit;
-       struct isis_area *area;
-       const char *af = argv[idx_afi]->arg;
-       const char *area_tag = argv[idx_word]->arg;
-
-       /* Prevent more than one area per circuit */
-       circuit = circuit_scan_by_ifp(ifp);
-       if (circuit && circuit->area) {
-               if (strcmp(circuit->area->area_tag, area_tag)) {
-                       vty_out(vty, "ISIS circuit is already defined on %s\n",
-                               circuit->area->area_tag);
-                       return CMD_ERR_NOTHING_TODO;
-               }
-       }
-
-       area = isis_area_lookup(area_tag);
-       if (!area)
-               area = isis_area_create(area_tag);
-
-       if (!circuit || !circuit->area) {
-               circuit = isis_circuit_create(area, ifp);
-
-               if (circuit->state != C_STATE_CONF
-                   && circuit->state != C_STATE_UP) {
-                       vty_out(vty,
-                               "Couldn't bring up interface, please check log.\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
-       if (af[2] != '\0')
-               ipv6 = true;
-       else
-               ip = true;
-
-       isis_circuit_af_set(circuit, ip, ipv6);
-       return CMD_SUCCESS;
-}
-
-DEFUN (ip6_router_isis,
-       ip6_router_isis_cmd,
-       "ipv6 router " PROTO_NAME " WORD",
-       "Interface Internet Protocol config commands\n"
-       "IP router interface commands\n"
-       PROTO_HELP
-       "Routing process tag\n")
-{
-       return ip_router_isis(self, vty, argc, argv);
-}
-
-DEFUN (no_ip_router_isis,
-       no_ip_router_isis_cmd,
-       "no <ip|ipv6> router " PROTO_NAME " WORD",
-       NO_STR
-       "Interface Internet Protocol config commands\n"
-       "IP router interface commands\n"
-       "IP router interface commands\n"
-       PROTO_HELP
-       "Routing process tag\n")
-{
-       int idx_afi = 1;
-       int idx_word = 4;
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct isis_area *area;
-       struct isis_circuit *circuit;
-       const char *af = argv[idx_afi]->arg;
-       const char *area_tag = argv[idx_word]->arg;
-
-       area = isis_area_lookup(area_tag);
-       if (!area) {
-               vty_out(vty, "Can't find ISIS instance %s\n",
-                       area_tag);
-               return CMD_ERR_NO_MATCH;
-       }
-
-       circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
-       if (!circuit) {
-               vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
-               return CMD_ERR_NO_MATCH;
-       }
-
-       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
-       if (af[2] != '\0')
-               ipv6 = false;
-       else
-               ip = false;
-
-       isis_circuit_af_set(circuit, ip, ipv6);
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_passive,
-       isis_passive_cmd,
-       PROTO_NAME " passive",
-       PROTO_HELP
-       "Configure the passive mode for interface\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1),
-                       "Cannot set passive: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_passive,
-       no_isis_passive_cmd,
-       "no " PROTO_NAME " passive",
-       NO_STR
-       PROTO_HELP
-       "Configure the passive mode for interface\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0),
-                       "Cannot set no passive: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_passwd,
-       isis_passwd_cmd,
-       PROTO_NAME " password <md5|clear> WORD",
-       PROTO_HELP
-       "Configure the authentication password for a circuit\n"
-       "HMAC-MD5 authentication\n"
-       "Cleartext password\n"
-       "Circuit password\n")
-{
-       int idx_encryption = 2;
-       int idx_word = 3;
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       ferr_r rv;
-
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       if (argv[idx_encryption]->arg[0] == 'm')
-               rv = isis_circuit_passwd_hmac_md5_set(circuit,
-                                                     argv[idx_word]->arg);
-       else
-               rv = isis_circuit_passwd_cleartext_set(circuit,
-                                                      argv[idx_word]->arg);
-
-       CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_passwd,
-       no_isis_passwd_cmd,
-       "no " PROTO_NAME " password [<md5|clear> WORD]",
-       NO_STR
-       PROTO_HELP
-       "Configure the authentication password for a circuit\n"
-       "HMAC-MD5 authentication\n"
-       "Cleartext password\n"
-       "Circuit password\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit),
-                       "Failed to unset circuit password: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_metric,
-       isis_metric_cmd,
-       PROTO_NAME " metric (0-16777215)",
-       PROTO_HELP
-       "Set default metric for circuit\n"
-       "Default metric value\n")
-{
-       int idx_number = 2;
-       int met;
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       met = atoi(argv[idx_number]->arg);
-
-       /* RFC3787 section 5.1 */
-       if (circuit->area && circuit->area->oldmetric == 1
-           && met > MAX_NARROW_LINK_METRIC) {
-               vty_out(vty,
-                       "Invalid metric %d - should be <0-63> "
-                       "when narrow metric type enabled\n",
-                       met);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* RFC4444 */
-       if (circuit->area && circuit->area->newmetric == 1
-           && met > MAX_WIDE_LINK_METRIC) {
-               vty_out(vty,
-                       "Invalid metric %d - should be <0-16777215> "
-                       "when wide metric type enabled\n",
-                       met);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met),
-                       "Failed to set L1 metric: $ERR");
-       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met),
-                       "Failed to set L2 metric: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_metric,
-       no_isis_metric_cmd,
-       "no " PROTO_NAME " metric [(0-16777215)]",
-       NO_STR
-       PROTO_HELP
-       "Set default metric for circuit\n"
-       "Default metric value\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1,
-                                               DEFAULT_CIRCUIT_METRIC),
-                       "Failed to set L1 metric: $ERR");
-       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2,
-                                               DEFAULT_CIRCUIT_METRIC),
-                       "Failed to set L2 metric: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_hello_interval,
-       isis_hello_interval_cmd,
-       PROTO_NAME " hello-interval (1-600)",
-       PROTO_HELP
-       "Set Hello interval\n"
-       "Holdtime 1 seconds, interval depends on multiplier\n")
-{
-       uint32_t interval = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_interval[0] = interval;
-       circuit->hello_interval[1] = interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_hello_interval,
-       no_isis_hello_interval_cmd,
-       "no " PROTO_NAME " hello-interval [(1-600)]",
-       NO_STR
-       PROTO_HELP
-       "Set Hello interval\n"
-       "Holdtime 1 second, interval depends on multiplier\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
-       circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_hello_multiplier,
-       isis_hello_multiplier_cmd,
-       PROTO_NAME " hello-multiplier (2-100)",
-       PROTO_HELP
-       "Set multiplier for Hello holding time\n"
-       "Hello multiplier value\n")
-{
-       uint16_t mult = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_multiplier[0] = mult;
-       circuit->hello_multiplier[1] = mult;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_hello_multiplier,
-       no_isis_hello_multiplier_cmd,
-       "no " PROTO_NAME " hello-multiplier [(2-100)]",
-       NO_STR
-       PROTO_HELP
-       "Set multiplier for Hello holding time\n"
-       "Hello multiplier value\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
-       circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (csnp_interval,
-       csnp_interval_cmd,
-       PROTO_NAME " csnp-interval (1-600)",
-       PROTO_HELP
-       "Set CSNP interval in seconds\n"
-       "CSNP interval value\n")
-{
-       uint16_t interval = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->csnp_interval[0] = interval;
-       circuit->csnp_interval[1] = interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_csnp_interval,
-       no_csnp_interval_cmd,
-       "no " PROTO_NAME " csnp-interval [(1-600)]",
-       NO_STR
-       PROTO_HELP
-       "Set CSNP interval in seconds\n"
-       "CSNP interval value\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
-       circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (psnp_interval,
-       psnp_interval_cmd,
-       PROTO_NAME " psnp-interval (1-120)",
-       PROTO_HELP
-       "Set PSNP interval in seconds\n"
-       "PSNP interval value\n")
-{
-       uint16_t interval = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->psnp_interval[0] = interval;
-       circuit->psnp_interval[1] = interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_psnp_interval,
-       no_psnp_interval_cmd,
-       "no " PROTO_NAME " psnp-interval [(1-120)]",
-       NO_STR
-       PROTO_HELP
-       "Set PSNP interval in seconds\n"
-       "PSNP interval value\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
-       circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (circuit_topology,
-       circuit_topology_cmd,
-       PROTO_NAME " topology " ISIS_MT_NAMES,
-       PROTO_HELP
-       "Configure interface IS-IS topologies\n"
-       ISIS_MT_DESCRIPTIONS)
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-       const char *arg = argv[2]->arg;
-       uint16_t mtid = isis_str2mtid(arg);
-
-       if (circuit->area && circuit->area->oldmetric) {
-               vty_out(vty,
-                       "Multi topology IS-IS can only be used with wide metrics\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (mtid == (uint16_t)-1) {
-               vty_out(vty, "Don't know topology '%s'\n", arg);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return isis_circuit_mt_enabled_set(circuit, mtid, true);
-}
-
-DEFUN (no_circuit_topology,
-       no_circuit_topology_cmd,
-       "no " PROTO_NAME " topology " ISIS_MT_NAMES,
-       NO_STR
-       PROTO_HELP
-       "Configure interface IS-IS topologies\n"
-       ISIS_MT_DESCRIPTIONS)
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-       const char *arg = argv[3]->arg;
-       uint16_t mtid = isis_str2mtid(arg);
-
-       if (circuit->area && circuit->area->oldmetric) {
-               vty_out(vty,
-                       "Multi topology IS-IS can only be used with wide metrics\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (mtid == (uint16_t)-1) {
-               vty_out(vty, "Don't know topology '%s'\n", arg);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return isis_circuit_mt_enabled_set(circuit, mtid, false);
-}
-
 DEFUN (isis_bfd,
        isis_bfd_cmd,
        PROTO_NAME " bfd",
@@ -543,466 +98,12 @@ DEFUN (no_isis_bfd,
        return CMD_SUCCESS;
 }
 
-DEFUN (set_overload_bit,
-       set_overload_bit_cmd,
-       "set-overload-bit",
-       "Set overload bit to avoid any transit traffic\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       isis_area_overload_bit_set(area, true);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_set_overload_bit,
-       no_set_overload_bit_cmd,
-       "no set-overload-bit",
-       "Reset overload bit to accept transit traffic\n"
-       "Reset overload bit\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       isis_area_overload_bit_set(area, false);
-       return CMD_SUCCESS;
-}
-
-static int isis_vty_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu)
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       struct listnode *node;
-       struct isis_circuit *circuit;
-
-       for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
-               if (circuit->state != C_STATE_INIT
-                   && circuit->state != C_STATE_UP)
-                       continue;
-               if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
-                       vty_out(vty,
-                               "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n",
-                               circuit->interface->name,
-                               isis_circuit_pdu_size(circuit));
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       isis_area_lsp_mtu_set(area, lsp_mtu);
-       return CMD_SUCCESS;
-}
-
-DEFUN (area_lsp_mtu,
-       area_lsp_mtu_cmd,
-       "lsp-mtu (128-4352)",
-       "Configure the maximum size of generated LSPs\n"
-       "Maximum size of generated LSPs\n")
-{
-       int idx_number = 1;
-       unsigned int lsp_mtu;
-
-       lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10);
-
-       return isis_vty_lsp_mtu_set(vty, lsp_mtu);
-}
-
-DEFUN (no_area_lsp_mtu,
-       no_area_lsp_mtu_cmd,
-       "no lsp-mtu [(128-4352)]",
-       NO_STR
-       "Configure the maximum size of generated LSPs\n"
-       "Maximum size of generated LSPs\n")
-{
-       return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU);
-}
-
-DEFUN (area_purge_originator,
-       area_purge_originator_cmd,
-       "[no] purge-originator",
-       NO_STR
-       "Use the RFC 6232 purge-originator\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       area->purge_originator = !!strcmp(argv[0]->text, "no");
-       return CMD_SUCCESS;
-}
-
-int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval)
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int lvl;
-
-       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
-               if (!(lvl & level))
-                       continue;
-
-               if (interval >= area->lsp_refresh[lvl - 1]) {
-                       vty_out(vty,
-                               "LSP gen interval %us must be less than "
-                               "the LSP refresh interval %us\n",
-                               interval, area->lsp_refresh[lvl - 1]);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
-               if (!(lvl & level))
-                       continue;
-               area->lsp_gen_interval[lvl - 1] = interval;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (lsp_gen_interval,
-       lsp_gen_interval_cmd,
-       "lsp-gen-interval (1-120)",
-       "Minimum interval between regenerating same LSP\n"
-       "Minimum interval in seconds\n")
-{
-       uint16_t interval = atoi(argv[1]->arg);
-
-       return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval);
-}
-
-DEFUN (no_lsp_gen_interval,
-       no_lsp_gen_interval_cmd,
-       "no lsp-gen-interval [(1-120)]",
-       NO_STR
-       "Minimum interval between regenerating same LSP\n"
-       "Minimum interval in seconds\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2,
-                                            DEFAULT_MIN_LSP_GEN_INTERVAL);
-}
-
-DEFUN (spf_interval,
-       spf_interval_cmd,
-       "spf-interval (1-120)",
-       "Minimum interval between SPF calculations\n"
-       "Minimum interval between consecutive SPFs in seconds\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       uint16_t interval = atoi(argv[1]->arg);
-
-       area->min_spf_interval[0] = interval;
-       area->min_spf_interval[1] = interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_spf_interval,
-       no_spf_interval_cmd,
-       "no spf-interval [(1-120)]",
-       NO_STR
-       "Minimum interval between SPF calculations\n"
-       "Minimum interval between consecutive SPFs in seconds\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
-       area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_spf_delay_ietf,
-       no_spf_delay_ietf_cmd,
-       "no spf-delay-ietf",
-       NO_STR
-       "IETF SPF delay algorithm\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       spf_backoff_free(area->spf_delay_ietf[0]);
-       spf_backoff_free(area->spf_delay_ietf[1]);
-       area->spf_delay_ietf[0] = NULL;
-       area->spf_delay_ietf[1] = NULL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (spf_delay_ietf,
-       spf_delay_ietf_cmd,
-       "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)",
-       "IETF SPF delay algorithm\n"
-       "Delay used while in QUIET state\n"
-       "Delay used while in QUIET state in milliseconds\n"
-       "Delay used while in SHORT_WAIT state\n"
-       "Delay used while in SHORT_WAIT state in milliseconds\n"
-       "Delay used while in LONG_WAIT\n"
-       "Delay used while in LONG_WAIT state in milliseconds\n"
-       "Time with no received IGP events before considering IGP stable\n"
-       "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
-       "Maximum duration needed to learn all the events related to a single failure\n"
-       "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       long init_delay = atol(argv[2]->arg);
-       long short_delay = atol(argv[4]->arg);
-       long long_delay = atol(argv[6]->arg);
-       long holddown = atol(argv[8]->arg);
-       long timetolearn = atol(argv[10]->arg);
-
-       size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS  Lx");
-       char *buf = XCALLOC(MTYPE_TMP, bufsiz);
-
-       snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
-       spf_backoff_free(area->spf_delay_ietf[0]);
-       area->spf_delay_ietf[0] =
-               spf_backoff_new(master, buf, init_delay, short_delay,
-                               long_delay, holddown, timetolearn);
-
-       snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
-       spf_backoff_free(area->spf_delay_ietf[1]);
-       area->spf_delay_ietf[1] =
-               spf_backoff_new(master, buf, init_delay, short_delay,
-                               long_delay, holddown, timetolearn);
-
-       XFREE(MTYPE_TMP, buf);
-       return CMD_SUCCESS;
-}
-
-int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval)
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int lvl;
-       uint16_t refresh_interval = interval - 300;
-       int set_refresh_interval[ISIS_LEVELS] = {0, 0};
-
-       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
-               if (!(lvl & level))
-                       continue;
-
-               if (refresh_interval < area->lsp_refresh[lvl - 1]) {
-                       vty_out(vty,
-                               "Level %d Max LSP lifetime %us must be 300s greater than "
-                               "the configured LSP refresh interval %us\n",
-                               lvl, interval, area->lsp_refresh[lvl - 1]);
-                       vty_out(vty,
-                               "Automatically reducing level %d LSP refresh interval "
-                               "to %us\n",
-                               lvl, refresh_interval);
-                       set_refresh_interval[lvl - 1] = 1;
-
-                       if (refresh_interval
-                           <= area->lsp_gen_interval[lvl - 1]) {
-                               vty_out(vty,
-                                       "LSP refresh interval %us must be greater than "
-                                       "the configured LSP gen interval %us\n",
-                                       refresh_interval,
-                                       area->lsp_gen_interval[lvl - 1]);
-                               return CMD_WARNING_CONFIG_FAILED;
-                       }
-               }
-       }
-
-       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
-               if (!(lvl & level))
-                       continue;
-               isis_area_max_lsp_lifetime_set(area, lvl, interval);
-               if (set_refresh_interval[lvl - 1])
-                       isis_area_lsp_refresh_set(area, lvl, refresh_interval);
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (max_lsp_lifetime,
-       max_lsp_lifetime_cmd,
-       "max-lsp-lifetime (350-65535)",
-       "Maximum LSP lifetime\n"
-       "LSP lifetime in seconds\n")
-{
-       int lifetime = atoi(argv[1]->arg);
-
-       return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime);
-}
-
-
-DEFUN (no_max_lsp_lifetime,
-       no_max_lsp_lifetime_cmd,
-       "no max-lsp-lifetime [(350-65535)]",
-       NO_STR
-       "Maximum LSP lifetime\n"
-       "LSP lifetime in seconds\n")
-{
-       return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2,
-                                            DEFAULT_LSP_LIFETIME);
-}
-
-int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval)
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int lvl;
-
-       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
-               if (!(lvl & level))
-                       continue;
-               if (interval <= area->lsp_gen_interval[lvl - 1]) {
-                       vty_out(vty,
-                               "LSP refresh interval %us must be greater than "
-                               "the configured LSP gen interval %us\n",
-                               interval, area->lsp_gen_interval[lvl - 1]);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-               if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) {
-                       vty_out(vty,
-                               "LSP refresh interval %us must be less than "
-                               "the configured LSP lifetime %us less 300\n",
-                               interval, area->max_lsp_lifetime[lvl - 1]);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
-               if (!(lvl & level))
-                       continue;
-               isis_area_lsp_refresh_set(area, lvl, interval);
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (lsp_refresh_interval,
-       lsp_refresh_interval_cmd,
-       "lsp-refresh-interval (1-65235)",
-       "LSP refresh interval\n"
-       "LSP refresh interval in seconds\n")
-{
-       unsigned int interval = atoi(argv[1]->arg);
-       return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval);
-}
-
-DEFUN (no_lsp_refresh_interval,
-       no_lsp_refresh_interval_cmd,
-       "no lsp-refresh-interval [(1-65235)]",
-       NO_STR
-       "LSP refresh interval\n"
-       "LSP refresh interval in seconds\n")
-{
-       return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2,
-                                       DEFAULT_MAX_LSP_GEN_INTERVAL);
-}
-
-int isis_vty_password_set(struct vty *vty, int argc,
-                         struct cmd_token *argv[], int level)
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       int idx_algo = 1;
-       int idx_password = 2;
-       int idx_snp_auth = 5;
-       uint8_t snp_auth = 0;
-
-       const char *passwd = argv[idx_password]->arg;
-       if (strlen(passwd) > 254) {
-               vty_out(vty, "Too long area password (>254)\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (argc > idx_snp_auth) {
-               snp_auth = SNP_AUTH_SEND;
-               if (strmatch(argv[idx_snp_auth]->text, "validate"))
-                       snp_auth |= SNP_AUTH_RECV;
-       }
-
-       if (strmatch(argv[idx_algo]->text, "clear")) {
-               return isis_area_passwd_cleartext_set(area, level,
-                                                     passwd, snp_auth);
-       } else if (strmatch(argv[idx_algo]->text, "md5")) {
-               return isis_area_passwd_hmac_md5_set(area, level,
-                                                    passwd, snp_auth);
-       }
-       
-       return CMD_WARNING_CONFIG_FAILED;
-}
-
-DEFUN (domain_passwd,
-       domain_passwd_cmd,
-       "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]",
-       "Set the authentication password for a routing domain\n"
-       "Authentication type\n"
-       "Authentication type\n"
-       "Level-wide password\n"
-       "Authentication\n"
-       "SNP PDUs\n"
-       "Send but do not check PDUs on receiving\n"
-       "Send and check PDUs on receiving\n")
-{
-       return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2);
-}
-
-DEFUN (no_domain_passwd,
-       no_domain_passwd_cmd,
-       "no domain-password",
-       NO_STR
-       "Set the authentication password for a routing domain\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       return isis_area_passwd_unset(area, IS_LEVEL_2);
-}
-
 void isis_vty_init(void)
 {
-       install_element(INTERFACE_NODE, &ip_router_isis_cmd);
-       install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
-       install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
-
-       install_element(INTERFACE_NODE, &isis_passive_cmd);
-       install_element(INTERFACE_NODE, &no_isis_passive_cmd);
-
-       install_element(INTERFACE_NODE, &isis_passwd_cmd);
-       install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
-
-       install_element(INTERFACE_NODE, &isis_metric_cmd);
-       install_element(INTERFACE_NODE, &no_isis_metric_cmd);
-
-       install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
-       install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
-
-       install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
-       install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
-
-       install_element(INTERFACE_NODE, &csnp_interval_cmd);
-       install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
-
-       install_element(INTERFACE_NODE, &psnp_interval_cmd);
-       install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
-
-       install_element(INTERFACE_NODE, &circuit_topology_cmd);
-       install_element(INTERFACE_NODE, &no_circuit_topology_cmd);
-
        install_element(INTERFACE_NODE, &isis_bfd_cmd);
        install_element(INTERFACE_NODE, &no_isis_bfd_cmd);
 
-       install_element(ROUTER_NODE, &set_overload_bit_cmd);
-       install_element(ROUTER_NODE, &no_set_overload_bit_cmd);
-
-       install_element(ROUTER_NODE, &area_lsp_mtu_cmd);
-       install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd);
-
-       install_element(ROUTER_NODE, &area_purge_originator_cmd);
-
-       install_element(ROUTER_NODE, &lsp_gen_interval_cmd);
-       install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd);
-
-       install_element(ROUTER_NODE, &spf_interval_cmd);
-       install_element(ROUTER_NODE, &no_spf_interval_cmd);
-
-       install_element(ROUTER_NODE, &max_lsp_lifetime_cmd);
-       install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd);
-
-       install_element(ROUTER_NODE, &lsp_refresh_interval_cmd);
-       install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd);
-
-       install_element(ROUTER_NODE, &domain_passwd_cmd);
-       install_element(ROUTER_NODE, &no_domain_passwd_cmd);
-
-       install_element(ROUTER_NODE, &spf_delay_ietf_cmd);
-       install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd);
-
+#ifdef FABRICD
        isis_vty_daemon_init();
+#endif /* ifdef FABRICD */
 }
index b726b4ee83870a335772b41db9f2c2bb3fe00032..297da0e2c1102bef850b079e3d14a12df5035b63 100644 (file)
 
 struct isis_circuit *isis_circuit_lookup(struct vty *vty);
 
-int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval);
-int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval);
-int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval);
-int isis_vty_password_set(struct vty *vty, int argc,
-                         struct cmd_token *argv[], int level);
-
 void isis_vty_daemon_init(void);
 void isis_vty_init(void);
 
index 95ebe0de81dd23b3a478d0de61b0b8408424647d..b2c0440de6ce8f1a453dab35f49742233de17adf 100644 (file)
 
 #include "command.h"
 
-#include "isisd.h"
-#include "isis_vty_common.h"
-#include "fabricd.h"
-#include "isis_tlvs.h"
+#include "isisd/isisd.h"
+#include "isisd/isis_vty_common.h"
+#include "isisd/fabricd.h"
+#include "isisd/isis_tlvs.h"
+#include "isisd/isis_misc.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_csm.h"
+#include "isisd/isis_circuit.h"
+#include "lib/spf_backoff.h"
+#include "isisd/isis_mt.h"
 
 DEFUN (fabric_tier,
        fabric_tier_cmd,
@@ -55,40 +61,1038 @@ DEFUN (no_fabric_tier,
        return CMD_SUCCESS;
 }
 
-DEFUN (debug_fabric_flooding,
-       debug_fabric_flooding_cmd,
-       "debug openfabric flooding",
-       DEBUG_STR
+DEFUN (triggered_csnp,
+       triggered_csnp_cmd,
+       "triggered-csnp-delay (100-10000) [always]",
+       "Configure the delay for triggered CSNPs\n"
+       "Delay in milliseconds\n"
+       "Trigger CSNP for all LSPs, not only circuit-scoped\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       int csnp_delay = atoi(argv[1]->arg);
+       bool always_send_csnp = (argc == 3);
+
+       fabricd_configure_triggered_csnp(area, csnp_delay, always_send_csnp);
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_triggered_csnp,
+       no_triggered_csnp_cmd,
+       "no triggered-csnp-delay [(100-10000) [always]]",
+       NO_STR
+       "Configure the delay for triggered CSNPs\n"
+       "Delay in milliseconds\n"
+       "Trigger CSNP for all LSPs, not only circuit-scoped\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       fabricd_configure_triggered_csnp(area, FABRICD_DEFAULT_CSNP_DELAY,
+                                        false);
+       return CMD_SUCCESS;
+}
+
+static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp)
+{
+       char lspid[255];
+
+       lspid_print(lsp->hdr.lsp_id, lspid, true, true);
+       vty_out(vty, "Flooding information for %s\n", lspid);
+
+       if (!lsp->flooding_neighbors[TX_LSP_NORMAL]) {
+               vty_out(vty, "    Never received.\n");
+               return;
+       }
+
+       vty_out(vty, "    Last received on: %s (",
+               lsp->flooding_interface ?
+               lsp->flooding_interface : "(null)");
+
+       time_t uptime = time(NULL) - lsp->flooding_time;
+       struct tm *tm = gmtime(&uptime);
+
+       if (uptime < ONE_DAY_SECOND)
+               vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
+                       tm->tm_sec);
+       else if (uptime < ONE_WEEK_SECOND)
+               vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
+                       tm->tm_min);
+       else
+               vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
+                       tm->tm_yday - ((tm->tm_yday / 7) * 7),
+                       tm->tm_hour);
+       vty_out(vty, " ago)\n");
+
+       if (lsp->flooding_circuit_scoped) {
+               vty_out(vty, "    Received as circuit-scoped LSP, so not "
+                       "flooded.\n");
+               return;
+       }
+
+       for (enum isis_tx_type type = TX_LSP_NORMAL;
+            type <= TX_LSP_CIRCUIT_SCOPED; type++) {
+               struct listnode *node;
+               uint8_t *neighbor_id;
+
+               vty_out(vty, "    %s:\n",
+                       (type == TX_LSP_NORMAL) ? "RF" : "DNR");
+               for (ALL_LIST_ELEMENTS_RO(lsp->flooding_neighbors[type],
+                                         node, neighbor_id)) {
+                       vty_out(vty, "        %s\n",
+                               print_sys_hostname(neighbor_id));
+               }
+       }
+}
+
+DEFUN (show_lsp_flooding,
+       show_lsp_flooding_cmd,
+       "show openfabric flooding [WORD]",
+       SHOW_STR
+       PROTO_HELP
+       "Flooding information\n"
+       "LSP ID\n")
+{
+       const char *lspid = NULL;
+
+       if (argc == 4)
+               lspid = argv[3]->arg;
+
+       struct listnode *node;
+       struct isis_area *area;
+
+       for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
+               dict_t *lspdb = area->lspdb[ISIS_LEVEL2 - 1];
+
+               vty_out(vty, "Area %s:\n", area->area_tag ?
+                       area->area_tag : "null");
+
+               if (lspid) {
+                       struct isis_lsp *lsp = lsp_for_arg(lspid, lspdb);
+
+                       if (lsp)
+                               lsp_print_flooding(vty, lsp);
+
+                       continue;
+               }
+
+               for (dnode_t *dnode = dict_first(lspdb); dnode;
+                    dnode = dict_next(lspdb, dnode)) {
+                       lsp_print_flooding(vty, dnode_get(dnode));
+                       vty_out(vty, "\n");
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (ip_router_isis,
+       ip_router_isis_cmd,
+       "ip router " PROTO_NAME " WORD",
+       "Interface Internet Protocol config commands\n"
+       "IP router interface commands\n"
        PROTO_HELP
-       "Flooding optimization algorithm\n")
+       "Routing process tag\n")
 {
-       isis->debugs |= DEBUG_FABRICD_FLOODING;
-       print_debug(vty, DEBUG_FABRICD_FLOODING, 1);
+       int idx_afi = 0;
+       int idx_word = 3;
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct isis_circuit *circuit;
+       struct isis_area *area;
+       const char *af = argv[idx_afi]->arg;
+       const char *area_tag = argv[idx_word]->arg;
+
+       /* Prevent more than one area per circuit */
+       circuit = circuit_scan_by_ifp(ifp);
+       if (circuit && circuit->area) {
+               if (strcmp(circuit->area->area_tag, area_tag)) {
+                       vty_out(vty, "ISIS circuit is already defined on %s\n",
+                               circuit->area->area_tag);
+                       return CMD_ERR_NOTHING_TODO;
+               }
+       }
+
+       area = isis_area_lookup(area_tag);
+       if (!area)
+               area = isis_area_create(area_tag);
 
+       if (!circuit || !circuit->area) {
+               circuit = isis_circuit_create(area, ifp);
+
+               if (circuit->state != C_STATE_CONF
+                   && circuit->state != C_STATE_UP) {
+                       vty_out(vty,
+                               "Couldn't bring up interface, please check log.\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
+       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
+       if (af[2] != '\0')
+               ipv6 = true;
+       else
+               ip = true;
+
+       isis_circuit_af_set(circuit, ip, ipv6);
        return CMD_SUCCESS;
 }
 
-DEFUN (no_debug_fabric_flooding,
-       no_debug_fabric_flooding_cmd,
-       "no debug openfabric flooding",
+DEFUN (ip6_router_isis,
+       ip6_router_isis_cmd,
+       "ipv6 router " PROTO_NAME " WORD",
+       "Interface Internet Protocol config commands\n"
+       "IP router interface commands\n"
+       PROTO_HELP
+       "Routing process tag\n")
+{
+       return ip_router_isis(self, vty, argc, argv);
+}
+
+DEFUN (no_ip_router_isis,
+       no_ip_router_isis_cmd,
+       "no <ip|ipv6> router " PROTO_NAME " WORD",
        NO_STR
-       UNDEBUG_STR
+       "Interface Internet Protocol config commands\n"
+       "IP router interface commands\n"
+       "IP router interface commands\n"
        PROTO_HELP
-       "Flooding optimization algorithm\n")
+       "Routing process tag\n")
+{
+       int idx_afi = 1;
+       int idx_word = 4;
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct isis_area *area;
+       struct isis_circuit *circuit;
+       const char *af = argv[idx_afi]->arg;
+       const char *area_tag = argv[idx_word]->arg;
+
+       area = isis_area_lookup(area_tag);
+       if (!area) {
+               vty_out(vty, "Can't find ISIS instance %s\n",
+                       area_tag);
+               return CMD_ERR_NO_MATCH;
+       }
+
+       circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
+       if (!circuit) {
+               vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
+               return CMD_ERR_NO_MATCH;
+       }
+
+       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
+       if (af[2] != '\0')
+               ipv6 = false;
+       else
+               ip = false;
+
+       isis_circuit_af_set(circuit, ip, ipv6);
+       return CMD_SUCCESS;
+}
+
+DEFUN (set_overload_bit,
+       set_overload_bit_cmd,
+       "set-overload-bit",
+       "Set overload bit to avoid any transit traffic\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       isis_area_overload_bit_set(area, true);
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_set_overload_bit,
+       no_set_overload_bit_cmd,
+       "no set-overload-bit",
+       "Reset overload bit to accept transit traffic\n"
+       "Reset overload bit\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       isis_area_overload_bit_set(area, false);
+       return CMD_SUCCESS;
+}
+
+static int isis_vty_password_set(struct vty *vty, int argc,
+                         struct cmd_token *argv[], int level)
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       int idx_algo = 1;
+       int idx_password = 2;
+       int idx_snp_auth = 5;
+       uint8_t snp_auth = 0;
+
+       const char *passwd = argv[idx_password]->arg;
+       if (strlen(passwd) > 254) {
+               vty_out(vty, "Too long area password (>254)\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (argc > idx_snp_auth) {
+               snp_auth = SNP_AUTH_SEND;
+               if (strmatch(argv[idx_snp_auth]->text, "validate"))
+                       snp_auth |= SNP_AUTH_RECV;
+       }
+
+       if (strmatch(argv[idx_algo]->text, "clear")) {
+               return isis_area_passwd_cleartext_set(area, level,
+                                                     passwd, snp_auth);
+       } else if (strmatch(argv[idx_algo]->text, "md5")) {
+               return isis_area_passwd_hmac_md5_set(area, level,
+                                                    passwd, snp_auth);
+       }
+
+       return CMD_WARNING_CONFIG_FAILED;
+}
+
+DEFUN (domain_passwd,
+       domain_passwd_cmd,
+       "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]",
+       "Set the authentication password for a routing domain\n"
+       "Authentication type\n"
+       "Authentication type\n"
+       "Level-wide password\n"
+       "Authentication\n"
+       "SNP PDUs\n"
+       "Send but do not check PDUs on receiving\n"
+       "Send and check PDUs on receiving\n")
+{
+       return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2);
+}
+
+DEFUN (no_domain_passwd,
+       no_domain_passwd_cmd,
+       "no domain-password",
+       NO_STR
+       "Set the authentication password for a routing domain\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       return isis_area_passwd_unset(area, IS_LEVEL_2);
+}
+
+static int
+isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval)
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+       int lvl;
+
+       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
+               if (!(lvl & level))
+                       continue;
+
+               if (interval >= area->lsp_refresh[lvl - 1]) {
+                       vty_out(vty,
+                               "LSP gen interval %us must be less than "
+                               "the LSP refresh interval %us\n",
+                               interval, area->lsp_refresh[lvl - 1]);
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
+       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
+               if (!(lvl & level))
+                       continue;
+               area->lsp_gen_interval[lvl - 1] = interval;
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (lsp_gen_interval,
+       lsp_gen_interval_cmd,
+       "lsp-gen-interval (1-120)",
+       "Minimum interval between regenerating same LSP\n"
+       "Minimum interval in seconds\n")
+{
+       uint16_t interval = atoi(argv[1]->arg);
+
+       return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval);
+}
+
+DEFUN (no_lsp_gen_interval,
+       no_lsp_gen_interval_cmd,
+       "no lsp-gen-interval [(1-120)]",
+       NO_STR
+       "Minimum interval between regenerating same LSP\n"
+       "Minimum interval in seconds\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2,
+                                            DEFAULT_MIN_LSP_GEN_INTERVAL);
+}
+
+static int
+isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval)
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+       int lvl;
+
+       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
+               if (!(lvl & level))
+                       continue;
+               if (interval <= area->lsp_gen_interval[lvl - 1]) {
+                       vty_out(vty,
+                               "LSP refresh interval %us must be greater than "
+                               "the configured LSP gen interval %us\n",
+                               interval, area->lsp_gen_interval[lvl - 1]);
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+               if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) {
+                       vty_out(vty,
+                               "LSP refresh interval %us must be less than "
+                               "the configured LSP lifetime %us less 300\n",
+                               interval, area->max_lsp_lifetime[lvl - 1]);
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
+       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
+               if (!(lvl & level))
+                       continue;
+               isis_area_lsp_refresh_set(area, lvl, interval);
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (lsp_refresh_interval,
+       lsp_refresh_interval_cmd,
+       "lsp-refresh-interval (1-65235)",
+       "LSP refresh interval\n"
+       "LSP refresh interval in seconds\n")
+{
+       unsigned int interval = atoi(argv[1]->arg);
+       return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval);
+}
+
+DEFUN (no_lsp_refresh_interval,
+       no_lsp_refresh_interval_cmd,
+       "no lsp-refresh-interval [(1-65235)]",
+       NO_STR
+       "LSP refresh interval\n"
+       "LSP refresh interval in seconds\n")
+{
+       return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2,
+                                       DEFAULT_MAX_LSP_GEN_INTERVAL);
+}
+
+static int
+isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval)
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+       int lvl;
+       uint16_t refresh_interval = interval - 300;
+       int set_refresh_interval[ISIS_LEVELS] = {0, 0};
+
+       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
+               if (!(lvl & level))
+                       continue;
+
+               if (refresh_interval < area->lsp_refresh[lvl - 1]) {
+                       vty_out(vty,
+                               "Level %d Max LSP lifetime %us must be 300s greater than "
+                               "the configured LSP refresh interval %us\n",
+                               lvl, interval, area->lsp_refresh[lvl - 1]);
+                       vty_out(vty,
+                               "Automatically reducing level %d LSP refresh interval "
+                               "to %us\n",
+                               lvl, refresh_interval);
+                       set_refresh_interval[lvl - 1] = 1;
+
+                       if (refresh_interval
+                           <= area->lsp_gen_interval[lvl - 1]) {
+                               vty_out(vty,
+                                       "LSP refresh interval %us must be greater than "
+                                       "the configured LSP gen interval %us\n",
+                                       refresh_interval,
+                                       area->lsp_gen_interval[lvl - 1]);
+                               return CMD_WARNING_CONFIG_FAILED;
+                       }
+               }
+       }
+
+       for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) {
+               if (!(lvl & level))
+                       continue;
+               isis_area_max_lsp_lifetime_set(area, lvl, interval);
+               if (set_refresh_interval[lvl - 1])
+                       isis_area_lsp_refresh_set(area, lvl, refresh_interval);
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (max_lsp_lifetime,
+       max_lsp_lifetime_cmd,
+       "max-lsp-lifetime (350-65535)",
+       "Maximum LSP lifetime\n"
+       "LSP lifetime in seconds\n")
 {
-       isis->debugs &= ~DEBUG_FABRICD_FLOODING;
-       print_debug(vty, DEBUG_FABRICD_FLOODING, 0);
+       int lifetime = atoi(argv[1]->arg);
+
+       return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime);
+}
+
+
+DEFUN (no_max_lsp_lifetime,
+       no_max_lsp_lifetime_cmd,
+       "no max-lsp-lifetime [(350-65535)]",
+       NO_STR
+       "Maximum LSP lifetime\n"
+       "LSP lifetime in seconds\n")
+{
+       return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2,
+                                            DEFAULT_LSP_LIFETIME);
+}
+
+DEFUN (spf_interval,
+       spf_interval_cmd,
+       "spf-interval (1-120)",
+       "Minimum interval between SPF calculations\n"
+       "Minimum interval between consecutive SPFs in seconds\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+       uint16_t interval = atoi(argv[1]->arg);
+
+       area->min_spf_interval[0] = interval;
+       area->min_spf_interval[1] = interval;
 
        return CMD_SUCCESS;
 }
 
+DEFUN (no_spf_interval,
+       no_spf_interval_cmd,
+       "no spf-interval [(1-120)]",
+       NO_STR
+       "Minimum interval between SPF calculations\n"
+       "Minimum interval between consecutive SPFs in seconds\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
+       area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
+
+       return CMD_SUCCESS;
+}
+
+static int isis_vty_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu)
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+       struct listnode *node;
+       struct isis_circuit *circuit;
+
+       for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
+               if (circuit->state != C_STATE_INIT
+                   && circuit->state != C_STATE_UP)
+                       continue;
+               if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
+                       vty_out(vty,
+                               "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n",
+                               circuit->interface->name,
+                               isis_circuit_pdu_size(circuit));
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
+       isis_area_lsp_mtu_set(area, lsp_mtu);
+       return CMD_SUCCESS;
+}
+
+DEFUN (area_lsp_mtu,
+       area_lsp_mtu_cmd,
+       "lsp-mtu (128-4352)",
+       "Configure the maximum size of generated LSPs\n"
+       "Maximum size of generated LSPs\n")
+{
+       int idx_number = 1;
+       unsigned int lsp_mtu;
+
+       lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10);
+
+       return isis_vty_lsp_mtu_set(vty, lsp_mtu);
+}
+
+DEFUN (no_area_lsp_mtu,
+       no_area_lsp_mtu_cmd,
+       "no lsp-mtu [(128-4352)]",
+       NO_STR
+       "Configure the maximum size of generated LSPs\n"
+       "Maximum size of generated LSPs\n")
+{
+       return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU);
+}
+
+DEFUN (no_spf_delay_ietf,
+       no_spf_delay_ietf_cmd,
+       "no spf-delay-ietf",
+       NO_STR
+       "IETF SPF delay algorithm\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       spf_backoff_free(area->spf_delay_ietf[0]);
+       spf_backoff_free(area->spf_delay_ietf[1]);
+       area->spf_delay_ietf[0] = NULL;
+       area->spf_delay_ietf[1] = NULL;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (spf_delay_ietf,
+       spf_delay_ietf_cmd,
+       "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)",
+       "IETF SPF delay algorithm\n"
+       "Delay used while in QUIET state\n"
+       "Delay used while in QUIET state in milliseconds\n"
+       "Delay used while in SHORT_WAIT state\n"
+       "Delay used while in SHORT_WAIT state in milliseconds\n"
+       "Delay used while in LONG_WAIT\n"
+       "Delay used while in LONG_WAIT state in milliseconds\n"
+       "Time with no received IGP events before considering IGP stable\n"
+       "Time with no received IGP events before considering IGP stable (in milliseconds)\n"
+       "Maximum duration needed to learn all the events related to a single failure\n"
+       "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       long init_delay = atol(argv[2]->arg);
+       long short_delay = atol(argv[4]->arg);
+       long long_delay = atol(argv[6]->arg);
+       long holddown = atol(argv[8]->arg);
+       long timetolearn = atol(argv[10]->arg);
+
+       size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS  Lx");
+       char *buf = XCALLOC(MTYPE_TMP, bufsiz);
+
+       snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag);
+       spf_backoff_free(area->spf_delay_ietf[0]);
+       area->spf_delay_ietf[0] =
+               spf_backoff_new(master, buf, init_delay, short_delay,
+                               long_delay, holddown, timetolearn);
+
+       snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag);
+       spf_backoff_free(area->spf_delay_ietf[1]);
+       area->spf_delay_ietf[1] =
+               spf_backoff_new(master, buf, init_delay, short_delay,
+                               long_delay, holddown, timetolearn);
+
+       XFREE(MTYPE_TMP, buf);
+       return CMD_SUCCESS;
+}
+
+DEFUN (area_purge_originator,
+       area_purge_originator_cmd,
+       "[no] purge-originator",
+       NO_STR
+       "Use the RFC 6232 purge-originator\n")
+{
+       VTY_DECLVAR_CONTEXT(isis_area, area);
+
+       area->purge_originator = !!strcmp(argv[0]->text, "no");
+       return CMD_SUCCESS;
+}
+
+DEFUN (isis_passive,
+       isis_passive_cmd,
+       PROTO_NAME " passive",
+       PROTO_HELP
+       "Configure the passive mode for interface\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1),
+                       "Cannot set passive: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_passive,
+       no_isis_passive_cmd,
+       "no " PROTO_NAME " passive",
+       NO_STR
+       PROTO_HELP
+       "Configure the passive mode for interface\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0),
+                       "Cannot set no passive: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (isis_passwd,
+       isis_passwd_cmd,
+       PROTO_NAME " password <md5|clear> WORD",
+       PROTO_HELP
+       "Configure the authentication password for a circuit\n"
+       "HMAC-MD5 authentication\n"
+       "Cleartext password\n"
+       "Circuit password\n")
+{
+       int idx_encryption = 2;
+       int idx_word = 3;
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       ferr_r rv;
+
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       if (argv[idx_encryption]->arg[0] == 'm')
+               rv = isis_circuit_passwd_hmac_md5_set(circuit,
+                                                     argv[idx_word]->arg);
+       else
+               rv = isis_circuit_passwd_cleartext_set(circuit,
+                                                      argv[idx_word]->arg);
+
+       CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_passwd,
+       no_isis_passwd_cmd,
+       "no " PROTO_NAME " password [<md5|clear> WORD]",
+       NO_STR
+       PROTO_HELP
+       "Configure the authentication password for a circuit\n"
+       "HMAC-MD5 authentication\n"
+       "Cleartext password\n"
+       "Circuit password\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit),
+                       "Failed to unset circuit password: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (isis_metric,
+       isis_metric_cmd,
+       PROTO_NAME " metric (0-16777215)",
+       PROTO_HELP
+       "Set default metric for circuit\n"
+       "Default metric value\n")
+{
+       int idx_number = 2;
+       int met;
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       met = atoi(argv[idx_number]->arg);
+
+       /* RFC3787 section 5.1 */
+       if (circuit->area && circuit->area->oldmetric == 1
+           && met > MAX_NARROW_LINK_METRIC) {
+               vty_out(vty,
+                       "Invalid metric %d - should be <0-63> "
+                       "when narrow metric type enabled\n",
+                       met);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       /* RFC4444 */
+       if (circuit->area && circuit->area->newmetric == 1
+           && met > MAX_WIDE_LINK_METRIC) {
+               vty_out(vty,
+                       "Invalid metric %d - should be <0-16777215> "
+                       "when wide metric type enabled\n",
+                       met);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met),
+                       "Failed to set L1 metric: $ERR");
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met),
+                       "Failed to set L2 metric: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_metric,
+       no_isis_metric_cmd,
+       "no " PROTO_NAME " metric [(0-16777215)]",
+       NO_STR
+       PROTO_HELP
+       "Set default metric for circuit\n"
+       "Default metric value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1,
+                                               DEFAULT_CIRCUIT_METRIC),
+                       "Failed to set L1 metric: $ERR");
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2,
+                                               DEFAULT_CIRCUIT_METRIC),
+                       "Failed to set L2 metric: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (isis_hello_interval,
+       isis_hello_interval_cmd,
+       PROTO_NAME " hello-interval (1-600)",
+       PROTO_HELP
+       "Set Hello interval\n"
+       "Holdtime 1 seconds, interval depends on multiplier\n")
+{
+       uint32_t interval = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_interval[0] = interval;
+       circuit->hello_interval[1] = interval;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_hello_interval,
+       no_isis_hello_interval_cmd,
+       "no " PROTO_NAME " hello-interval [(1-600)]",
+       NO_STR
+       PROTO_HELP
+       "Set Hello interval\n"
+       "Holdtime 1 second, interval depends on multiplier\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
+       circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (isis_hello_multiplier,
+       isis_hello_multiplier_cmd,
+       PROTO_NAME " hello-multiplier (2-100)",
+       PROTO_HELP
+       "Set multiplier for Hello holding time\n"
+       "Hello multiplier value\n")
+{
+       uint16_t mult = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_multiplier[0] = mult;
+       circuit->hello_multiplier[1] = mult;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_hello_multiplier,
+       no_isis_hello_multiplier_cmd,
+       "no " PROTO_NAME " hello-multiplier [(2-100)]",
+       NO_STR
+       PROTO_HELP
+       "Set multiplier for Hello holding time\n"
+       "Hello multiplier value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
+       circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (csnp_interval,
+       csnp_interval_cmd,
+       PROTO_NAME " csnp-interval (1-600)",
+       PROTO_HELP
+       "Set CSNP interval in seconds\n"
+       "CSNP interval value\n")
+{
+       uint16_t interval = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->csnp_interval[0] = interval;
+       circuit->csnp_interval[1] = interval;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_csnp_interval,
+       no_csnp_interval_cmd,
+       "no " PROTO_NAME " csnp-interval [(1-600)]",
+       NO_STR
+       PROTO_HELP
+       "Set CSNP interval in seconds\n"
+       "CSNP interval value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
+       circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (psnp_interval,
+       psnp_interval_cmd,
+       PROTO_NAME " psnp-interval (1-120)",
+       PROTO_HELP
+       "Set PSNP interval in seconds\n"
+       "PSNP interval value\n")
+{
+       uint16_t interval = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->psnp_interval[0] = interval;
+       circuit->psnp_interval[1] = interval;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_psnp_interval,
+       no_psnp_interval_cmd,
+       "no " PROTO_NAME " psnp-interval [(1-120)]",
+       NO_STR
+       PROTO_HELP
+       "Set PSNP interval in seconds\n"
+       "PSNP interval value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
+       circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (circuit_topology,
+       circuit_topology_cmd,
+       PROTO_NAME " topology " ISIS_MT_NAMES,
+       PROTO_HELP
+       "Configure interface IS-IS topologies\n"
+       ISIS_MT_DESCRIPTIONS)
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+       const char *arg = argv[2]->arg;
+       uint16_t mtid = isis_str2mtid(arg);
+
+       if (circuit->area && circuit->area->oldmetric) {
+               vty_out(vty,
+                       "Multi topology IS-IS can only be used with wide metrics\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (mtid == (uint16_t)-1) {
+               vty_out(vty, "Don't know topology '%s'\n", arg);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       return isis_circuit_mt_enabled_set(circuit, mtid, true);
+}
+
+DEFUN (no_circuit_topology,
+       no_circuit_topology_cmd,
+       "no " PROTO_NAME " topology " ISIS_MT_NAMES,
+       NO_STR
+       PROTO_HELP
+       "Configure interface IS-IS topologies\n"
+       ISIS_MT_DESCRIPTIONS)
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+       const char *arg = argv[3]->arg;
+       uint16_t mtid = isis_str2mtid(arg);
+
+       if (circuit->area && circuit->area->oldmetric) {
+               vty_out(vty,
+                       "Multi topology IS-IS can only be used with wide metrics\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (mtid == (uint16_t)-1) {
+               vty_out(vty, "Don't know topology '%s'\n", arg);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       return isis_circuit_mt_enabled_set(circuit, mtid, false);
+}
 
 void isis_vty_daemon_init(void)
 {
        install_element(ROUTER_NODE, &fabric_tier_cmd);
        install_element(ROUTER_NODE, &no_fabric_tier_cmd);
-       install_element(ENABLE_NODE, &debug_fabric_flooding_cmd);
-       install_element(ENABLE_NODE, &no_debug_fabric_flooding_cmd);
-       install_element(CONFIG_NODE, &debug_fabric_flooding_cmd);
-       install_element(CONFIG_NODE, &no_debug_fabric_flooding_cmd);
+       install_element(ROUTER_NODE, &triggered_csnp_cmd);
+       install_element(ROUTER_NODE, &no_triggered_csnp_cmd);
+
+       install_element(ENABLE_NODE, &show_lsp_flooding_cmd);
+
+       install_element(INTERFACE_NODE, &ip_router_isis_cmd);
+       install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
+       install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
+
+       install_element(ROUTER_NODE, &set_overload_bit_cmd);
+       install_element(ROUTER_NODE, &no_set_overload_bit_cmd);
+
+       install_element(ROUTER_NODE, &domain_passwd_cmd);
+       install_element(ROUTER_NODE, &no_domain_passwd_cmd);
+
+       install_element(ROUTER_NODE, &lsp_gen_interval_cmd);
+       install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd);
+
+       install_element(ROUTER_NODE, &lsp_refresh_interval_cmd);
+       install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd);
+
+       install_element(ROUTER_NODE, &max_lsp_lifetime_cmd);
+       install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd);
+
+       install_element(ROUTER_NODE, &area_lsp_mtu_cmd);
+       install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd);
+
+       install_element(ROUTER_NODE, &spf_interval_cmd);
+       install_element(ROUTER_NODE, &no_spf_interval_cmd);
+
+       install_element(ROUTER_NODE, &spf_delay_ietf_cmd);
+       install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd);
+
+       install_element(ROUTER_NODE, &area_purge_originator_cmd);
+
+       install_element(INTERFACE_NODE, &isis_passive_cmd);
+       install_element(INTERFACE_NODE, &no_isis_passive_cmd);
+
+       install_element(INTERFACE_NODE, &isis_passwd_cmd);
+       install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
+
+       install_element(INTERFACE_NODE, &isis_metric_cmd);
+       install_element(INTERFACE_NODE, &no_isis_metric_cmd);
+
+       install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
+       install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
+
+       install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
+       install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
+
+       install_element(INTERFACE_NODE, &csnp_interval_cmd);
+       install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
+
+       install_element(INTERFACE_NODE, &psnp_interval_cmd);
+       install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
+
+       install_element(INTERFACE_NODE, &circuit_topology_cmd);
+       install_element(INTERFACE_NODE, &no_circuit_topology_cmd);
 }
diff --git a/isisd/isis_vty_isisd.c b/isisd/isis_vty_isisd.c
deleted file mode 100644 (file)
index 95aaeae..0000000
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * IS-IS Rout(e)ing protocol - isis_vty_isisd.c
- *
- * This file contains the CLI that is specific to IS-IS
- *
- * Copyright (C) 2001,2002   Sampo Saaristo
- *                           Tampere University of Technology
- *                           Institute of Communications Engineering
- * Copyright (C) 2016        David Lamparter, for NetDEF, Inc.
- * Copyright (C) 2018        Christian Franke, for NetDEF, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public Licenseas published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <zebra.h>
-
-#include "command.h"
-
-#include "isis_circuit.h"
-#include "isis_csm.h"
-#include "isis_misc.h"
-#include "isis_mt.h"
-#include "isisd.h"
-#include "isis_vty_common.h"
-
-static int level_for_arg(const char *arg)
-{
-       if (!strcmp(arg, "level-1"))
-               return IS_LEVEL_1;
-       else
-               return IS_LEVEL_2;
-}
-
-DEFUN (isis_circuit_type,
-       isis_circuit_type_cmd,
-       "isis circuit-type <level-1|level-1-2|level-2-only>",
-       "IS-IS routing protocol\n"
-       "Configure circuit type for interface\n"
-       "Level-1 only adjacencies are formed\n"
-       "Level-1-2 adjacencies are formed\n"
-       "Level-2 only adjacencies are formed\n")
-{
-       int idx_level = 2;
-       int is_type;
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       is_type = string2circuit_t(argv[idx_level]->arg);
-       if (!is_type) {
-               vty_out(vty, "Unknown circuit-type \n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (circuit->state == C_STATE_UP
-           && circuit->area->is_type != IS_LEVEL_1_AND_2
-           && circuit->area->is_type != is_type) {
-               vty_out(vty, "Invalid circuit level for area %s.\n",
-                       circuit->area->area_tag);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       isis_circuit_is_type_set(circuit, is_type);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_circuit_type,
-       no_isis_circuit_type_cmd,
-       "no isis circuit-type <level-1|level-1-2|level-2-only>",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Configure circuit type for interface\n"
-       "Level-1 only adjacencies are formed\n"
-       "Level-1-2 adjacencies are formed\n"
-       "Level-2 only adjacencies are formed\n")
-{
-       int is_type;
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       /*
-        * Set the circuits level to its default value
-        */
-       if (circuit->state == C_STATE_UP)
-               is_type = circuit->area->is_type;
-       else
-               is_type = IS_LEVEL_1_AND_2;
-       isis_circuit_is_type_set(circuit, is_type);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_network,
-       isis_network_cmd,
-       "isis network point-to-point",
-       "IS-IS routing protocol\n"
-       "Set network type\n"
-       "point-to-point network type\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) {
-               vty_out(vty,
-                       "isis network point-to-point is valid only on broadcast interfaces\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_network,
-       no_isis_network_cmd,
-       "no isis network point-to-point",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set network type for circuit\n"
-       "point-to-point network type\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) {
-               vty_out(vty,
-                       "isis network point-to-point is valid only on broadcast interfaces\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_priority,
-       isis_priority_cmd,
-       "isis priority (0-127)",
-       "IS-IS routing protocol\n"
-       "Set priority for Designated Router election\n"
-       "Priority value\n")
-{
-       uint8_t prio = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->priority[0] = prio;
-       circuit->priority[1] = prio;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_priority,
-       no_isis_priority_cmd,
-       "no isis priority [(0-127)]",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set priority for Designated Router election\n"
-       "Priority value\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->priority[0] = DEFAULT_PRIORITY;
-       circuit->priority[1] = DEFAULT_PRIORITY;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_priority_level,
-       isis_priority_level_cmd,
-       "isis priority (0-127) <level-1|level-2>",
-       "IS-IS routing protocol\n"
-       "Set priority for Designated Router election\n"
-       "Priority value\n"
-       "Specify priority for level-1 routing\n"
-       "Specify priority for level-2 routing\n")
-{
-       uint8_t prio = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->priority[level_for_arg(argv[3]->text)] = prio;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_priority_level,
-       no_isis_priority_level_cmd,
-       "no isis priority [(0-127)] <level-1|level-2>",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set priority for Designated Router election\n"
-       "Priority value\n"
-       "Specify priority for level-1 routing\n"
-       "Specify priority for level-2 routing\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       int level = level_for_arg(argv[argc - 1]->text);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->priority[level] = DEFAULT_PRIORITY;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_metric_level,
-       isis_metric_level_cmd,
-       "isis metric (0-16777215) <level-1|level-2>",
-       "IS-IS routing protocol\n"
-       "Set default metric for circuit\n"
-       "Default metric value\n"
-       "Specify metric for level-1 routing\n"
-       "Specify metric for level-2 routing\n")
-{
-       uint32_t met = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       CMD_FERR_RETURN(isis_circuit_metric_set(circuit,
-                                               level_for_arg(argv[3]->text),
-                                               met),
-                       "Failed to set metric: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_metric_level,
-       no_isis_metric_level_cmd,
-       "no isis metric [(0-16777215)] <level-1|level-2>",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set default metric for circuit\n"
-       "Default metric value\n"
-       "Specify metric for level-1 routing\n"
-       "Specify metric for level-2 routing\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       int level = level_for_arg(argv[argc - 1]->text);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, level,
-                                               DEFAULT_CIRCUIT_METRIC),
-                       "Failed to set L1 metric: $ERR");
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_hello_interval_level,
-       isis_hello_interval_level_cmd,
-       "isis hello-interval (1-600) <level-1|level-2>",
-       "IS-IS routing protocol\n"
-       "Set Hello interval\n"
-       "Holdtime 1 second, interval depends on multiplier\n"
-       "Specify hello-interval for level-1 IIHs\n"
-       "Specify hello-interval for level-2 IIHs\n")
-{
-       uint32_t interval = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_interval[level_for_arg(argv[3]->text)] = interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_hello_interval_level,
-       no_isis_hello_interval_level_cmd,
-       "no isis hello-interval [(1-600)] <level-1|level-2>",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set Hello interval\n"
-       "Holdtime 1 second, interval depends on multiplier\n"
-       "Specify hello-interval for level-1 IIHs\n"
-       "Specify hello-interval for level-2 IIHs\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       int level = level_for_arg(argv[argc - 1]->text);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_interval[level] = DEFAULT_HELLO_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_hello_multiplier_level,
-       isis_hello_multiplier_level_cmd,
-       "isis hello-multiplier (2-100) <level-1|level-2>",
-       "IS-IS routing protocol\n"
-       "Set multiplier for Hello holding time\n"
-       "Hello multiplier value\n"
-       "Specify hello multiplier for level-1 IIHs\n"
-       "Specify hello multiplier for level-2 IIHs\n")
-{
-       uint16_t mult = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_multiplier[level_for_arg(argv[3]->text)] = mult;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_hello_multiplier_level,
-       no_isis_hello_multiplier_level_cmd,
-       "no isis hello-multiplier [(2-100)] <level-1|level-2>",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set multiplier for Hello holding time\n"
-       "Hello multiplier value\n"
-       "Specify hello multiplier for level-1 IIHs\n"
-       "Specify hello multiplier for level-2 IIHs\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       int level = level_for_arg(argv[argc - 1]->text);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->hello_multiplier[level] = DEFAULT_HELLO_MULTIPLIER;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_threeway_adj,
-       isis_threeway_adj_cmd,
-       "[no] isis three-way-handshake",
-       NO_STR
-       "IS-IS commands\n"
-       "Enable/Disable three-way handshake\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->disable_threeway_adj = !strcmp(argv[0]->text, "no");
-       return CMD_SUCCESS;
-}
-
-DEFUN (isis_hello_padding,
-       isis_hello_padding_cmd,
-       "isis hello padding",
-       "IS-IS routing protocol\n"
-       "Add padding to IS-IS hello packets\n"
-       "Pad hello packets\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->pad_hellos = 1;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_hello_padding,
-       no_isis_hello_padding_cmd,
-       "no isis hello padding",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Add padding to IS-IS hello packets\n"
-       "Pad hello packets\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->pad_hellos = 0;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (csnp_interval_level,
-       csnp_interval_level_cmd,
-       "isis csnp-interval (1-600) <level-1|level-2>",
-       "IS-IS routing protocol\n"
-       "Set CSNP interval in seconds\n"
-       "CSNP interval value\n"
-       "Specify interval for level-1 CSNPs\n"
-       "Specify interval for level-2 CSNPs\n")
-{
-       uint16_t interval = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->csnp_interval[level_for_arg(argv[3]->text)] = interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_csnp_interval_level,
-       no_csnp_interval_level_cmd,
-       "no isis csnp-interval [(1-600)] <level-1|level-2>",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set CSNP interval in seconds\n"
-       "CSNP interval value\n"
-       "Specify interval for level-1 CSNPs\n"
-       "Specify interval for level-2 CSNPs\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       int level = level_for_arg(argv[argc - 1]->text);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->csnp_interval[level] = DEFAULT_CSNP_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (psnp_interval_level,
-       psnp_interval_level_cmd,
-       "isis psnp-interval (1-120) <level-1|level-2>",
-       "IS-IS routing protocol\n"
-       "Set PSNP interval in seconds\n"
-       "PSNP interval value\n"
-       "Specify interval for level-1 PSNPs\n"
-       "Specify interval for level-2 PSNPs\n")
-{
-       uint16_t interval = atoi(argv[2]->arg);
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->psnp_interval[level_for_arg(argv[3]->text)] = (uint16_t)interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_psnp_interval_level,
-       no_psnp_interval_level_cmd,
-       "no isis psnp-interval [(1-120)] <level-1|level-2>",
-       NO_STR
-       "IS-IS routing protocol\n"
-       "Set PSNP interval in seconds\n"
-       "PSNP interval value\n"
-       "Specify interval for level-1 PSNPs\n"
-       "Specify interval for level-2 PSNPs\n")
-{
-       struct isis_circuit *circuit = isis_circuit_lookup(vty);
-       int level = level_for_arg(argv[argc - 1]->text);
-       if (!circuit)
-               return CMD_ERR_NO_MATCH;
-
-       circuit->psnp_interval[level] = DEFAULT_PSNP_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area)
-{
-       struct isis_circuit *circuit;
-       struct listnode *node;
-
-       if (!vty)
-               return CMD_WARNING_CONFIG_FAILED;
-
-       if (!area) {
-               vty_out(vty, "ISIS area is invalid\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
-               if ((area->is_type & IS_LEVEL_1)
-                   && (circuit->is_type & IS_LEVEL_1)
-                   && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) {
-                       vty_out(vty, "ISIS circuit %s metric is invalid\n",
-                               circuit->interface->name);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-               if ((area->is_type & IS_LEVEL_2)
-                   && (circuit->is_type & IS_LEVEL_2)
-                   && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) {
-                       vty_out(vty, "ISIS circuit %s metric is invalid\n",
-                               circuit->interface->name);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (metric_style,
-       metric_style_cmd,
-       "metric-style <narrow|transition|wide>",
-       "Use old-style (ISO 10589) or new-style packet formats\n"
-       "Use old style of TLVs with narrow metric\n"
-       "Send and accept both styles of TLVs during transition\n"
-       "Use new style of TLVs to carry wider metric\n")
-{
-       int idx_metric_style = 1;
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int ret;
-
-       if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) {
-               isis_area_metricstyle_set(area, false, true);
-               return CMD_SUCCESS;
-       }
-
-       if (area_is_mt(area)) {
-               vty_out(vty,
-                       "Narrow metrics cannot be used while multi topology IS-IS is active\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       ret = validate_metric_style_narrow(vty, area);
-       if (ret != CMD_SUCCESS)
-               return ret;
-
-       if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0)
-               isis_area_metricstyle_set(area, true, true);
-       else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0)
-               isis_area_metricstyle_set(area, true, false);
-       return CMD_SUCCESS;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_metric_style,
-       no_metric_style_cmd,
-       "no metric-style",
-       NO_STR
-       "Use old-style (ISO 10589) or new-style packet formats\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int ret;
-
-       if (area_is_mt(area)) {
-               vty_out(vty,
-                       "Narrow metrics cannot be used while multi topology IS-IS is active\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       ret = validate_metric_style_narrow(vty, area);
-       if (ret != CMD_SUCCESS)
-               return ret;
-
-       isis_area_metricstyle_set(area, true, false);
-       return CMD_SUCCESS;
-}
-
-DEFUN (set_attached_bit,
-       set_attached_bit_cmd,
-       "set-attached-bit",
-       "Set attached bit to identify as L1/L2 router for inter-area traffic\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       isis_area_attached_bit_set(area, true);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_set_attached_bit,
-       no_set_attached_bit_cmd,
-       "no set-attached-bit",
-       NO_STR
-       "Reset attached bit\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       isis_area_attached_bit_set(area, false);
-       return CMD_SUCCESS;
-}
-
-DEFUN (dynamic_hostname,
-       dynamic_hostname_cmd,
-       "hostname dynamic",
-       "Dynamic hostname for IS-IS\n"
-       "Dynamic hostname\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       isis_area_dynhostname_set(area, true);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_dynamic_hostname,
-       no_dynamic_hostname_cmd,
-       "no hostname dynamic",
-       NO_STR
-       "Dynamic hostname for IS-IS\n"
-       "Dynamic hostname\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       isis_area_dynhostname_set(area, false);
-       return CMD_SUCCESS;
-}
-
-DEFUN (is_type,
-       is_type_cmd,
-       "is-type <level-1|level-1-2|level-2-only>",
-       "IS Level for this routing process (OSI only)\n"
-       "Act as a station router only\n"
-       "Act as both a station router and an area router\n"
-       "Act as an area router only\n")
-{
-       int idx_level = 1;
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int type;
-
-       type = string2circuit_t(argv[idx_level]->arg);
-       if (!type) {
-               vty_out(vty, "Unknown IS level \n");
-               return CMD_SUCCESS;
-       }
-
-       isis_area_is_type_set(area, type);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_is_type,
-       no_is_type_cmd,
-       "no is-type <level-1|level-1-2|level-2-only>",
-       NO_STR
-       "IS Level for this routing process (OSI only)\n"
-       "Act as a station router only\n"
-       "Act as both a station router and an area router\n"
-       "Act as an area router only\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int type;
-
-       /*
-        * Put the is-type back to defaults:
-        * - level-1-2 on first area
-        * - level-1 for the rest
-        */
-       if (listgetdata(listhead(isis->area_list)) == area)
-               type = IS_LEVEL_1_AND_2;
-       else
-               type = IS_LEVEL_1;
-
-       isis_area_is_type_set(area, type);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (lsp_gen_interval_level,
-       lsp_gen_interval_level_cmd,
-       "lsp-gen-interval <level-1|level-2> (1-120)",
-       "Minimum interval between regenerating same LSP\n"
-       "Set interval for level 1 only\n"
-       "Set interval for level 2 only\n"
-       "Minimum interval in seconds\n")
-{
-       uint16_t interval = atoi(argv[2]->arg);
-
-       return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[1]->text),
-                                            interval);
-}
-
-DEFUN (no_lsp_gen_interval_level,
-       no_lsp_gen_interval_level_cmd,
-       "no lsp-gen-interval <level-1|level-2> [(1-120)]",
-       NO_STR
-       "Minimum interval between regenerating same LSP\n"
-       "Set interval for level 1 only\n"
-       "Set interval for level 2 only\n"
-       "Minimum interval in seconds\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[2]->text),
-                                            DEFAULT_MIN_LSP_GEN_INTERVAL);
-}
-
-DEFUN (max_lsp_lifetime_level,
-       max_lsp_lifetime_level_cmd,
-       "max-lsp-lifetime <level-1|level-2> (350-65535)",
-       "Maximum LSP lifetime\n"
-       "Maximum LSP lifetime for Level 1 only\n"
-       "Maximum LSP lifetime for Level 2 only\n"
-       "LSP lifetime in seconds\n")
-{
-       uint16_t lifetime = atoi(argv[2]->arg);
-
-       return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text),
-                                            lifetime);
-}
-
-DEFUN (no_max_lsp_lifetime_level,
-       no_max_lsp_lifetime_level_cmd,
-       "no max-lsp-lifetime <level-1|level-2> [(350-65535)]",
-       NO_STR
-       "Maximum LSP lifetime\n"
-       "Maximum LSP lifetime for Level 1 only\n"
-       "Maximum LSP lifetime for Level 2 only\n"
-       "LSP lifetime in seconds\n")
-{
-       return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text),
-                                            DEFAULT_LSP_LIFETIME);
-}
-
-DEFUN (spf_interval_level,
-       spf_interval_level_cmd,
-       "spf-interval <level-1|level-2> (1-120)",
-       "Minimum interval between SPF calculations\n"
-       "Set interval for level 1 only\n"
-       "Set interval for level 2 only\n"
-       "Minimum interval between consecutive SPFs in seconds\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       uint16_t interval = atoi(argv[2]->arg);
-
-       area->min_spf_interval[level_for_arg(argv[1]->text)] = interval;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_spf_interval_level,
-       no_spf_interval_level_cmd,
-       "no spf-interval <level-1|level-2> [(1-120)]",
-       NO_STR
-       "Minimum interval between SPF calculations\n"
-       "Set interval for level 1 only\n"
-       "Set interval for level 2 only\n"
-       "Minimum interval between consecutive SPFs in seconds\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-       int level = level_for_arg(argv[1]->text);
-
-       area->min_spf_interval[level] = MINIMUM_SPF_INTERVAL;
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (lsp_refresh_interval_level,
-       lsp_refresh_interval_level_cmd,
-       "lsp-refresh-interval <level-1|level-2> (1-65235)",
-       "LSP refresh interval\n"
-       "LSP refresh interval for Level 1 only\n"
-       "LSP refresh interval for Level 2 only\n"
-       "LSP refresh interval in seconds\n")
-{
-       uint16_t interval = atoi(argv[2]->arg);
-       return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[1]->text),
-                                       interval);
-}
-
-DEFUN (no_lsp_refresh_interval_level,
-       no_lsp_refresh_interval_level_cmd,
-       "no lsp-refresh-interval <level-1|level-2> [(1-65235)]",
-       NO_STR
-       "LSP refresh interval\n"
-       "LSP refresh interval for Level 1 only\n"
-       "LSP refresh interval for Level 2 only\n"
-       "LSP refresh interval in seconds\n")
-{
-       return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[2]->text),
-                                       DEFAULT_MAX_LSP_GEN_INTERVAL);
-}
-
-DEFUN (area_passwd,
-       area_passwd_cmd,
-       "area-password <clear|md5> WORD [authenticate snp <send-only|validate>]",
-       "Configure the authentication password for an area\n"
-       "Authentication type\n"
-       "Authentication type\n"
-       "Area password\n"
-       "Authentication\n"
-       "SNP PDUs\n"
-       "Send but do not check PDUs on receiving\n"
-       "Send and check PDUs on receiving\n")
-{
-       return isis_vty_password_set(vty, argc, argv, IS_LEVEL_1);
-}
-
-DEFUN (no_area_passwd,
-       no_area_passwd_cmd,
-       "no area-password",
-       NO_STR
-       "Configure the authentication password for an area\n")
-{
-       VTY_DECLVAR_CONTEXT(isis_area, area);
-
-       return isis_area_passwd_unset(area, IS_LEVEL_1);
-}
-
-void isis_vty_daemon_init(void)
-{
-       install_element(INTERFACE_NODE, &isis_circuit_type_cmd);
-       install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd);
-
-       install_element(INTERFACE_NODE, &isis_network_cmd);
-       install_element(INTERFACE_NODE, &no_isis_network_cmd);
-
-       install_element(INTERFACE_NODE, &isis_priority_cmd);
-       install_element(INTERFACE_NODE, &no_isis_priority_cmd);
-       install_element(INTERFACE_NODE, &isis_priority_level_cmd);
-       install_element(INTERFACE_NODE, &no_isis_priority_level_cmd);
-
-       install_element(INTERFACE_NODE, &isis_metric_level_cmd);
-       install_element(INTERFACE_NODE, &no_isis_metric_level_cmd);
-
-       install_element(INTERFACE_NODE, &isis_hello_interval_level_cmd);
-       install_element(INTERFACE_NODE, &no_isis_hello_interval_level_cmd);
-
-       install_element(INTERFACE_NODE, &isis_hello_multiplier_level_cmd);
-       install_element(INTERFACE_NODE, &no_isis_hello_multiplier_level_cmd);
-
-       install_element(INTERFACE_NODE, &isis_threeway_adj_cmd);
-
-       install_element(INTERFACE_NODE, &isis_hello_padding_cmd);
-       install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd);
-
-       install_element(INTERFACE_NODE, &csnp_interval_level_cmd);
-       install_element(INTERFACE_NODE, &no_csnp_interval_level_cmd);
-
-       install_element(INTERFACE_NODE, &psnp_interval_level_cmd);
-       install_element(INTERFACE_NODE, &no_psnp_interval_level_cmd);
-
-       install_element(ROUTER_NODE, &metric_style_cmd);
-       install_element(ROUTER_NODE, &no_metric_style_cmd);
-
-       install_element(ROUTER_NODE, &set_attached_bit_cmd);
-       install_element(ROUTER_NODE, &no_set_attached_bit_cmd);
-
-       install_element(ROUTER_NODE, &dynamic_hostname_cmd);
-       install_element(ROUTER_NODE, &no_dynamic_hostname_cmd);
-
-       install_element(ROUTER_NODE, &is_type_cmd);
-       install_element(ROUTER_NODE, &no_is_type_cmd);
-
-       install_element(ROUTER_NODE, &lsp_gen_interval_level_cmd);
-       install_element(ROUTER_NODE, &no_lsp_gen_interval_level_cmd);
-
-       install_element(ROUTER_NODE, &max_lsp_lifetime_level_cmd);
-       install_element(ROUTER_NODE, &no_max_lsp_lifetime_level_cmd);
-
-       install_element(ROUTER_NODE, &spf_interval_level_cmd);
-       install_element(ROUTER_NODE, &no_spf_interval_level_cmd);
-
-       install_element(ROUTER_NODE, &lsp_refresh_interval_level_cmd);
-       install_element(ROUTER_NODE, &no_lsp_refresh_interval_level_cmd);
-
-       install_element(ROUTER_NODE, &area_passwd_cmd);
-       install_element(ROUTER_NODE, &no_area_passwd_cmd);
-}
index ce45ba65ece61f764b38513d10ad501cac77f223..419127c34e4db8edc6c227273a84f7cf2773aa1b 100644 (file)
@@ -36,6 +36,7 @@
 #include "table.h"
 #include "qobj.h"
 #include "spf_backoff.h"
+#include "lib/northbound_cli.h"
 
 #include "isisd/dict.h"
 #include "isisd/isis_constants.h"
@@ -67,7 +68,6 @@ DEFINE_QOBJ_TYPE(isis_area)
  * Prototypes.
  */
 int isis_area_get(struct vty *, const char *);
-int isis_area_destroy(struct vty *, const char *);
 int area_net_title(struct vty *, const char *);
 int area_clear_net_title(struct vty *, const char *);
 int show_isis_interface_common(struct vty *, const char *ifname, char);
@@ -113,10 +113,11 @@ struct isis_area *isis_area_create(const char *area_tag)
         */
        if (fabricd) {
                area->is_type = IS_LEVEL_2;
-       } else if (listcount(isis->area_list) > 0)
-               area->is_type = IS_LEVEL_1;
-       else
+       } else if (listcount(isis->area_list) == 0)
                area->is_type = IS_LEVEL_1_AND_2;
+       else
+               area->is_type = yang_get_default_enum(
+                       "/frr-isisd:isis/instance/is-type");
 
        /*
         * intialize the databases
@@ -138,6 +139,35 @@ struct isis_area *isis_area_create(const char *area_tag)
        /*
         * Default values
         */
+#ifndef FABRICD
+       enum isis_metric_style default_style;
+
+       area->max_lsp_lifetime[0] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-1");
+       area->max_lsp_lifetime[1] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-2");
+       area->lsp_refresh[0] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/lsp/refresh-interval/level-1");
+       area->lsp_refresh[1] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/lsp/refresh-interval/level-2");
+       area->lsp_gen_interval[0] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/lsp/generation-interval/level-1");
+       area->lsp_gen_interval[1] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/lsp/generation-interval/level-2");
+       area->min_spf_interval[0] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
+       area->min_spf_interval[1] = yang_get_default_uint16(
+               "/frr-isisd:isis/instance/spf/minimum-interval/level-1");
+       area->dynhostname = yang_get_default_bool(
+               "/frr-isisd:isis/instance/dynamic-hostname");
+       default_style =
+               yang_get_default_enum("/frr-isisd:isis/instance/metric-style");
+       area->oldmetric = default_style == ISIS_WIDE_METRIC ? 0 : 1;
+       area->newmetric = default_style == ISIS_NARROW_METRIC ? 0 : 1;
+       area->lsp_frag_threshold = 90; /* not currently configurable */
+       area->lsp_mtu =
+               yang_get_default_uint16("/frr-isisd:isis/instance/lsp/mtu");
+#else
        area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME;    /* 1200 */
        area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME;    /* 1200 */
        area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */
@@ -151,6 +181,7 @@ struct isis_area *isis_area_create(const char *area_tag)
        area->newmetric = 1;
        area->lsp_frag_threshold = 90;
        area->lsp_mtu = DEFAULT_LSP_MTU;
+#endif /* ifndef FABRICD */
 
        area_mt_init(area);
 
@@ -207,7 +238,7 @@ int isis_area_get(struct vty *vty, const char *area_tag)
        return CMD_SUCCESS;
 }
 
-int isis_area_destroy(struct vty *vty, const char *area_tag)
+int isis_area_destroy(const char *area_tag)
 {
        struct isis_area *area;
        struct listnode *node, *nnode;
@@ -217,7 +248,8 @@ int isis_area_destroy(struct vty *vty, const char *area_tag)
        area = isis_area_lookup(area_tag);
 
        if (area == NULL) {
-               vty_out(vty, "Can't find ISIS instance \n");
+               zlog_warn("%s: could not find area with area-tag %s",
+                               __func__, area_tag);
                return CMD_ERR_NO_MATCH;
        }
 
@@ -287,6 +319,7 @@ int isis_area_destroy(struct vty *vty, const char *area_tag)
        return CMD_SUCCESS;
 }
 
+#ifdef FABRICD
 static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid,
                                bool enabled)
 {
@@ -312,6 +345,7 @@ static void area_set_mt_overload(struct isis_area *area, uint16_t mtid,
                                                0);
        }
 }
+#endif /* ifdef FABRICD */
 
 int area_net_title(struct vty *vty, const char *net_title)
 {
@@ -720,6 +754,9 @@ void print_debug(struct vty *vty, int flags, int onoff)
                vty_out(vty,
                        "IS-IS Adjacency related packets debugging is %s\n",
                        onoffs);
+       if (flags & DEBUG_TX_QUEUE)
+               vty_out(vty, "IS-IS TX queue debugging is %s\n",
+                       onoffs);
        if (flags & DEBUG_SNP_PACKETS)
                vty_out(vty, "IS-IS CSNP/PSNP packets debugging is %s\n",
                        onoffs);
@@ -738,8 +775,8 @@ void print_debug(struct vty *vty, int flags, int onoff)
                vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs);
        if (flags & DEBUG_LSP_SCHED)
                vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs);
-       if (flags & DEBUG_FABRICD_FLOODING)
-               vty_out(vty, "OpenFabric Flooding debugging is %s\n", onoffs);
+       if (flags & DEBUG_FLOODING)
+               vty_out(vty, "IS-IS Flooding debugging is %s\n", onoffs);
        if (flags & DEBUG_BFD)
                vty_out(vty, "IS-IS BFD debugging is %s\n", onoffs);
 }
@@ -771,6 +808,10 @@ static int config_write_debug(struct vty *vty)
                vty_out(vty, "debug " PROTO_NAME " adj-packets\n");
                write++;
        }
+       if (flags & DEBUG_TX_QUEUE) {
+               vty_out(vty, "debug " PROTO_NAME " tx-queue\n");
+               write++;
+       }
        if (flags & DEBUG_SNP_PACKETS) {
                vty_out(vty, "debug " PROTO_NAME " snp-packets\n");
                write++;
@@ -803,7 +844,7 @@ static int config_write_debug(struct vty *vty)
                vty_out(vty, "debug " PROTO_NAME " lsp-sched\n");
                write++;
        }
-       if (flags & DEBUG_FABRICD_FLOODING) {
+       if (flags & DEBUG_FLOODING) {
                vty_out(vty, "debug " PROTO_NAME " flooding\n");
                write++;
        }
@@ -843,6 +884,60 @@ DEFUN (no_debug_isis_adj,
        return CMD_SUCCESS;
 }
 
+DEFUN (debug_isis_tx_queue,
+       debug_isis_tx_queue_cmd,
+       "debug " PROTO_NAME " tx-queue",
+       DEBUG_STR
+       PROTO_HELP
+       "IS-IS TX queues\n")
+{
+       isis->debugs |= DEBUG_TX_QUEUE;
+       print_debug(vty, DEBUG_TX_QUEUE, 1);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_isis_tx_queue,
+       no_debug_isis_tx_queue_cmd,
+       "no debug " PROTO_NAME " tx-queue",
+       NO_STR
+       UNDEBUG_STR
+       PROTO_HELP
+       "IS-IS TX queues\n")
+{
+       isis->debugs &= ~DEBUG_TX_QUEUE;
+       print_debug(vty, DEBUG_TX_QUEUE, 0);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (debug_isis_flooding,
+       debug_isis_flooding_cmd,
+       "debug " PROTO_NAME " flooding",
+       DEBUG_STR
+       PROTO_HELP
+       "Flooding algorithm\n")
+{
+       isis->debugs |= DEBUG_FLOODING;
+       print_debug(vty, DEBUG_FLOODING, 1);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_isis_flooding,
+       no_debug_isis_flooding_cmd,
+       "no debug " PROTO_NAME " flooding",
+       NO_STR
+       UNDEBUG_STR
+       PROTO_HELP
+       "Flooding algorithm\n")
+{
+       isis->debugs &= ~DEBUG_FLOODING;
+       print_debug(vty, DEBUG_FLOODING, 0);
+
+       return CMD_SUCCESS;
+}
+
 DEFUN (debug_isis_snp,
        debug_isis_snp_cmd,
        "debug " PROTO_NAME " snp-packets",
@@ -1197,11 +1292,25 @@ DEFUN (show_isis_summary,
                        }
                }
 
+               vty_out(vty, "  TX counters per PDU type:\n");
+               pdu_counter_print(vty, "    ", area->pdu_tx_counters);
+               vty_out(vty, "   LSP RXMT: %" PRIu64 "\n",
+                       area->lsp_rxmt_count);
+               vty_out(vty, "  RX counters per PDU type:\n");
+               pdu_counter_print(vty, "    ", area->pdu_rx_counters);
+
                for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
                        if ((area->is_type & level) == 0)
                                continue;
 
                        vty_out(vty, "  Level-%d:\n", level);
+
+                       vty_out(vty, "    LSP0 regenerated: %" PRIu64 "\n",
+                               area->lsp_gen_count[level - 1]);
+
+                       vty_out(vty, "         LSPs purged: %" PRIu64 "\n",
+                               area->lsp_purge_count[level - 1]);
+
                        if (area->spf_timer[level - 1])
                                vty_out(vty, "    SPF: (pending)\n");
                        else
@@ -1232,39 +1341,17 @@ DEFUN (show_isis_summary,
        return CMD_SUCCESS;
 }
 
-/*
- * This function supports following display options:
- * [ show isis database [detail] ]
- * [ show isis database <sysid> [detail] ]
- * [ show isis database <hostname> [detail] ]
- * [ show isis database <sysid>.<pseudo-id> [detail] ]
- * [ show isis database <hostname>.<pseudo-id> [detail] ]
- * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
- * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
- * [ show isis database detail <sysid> ]
- * [ show isis database detail <hostname> ]
- * [ show isis database detail <sysid>.<pseudo-id> ]
- * [ show isis database detail <hostname>.<pseudo-id> ]
- * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
- * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
- */
-static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
+struct isis_lsp *lsp_for_arg(const char *argv, dict_t *lspdb)
 {
-       struct listnode *node;
-       struct isis_area *area;
-       struct isis_lsp *lsp;
-       struct isis_dynhn *dynhn;
-       const char *pos;
-       uint8_t lspid[ISIS_SYS_ID_LEN + 2];
-       char sysid[255];
+       char sysid[255] = {0};
        uint8_t number[3];
-       int level, lsp_count;
-
-       if (isis->area_list->count == 0)
-               return CMD_SUCCESS;
+       const char *pos;
+       uint8_t lspid[ISIS_SYS_ID_LEN + 2] = {0};
+       struct isis_dynhn *dynhn;
+       struct isis_lsp *lsp = NULL;
 
-       memset(&lspid, 0, ISIS_SYS_ID_LEN);
-       memset(&sysid, 0, 255);
+       if (!argv)
+               return NULL;
 
        /*
         * extract fragment and pseudo id from the string argv
@@ -1285,7 +1372,7 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
                                (uint8_t)strtol((char *)number, NULL, 16);
                        pos -= 4;
                        if (strncmp(pos, ".", 1) != 0)
-                               return CMD_WARNING;
+                               return NULL;
                }
                if (strncmp(pos, ".", 1) == 0) {
                        memcpy(number, ++pos, 2);
@@ -1295,6 +1382,51 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
                }
        }
 
+       /*
+        * Try to find the lsp-id if the argv
+        * string is in
+        * the form
+        * hostname.<pseudo-id>-<fragment>
+        */
+       if (sysid2buff(lspid, sysid)) {
+               lsp = lsp_search(lspid, lspdb);
+       } else if ((dynhn = dynhn_find_by_name(sysid))) {
+               memcpy(lspid, dynhn->id, ISIS_SYS_ID_LEN);
+               lsp = lsp_search(lspid, lspdb);
+       } else if (strncmp(cmd_hostname_get(), sysid, 15) == 0) {
+               memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN);
+               lsp = lsp_search(lspid, lspdb);
+       }
+
+       return lsp;
+}
+
+/*
+ * This function supports following display options:
+ * [ show isis database [detail] ]
+ * [ show isis database <sysid> [detail] ]
+ * [ show isis database <hostname> [detail] ]
+ * [ show isis database <sysid>.<pseudo-id> [detail] ]
+ * [ show isis database <hostname>.<pseudo-id> [detail] ]
+ * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
+ * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
+ * [ show isis database detail <sysid> ]
+ * [ show isis database detail <hostname> ]
+ * [ show isis database detail <sysid>.<pseudo-id> ]
+ * [ show isis database detail <hostname>.<pseudo-id> ]
+ * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
+ * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
+ */
+static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
+{
+       struct listnode *node;
+       struct isis_area *area;
+       struct isis_lsp *lsp;
+       int level, lsp_count;
+
+       if (isis->area_list->count == 0)
+               return CMD_SUCCESS;
+
        for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
                vty_out(vty, "Area %s:\n",
                        area->area_tag ? area->area_tag : "null");
@@ -1302,35 +1434,7 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
                for (level = 0; level < ISIS_LEVELS; level++) {
                        if (area->lspdb[level]
                            && dict_count(area->lspdb[level]) > 0) {
-                               lsp = NULL;
-                               if (argv != NULL) {
-                                       /*
-                                        * Try to find the lsp-id if the argv
-                                        * string is in
-                                        * the form
-                                        * hostname.<pseudo-id>-<fragment>
-                                        */
-                                       if (sysid2buff(lspid, sysid)) {
-                                               lsp = lsp_search(
-                                                       lspid,
-                                                       area->lspdb[level]);
-                                       } else if ((dynhn = dynhn_find_by_name(
-                                                           sysid))) {
-                                               memcpy(lspid, dynhn->id,
-                                                      ISIS_SYS_ID_LEN);
-                                               lsp = lsp_search(
-                                                       lspid,
-                                                       area->lspdb[level]);
-                                       } else if (strncmp(cmd_hostname_get(),
-                                                          sysid, 15)
-                                                  == 0) {
-                                               memcpy(lspid, isis->sysid,
-                                                      ISIS_SYS_ID_LEN);
-                                               lsp = lsp_search(
-                                                       lspid,
-                                                       area->lspdb[level]);
-                                       }
-                               }
+                               lsp = lsp_for_arg(argv, area->lspdb[level]);
 
                                if (lsp != NULL || argv == NULL) {
                                        vty_out(vty,
@@ -1382,12 +1486,13 @@ DEFUN (show_database,
        return show_isis_database(vty, id, uilevel);
 }
 
+#ifdef FABRICD
 /*
- * 'router isis' command
+ * 'router openfabric' command
  */
-DEFUN_NOSH (router_isis,
-       router_isis_cmd,
-       "router " PROTO_NAME " WORD",
+DEFUN_NOSH (router_openfabric,
+       router_openfabric_cmd,
+       "router openfabric WORD",
        ROUTER_STR
        PROTO_HELP
        "ISO Routing area tag\n")
@@ -1397,20 +1502,21 @@ DEFUN_NOSH (router_isis,
 }
 
 /*
- *'no router isis' command
+ *'no router openfabric' command
  */
-DEFUN (no_router_isis,
-       no_router_isis_cmd,
-       "no router " PROTO_NAME " WORD",
+DEFUN (no_router_openfabric,
+       no_router_openfabric_cmd,
+       "no router openfabric WORD",
        NO_STR
        ROUTER_STR
        PROTO_HELP
        "ISO Routing area tag\n")
 {
        int idx_word = 3;
-       return isis_area_destroy(vty, argv[idx_word]->arg);
+       return isis_area_destroy(argv[idx_word]->arg);
 }
-
+#endif /* ifdef FABRICD */
+#ifdef FABRICD
 /*
  * 'net' command
  */
@@ -1437,7 +1543,8 @@ DEFUN (no_net,
        int idx_word = 2;
        return area_clear_net_title(vty, argv[idx_word]->arg);
 }
-
+#endif /* ifdef FABRICD */
+#ifdef FABRICD
 DEFUN (isis_topology,
        isis_topology_cmd,
        "topology " ISIS_MT_NAMES " [overload]",
@@ -1502,6 +1609,7 @@ DEFUN (no_isis_topology,
        area_set_mt_overload(area, mtid, false);
        return CMD_SUCCESS;
 }
+#endif /* ifdef FABRICD */
 
 void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu)
 {
@@ -1673,11 +1781,9 @@ void isis_area_is_type_set(struct isis_area *area, int is_type)
 void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
                               bool new_metric)
 {
-       if (area->oldmetric != old_metric || area->newmetric != new_metric) {
-               area->oldmetric = old_metric;
-               area->newmetric = new_metric;
-               lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
-       }
+       area->oldmetric = old_metric;
+       area->newmetric = new_metric;
+       lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
 }
 
 void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
@@ -1688,6 +1794,9 @@ void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
                area->overload_bit = new_overload_bit;
                lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
        }
+#ifndef FABRICD
+       isis_notif_db_overload(area, overload_bit);
+#endif /* ifndef FABRICD */
 }
 
 void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit)
@@ -1732,6 +1841,7 @@ void isis_area_lsp_refresh_set(struct isis_area *area, int level,
        lsp_regenerate_schedule(area, level, 1);
 }
 
+#ifdef FABRICD
 DEFUN (log_adj_changes,
        log_adj_changes_cmd,
        "log-adjacency-changes",
@@ -1756,7 +1866,8 @@ DEFUN (no_log_adj_changes,
 
        return CMD_SUCCESS;
 }
-
+#endif /* ifdef FABRICD */
+#ifdef FABRICD
 /* IS-IS configuration write function */
 int isis_config_write(struct vty *vty)
 {
@@ -2031,6 +2142,23 @@ int isis_config_write(struct vty *vty)
        return write;
 }
 
+#else
+/* IS-IS configuration write function */
+int isis_config_write(struct vty *vty)
+{
+       int write = 0;
+       struct lyd_node *dnode;
+
+       dnode = yang_dnode_get(running_config->dnode, "/frr-isisd:isis");
+       if (dnode) {
+               nb_cli_show_dnode_cmds(vty, dnode, false);
+               write++;
+       }
+
+       return write;
+}
+#endif /* ifdef FABRICD */
+
 struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1};
 
 void isis_init()
@@ -2061,6 +2189,10 @@ void isis_init()
 
        install_element(ENABLE_NODE, &debug_isis_adj_cmd);
        install_element(ENABLE_NODE, &no_debug_isis_adj_cmd);
+       install_element(ENABLE_NODE, &debug_isis_tx_queue_cmd);
+       install_element(ENABLE_NODE, &no_debug_isis_tx_queue_cmd);
+       install_element(ENABLE_NODE, &debug_isis_flooding_cmd);
+       install_element(ENABLE_NODE, &no_debug_isis_flooding_cmd);
        install_element(ENABLE_NODE, &debug_isis_snp_cmd);
        install_element(ENABLE_NODE, &no_debug_isis_snp_cmd);
        install_element(ENABLE_NODE, &debug_isis_upd_cmd);
@@ -2082,6 +2214,10 @@ void isis_init()
 
        install_element(CONFIG_NODE, &debug_isis_adj_cmd);
        install_element(CONFIG_NODE, &no_debug_isis_adj_cmd);
+       install_element(CONFIG_NODE, &debug_isis_tx_queue_cmd);
+       install_element(CONFIG_NODE, &no_debug_isis_tx_queue_cmd);
+       install_element(CONFIG_NODE, &debug_isis_flooding_cmd);
+       install_element(CONFIG_NODE, &no_debug_isis_flooding_cmd);
        install_element(CONFIG_NODE, &debug_isis_snp_cmd);
        install_element(CONFIG_NODE, &no_debug_isis_snp_cmd);
        install_element(CONFIG_NODE, &debug_isis_upd_cmd);
@@ -2101,11 +2237,12 @@ void isis_init()
        install_element(CONFIG_NODE, &debug_isis_bfd_cmd);
        install_element(CONFIG_NODE, &no_debug_isis_bfd_cmd);
 
-       install_element(CONFIG_NODE, &router_isis_cmd);
-       install_element(CONFIG_NODE, &no_router_isis_cmd);
-
        install_default(ROUTER_NODE);
 
+#ifdef FABRICD
+       install_element(CONFIG_NODE, &router_openfabric_cmd);
+       install_element(CONFIG_NODE, &no_router_openfabric_cmd);
+
        install_element(ROUTER_NODE, &net_cmd);
        install_element(ROUTER_NODE, &no_net_cmd);
 
@@ -2114,6 +2251,7 @@ void isis_init()
 
        install_element(ROUTER_NODE, &log_adj_changes_cmd);
        install_element(ROUTER_NODE, &no_log_adj_changes_cmd);
+#endif /* ifdef FABRICD */
 
        spf_backoff_cmd_init();
 }
index fe9abff93c1b19aa42953ef1c4a64cf51ac404e1..fb879395c1b70ec8cf9c51140933a858fcc9e698 100644 (file)
@@ -28,6 +28,8 @@
 #include "isisd/isis_constants.h"
 #include "isisd/isis_common.h"
 #include "isisd/isis_redist.h"
+#include "isisd/isis_pdu_counter.h"
+#include "isisd/isis_circuit.h"
 #include "isis_flags.h"
 #include "dict.h"
 #include "isis_memory.h"
@@ -49,6 +51,7 @@ static const bool fabricd = false;
 #define PROTO_REDIST_STR FRR_REDIST_STR_ISISD
 #define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_ISISD
 #define ROUTER_NODE ISIS_NODE
+extern void isis_cli_init(void);
 #endif
 
 extern struct zebra_privs_t isisd_privs;
@@ -95,6 +98,13 @@ struct lsp_refresh_arg {
        int level;
 };
 
+/* for yang configuration */
+enum isis_metric_style {
+       ISIS_NARROW_METRIC = 0,
+       ISIS_WIDE_METRIC,
+       ISIS_TRANSITION_METRIC,
+};
+
 struct isis_area {
        struct isis *isis;                             /* back pointer */
        dict_t *lspdb[ISIS_LEVELS];                    /* link-state dbs */
@@ -148,6 +158,8 @@ struct isis_area {
        uint16_t min_spf_interval[ISIS_LEVELS];
        /* the percentage of LSP mtu size used, before generating a new frag */
        int lsp_frag_threshold;
+       uint64_t lsp_gen_count[ISIS_LEVELS];
+       uint64_t lsp_purge_count[ISIS_LEVELS];
        int ip_circuits;
        /* logging adjacency changes? */
        uint8_t log_adj_changes;
@@ -168,6 +180,10 @@ struct isis_area {
 
        struct lsp_refresh_arg lsp_refresh_arg[ISIS_LEVELS];
 
+       pdu_counter_t pdu_tx_counters;
+       pdu_counter_t pdu_rx_counters;
+       uint64_t lsp_rxmt_count;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(isis_area)
@@ -177,7 +193,9 @@ void isis_new(unsigned long);
 struct isis_area *isis_area_create(const char *);
 struct isis_area *isis_area_lookup(const char *);
 int isis_area_get(struct vty *vty, const char *area_tag);
+int isis_area_destroy(const char *area_tag);
 void print_debug(struct vty *, int, int);
+struct isis_lsp *lsp_for_arg(const char *argv, dict_t *lspdb);
 
 void isis_area_invalidate_routes(struct isis_area *area, int levels);
 void isis_area_verify_routes(struct isis_area *area);
@@ -200,6 +218,52 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
 int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
                                  const char *passwd, uint8_t snp_auth);
 
+extern const struct frr_yang_module_info frr_isisd_info;
+extern void isis_northbound_init(void);
+
+/* YANG northbound notifications */
+extern void isis_notif_db_overload(const struct isis_area *area, bool overload);
+extern void isis_notif_lsp_too_large(const struct isis_circuit *circuit,
+                                    uint32_t pdu_size, const char *lsp_id);
+extern void isis_notif_if_state_change(const struct isis_circuit *circuit,
+                                      bool down);
+extern void isis_notif_corrupted_lsp(const struct isis_area *area,
+                                    const char *lsp_id); /* currently unused */
+extern void isis_notif_lsp_exceed_max(const struct isis_area *area,
+                                     const char *lsp_id);
+extern void
+isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
+                                 uint8_t max_area_addrs, const char *raw_pdu);
+extern void
+isis_notif_authentication_type_failure(const struct isis_circuit *circuit,
+                                      const char *raw_pdu);
+extern void
+isis_notif_authentication_failure(const struct isis_circuit *circuit,
+                                 const char *raw_pdu);
+extern void isis_notif_adj_state_change(const struct isis_adjacency *adj,
+                                       int new_state, const char *reason);
+extern void isis_notif_reject_adjacency(const struct isis_circuit *circuit,
+                                       const char *reason,
+                                       const char *raw_pdu);
+extern void isis_notif_area_mismatch(const struct isis_circuit *circuit,
+                                    const char *raw_pdu);
+extern void isis_notif_lsp_received(const struct isis_circuit *circuit,
+                                   const char *lsp_id, uint32_t seqno,
+                                   uint32_t timestamp, const char *sys_id);
+extern void isis_notif_lsp_gen(const struct isis_area *area, const char *lsp_id,
+                              uint32_t seqno, uint32_t timestamp);
+extern void isis_notif_id_len_mismatch(const struct isis_circuit *circuit,
+                                      uint8_t rcv_id_len, const char *raw_pdu);
+extern void isis_notif_version_skew(const struct isis_circuit *circuit,
+                                   uint8_t version, const char *raw_pdu);
+extern void isis_notif_lsp_error(const struct isis_circuit *circuit,
+                                const char *lsp_id, const char *raw_pdu,
+                                uint32_t offset, uint8_t tlv_type);
+extern void isis_notif_seqno_skipped(const struct isis_circuit *circuit,
+                                    const char *lsp_id);
+extern void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,
+                                    const char *lsp_id);
+
 /* Master of threads. */
 extern struct thread_master *master;
 
@@ -212,8 +276,9 @@ extern struct thread_master *master;
 #define DEBUG_PACKET_DUMP                (1<<6)
 #define DEBUG_LSP_GEN                    (1<<7)
 #define DEBUG_LSP_SCHED                  (1<<8)
-#define DEBUG_FABRICD_FLOODING           (1<<9)
+#define DEBUG_FLOODING                   (1<<9)
 #define DEBUG_BFD                        (1<<10)
+#define DEBUG_TX_QUEUE                   (1<<11)
 
 #define lsp_debug(...)                                                         \
        do {                                                                   \
index 552bc49b80ebe82e2fea6a8036c7e2e673da6e23..c5b9b31a480735bc52f50bb54b98d775e6970647 100644 (file)
@@ -7,12 +7,12 @@ noinst_LIBRARIES += isisd/libisis.a
 sbin_PROGRAMS += isisd/isisd
 dist_examples_DATA += isisd/isisd.conf.sample
 vtysh_scan += \
+       $(top_srcdir)/isisd/isis_cli.c \
        $(top_srcdir)/isisd/isis_redist.c \
        $(top_srcdir)/isisd/isis_spf.c \
        $(top_srcdir)/isisd/isis_te.c \
        $(top_srcdir)/isisd/isis_vty_common.c \
        $(top_srcdir)/isisd/isis_vty_fabricd.c \
-       $(top_srcdir)/isisd/isis_vty_isisd.c \
        $(top_srcdir)/isisd/isisd.c \
        # end
 man8 += $(MANBUILD)/isisd.8
@@ -43,6 +43,7 @@ noinst_HEADERS += \
        isisd/isis_mt.h \
        isisd/isis_network.h \
        isisd/isis_pdu.h \
+       isisd/isis_pdu_counter.h \
        isisd/isis_redist.h \
        isisd/isis_route.h \
        isisd/isis_routemap.h \
@@ -56,6 +57,7 @@ noinst_HEADERS += \
        isisd/isisd.h \
        isisd/iso_checksum.h \
        isisd/fabricd.h \
+       isisd/isis_cli.h \
        # end
 
 LIBISIS_SOURCES = \
@@ -74,6 +76,7 @@ LIBISIS_SOURCES = \
        isisd/isis_misc.c \
        isisd/isis_mt.c \
        isisd/isis_pdu.c \
+       isisd/isis_pdu_counter.c \
        isisd/isis_redist.c \
        isisd/isis_route.c \
        isisd/isis_routemap.c \
@@ -101,11 +104,19 @@ ISIS_LDADD_COMMON = lib/libfrr.la @LIBCAP@
 
 isisd_libisis_a_SOURCES = \
        $(LIBISIS_SOURCES) \
-       isisd/isis_vty_isisd.c \
+       isisd/isis_northbound.c \
+       isisd/isis_cli.c \
        #end
+
+isisd/isis_cli_clippy.c: $(CLIPPY_DEPS)
+isisd/isis_cli.$(OBJEXT): isisd/isis_cli_clippy.c
+
 isisd_isisd_LDADD = isisd/libisis.a $(ISIS_LDADD_COMMON)
 isisd_isisd_SOURCES = $(ISIS_SOURCES)
-
+nodist_isisd_isisd_SOURCES = \
+       yang/frr-isisd.yang.c \
+       # end
+       
 # Building fabricd
 
 FABRICD_CPPFLAGS = -DFABRICD=1 $(AM_CPPFLAGS)
index 4fe305f282681009ec462869e75968e6af31fd47..870d158aac4484d540251c4681c5aa5c20bebb59 100644 (file)
@@ -1,23 +1,17 @@
 /*
  * Copyright (c) 2016  David Lamparter, for NetDEF, Inc.
  *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #ifdef HAVE_CONFIG_H
index ee496ab3658a1b62201a401180ad6aa6809bc18a..96fec97d7efa761f5bd350a057244304b9f043a2 100644 (file)
@@ -1,23 +1,17 @@
 /*
  * Copyright (c) 2016  David Lamparter, for NetDEF, Inc.
  *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #ifndef _FRR_HOOK_H
index b1ed7d2f6b15f159696996b153ac34060a5127fd..7e428f135c4bbce018489d562c0b55527dbb1c30 100644 (file)
@@ -105,10 +105,16 @@ static struct log_ref ferr_lib_warn[] = {
                .suggestion = "Check if the installed FRR YANG modules are in sync with the FRR binaries",
        },
        {
-               .code = EC_LIB_NB_CB_CONFIG,
-               .title = "A northbound configuration callback has failed",
-               .description = "The northbound subsystem has detected that a callback used to process a configuration change has returned an error",
-               .suggestion = "The log message should contain further details on the specific error that occurred; investigate the reported error.",
+               .code = EC_LIB_NB_CB_CONFIG_VALIDATE,
+               .title = "A northbound configuration callback has failed in the VALIDATE phase",
+               .description = "A callback used to process a configuration change has returned a validation error",
+               .suggestion = "The provided configuration is invalid. Fix any inconsistency and try again.",
+       },
+       {
+               .code = EC_LIB_NB_CB_CONFIG_PREPARE,
+               .title = "A northbound configuration callback has failed in the PREPARE phase",
+               .description = "A callback used to process a configuration change has returned a resource allocation error",
+               .suggestion = "The system might be running out of resources. Check the log for more details.",
        },
        {
                .code = EC_LIB_NB_CB_STATE,
@@ -326,6 +332,18 @@ static struct log_ref ferr_lib_err[] = {
                .description = "The northbound subsystem has detected that the libsysrepo library returned an error",
                .suggestion = "Open an Issue with all relevant log files and restart FRR"
        },
+       {
+               .code = EC_LIB_NB_CB_CONFIG_ABORT,
+               .title = "A northbound configuration callback has failed in the ABORT phase",
+               .description = "A callback used to process a configuration change has returned an error while trying to abort a change",
+               .suggestion = "Gather log data and open an Issue.",
+       },
+       {
+               .code = EC_LIB_NB_CB_CONFIG_APPLY,
+               .title = "A northbound configuration callback has failed in the APPLY phase",
+               .description = "A callback used to process a configuration change has returned an error while applying the changes",
+               .suggestion = "Gather log data and open an Issue.",
+       },
        {
                .code = END_FERR,
        }
index 5534edbd8d9faf2b310c74346355b139d612a090..86a83df46c216ae19f406d3dc1109b26efb55c14 100644 (file)
@@ -57,7 +57,10 @@ enum lib_log_refs {
        EC_LIB_NB_CB_MISSING,
        EC_LIB_NB_CB_INVALID_PRIO,
        EC_LIB_NB_CBS_VALIDATION,
-       EC_LIB_NB_CB_CONFIG,
+       EC_LIB_NB_CB_CONFIG_VALIDATE,
+       EC_LIB_NB_CB_CONFIG_PREPARE,
+       EC_LIB_NB_CB_CONFIG_ABORT,
+       EC_LIB_NB_CB_CONFIG_APPLY,
        EC_LIB_NB_CB_STATE,
        EC_LIB_NB_CB_RPC,
        EC_LIB_NB_CANDIDATE_INVALID,
index 6ebe24eef7940b550f653141f6f66da27a629e47..9119b04992aabb62f5c96121686c6576da61d212 100644 (file)
@@ -653,7 +653,7 @@ struct thread_master *frr_init(void)
        lib_error_init();
 
        yang_init();
-       nb_init(di->yang_modules, di->n_yang_modules);
+       nb_init(master, di->yang_modules, di->n_yang_modules);
 
        return master;
 }
index 7d5671290bc75c28e056d4bde0bacb5eea476c9e..6754b945796ac174041190eec6fd9383a422448e 100644 (file)
@@ -1,23 +1,17 @@
 /*
  * Copyright (c) 2015-16  David Lamparter, for NetDEF, Inc.
  *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include "config.h"
index e66e5cd650fc29215d672cfe90a5e68c143a687b..68ed959270c9122c4bb755b659d135155e0aaeed 100644 (file)
@@ -1,23 +1,17 @@
 /*
  * Copyright (c) 2015-16  David Lamparter, for NetDEF, Inc.
  *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #ifndef _FRR_MODULE_H
index 490b3abe576ea00467914d667c9944c49675d8c5..a7f9c8620ef9e57c5fa1331bca35471e2023bc0a 100644 (file)
@@ -95,6 +95,13 @@ static int nb_node_new_cb(const struct lys_node *snode, void *arg)
                if (config_only)
                        SET_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY);
        }
+       if (CHECK_FLAG(snode->nodetype, LYS_LIST)) {
+               struct lys_node_list *slist;
+
+               slist = (struct lys_node_list *)snode;
+               if (slist->keys_size == 0)
+                       SET_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST);
+       }
 
        /*
         * Link the northbound node and the libyang schema node with one
@@ -712,6 +719,7 @@ static int nb_configuration_callback(const enum nb_event event,
        const struct lyd_node *dnode = change->cb.dnode;
        union nb_resource *resource;
        int ret = NB_ERR;
+       enum lib_log_refs ref;
 
        if (debug_northbound) {
                const char *value = "(none)";
@@ -744,12 +752,36 @@ static int nb_configuration_callback(const enum nb_event event,
                break;
        }
 
-       if (ret != NB_OK)
-               flog_warn(
-                       EC_LIB_NB_CB_CONFIG,
-                       "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]",
-                       __func__, nb_err_name(ret), nb_event_name(event),
-                       nb_operation_name(operation), xpath);
+       if (ret != NB_OK) {
+               switch (event) {
+               case NB_EV_VALIDATE:
+                       ref = EC_LIB_NB_CB_CONFIG_VALIDATE;
+                       break;
+               case NB_EV_PREPARE:
+                       ref = EC_LIB_NB_CB_CONFIG_PREPARE;
+                       break;
+               case NB_EV_ABORT:
+                       ref = EC_LIB_NB_CB_CONFIG_ABORT;
+                       break;
+               case NB_EV_APPLY:
+                       ref = EC_LIB_NB_CB_CONFIG_APPLY;
+                       break;
+               }
+               if (event == NB_EV_VALIDATE || event == NB_EV_PREPARE)
+                       flog_warn(
+                               ref,
+                               "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]",
+                               __func__, nb_err_name(ret),
+                               nb_event_name(event),
+                               nb_operation_name(operation), xpath);
+               else
+                       flog_err(
+                               ref,
+                               "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]",
+                               __func__, nb_err_name(ret),
+                               nb_event_name(event),
+                               nb_operation_name(operation), xpath);
+       }
 
        return ret;
 }
@@ -1056,6 +1088,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
 {
        struct lys_node_list *slist = (struct lys_node_list *)nb_node->snode;
        const void *list_entry = NULL;
+       uint32_t position = 1;
 
        if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY))
                return NB_OK;
@@ -1063,7 +1096,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
        /* Iterate over all list entries. */
        do {
                struct yang_list_keys list_keys;
-               char xpath[XPATH_MAXLEN];
+               char xpath[XPATH_MAXLEN * 2];
                int ret;
 
                /* Obtain list entry. */
@@ -1073,19 +1106,31 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
                        /* End of the list. */
                        break;
 
-               /* Obtain the list entry keys. */
-               if (nb_node->cbs.get_keys(list_entry, &list_keys) != NB_OK) {
-                       flog_warn(EC_LIB_NB_CB_STATE,
-                                 "%s: failed to get list keys", __func__);
-                       return NB_ERR;
-               }
-
-               /* Build XPath of the list entry. */
-               strlcpy(xpath, xpath_list, sizeof(xpath));
-               for (unsigned int i = 0; i < list_keys.num; i++) {
-                       snprintf(xpath + strlen(xpath),
-                                sizeof(xpath) - strlen(xpath), "[%s='%s']",
-                                slist->keys[i]->name, list_keys.key[i]);
+               if (!CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST)) {
+                       /* Obtain the list entry keys. */
+                       if (nb_node->cbs.get_keys(list_entry, &list_keys)
+                           != NB_OK) {
+                               flog_warn(EC_LIB_NB_CB_STATE,
+                                         "%s: failed to get list keys",
+                                         __func__);
+                               return NB_ERR;
+                       }
+
+                       /* Build XPath of the list entry. */
+                       strlcpy(xpath, xpath_list, sizeof(xpath));
+                       for (unsigned int i = 0; i < list_keys.num; i++) {
+                               snprintf(xpath + strlen(xpath),
+                                        sizeof(xpath) - strlen(xpath),
+                                        "[%s='%s']", slist->keys[i]->name,
+                                        list_keys.key[i]);
+                       }
+               } else {
+                       /*
+                        * Keyless list - build XPath using a positional index.
+                        */
+                       snprintf(xpath, sizeof(xpath), "%s[%u]", xpath_list,
+                                position);
+                       position++;
                }
 
                /* Iterate over the child nodes. */
@@ -1400,6 +1445,8 @@ bool nb_operation_is_valid(enum nb_operation operation,
                case LYS_LIST:
                        if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY))
                                return false;
+                       if (CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST))
+                               return false;
                        break;
                default:
                        return false;
@@ -1539,7 +1586,8 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module)
        }
 }
 
-void nb_init(const struct frr_yang_module_info *modules[], size_t nmodules)
+void nb_init(struct thread_master *tm,
+            const struct frr_yang_module_info *modules[], size_t nmodules)
 {
        unsigned int errors = 0;
 
@@ -1574,7 +1622,7 @@ void nb_init(const struct frr_yang_module_info *modules[], size_t nmodules)
        running_config = nb_config_new(NULL);
 
        /* Initialize the northbound CLI. */
-       nb_cli_init();
+       nb_cli_init(tm);
 }
 
 void nb_terminate(void)
index e26a2f861723e1a3b6d9899d508678012136866f..9d35a4e64a09daf0739ab1a034859353f086c60c 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef _FRR_NORTHBOUND_H_
 #define _FRR_NORTHBOUND_H_
 
+#include "thread.h"
 #include "hook.h"
 #include "linklist.h"
 #include "openbsd-tree.h"
@@ -253,7 +254,8 @@ struct nb_callbacks {
         * Operational data callback for YANG lists.
         *
         * The callback function should fill the 'keys' parameter based on the
-        * given list_entry.
+        * given list_entry. Keyless lists don't need to implement this
+        * callback.
         *
         * list_entry
         *    Pointer to list entry.
@@ -271,7 +273,8 @@ struct nb_callbacks {
         * Operational data callback for YANG lists.
         *
         * The callback function should return a list entry based on the list
-        * keys given as a parameter.
+        * keys given as a parameter. Keyless lists don't need to implement this
+        * callback.
         *
         * parent_list_entry
         *    Pointer to parent list entry.
@@ -366,6 +369,8 @@ struct nb_node {
 };
 /* The YANG container or list contains only config data. */
 #define F_NB_NODE_CONFIG_ONLY 0x01
+/* The YANG list doesn't contain key leafs. */
+#define F_NB_NODE_KEYLESS_LIST 0x02
 
 struct frr_yang_module_info {
        /* YANG module name. */
@@ -825,7 +830,7 @@ extern const char *nb_client_name(enum nb_client client);
  * nmodules
  *    Size of the modules array.
  */
-extern void nb_init(const struct frr_yang_module_info *modules[],
+extern void nb_init(struct thread_master *tm, const struct frr_yang_module_info *modules[],
                    size_t nmodules);
 
 /*
index 2cacc6b1dc79178d82fba3b883c6ad09d2658820..acde0ead025ac47d62750a6baff0480a06995cd0 100644 (file)
@@ -36,6 +36,7 @@
 
 int debug_northbound;
 struct nb_config *vty_shared_candidate_config;
+static struct thread_master *master;
 
 static void vty_show_libyang_errors(struct vty *vty, struct ly_ctx *ly_ctx)
 {
@@ -70,7 +71,7 @@ void nb_cli_enqueue_change(struct vty *vty, const char *xpath,
        }
 
        change = &vty->cfg_changes[vty->num_cfg_changes++];
-       change->xpath = xpath;
+       strlcpy(change->xpath, xpath, sizeof(change->xpath));
        change->operation = operation;
        change->value = value;
 }
@@ -213,16 +214,80 @@ int nb_cli_rpc(const char *xpath, struct list *input, struct list *output)
        }
 }
 
-static int nb_cli_commit(struct vty *vty, bool force, char *comment)
+void nb_cli_confirmed_commit_clean(struct vty *vty)
+{
+       THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout);
+       nb_config_free(vty->confirmed_commit_rollback);
+       vty->confirmed_commit_rollback = NULL;
+}
+
+int nb_cli_confirmed_commit_rollback(struct vty *vty)
+{
+       uint32_t transaction_id;
+       int ret;
+
+       /* Perform the rollback. */
+       ret = nb_candidate_commit(
+               vty->confirmed_commit_rollback, NB_CLIENT_CLI, true,
+               "Rollback to previous configuration - confirmed commit has timed out",
+               &transaction_id);
+       if (ret == NB_OK)
+               vty_out(vty,
+                       "Rollback performed successfully (Transaction ID #%u).\n",
+                       transaction_id);
+       else
+               vty_out(vty, "Failed to rollback to previous configuration.\n");
+
+       return ret;
+}
+
+static int nb_cli_confirmed_commit_timeout(struct thread *thread)
+{
+       struct vty *vty = THREAD_ARG(thread);
+
+       /* XXX: broadcast this message to all logged-in users? */
+       vty_out(vty,
+               "\nConfirmed commit has timed out, rolling back to previous configuration.\n\n");
+
+       nb_cli_confirmed_commit_rollback(vty);
+       nb_cli_confirmed_commit_clean(vty);
+
+       return 0;
+}
+
+static int nb_cli_commit(struct vty *vty, bool force,
+                        unsigned int confirmed_timeout, char *comment)
 {
        uint32_t transaction_id;
        int ret;
 
+       /* Check if there's a pending confirmed commit. */
+       if (vty->t_confirmed_commit_timeout) {
+               if (confirmed_timeout) {
+                       /* Reset timeout if "commit confirmed" is used again. */
+                       vty_out(vty,
+                               "%% Resetting confirmed-commit timeout to %u minute(s)\n\n",
+                               confirmed_timeout);
+
+                       THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout);
+                       thread_add_timer(master,
+                                        nb_cli_confirmed_commit_timeout, vty,
+                                        confirmed_timeout * 60,
+                                        &vty->t_confirmed_commit_timeout);
+               } else {
+                       /* Accept commit confirmation. */
+                       vty_out(vty, "%% Commit complete.\n\n");
+                       nb_cli_confirmed_commit_clean(vty);
+               }
+               return CMD_SUCCESS;
+       }
+
        if (vty_exclusive_lock != NULL && vty_exclusive_lock != vty) {
                vty_out(vty, "%% Configuration is locked by another VTY.\n\n");
                return CMD_WARNING;
        }
 
+       /* "force" parameter. */
        if (!force && nb_candidate_needs_update(vty->candidate_config)) {
                vty_out(vty,
                        "%% Candidate configuration needs to be updated before commit.\n\n");
@@ -231,6 +296,16 @@ static int nb_cli_commit(struct vty *vty, bool force, char *comment)
                return CMD_WARNING;
        }
 
+       /* "confirm" parameter. */
+       if (confirmed_timeout) {
+               vty->confirmed_commit_rollback = nb_config_dup(running_config);
+
+               vty->t_confirmed_commit_timeout = NULL;
+               thread_add_timer(master, nb_cli_confirmed_commit_timeout, vty,
+                                confirmed_timeout * 60,
+                                &vty->t_confirmed_commit_timeout);
+       }
+
        ret = nb_candidate_commit(vty->candidate_config, NB_CLIENT_CLI, true,
                                  comment, &transaction_id);
 
@@ -534,18 +609,22 @@ DEFUN (config_private,
 
 DEFPY (config_commit,
        config_commit_cmd,
-       "commit [force$force]",
+       "commit [{force$force|confirmed (1-60)}]",
        "Commit changes into the running configuration\n"
-       "Force commit even if the candidate is outdated\n")
+       "Force commit even if the candidate is outdated\n"
+       "Rollback this commit unless there is a confirming commit\n"
+       "Timeout in minutes for the commit to be confirmed\n")
 {
-       return nb_cli_commit(vty, !!force, NULL);
+       return nb_cli_commit(vty, !!force, confirmed, NULL);
 }
 
 DEFPY (config_commit_comment,
        config_commit_comment_cmd,
-       "commit [force$force] comment LINE...",
+       "commit [{force$force|confirmed (1-60)}] comment LINE...",
        "Commit changes into the running configuration\n"
        "Force commit even if the candidate is outdated\n"
+       "Rollback this commit unless there is a confirming commit\n"
+       "Timeout in minutes for the commit to be confirmed\n"
        "Assign a comment to this commit\n"
        "Comment for this commit (Max 80 characters)\n")
 {
@@ -555,7 +634,7 @@ DEFPY (config_commit_comment,
 
        argv_find(argv, argc, "LINE", &idx);
        comment = argv_concat(argv, argc, idx);
-       ret = nb_cli_commit(vty, !!force, comment);
+       ret = nb_cli_commit(vty, !!force, confirmed, comment);
        XFREE(MTYPE_TMP, comment);
 
        return ret;
@@ -754,6 +833,30 @@ DEFPY (show_config_candidate,
        return CMD_SUCCESS;
 }
 
+DEFPY (show_config_candidate_section,
+       show_config_candidate_section_cmd,
+       "show",
+       SHOW_STR)
+{
+       struct lyd_node *dnode;
+
+       /* Top-level configuration node, display everything. */
+       if (vty->xpath_index == 0)
+               return nb_cli_show_config(vty, vty->candidate_config,
+                                         NB_CFG_FMT_CMDS, NULL, false);
+
+       /* Display only the current section of the candidate configuration. */
+       dnode = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+       if (!dnode)
+               /* Shouldn't happen. */
+               return CMD_WARNING;
+
+       nb_cli_show_dnode_cmds(vty, dnode, 0);
+       vty_out(vty, "!\n");
+
+       return CMD_SUCCESS;
+}
+
 DEFPY (show_config_compare,
        show_config_compare_cmd,
        "show configuration compare\
@@ -1468,6 +1571,8 @@ static struct cmd_node nb_debug_node = {NORTHBOUND_DEBUG_NODE, "", 1};
 
 void nb_cli_install_default(int node)
 {
+       install_element(node, &show_config_candidate_section_cmd);
+
        if (frr_get_cli_mode() != FRR_CLI_TRANSACTIONAL)
                return;
 
@@ -1517,8 +1622,10 @@ static const struct cmd_variable_handler yang_var_handlers[] = {
         .completions = yang_translator_autocomplete},
        {.completions = NULL}};
 
-void nb_cli_init(void)
+void nb_cli_init(struct thread_master *tm)
 {
+       master = tm;
+
        /* Initialize the shared candidate configuration. */
        vty_shared_candidate_config = nb_config_new(NULL);
 
index febcbd86f17baa40a9e711910b99764ffa0a46c3..362a4bc32528c262d01aaaa8c0a60b74c9cc11b4 100644 (file)
@@ -105,8 +105,10 @@ extern void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *dnode,
                                   bool show_defaults);
 
 /* Prototypes of internal functions. */
+extern void nb_cli_confirmed_commit_clean(struct vty *vty);
+extern int nb_cli_confirmed_commit_rollback(struct vty *vty);
 extern void nb_cli_install_default(int node);
-extern void nb_cli_init(void);
+extern void nb_cli_init(struct thread_master *tm);
 extern void nb_cli_terminate(void);
 
 #endif /* _FRR_NORTHBOUND_CLI_H_ */
index 3579d1da00151c02bdaa8171d8e6eaf18f9076cb..53149d0fd22b956d4341e78919e0d45bb7c86eb9 100644 (file)
@@ -41,6 +41,7 @@ static struct confd_daemon_ctx *dctx;
 static struct confd_notification_ctx *live_ctx;
 static bool confd_connected;
 static struct list *confd_spoints;
+static struct nb_transaction *transaction;
 
 static void frr_confd_finish_cdb(void);
 static void frr_confd_finish_dp(void);
@@ -137,10 +138,19 @@ static int frr_confd_hkeypath_get_list_entry(const confd_hkeypath_t *kp,
                        nb_node_list = nb_node_list->parent_list;
 
                /* Obtain list entry. */
-               *list_entry =
-                       nb_node_list->cbs.lookup_entry(*list_entry, &keys);
-               if (*list_entry == NULL)
-                       return -1;
+               if (!CHECK_FLAG(nb_node_list->flags, F_NB_NODE_KEYLESS_LIST)) {
+                       *list_entry = nb_node_list->cbs.lookup_entry(
+                               *list_entry, &keys);
+                       if (*list_entry == NULL)
+                               return -1;
+               } else {
+                       unsigned long ptr_ulong;
+
+                       /* Retrieve list entry from pseudo-key (string). */
+                       if (sscanf(keys.key[0], "%lu", &ptr_ulong) != 1)
+                               return -1;
+                       *list_entry = (const void *)ptr_ulong;
+               }
 
                curr_list++;
        }
@@ -270,41 +280,12 @@ frr_confd_cdb_diff_iter(confd_hkeypath_t *kp, enum cdb_iter_op cdb_op,
        return ITER_RECURSE;
 }
 
-static int frr_confd_cdb_read_cb(struct thread *thread)
+static int frr_confd_cdb_read_cb_prepare(int fd, int *subp, int reslen)
 {
-       int fd = THREAD_FD(thread);
-       int *subp = NULL;
-       enum cdb_sub_notification cdb_ev;
-       int flags;
-       int reslen = 0;
        struct nb_config *candidate;
        struct cdb_iter_args iter_args;
        int ret;
 
-       thread = NULL;
-       thread_add_read(master, frr_confd_cdb_read_cb, NULL, fd, &thread);
-
-       if (cdb_read_subscription_socket2(fd, &cdb_ev, &flags, &subp, &reslen)
-           != CONFD_OK) {
-               flog_err_confd("cdb_read_subscription_socket2");
-               return -1;
-       }
-
-       /*
-        * Ignore CDB_SUB_ABORT and CDB_SUB_COMMIT. We'll leverage the
-        * northbound layer itself to abort or apply the configuration changes
-        * when a transaction is created.
-        */
-       if (cdb_ev != CDB_SUB_PREPARE) {
-               free(subp);
-               if (cdb_sync_subscription_socket(fd, CDB_DONE_PRIORITY)
-                   != CONFD_OK) {
-                       flog_err_confd("cdb_sync_subscription_socket");
-                       return -1;
-               }
-               return 0;
-       }
-
        candidate = nb_config_dup(running_config);
 
        /* Iterate over all configuration changes. */
@@ -332,8 +313,13 @@ static int frr_confd_cdb_read_cb(struct thread *thread)
                return 0;
        }
 
-       ret = nb_candidate_commit(candidate, NB_CLIENT_CONFD, true, NULL, NULL);
-       nb_config_free(candidate);
+       /*
+        * Validate the configuration changes and allocate all resources
+        * required to apply them.
+        */
+       transaction = NULL;
+       ret = nb_candidate_commit_prepare(candidate, NB_CLIENT_CONFD, NULL,
+                                         &transaction);
        if (ret != NB_OK && ret != NB_ERR_NO_CHANGES) {
                enum confd_errcode errcode;
                const char *errmsg;
@@ -353,6 +339,7 @@ static int frr_confd_cdb_read_cb(struct thread *thread)
                        break;
                }
 
+               /* Reject the configuration changes. */
                if (cdb_sub_abort_trans(cdb_sub_sock, errcode, 0, 0, "%s",
                                        errmsg)
                    != CONFD_OK) {
@@ -360,16 +347,101 @@ static int frr_confd_cdb_read_cb(struct thread *thread)
                        return -1;
                }
        } else {
+               /* Acknowledge the notification. */
                if (cdb_sync_subscription_socket(fd, CDB_DONE_PRIORITY)
                    != CONFD_OK) {
                        flog_err_confd("cdb_sync_subscription_socket");
                        return -1;
                }
+
+               /* No configuration changes. */
+               if (!transaction)
+                       nb_config_free(candidate);
+       }
+
+       return 0;
+}
+
+static int frr_confd_cdb_read_cb_commit(int fd, int *subp, int reslen)
+{
+       /*
+        * No need to process the configuration changes again as we're already
+        * keeping track of them in the "transaction" variable.
+        */
+       free(subp);
+
+       /* Apply the transaction. */
+       if (transaction) {
+               struct nb_config *candidate = transaction->config;
+
+               nb_candidate_commit_apply(transaction, true, NULL);
+               nb_config_free(candidate);
+       }
+
+       /* Acknowledge the notification. */
+       if (cdb_sync_subscription_socket(fd, CDB_DONE_PRIORITY) != CONFD_OK) {
+               flog_err_confd("cdb_sync_subscription_socket");
+               return -1;
        }
 
        return 0;
 }
 
+static int frr_confd_cdb_read_cb_abort(int fd, int *subp, int reslen)
+{
+       /*
+        * No need to process the configuration changes again as we're already
+        * keeping track of them in the "transaction" variable.
+        */
+       free(subp);
+
+       /* Abort the transaction. */
+       if (transaction) {
+               struct nb_config *candidate = transaction->config;
+
+               nb_candidate_commit_abort(transaction);
+               nb_config_free(candidate);
+       }
+
+       /* Acknowledge the notification. */
+       if (cdb_sync_subscription_socket(fd, CDB_DONE_PRIORITY) != CONFD_OK) {
+               flog_err_confd("cdb_sync_subscription_socket");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int frr_confd_cdb_read_cb(struct thread *thread)
+{
+       int fd = THREAD_FD(thread);
+       enum cdb_sub_notification cdb_ev;
+       int flags;
+       int *subp = NULL;
+       int reslen = 0;
+
+       thread = NULL;
+       thread_add_read(master, frr_confd_cdb_read_cb, NULL, fd, &thread);
+
+       if (cdb_read_subscription_socket2(fd, &cdb_ev, &flags, &subp, &reslen)
+           != CONFD_OK) {
+               flog_err_confd("cdb_read_subscription_socket2");
+               return -1;
+       }
+
+       switch (cdb_ev) {
+       case CDB_SUB_PREPARE:
+               return frr_confd_cdb_read_cb_prepare(fd, subp, reslen);
+       case CDB_SUB_COMMIT:
+               return frr_confd_cdb_read_cb_commit(fd, subp, reslen);
+       case CDB_SUB_ABORT:
+               return frr_confd_cdb_read_cb_abort(fd, subp, reslen);
+       default:
+               flog_err_confd("unknown CDB event");
+               return -1;
+       }
+}
+
 /* Trigger CDB subscriptions to read the startup configuration. */
 static void *thread_cdb_trigger_subscriptions(void *data)
 {
@@ -577,7 +649,6 @@ static int frr_confd_data_get_next(struct confd_trans_ctx *tctx,
 {
        struct nb_node *nb_node;
        char xpath[BUFSIZ];
-       struct yang_list_keys keys;
        struct yang_data *data;
        const void *parent_list_entry, *nb_next;
        confd_value_t v[LIST_MAXKEYS];
@@ -609,18 +680,53 @@ static int frr_confd_data_get_next(struct confd_trans_ctx *tctx,
 
        switch (nb_node->snode->nodetype) {
        case LYS_LIST:
-               memset(&keys, 0, sizeof(keys));
-               if (nb_node->cbs.get_keys(nb_next, &keys) != NB_OK) {
-                       flog_warn(EC_LIB_NB_CB_STATE,
-                                 "%s: failed to get list keys", __func__);
-                       confd_data_reply_next_key(tctx, NULL, -1, -1);
-                       return CONFD_OK;
-               }
+               if (!CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST)) {
+                       struct yang_list_keys keys;
+
+                       memset(&keys, 0, sizeof(keys));
+                       if (nb_node->cbs.get_keys(nb_next, &keys) != NB_OK) {
+                               flog_warn(EC_LIB_NB_CB_STATE,
+                                         "%s: failed to get list keys",
+                                         __func__);
+                               confd_data_reply_next_key(tctx, NULL, -1, -1);
+                               return CONFD_OK;
+                       }
 
-               /* Feed keys to ConfD. */
-               for (size_t i = 0; i < keys.num; i++)
-                       CONFD_SET_STR(&v[i], keys.key[i]);
-               confd_data_reply_next_key(tctx, v, keys.num, (long)nb_next);
+                       /* Feed keys to ConfD. */
+                       for (size_t i = 0; i < keys.num; i++)
+                               CONFD_SET_STR(&v[i], keys.key[i]);
+                       confd_data_reply_next_key(tctx, v, keys.num,
+                                                 (long)nb_next);
+               } else {
+                       char pointer_str[16];
+
+                       /*
+                        * ConfD 6.6 user guide, chapter 6.11 (Operational data
+                        * lists without keys):
+                        * "To support this without having completely separate
+                        * APIs, we use a "pseudo" key in the ConfD APIs for
+                        * this type of list. This key is not part of the data
+                        * model, and completely hidden in the northbound agent
+                        * interfaces, but is used with e.g. the get_next() and
+                        * get_elem() callbacks as if it were a normal key. This
+                        * "pseudo" key is always a single signed 64-bit
+                        * integer, i.e. the confd_value_t type is C_INT64. The
+                        * values can be chosen arbitrarily by the application,
+                        * as long as a key value returned by get_next() can be
+                        * used to get the data for the corresponding list entry
+                        * with get_elem() or get_object() as usual. It could
+                        * e.g. be an index into an array that holds the data,
+                        * or even a memory address in integer form".
+                        *
+                        * Since we're using the CONFD_DAEMON_FLAG_STRINGSONLY
+                        * option, we must convert our pseudo-key (a void
+                        * pointer) to a string before sending it to confd.
+                        */
+                       snprintf(pointer_str, sizeof(pointer_str), "%lu",
+                                (unsigned long)nb_next);
+                       CONFD_SET_STR(&v[0], pointer_str);
+                       confd_data_reply_next_key(tctx, v, 1, (long)nb_next);
+               }
                break;
        case LYS_LEAFLIST:
                data = nb_node->cbs.get_elem(xpath, nb_next);
@@ -729,6 +835,7 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
        const void *nb_next;
 #define CONFD_OBJECTS_PER_TIME 100
        struct confd_next_object objects[CONFD_OBJECTS_PER_TIME + 1];
+       char pseudo_keys[CONFD_OBJECTS_PER_TIME][16];
        int nobjects = 0;
 
        frr_confd_get_xpath(kp, xpath, sizeof(xpath));
@@ -781,6 +888,26 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
                        XMALLOC(MTYPE_CONFD,
                                CONFD_MAX_CHILD_NODES * sizeof(confd_value_t));
 
+               /*
+                * ConfD 6.6 user guide, chapter 6.11 (Operational data lists
+                * without keys):
+                * "In the response to the get_next_object() callback, the data
+                * provider is expected to provide the key values along with the
+                * other leafs in an array that is populated according to the
+                * data model. This must be done also for this type of list,
+                * even though the key isn't actually in the data model. The
+                * "pseudo" key must always be the first element in the array".
+                */
+               if (CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST)) {
+                       confd_value_t *v;
+
+                       snprintf(pseudo_keys[j], sizeof(pseudo_keys[j]), "%lu",
+                                (unsigned long)nb_next);
+
+                       v = &object->v[nvalues++];
+                       CONFD_SET_STR(v, pseudo_keys[j]);
+               }
+
                /* Loop through list child nodes. */
                LY_TREE_FOR (nb_node->snode->child, child) {
                        struct nb_node *nb_node_child = child->priv;
index ffda4c65d0420b7eb4b5c099455e64fa2b076e03..860c27edbd023c5809f60d0889096c6131a6c3ca 100644 (file)
@@ -37,6 +37,7 @@ static struct thread_master *master;
 static struct list *sysrepo_threads;
 static sr_session_ctx_t *session;
 static sr_conn_ctx_t *connection;
+static struct nb_transaction *transaction;
 
 static int frr_sr_read_cb(struct thread *thread);
 static int frr_sr_write_cb(struct thread *thread);
@@ -232,10 +233,9 @@ static int frr_sr_process_change(struct nb_config *candidate,
        return NB_OK;
 }
 
-/* Callback for changes in the running configuration. */
-static int frr_sr_config_change_cb(sr_session_ctx_t *session,
-                                  const char *module_name,
-                                  sr_notif_event_t sr_ev, void *private_ctx)
+static int frr_sr_config_change_cb_verify(sr_session_ctx_t *session,
+                                         const char *module_name,
+                                         bool startup_config)
 {
        sr_change_iter_t *it;
        int ret;
@@ -244,14 +244,6 @@ static int frr_sr_config_change_cb(sr_session_ctx_t *session,
        char xpath[XPATH_MAXLEN];
        struct nb_config *candidate;
 
-       /*
-        * Ignore SR_EV_ABORT and SR_EV_APPLY. We'll leverage the northbound
-        * layer itself to abort or apply the configuration changes when a
-        * transaction is created.
-        */
-       if (sr_ev != SR_EV_ENABLED && sr_ev != SR_EV_VERIFY)
-               return SR_ERR_OK;
-
        snprintf(xpath, sizeof(xpath), "/%s:*", module_name);
        ret = sr_get_changes_iter(session, xpath, &it);
        if (ret != SR_ERR_OK) {
@@ -280,15 +272,30 @@ static int frr_sr_config_change_cb(sr_session_ctx_t *session,
                return SR_ERR_INTERNAL;
        }
 
-       /* Commit changes. */
-       ret = nb_candidate_commit(candidate, NB_CLIENT_SYSREPO, true, NULL,
-                                 NULL);
-       nb_config_free(candidate);
+       transaction = NULL;
+       if (startup_config) {
+               /*
+                * sysrepod sends the entire startup configuration using a
+                * single event (SR_EV_ENABLED). This means we need to perform
+                * the full two-phase commit protocol in one go here.
+                */
+               ret = nb_candidate_commit(candidate, NB_CLIENT_SYSREPO, true,
+                                         NULL, NULL);
+       } else {
+               /*
+                * Validate the configuration changes and allocate all resources
+                * required to apply them.
+                */
+               ret = nb_candidate_commit_prepare(candidate, NB_CLIENT_SYSREPO,
+                                                 NULL, &transaction);
+       }
 
        /* Map northbound return code to sysrepo return code. */
        switch (ret) {
        case NB_OK:
+               return SR_ERR_OK;
        case NB_ERR_NO_CHANGES:
+               nb_config_free(candidate);
                return SR_ERR_OK;
        case NB_ERR_LOCKED:
                return SR_ERR_LOCKED;
@@ -299,6 +306,57 @@ static int frr_sr_config_change_cb(sr_session_ctx_t *session,
        }
 }
 
+static int frr_sr_config_change_cb_apply(sr_session_ctx_t *session,
+                                        const char *module_name)
+{
+       /* Apply the transaction. */
+       if (transaction) {
+               struct nb_config *candidate = transaction->config;
+
+               nb_candidate_commit_apply(transaction, true, NULL);
+               nb_config_free(candidate);
+       }
+
+       return SR_ERR_OK;
+}
+
+static int frr_sr_config_change_cb_abort(sr_session_ctx_t *session,
+                                        const char *module_name)
+{
+       /* Abort the transaction. */
+       if (transaction) {
+               struct nb_config *candidate = transaction->config;
+
+               nb_candidate_commit_abort(transaction);
+               nb_config_free(candidate);
+       }
+
+       return SR_ERR_OK;
+}
+
+/* Callback for changes in the running configuration. */
+static int frr_sr_config_change_cb(sr_session_ctx_t *session,
+                                  const char *module_name,
+                                  sr_notif_event_t sr_ev, void *private_ctx)
+{
+       switch (sr_ev) {
+       case SR_EV_ENABLED:
+               return frr_sr_config_change_cb_verify(session, module_name,
+                                                     true);
+       case SR_EV_VERIFY:
+               return frr_sr_config_change_cb_verify(session, module_name,
+                                                     false);
+       case SR_EV_APPLY:
+               return frr_sr_config_change_cb_apply(session, module_name);
+       case SR_EV_ABORT:
+               return frr_sr_config_change_cb_abort(session, module_name);
+       default:
+               flog_err(EC_LIB_LIBSYSREPO, "%s: unknown sysrepo event: %u",
+                        __func__, sr_ev);
+               return SR_ERR_INTERNAL;
+       }
+}
+
 static int frr_sr_state_data_iter_cb(const struct lys_node *snode,
                                     struct yang_translator *translator,
                                     struct yang_data *data, void *arg)
index 9908ada7f04607eab8cf576f64222fafcda976e1..085cbac742a004082a1594870d828994c671e815 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -2714,6 +2714,14 @@ int vty_config_enter(struct vty *vty, bool private_config, bool exclusive)
 
 void vty_config_exit(struct vty *vty)
 {
+       /* Check if there's a pending confirmed commit. */
+       if (vty->t_confirmed_commit_timeout) {
+               vty_out(vty,
+                       "WARNING: exiting with a pending confirmed commit. Rolling back to previous configuration.\n\n");
+               nb_cli_confirmed_commit_rollback(vty);
+               nb_cli_confirmed_commit_clean(vty);
+       }
+
        vty_config_exclusive_unlock(vty);
 
        if (vty->candidate_config) {
index ae6c4bae965390db8fd20af8287c32648fcc6cc4..79b1bd5e9311aee3d44d0e3947d6f1e294e287f5 100644 (file)
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -43,7 +43,7 @@ struct vty_error {
 };
 
 struct vty_cfg_change {
-       const char *xpath;
+       char xpath[XPATH_MAXLEN];
        enum nb_operation operation;
        const char *value;
 };
@@ -126,6 +126,10 @@ struct vty {
        /* Base candidate configuration. */
        struct nb_config *candidate_config_base;
 
+       /* Confirmed-commit timeout and rollback configuration. */
+       struct thread *t_confirmed_commit_timeout;
+       struct nb_config *confirmed_commit_rollback;
+
        /* qobj object ID (replacement for "index") */
        uint64_t qobj_index;
 
index c927d5d714118c4745a99cb6358e518f8ae6ba88..24ef24c7744930fb8978ad40d41112c4a0fad91c 100644 (file)
@@ -91,9 +91,10 @@ struct work_queue *work_queue_new(struct thread_master *m,
 
        new->cycles.granularity = WORK_QUEUE_MIN_GRANULARITY;
 
-       /* Default values, can be overriden by caller */
+       /* Default values, can be overridden by caller */
        new->spec.hold = WORK_QUEUE_DEFAULT_HOLD;
        new->spec.yield = THREAD_YIELD_TIME_SLOT;
+       new->spec.retry = WORK_QUEUE_DEFAULT_RETRY;
 
        return new;
 }
@@ -133,8 +134,17 @@ static int work_queue_schedule(struct work_queue *wq, unsigned int delay)
        if (CHECK_FLAG(wq->flags, WQ_UNPLUGGED) && (wq->thread == NULL)
            && !work_queue_empty(wq)) {
                wq->thread = NULL;
-               thread_add_timer_msec(wq->master, work_queue_run, wq, delay,
-                                     &wq->thread);
+
+               /* Schedule timer if there's a delay, otherwise just schedule
+                * as an 'event'
+                */
+               if (delay > 0)
+                       thread_add_timer_msec(wq->master, work_queue_run, wq,
+                                             delay, &wq->thread);
+               else
+                       thread_add_event(wq->master, work_queue_run, wq, 0,
+                                        &wq->thread);
+
                /* set thread yield time, if needed */
                if (wq->thread && wq->spec.yield != THREAD_YIELD_TIME_SLOT)
                        thread_set_yield_time(wq->thread, wq->spec.yield);
@@ -234,7 +244,7 @@ int work_queue_run(struct thread *thread)
 {
        struct work_queue *wq;
        struct work_queue_item *item, *titem;
-       wq_item_status ret;
+       wq_item_status ret = WQ_SUCCESS;
        unsigned int cycles = 0;
        char yielded = 0;
 
@@ -376,9 +386,14 @@ stats:
 #endif
 
        /* Is the queue done yet? If it is, call the completion callback. */
-       if (!work_queue_empty(wq))
-               work_queue_schedule(wq, 0);
-       else if (wq->spec.completion_func)
+       if (!work_queue_empty(wq)) {
+               if (ret == WQ_RETRY_LATER ||
+                   ret == WQ_QUEUE_BLOCKED)
+                       work_queue_schedule(wq, wq->spec.retry);
+               else
+                       work_queue_schedule(wq, 0);
+
+       } else if (wq->spec.completion_func)
                wq->spec.completion_func(wq);
 
        return 0;
index fe1700f8ded5aaf79eff7b3a232d9e51c1cdac29..7c846550631df99d904f79aca57eb094e3007589 100644 (file)
@@ -30,6 +30,9 @@ DECLARE_MTYPE(WORK_QUEUE)
 /* Hold time for the initial schedule of a queue run, in  millisec */
 #define WORK_QUEUE_DEFAULT_HOLD 50
 
+/* Retry for queue that is 'blocked' or 'retry later' */
+#define WORK_QUEUE_DEFAULT_RETRY 0
+
 /* action value, for use by item processor and item error handlers */
 typedef enum {
        WQ_SUCCESS = 0,
@@ -90,6 +93,8 @@ struct work_queue {
 
                unsigned long
                        yield; /* yield time in us for associated thread */
+
+               uint32_t retry; /* Optional retry timeout if queue is blocked */
        } spec;
 
        /* remaining fields should be opaque to users */
index 462e693549ea832b17db3d579a62840aa7558040..71b41c35d8225a660650a573549b1c93617c12a2 100644 (file)
@@ -71,9 +71,11 @@ static const char *yang_module_imp_clb(const char *mod_name,
        return NULL;
 }
 
-static const char * const frr_native_modules[] = {
+static const char *const frr_native_modules[] = {
        "frr-interface",
        "frr-ripd",
+       "frr-ripngd",
+       "frr-isisd",
 };
 
 /* Generate the yang_modules tree. */
index 96076d6468b30a8efc9f6417cf84d73efd1a2d6a..6273dff3ce8e83cf929e77336b71599b0fb11feb 100644 (file)
@@ -171,6 +171,7 @@ int yang_str2enum(const char *xpath, const char *value)
 {
        const struct lys_node *snode;
        const struct lys_node_leaf *sleaf;
+       const struct lys_type *type;
        const struct lys_type_info_enums *enums;
 
        snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
@@ -182,7 +183,12 @@ int yang_str2enum(const char *xpath, const char *value)
        }
 
        sleaf = (const struct lys_node_leaf *)snode;
-       enums = &sleaf->type.info.enums;
+       type = &sleaf->type;
+       enums = &type->info.enums;
+       while (enums->count == 0 && type->der) {
+               type = &type->der->type;
+               enums = &type->info.enums;
+       }
        for (unsigned int i = 0; i < enums->count; i++) {
                const struct lys_type_enum *enm = &enums->enm[i];
 
index 46721cc1ab6d32c7b146f8387efc4fa6cf748a22..0f3f45f7ba1807a8344e47ba95c5f769c2ede43e 100644 (file)
@@ -410,18 +410,47 @@ extern const char *zserv_command_string(unsigned int command);
 #define strmatch(a,b) (!strcmp((a), (b)))
 
 /* Zebra message flags */
+
+/*
+ * Cause Zebra to consider this routes nexthops recursively
+ */
 #define ZEBRA_FLAG_ALLOW_RECURSION    0x01
+/*
+ * This is a route that is read in on startup that was left around
+ * from a previous run of FRR
+ */
 #define ZEBRA_FLAG_SELFROUTE          0x02
-#define ZEBRA_FLAG_IBGP               0x08
-#define ZEBRA_FLAG_SELECTED           0x10
-#define ZEBRA_FLAG_STATIC             0x40
-#define ZEBRA_FLAG_SCOPE_LINK         0x100
-#define ZEBRA_FLAG_FIB_OVERRIDE       0x200
-#define ZEBRA_FLAG_EVPN_ROUTE         0x400
-#define ZEBRA_FLAG_RR_USE_DISTANCE    0x800
-#define ZEBRA_FLAG_ONLINK             0x1000
-/* ZEBRA_FLAG_BLACKHOLE was 0x04 */
-/* ZEBRA_FLAG_REJECT was 0x80 */
+/*
+ * This flag is used to tell Zebra that the BGP route being passed
+ * down is a IBGP route
+ */
+#define ZEBRA_FLAG_IBGP               0x04
+/*
+ * This is a route that has been selected for FIB installation.
+ * This flag is set in zebra and can be passed up to routing daemons
+ */
+#define ZEBRA_FLAG_SELECTED           0x08
+/*
+ * This is a route that we are telling Zebra that this route *must*
+ * win and will be installed even over ZEBRA_FLAG_SELECTED
+ */
+#define ZEBRA_FLAG_FIB_OVERRIDE       0x10
+/*
+ * This flag tells Zebra that the route is a EVPN route and should
+ * be treated specially
+ */
+#define ZEBRA_FLAG_EVPN_ROUTE         0x20
+/*
+ * This flag tells Zebra that it should treat the distance passed
+ * down as an additional discriminator for route selection of the
+ * route entry.  This mainly is used for backup static routes.
+ */
+#define ZEBRA_FLAG_RR_USE_DISTANCE    0x40
+/*
+ * This flag tells Zebra that the passed down route is ONLINK and the
+ * kernel install flag for it should be turned on
+ */
+#define ZEBRA_FLAG_ONLINK             0x80
 
 /* Zebra FEC flags. */
 #define ZEBRA_FEC_REGISTER_LABEL_INDEX        0x1
diff --git a/ospf6d/OSPFv3-MIB.txt b/ospf6d/OSPFv3-MIB.txt
deleted file mode 100644 (file)
index 258f533..0000000
+++ /dev/null
@@ -1,3951 +0,0 @@
- OSPFV3-MIB DEFINITIONS ::= BEGIN
-
- IMPORTS
-         MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, mib-2,
-         Counter32, Gauge32, Integer32, Unsigned32
-                 FROM SNMPv2-SMI
-         TEXTUAL-CONVENTION, TruthValue, RowStatus, TimeStamp
-                 FROM SNMPv2-TC
-         MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
-                 FROM SNMPv2-CONF
-         InterfaceIndex
-                 FROM IF-MIB
-         InetAddressType, InetAddress, InetAddressPrefixLength,
-         InetAddressIPv6
-                 FROM INET-ADDRESS-MIB
-         Metric, BigMetric, Status,
-         HelloRange, DesignatedRouterPriority
-                 FROM OSPF-MIB;
-
- ospfv3MIB MODULE-IDENTITY
-         LAST-UPDATED "200908130000Z"
-         ORGANIZATION "IETF OSPF Working Group"
-         CONTACT-INFO
-             "WG E-Mail: ospf@ietf.org
-              WG Chairs: Acee Lindem
-                         acee@redback.com
-
-                         Abhay Roy
-                         akr@cisco.com
-
-              Editors:   Dan Joyal
-                         Nortel
-                         600 Technology Park Drive
-                         Billerica, MA  01821, USA
-                         djoyal@nortel.com
-
-                         Vishwas Manral
-                         IP Infusion
-                         Almora, Uttarakhand
-                         India
-                         vishwas@ipinfusion.com"
-          DESCRIPTION
-             "The MIB module for OSPF version 3.
-
-              Copyright (c) 2009 IETF Trust and the persons
-              identified as authors of the code.  All rights
-              reserved.
-
-              Redistribution and use in source and binary forms, with
-              or without modification, are permitted provided that
-              the following conditions are met:
-
-              - Redistributions of source code must retain the above
-                copyright notice, this list of conditions and the
-                following disclaimer.
-
-             - Redistributions in binary form must reproduce the
-               above copyright notice, this list of conditions and
-               the following disclaimer in the documentation and/or
-               other materials provided with the distribution.
-
-             - Neither the name of Internet Society, IETF or IETF
-               Trust, nor the names of specific contributors, may be
-               used to endorse or promote products derived from this
-               software without specific prior written permission.
-
-               THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-               CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED
-               WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-               WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-               PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
-               THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
-               DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-               CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-               PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-               USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-               HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-               IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-               NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-               USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-               POSSIBILITY OF SUCH DAMAGE.
-
-               This version of this MIB module is part of RFC 5643;
-               see the RFC itself for full legal notices."
-
-          REVISION "200908130000Z"
-          DESCRIPTION
-              "Initial version, published as RFC 5643"
-          ::= { mib-2 191 }
-
- -- Textual conventions
-
- Ospfv3UpToRefreshIntervalTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS        current
-          DESCRIPTION
-               "The values one might be able to configure for
-               variables bounded by the Refresh Interval."
-          REFERENCE
-               "OSPF Version 2, Appendix B, Architectural Constants"
-          SYNTAX      Unsigned32 (1..1800)
-
- Ospfv3DeadIntervalRangeTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS        current
-          DESCRIPTION
-               "The range, in seconds, of dead interval value."
-          REFERENCE
-               "OSPF for IPv6, Appendix C.3, Router Interface
-               Parameters"
-          SYNTAX      Unsigned32 (1..'FFFF'h)
-
- Ospfv3RouterIdTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS      current
-          DESCRIPTION
-               "A 32-bit, unsigned integer uniquely identifying the
-               router in the Autonomous System.  To ensure
-               uniqueness, this may default to the value of one of
-               the router's IPv4 host addresses if IPv4 is
-               configured on the router."
-          REFERENCE
-               "OSPF for IPv6, Appendix C.1, Global Parameters"
-          SYNTAX      Unsigned32 (1..'FFFFFFFF'h)
-
- Ospfv3LsIdTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS      current
-          DESCRIPTION
-               "A unique 32-bit identifier of the piece of the
-               routing domain that is being described by a link
-               state advertisement.  In contrast to OSPFv2, the
-               Link State ID (LSID) has no addressing semantics."
-          REFERENCE
-               "OSPF Version 2, Section 12.1.4, Link State ID"
-          SYNTAX      Unsigned32 (1..'FFFFFFFF'h)
-
- Ospfv3AreaIdTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS      current
-          DESCRIPTION
-               "An OSPFv3 Area Identifier.  A value of zero
-               identifies the backbone area."
-          REFERENCE
-               "OSPF for IPv6, Appendix C.3 Router Interface
-               Parameters"
-          SYNTAX      Unsigned32 (0..'FFFFFFFF'h)
-
- Ospfv3IfInstIdTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS      current
-          DESCRIPTION
-               "An OSPFv3 Interface Instance ID."
-          REFERENCE
-               "OSPF for IPv6, Appendix C.3, Router Interface
-               Parameters"
-          SYNTAX      Unsigned32 (0..255)
-
- Ospfv3LsaSequenceTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS      current
-          DESCRIPTION
-             "The sequence number field is a signed 32-bit
-             integer.  It is used to detect old and duplicate
-             link state advertisements.  The space of
-             sequence numbers is linearly ordered.  The
-             larger the sequence number, the more recent the
-             advertisement."
-          REFERENCE
-             "OSPF Version 2, Section 12.1.6, LS sequence
-             number"
-          SYNTAX      Integer32
-
- Ospfv3LsaAgeTC ::= TEXTUAL-CONVENTION
-          DISPLAY-HINT "d"
-          STATUS      current
-          DESCRIPTION
-             "The age of the link state advertisement in
-             seconds.  The high-order bit of the LS age
-             field is considered the DoNotAge bit for
-             support of on-demand circuits."
-          REFERENCE
-             "OSPF Version 2, Section 12.1.1, LS age;
-              Extending OSPF to Support Demand Circuits,
-              Section 2.2, The LS age field"
-          SYNTAX      Unsigned32 (0..3600 | 32768..36368)
-
- -- Top-level structure of MIB
- ospfv3Notifications  OBJECT IDENTIFIER ::= { ospfv3MIB 0 }
- ospfv3Objects        OBJECT IDENTIFIER ::= { ospfv3MIB 1 }
- ospfv3Conformance    OBJECT IDENTIFIER ::= { ospfv3MIB 2 }
-
- -- OSPFv3 General Variables
-
- -- These parameters apply globally to the Router's
- -- OSPFv3 Process.
-
- ospfv3GeneralGroup OBJECT IDENTIFIER ::= { ospfv3Objects 1 }
-
- ospfv3RouterId OBJECT-TYPE
-         SYNTAX         Ospfv3RouterIdTC
-         MAX-ACCESS     read-write
-         STATUS         current
-         DESCRIPTION
-             "A 32-bit unsigned integer uniquely identifying
-             the router in the Autonomous System.  To ensure
-             uniqueness, this may default to the 32-bit
-             unsigned integer representation of one of
-             the router's IPv4 interface addresses (if IPv4
-             is configured on the router).
-
-             This object is persistent, and when written, the
-             entity SHOULD save the change to non-volatile
-             storage."
-         REFERENCE
-               "OSPF for IPv6, Appendix C.1, Global Parameters"
-         ::= { ospfv3GeneralGroup 1 }
-
- ospfv3AdminStatus OBJECT-TYPE
-         SYNTAX          Status
-         MAX-ACCESS      read-write
-         STATUS          current
-         DESCRIPTION
-             "The administrative status of OSPFv3 in the
-             router.  The value 'enabled' denotes that the
-             OSPFv3 Process is active on at least one
-             interface; 'disabled' disables it on all
-             interfaces.
-
-             This object is persistent, and when written, the
-             entity SHOULD save the change to non-volatile
-             storage."
-         ::= { ospfv3GeneralGroup 2 }
-
- ospfv3VersionNumber OBJECT-TYPE
-         SYNTAX          INTEGER { version3 (3) }
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The version number of OSPF for IPv6 is 3."
-         ::= { ospfv3GeneralGroup 3 }
-
- ospfv3AreaBdrRtrStatus OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "A flag to denote whether this router is an area
-             border router.  The value of this object is true (1)
-             when the router is an area border router."
-         REFERENCE
-             "OSPF Version 2, Section 3, Splitting the AS into
-             Areas"
-         ::= { ospfv3GeneralGroup 4 }
-
- ospfv3ASBdrRtrStatus OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-write
-         STATUS          current
-         DESCRIPTION
-             "A flag to note whether this router is
-             configured as an Autonomous System border router.
-
-             This object is persistent, and when written, the
-             entity SHOULD save the change to non-volatile
-             storage."
-         REFERENCE
-             "OSPF Version 2, Section 3.3, Classification of
-             routers"
-         ::= { ospfv3GeneralGroup 5 }
-
- ospfv3AsScopeLsaCount OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of AS-scope (e.g., AS-External) link state
-             advertisements in the link state database."
-         ::= { ospfv3GeneralGroup 6 }
-
- ospfv3AsScopeLsaCksumSum OBJECT-TYPE
-         SYNTAX          Unsigned32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit unsigned sum of the LS checksums of
-             the AS-scoped link state advertisements
-             contained in the link state database.  This sum
-             can be used to determine if there has been a
-             change in a router's link state database or
-             to compare the link state database of two
-             routers."
-         ::= { ospfv3GeneralGroup 7 }
-
- ospfv3OriginateNewLsas OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of new link state advertisements
-             that have been originated.  This number is
-             incremented each time the router originates a new
-             LSA.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3GeneralGroup 8 }
-
- ospfv3RxNewLsas OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of link state advertisements
-             received that are determined to be new
-             instantiations.  This number does not include
-             newer instantiations of self-originated link state
-             advertisements.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3GeneralGroup 9 }
-
- ospfv3ExtLsaCount OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-              "The number of External (LS type 0x4005) in the
-              link state database."
-         ::= { ospfv3GeneralGroup 10 }
-
- ospfv3ExtAreaLsdbLimit OBJECT-TYPE
-         SYNTAX          Integer32 (-1..'7FFFFFFF'h)
-         MAX-ACCESS      read-write
-         STATUS          current
-         DESCRIPTION
-             "The maximum number of non-default
-             AS-external-LSA entries that can be stored in the
-             link state database.  If the value is -1, then
-             there is no limit.
-
-             When the number of non-default AS-external-LSAs
-             in a router's link state database reaches
-             ospfv3ExtAreaLsdbLimit, the router enters Overflow
-             state.  The router never holds more than
-             ospfv3ExtAreaLsdbLimit non-default AS-external-LSAs
-             in its database.  ospfv3ExtAreaLsdbLimit MUST be set
-             identically in all routers attached to the OSPFv3
-             backbone and/or any regular OSPFv3 area (i.e.,
-             OSPFv3 stub areas and not-so-stubby-areas (NSSAs)
-             are excluded).
-
-             This object is persistent, and when written, the
-             entity SHOULD save the change to non-volatile
-             storage."
-         ::= { ospfv3GeneralGroup 11 }
-
- ospfv3ExitOverflowInterval OBJECT-TYPE
-         SYNTAX          Unsigned32
-         UNITS           "seconds"
-         MAX-ACCESS      read-write
-         STATUS          current
-         DESCRIPTION
-             "The number of seconds that, after entering
-             Overflow state, a router will attempt to leave
-             Overflow state.  This allows the router to again
-             originate non-default, AS-External-LSAs.  When
-             set to 0, the router will not leave Overflow
-             state until restarted.
-
-             This object is persistent, and when written, the
-             entity SHOULD save the change to non-volatile
-             storage."
-         ::= { ospfv3GeneralGroup 12 }
-
- ospfv3DemandExtensions OBJECT-TYPE
-         SYNTAX         TruthValue
-         MAX-ACCESS     read-write
-         STATUS         current
-         DESCRIPTION
-             "The router's support for demand circuits.
-             The value of this object is true (1) when
-             demand circuits are supported.
-
-             This object is persistent, and when written, the
-             entity SHOULD save the change to non-volatile
-             storage."
-         REFERENCE
-             "OSPF Version 2; Extending OSPF to Support Demand
-             Circuits"
-         ::= { ospfv3GeneralGroup 13 }
-
- ospfv3ReferenceBandwidth OBJECT-TYPE
-        SYNTAX       Unsigned32
-        UNITS        "kilobits per second"
-        MAX-ACCESS   read-write
-        STATUS       current
-        DESCRIPTION
-            "Reference bandwidth in kilobits per second for
-            calculating default interface metrics.  The
-            default value is 100,000 KBPS (100 MBPS).
-
-            This object is persistent, and when written, the
-            entity SHOULD save the change to non-volatile
-            storage."
-        REFERENCE
-            "OSPF Version 2, Appendix C.3, Router interface
-            parameters"
-        DEFVAL { 100000 }
-     ::= { ospfv3GeneralGroup 14 }
-
- ospfv3RestartSupport OBJECT-TYPE
-        SYNTAX       INTEGER { none(1),
-                               plannedOnly(2),
-                               plannedAndUnplanned(3)
-                          }
-        MAX-ACCESS   read-write
-        STATUS       current
-        DESCRIPTION
-            "The router's support for OSPF graceful restart.
-            Options include no restart support, only planned
-
-            restarts, or both planned and unplanned restarts.
-
-            This object is persistent, and when written, the
-            entity SHOULD save the change to non-volatile
-            storage."
-        REFERENCE "Graceful OSPF Restart, Appendix B.1, Global
-                     Parameters (Minimum subset)"
-        ::= { ospfv3GeneralGroup 15 }
-
- ospfv3RestartInterval OBJECT-TYPE
-        SYNTAX       Ospfv3UpToRefreshIntervalTC
-        UNITS        "seconds"
-        MAX-ACCESS   read-write
-        STATUS       current
-        DESCRIPTION
-            "Configured OSPF graceful restart timeout interval.
-
-            This object is persistent, and when written, the
-            entity SHOULD save the change to non-volatile
-            storage."
-        REFERENCE "Graceful OSPF Restart, Appendix B.1, Global
-                  Parameters (Minimum subset)"
-        DEFVAL { 120 }
-        ::= { ospfv3GeneralGroup 16 }
-
- ospfv3RestartStrictLsaChecking OBJECT-TYPE
-       SYNTAX       TruthValue
-       MAX-ACCESS   read-write
-       STATUS       current
-       DESCRIPTION
-          "Indicates if strict LSA checking is enabled for
-          graceful restart.  A value of true (1) indicates that
-          strict LSA checking is enabled.
-
-          This object is persistent, and when written,
-          the entity SHOULD save the change to non-volatile
-          storage."
-       REFERENCE "Graceful OSPF Restart, Appendix B.2, Global
-                 Parameters (Optional)"
-       DEFVAL { true }
-       ::= { ospfv3GeneralGroup 17 }
-
- ospfv3RestartStatus OBJECT-TYPE
-        SYNTAX       INTEGER { notRestarting(1),
-                               plannedRestart(2),
-                               unplannedRestart(3)
-                             }
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-           "The current status of OSPF graceful restart capability."
-        ::= { ospfv3GeneralGroup 18 }
-
- ospfv3RestartAge OBJECT-TYPE
-        SYNTAX       Ospfv3UpToRefreshIntervalTC
-        UNITS        "seconds"
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-           "Remaining time in the current OSPF graceful restart
-           interval."
-        ::= { ospfv3GeneralGroup 19 }
-
- ospfv3RestartExitReason OBJECT-TYPE
-        SYNTAX       INTEGER { none(1),
-                               inProgress(2),
-                               completed(3),
-                               timedOut(4),
-                               topologyChanged(5)
-                             }
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-           "Describes the outcome of the last attempt at a
-           graceful restart.
-
-           none:            no restart has yet been attempted.
-           inProgress:      a restart attempt is currently underway.
-           completed:       the last restart completed successfully.
-           timedOut:        the last restart timed out.
-           topologyChanged: the last restart was aborted due to
-                            a topology change."
-     ::= { ospfv3GeneralGroup 20 }
-
- ospfv3NotificationEnable OBJECT-TYPE
-        SYNTAX TruthValue
-        MAX-ACCESS read-write
-        STATUS current
-        DESCRIPTION
-            "This object provides a coarse level of control
-             over the generation of OSPFv3 notifications.
-
-             If this object is set to true (1), then it enables
-             the generation of OSPFv3 notifications.  If it is
-             set to false (2), these notifications are not
-             generated.
-
-             This object is persistent, and when written, the
-             entity SHOULD save the change to non-volatile
-             storage."
-    ::= { ospfv3GeneralGroup 21 }
-
-ospfv3StubRouterSupport OBJECT-TYPE
-     SYNTAX       TruthValue
-     MAX-ACCESS   read-only
-     STATUS       current
-     DESCRIPTION
-         "The router's support for stub router functionality.  An
-         object value of true (1) indicates that stub router
-         functionality is supported."
-     REFERENCE
-         "OSPF Stub Router Advertisement"
-     ::= { ospfv3GeneralGroup 22 }
-
- ospfv3StubRouterAdvertisement OBJECT-TYPE
-     SYNTAX       INTEGER {
-                        doNotAdvertise(1),
-                        advertise(2)
-                        }
-     MAX-ACCESS   read-write
-     STATUS       current
-     DESCRIPTION
-         "This object controls the advertisement of
-         stub LSAs by the router.  The value
-         doNotAdvertise (1) will result in the advertisement
-         of standard LSAs and is the default value.
-
-         This object is persistent, and when written,
-         the entity SHOULD save the change to non-volatile
-         storage."
-     REFERENCE
-         "OSPF Stub Router Advertisement, Section 2, Proposed
-         Solution"
-     DEFVAL { doNotAdvertise }
-     ::= { ospfv3GeneralGroup 23 }
-
-ospfv3DiscontinuityTime OBJECT-TYPE
-    SYNTAX     TimeStamp
-    MAX-ACCESS read-only
-    STATUS     current
-    DESCRIPTION
-       "The value of sysUpTime on the most recent occasion
-        at which any one of this MIB's counters suffered
-        a discontinuity.
-
-        If no such discontinuities have occurred since the last
-        re-initialization of the local management subsystem,
-        then this object contains a zero value."
-    ::= { ospfv3GeneralGroup 24 }
-
-  ospfv3RestartTime OBJECT-TYPE
-      SYNTAX     TimeStamp
-      MAX-ACCESS read-only
-      STATUS     current
-      DESCRIPTION
-         "The value of sysUpTime on the most recent occasion
-          at which the ospfv3RestartExitReason was updated."
-      ::= { ospfv3GeneralGroup 25 }
-
- -- The OSPFv3 Area Data Structure contains information
- -- regarding the various areas.  The interfaces and
- -- virtual links are configured as part of these areas.
- -- Area 0, by definition, is the backbone area.
-
- ospfv3AreaTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3AreaEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Information describing the configured
-             parameters and cumulative statistics of the router's
-             attached areas.  The interfaces and
-             virtual links are configured as part of these areas.
-             Area 0, by definition, is the backbone area."
-         REFERENCE
-             "OSPF Version 2, Section 6, The Area Data
-             Structure"
-         ::= { ospfv3Objects 2 }
-
- ospfv3AreaEntry OBJECT-TYPE
-         SYNTAX          Ospfv3AreaEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Information describing the configured
-             parameters and cumulative statistics of one of the
-             router's attached areas.
-
-             The information in this table is persistent,
-             and when written, the entity SHOULD save the a
-             change to non-volatile storage."
-         INDEX           { ospfv3AreaId }
-         ::= { ospfv3AreaTable 1 }
-
- Ospfv3AreaEntry ::= SEQUENCE {
-         ospfv3AreaId
-                 Ospfv3AreaIdTC,
-         ospfv3AreaImportAsExtern
-                 INTEGER,
-         ospfv3AreaSpfRuns
-                 Counter32,
-         ospfv3AreaBdrRtrCount
-                 Gauge32,
-         ospfv3AreaAsBdrRtrCount
-                 Gauge32,
-         ospfv3AreaScopeLsaCount
-                 Gauge32,
-         ospfv3AreaScopeLsaCksumSum
-                 Unsigned32,
-         ospfv3AreaSummary
-                 INTEGER,
-         ospfv3AreaRowStatus
-                 RowStatus,
-         ospfv3AreaStubMetric
-                 BigMetric,
-         ospfv3AreaNssaTranslatorRole
-                 INTEGER,
-         ospfv3AreaNssaTranslatorState
-                 INTEGER,
-         ospfv3AreaNssaTranslatorStabInterval
-                 Unsigned32,
-         ospfv3AreaNssaTranslatorEvents
-                 Counter32,
-         ospfv3AreaStubMetricType
-                 INTEGER,
-         ospfv3AreaTEEnabled
-                 TruthValue
-         }
-
- ospfv3AreaId OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A 32-bit unsigned integer uniquely identifying an area.
-             Area ID 0 is used for the OSPFv3 backbone."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         ::= { ospfv3AreaEntry 1 }
-
- ospfv3AreaImportAsExtern OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         importExternal(1),   -- normal area
-                         importNoExternal(2), -- stub area
-                         importNssa(3)        -- not-so-stubby-area
-                         }
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "Indicates whether an area is a stub area, NSSA, or
-             standard area.  AS-scope LSAs are not imported into stub
-             areas or NSSAs.  NSSAs import AS-External data as NSSA
-             LSAs that have Area-scope."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         DEFVAL { importExternal }
-         ::= { ospfv3AreaEntry 2 }
-
- ospfv3AreaSpfRuns OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of times that the intra-area route
-             table has been calculated using this area's
-             link state database.  This is typically done
-             using Dijkstra's algorithm.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3AreaEntry 3 }
-
- ospfv3AreaBdrRtrCount OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The total number of area border routers
-             reachable within this area.  This is initially zero,
-             and is calculated in each Shortest Path First (SPF)
-             pass."
-         DEFVAL { 0 }
-         ::= { ospfv3AreaEntry 4 }
-
- ospfv3AreaAsBdrRtrCount OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The total number of Autonomous System border
-             routers reachable within this area.  This is
-             initially zero, and is calculated in each SPF
-             pass."
-         DEFVAL { 0 }
-         ::= { ospfv3AreaEntry 5 }
-
- ospfv3AreaScopeLsaCount OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The total number of Area-scope link state
-             advertisements in this area's link state
-             database."
-          DEFVAL { 0 }
-         ::= { ospfv3AreaEntry 6 }
-
- ospfv3AreaScopeLsaCksumSum OBJECT-TYPE
-         SYNTAX          Unsigned32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit unsigned sum of the Area-scope link state
-             advertisements' LS checksums contained in this
-             area's link state database.  The sum can be used
-             to determine if there has been a change in a
-             router's link state database or to compare the
-             link state database of two routers."
-         ::= { ospfv3AreaEntry 7 }
-
- ospfv3AreaSummary OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         noAreaSummary(1),
-                         sendAreaSummary(2)
-                         }
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The variable ospfv3AreaSummary controls the
-             import of Inter-Area LSAs into stub and
-             NSSA areas.  It has no effect on other areas.
-
-             If it is noAreaSummary, the router will neither
-             originate nor propagate Inter-Area LSAs into the
-             stub or NSSA area.  It will only advertise a
-             default route.
-
-             If it is sendAreaSummary, the router will both
-             summarize and propagate Inter-Area LSAs."
-         DEFVAL   { sendAreaSummary }
-         ::= { ospfv3AreaEntry 8 }
-
- ospfv3AreaRowStatus OBJECT-TYPE
-         SYNTAX          RowStatus
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "This object permits management of the table by
-             facilitating actions such as row creation,
-             construction, and destruction.
-
-             The value of this object has no effect on
-             whether other objects in this conceptual row can be
-             modified."
-         ::= { ospfv3AreaEntry 9 }
-
- ospfv3AreaStubMetric OBJECT-TYPE
-         SYNTAX          BigMetric
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The metric value advertised for the default route
-             into stub and NSSA areas.  By default, this equals the
-             least metric among the interfaces to other areas."
-         ::= { ospfv3AreaEntry 10 }
-
- ospfv3AreaNssaTranslatorRole OBJECT-TYPE
-         SYNTAX          INTEGER { always(1), candidate(2) }
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "Indicates an NSSA border router's policy to
-             perform NSSA translation of NSSA-LSAs into
-             AS-External-LSAs."
-         DEFVAL { candidate }
-         ::= { ospfv3AreaEntry 11 }
-
- ospfv3AreaNssaTranslatorState OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         enabled(1),
-                         elected(2),
-                         disabled(3)
-                         }
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-              "Indicates if and how an NSSA border router is
-              performing NSSA translation of NSSA-LSAs into
-              AS-External-LSAs.  When this object is set to
-              'enabled', the NSSA border router's
-              ospfv3AreaNssaTranslatorRole has been set to 'always'.
-              When this object is set to 'elected', a candidate
-              NSSA border router is translating NSSA-LSAs into
-              AS-External-LSAs.  When this object is set to
-              'disabled', a candidate NSSA Border router is NOT
-              translating NSSA-LSAs into AS-External-LSAs."
-         ::= { ospfv3AreaEntry 12 }
-
- ospfv3AreaNssaTranslatorStabInterval OBJECT-TYPE
-         SYNTAX          Unsigned32
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The stability interval defined as the number of
-             seconds after an elected translator determines its
-             services are no longer required that it should
-             continue to perform its translation duties."
-         DEFVAL { 40 }
-         ::= { ospfv3AreaEntry 13 }
-
- ospfv3AreaNssaTranslatorEvents OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "Indicates the number of Translator state changes
-             that have occurred since the last start-up of the
-             OSPFv3 routing process.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3AreaEntry 14 }
-
- ospfv3AreaStubMetricType OBJECT-TYPE
-         SYNTAX       INTEGER {
-                         ospfv3Metric(1),   -- OSPF Metric
-                         comparableCost(2), -- external type 1
-                         nonComparable(3)   -- external type 2
-                         }
-         MAX-ACCESS   read-create
-         STATUS       current
-         DESCRIPTION
-             "This variable assigns the type of metric
-             advertised as a default route."
-         DEFVAL { ospfv3Metric }
-         ::= { ospfv3AreaEntry 15 }
-
- ospfv3AreaTEEnabled OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-                "Indicates whether or not traffic engineering
-                is enabled in the area.  The object is set
-                to the value true (1) to enable traffic engineering.
-                Traffic engineering is disabled by default."
-         DEFVAL { false }
-         ::= { ospfv3AreaEntry 16 }
-
- -- OSPFv3 AS-Scope Link State Database
-
- ospfv3AsLsdbTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3AsLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 Process's AS-scope link state database
-             (LSDB).  The LSDB contains the AS-scope link state
-             advertisements from throughout the areas that the
-             device is attached to."
-         ::= { ospfv3Objects 3 }
-
- ospfv3AsLsdbEntry OBJECT-TYPE
-         SYNTAX          Ospfv3AsLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A single AS-scope link state advertisement."
-         INDEX           { ospfv3AsLsdbType,
-                           ospfv3AsLsdbRouterId,
-                           ospfv3AsLsdbLsid }
-         ::= { ospfv3AsLsdbTable 1 }
-
- Ospfv3AsLsdbEntry ::= SEQUENCE {
-         ospfv3AsLsdbType
-                 Unsigned32,
-         ospfv3AsLsdbRouterId
-                 Ospfv3RouterIdTC,
-         ospfv3AsLsdbLsid
-                 Ospfv3LsIdTC,
-         ospfv3AsLsdbSequence
-                 Ospfv3LsaSequenceTC,
-         ospfv3AsLsdbAge
-                 Ospfv3LsaAgeTC,
-         ospfv3AsLsdbChecksum
-                 Integer32,
-         ospfv3AsLsdbAdvertisement
-                 OCTET STRING,
-         ospfv3AsLsdbTypeKnown
-                 TruthValue
-         }
-
- ospfv3AsLsdbType OBJECT-TYPE
-         SYNTAX          Unsigned32(0..'FFFFFFFF'h)
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The type of the link state advertisement.
-             Each link state type has a separate
-             advertisement format.  AS-scope LSAs not recognized
-             by the router may be stored in the database."
-         ::= { ospfv3AsLsdbEntry 1 }
-
- ospfv3AsLsdbRouterId OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit number that uniquely identifies the
-             originating router in the Autonomous System."
-         REFERENCE
-             "OSPF Version 2, Appendix C.1, Global parameters"
-         ::= { ospfv3AsLsdbEntry 2 }
-
- ospfv3AsLsdbLsid OBJECT-TYPE
-         SYNTAX          Ospfv3LsIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Link State ID is an LS type-specific field
-             containing a unique identifier;
-             it identifies the piece of the routing domain
-             that is being described by the advertisement.
-             In contrast to OSPFv2, the LSID has no
-             addressing semantics."
-         ::= { ospfv3AsLsdbEntry 3 }
-
- -- Note that the OSPF sequence number is a 32-bit signed
- -- integer.  It starts with the value '80000001'h
- -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h.
- -- Thus, a typical sequence number will be very negative.
-
- ospfv3AsLsdbSequence OBJECT-TYPE
-         SYNTAX          Ospfv3LsaSequenceTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The sequence number field is a signed 32-bit
-             integer.  It is used to detect old and duplicate
-             link state advertisements.  The space of
-             sequence numbers is linearly ordered.  The
-             larger the sequence number, the more recent the
-             advertisement."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.6, LS sequence
-             number"
-         ::= { ospfv3AsLsdbEntry 4 }
-
- ospfv3AsLsdbAge OBJECT-TYPE
-         SYNTAX          Ospfv3LsaAgeTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the age of the link state
-             advertisement in seconds.  The high-order bit
-             of the LS age field is considered the DoNotAge
-             bit for support of on-demand circuits."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.1, LS age;
-              Extending OSPF to Support Demand Circuits,
-              Section 2.2, The LS age field."
-         ::= { ospfv3AsLsdbEntry 5 }
-
- ospfv3AsLsdbChecksum OBJECT-TYPE
-         SYNTAX          Integer32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the checksum of the complete
-             contents of the advertisement, excepting the
-             age field.  The age field is excepted so that
-             an advertisement's age can be incremented
-             without updating the checksum.  The checksum
-             used is the same that is used for ISO
-             connectionless datagrams; it is commonly
-             referred to as the Fletcher checksum."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.7, LS checksum"
-         ::= { ospfv3AsLsdbEntry 6 }
-
- ospfv3AsLsdbAdvertisement OBJECT-TYPE
-         SYNTAX          OCTET STRING (SIZE (1..65535))
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The entire link state advertisement, including
-             its header."
-         ::= { ospfv3AsLsdbEntry 7 }
-
- ospfv3AsLsdbTypeKnown OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The value true (1) indicates that the LSA type
-             is recognized by this router."
-         ::= { ospfv3AsLsdbEntry 8 }
-
-  --  OSPFv3 Area-Scope Link State Database
-
- ospfv3AreaLsdbTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3AreaLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 Process's Area-scope LSDB.
-             The LSDB contains the Area-scope link state
-             advertisements from throughout the area that the
-             device is attached to."
-         ::= { ospfv3Objects 4 }
-
- ospfv3AreaLsdbEntry OBJECT-TYPE
-         SYNTAX          Ospfv3AreaLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A single Area-scope link state advertisement."
-         INDEX           { ospfv3AreaLsdbAreaId,
-                           ospfv3AreaLsdbType,
-                           ospfv3AreaLsdbRouterId,
-                           ospfv3AreaLsdbLsid }
-         ::= { ospfv3AreaLsdbTable 1 }
-
- Ospfv3AreaLsdbEntry ::= SEQUENCE {
-         ospfv3AreaLsdbAreaId
-                 Ospfv3AreaIdTC,
-         ospfv3AreaLsdbType
-                 Unsigned32,
-         ospfv3AreaLsdbRouterId
-                 Ospfv3RouterIdTC,
-         ospfv3AreaLsdbLsid
-                 Ospfv3LsIdTC,
-         ospfv3AreaLsdbSequence
-                 Ospfv3LsaSequenceTC,
-         ospfv3AreaLsdbAge
-                 Ospfv3LsaAgeTC,
-         ospfv3AreaLsdbChecksum
-                 Integer32,
-         ospfv3AreaLsdbAdvertisement
-                 OCTET STRING,
-         ospfv3AreaLsdbTypeKnown
-                 TruthValue
-         }
-
- ospfv3AreaLsdbAreaId OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit identifier of the Area from which the
-             LSA was received."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         ::= { ospfv3AreaLsdbEntry 1 }
-
- ospfv3AreaLsdbType OBJECT-TYPE
-         SYNTAX          Unsigned32(0..'FFFFFFFF'h)
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The type of the link state advertisement.
-             Each link state type has a separate
-             advertisement format.  Area-scope LSAs unrecognized
-             by the router are also stored in this database."
-         ::= { ospfv3AreaLsdbEntry 2 }
-
- ospfv3AreaLsdbRouterId OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit number that uniquely identifies the
-             originating router in the Autonomous System."
-         REFERENCE
-             "OSPF Version 2, Appendix C.1, Global parameters"
-         ::= { ospfv3AreaLsdbEntry 3 }
-
- ospfv3AreaLsdbLsid OBJECT-TYPE
-         SYNTAX          Ospfv3LsIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Link State ID is an LS type-specific field
-             containing a unique identifier;
-             it identifies the piece of the routing domain
-             that is being described by the advertisement.
-             In contrast to OSPFv2, the LSID has no
-             addressing semantics."
-         ::= { ospfv3AreaLsdbEntry 4 }
-
- -- Note that the OSPF sequence number is a 32-bit signed
- -- integer.  It starts with the value '80000001'h
- -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h.
- -- Thus, a typical sequence number will be very negative.
-
- ospfv3AreaLsdbSequence OBJECT-TYPE
-         SYNTAX          Ospfv3LsaSequenceTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The sequence number field is a signed 32-bit
-             integer.  It is used to detect old and
-             duplicate link state advertisements.  The space
-             of sequence numbers is linearly ordered.  The
-             larger the sequence number, the more recent the
-             advertisement."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.6, LS sequence
-             number"
-         ::= { ospfv3AreaLsdbEntry 5 }
-
- ospfv3AreaLsdbAge OBJECT-TYPE
-         SYNTAX          Ospfv3LsaAgeTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the age of the link state
-             advertisement in seconds.  The high-order bit
-             of the LS age field is considered the DoNotAge
-             bit for support of on-demand circuits."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.1, LS age;
-              Extending OSPF to Support Demand Circuits,
-              Section 2.2, The LS age field."
-         ::= { ospfv3AreaLsdbEntry 6 }
-
- ospfv3AreaLsdbChecksum OBJECT-TYPE
-         SYNTAX          Integer32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the checksum of the complete
-             contents of the advertisement, excepting the
-             age field.  The age field is excepted so that
-             an advertisement's age can be incremented
-             without updating the checksum.  The checksum
-             used is the same that is used for ISO
-             connectionless datagrams; it is commonly
-             referred to as the Fletcher checksum."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.7, LS checksum"
-         ::= { ospfv3AreaLsdbEntry 7 }
-
- ospfv3AreaLsdbAdvertisement OBJECT-TYPE
-         SYNTAX          OCTET STRING (SIZE (1..65535))
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The entire link state advertisement, including
-             its header."
-         ::= { ospfv3AreaLsdbEntry 8 }
-
- ospfv3AreaLsdbTypeKnown OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The value true (1) indicates that the LSA type is
-             recognized by this router."
-         ::= { ospfv3AreaLsdbEntry 9 }
-
- -- OSPFv3 Link-Scope Link State Database, for non-virtual interfaces
-
- ospfv3LinkLsdbTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3LinkLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 Process's Link-scope LSDB for non-virtual
-             interfaces.  The LSDB contains the Link-scope link
-             state advertisements from the interfaces that the
-             device is attached to."
-         ::= { ospfv3Objects 5 }
-
- ospfv3LinkLsdbEntry OBJECT-TYPE
-         SYNTAX          Ospfv3LinkLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A single Link-scope link state advertisement."
-         INDEX           { ospfv3LinkLsdbIfIndex,
-                           ospfv3LinkLsdbIfInstId,
-                           ospfv3LinkLsdbType,
-                           ospfv3LinkLsdbRouterId,
-                           ospfv3LinkLsdbLsid }
-         ::= { ospfv3LinkLsdbTable 1 }
-
- Ospfv3LinkLsdbEntry ::= SEQUENCE {
-         ospfv3LinkLsdbIfIndex
-                 InterfaceIndex,
-         ospfv3LinkLsdbIfInstId
-                 Ospfv3IfInstIdTC,
-         ospfv3LinkLsdbType
-                 Unsigned32,
-         ospfv3LinkLsdbRouterId
-                 Ospfv3RouterIdTC,
-         ospfv3LinkLsdbLsid
-                 Ospfv3LsIdTC,
-         ospfv3LinkLsdbSequence
-                 Ospfv3LsaSequenceTC,
-         ospfv3LinkLsdbAge
-                 Ospfv3LsaAgeTC,
-         ospfv3LinkLsdbChecksum
-                 Integer32,
-         ospfv3LinkLsdbAdvertisement
-                 OCTET STRING,
-         ospfv3LinkLsdbTypeKnown
-                 TruthValue
-         }
-
- ospfv3LinkLsdbIfIndex OBJECT-TYPE
-         SYNTAX         InterfaceIndex
-         MAX-ACCESS     not-accessible
-         STATUS         current
-         DESCRIPTION
-             "The identifier of the link from which the LSA
-             was received."
-         ::= { ospfv3LinkLsdbEntry 1 }
-
- ospfv3LinkLsdbIfInstId OBJECT-TYPE
-         SYNTAX         Ospfv3IfInstIdTC
-         MAX-ACCESS     not-accessible
-         STATUS         current
-         DESCRIPTION
-             "The identifier of the interface instance from
-             which the LSA was received."
-         ::= { ospfv3LinkLsdbEntry 2 }
-
- ospfv3LinkLsdbType OBJECT-TYPE
-         SYNTAX          Unsigned32(0..'FFFFFFFF'h)
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The type of the link state advertisement.
-             Each link state type has a separate
-             advertisement format.  Link-scope LSAs unrecognized
-             by the router are also stored in this database."
-         ::= { ospfv3LinkLsdbEntry 3 }
-
- ospfv3LinkLsdbRouterId OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit number that uniquely identifies the
-             originating router in the Autonomous System."
-         REFERENCE
-             "OSPF Version 2, Appendix C.1, Global parameters"
-         ::= { ospfv3LinkLsdbEntry 4 }
-
- ospfv3LinkLsdbLsid OBJECT-TYPE
-         SYNTAX        Ospfv3LsIdTC
-         MAX-ACCESS    not-accessible
-         STATUS        current
-         DESCRIPTION
-             "The Link State ID is an LS type-specific field
-             containing a unique identifier;
-             it identifies the piece of the routing domain
-             that is being described by the advertisement.
-             In contrast to OSPFv2, the LSID has no
-             addressing semantics.  However, in OSPFv3
-             the Link State ID always contains the flooding
-             scope of the LSA."
-         ::= { ospfv3LinkLsdbEntry 5 }
-
- -- Note that the OSPF sequence number is a 32-bit signed
- -- integer.  It starts with the value '80000001'h
- -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h.
- -- Thus, a typical sequence number will be very negative.
-
- ospfv3LinkLsdbSequence OBJECT-TYPE
-         SYNTAX          Ospfv3LsaSequenceTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The sequence number field is a signed 32-bit
-             integer.  It is used to detect old and duplicate
-             link state advertisements.  The space of
-             sequence numbers is linearly ordered.  The
-             larger the sequence number, the more recent the
-             advertisement."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.6, LS sequence
-             number"
-         ::= { ospfv3LinkLsdbEntry 6 }
-
- ospfv3LinkLsdbAge OBJECT-TYPE
-         SYNTAX          Ospfv3LsaAgeTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the age of the link state
-             advertisement in seconds.  The high-order bit
-             of the LS age field is considered the DoNotAge
-             bit for support of on-demand circuits."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.1, LS age;
-              Extending OSPF to Support Demand Circuits,
-              Section 2.2, The LS age field."
-         ::= { ospfv3LinkLsdbEntry 7 }
-
- ospfv3LinkLsdbChecksum OBJECT-TYPE
-         SYNTAX          Integer32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the checksum of the complete
-             contents of the advertisement, excepting the
-             age field.  The age field is excepted so that
-             an advertisement's age can be incremented
-             without updating the checksum.  The checksum
-             used is the same that is used for ISO
-             connectionless datagrams; it is commonly
-             referred to as the Fletcher checksum."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.7, LS checksum"
-         ::= { ospfv3LinkLsdbEntry 8 }
-
- ospfv3LinkLsdbAdvertisement OBJECT-TYPE
-         SYNTAX          OCTET STRING (SIZE (1..65535))
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The entire link state advertisement, including
-             its header."
-         ::= { ospfv3LinkLsdbEntry 9 }
-
- ospfv3LinkLsdbTypeKnown OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The value true (1) indicates that the LSA type is
-             recognized by this router."
-         ::= { ospfv3LinkLsdbEntry 10 }
-
- -- OSPF Host Table
-
- ospfv3HostTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3HostEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Host/Metric Table indicates what hosts are
-             directly attached to the router and their
-             corresponding metrics."
-         REFERENCE
-             "OSPF Version 2, Appendix C.7, Host route
-             parameters"
-         ::= { ospfv3Objects 6 }
-
- ospfv3HostEntry OBJECT-TYPE
-         SYNTAX          Ospfv3HostEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A metric to be advertised when a given host is
-             reachable.
-
-             The information in this table is persistent, and
-             when written, the entity SHOULD save the change
-             to non-volatile storage."
-         INDEX           { ospfv3HostAddressType,
-                           ospfv3HostAddress }
-         ::= { ospfv3HostTable 1 }
-
- Ospfv3HostEntry ::= SEQUENCE {
-         ospfv3HostAddressType
-                 InetAddressType,
-         ospfv3HostAddress
-                 InetAddress,
-         ospfv3HostMetric
-                 Metric,
-         ospfv3HostRowStatus
-                 RowStatus,
-         ospfv3HostAreaID
-                 Ospfv3AreaIdTC
-         }
-
- ospfv3HostAddressType OBJECT-TYPE
-         SYNTAX          InetAddressType
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The address type of ospfv3HostAddress.  Only IPv6
-             global address type is expected."
-         REFERENCE
-             "OSPF Version 2, Appendix C.7, Host route
-             parameters"
-         ::= { ospfv3HostEntry 1 }
-
- ospfv3HostAddress OBJECT-TYPE
-         SYNTAX          InetAddress
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The IPv6 address of the host.  Must be an
-             IPv6 global address."
-         REFERENCE
-             "OSPF Version 2, Appendix C.7, Host route
-             parameters"
-         ::= { ospfv3HostEntry 2 }
-
- ospfv3HostMetric OBJECT-TYPE
-         SYNTAX          Metric
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The metric to be advertised."
-         REFERENCE
-             "OSPF Version 2, Appendix C.7, Host route
-             parameters"
-         ::= { ospfv3HostEntry 3 }
-
- ospfv3HostRowStatus OBJECT-TYPE
-         SYNTAX          RowStatus
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "This object permits management of the table by
-             facilitating actions such as row creation,
-             construction, and destruction.
-
-             The value of this object has no effect on
-             whether other objects in this conceptual row can be
-             modified."
-         ::= { ospfv3HostEntry 4 }
-
- ospfv3HostAreaID OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The Area the host entry is to be found within.
-             By default, the area for the subsuming OSPFv3
-             interface, or Area 0 if there is no subsuming
-             interface."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         ::= { ospfv3HostEntry 5 }
-
- -- OSPFv3 Interface Table
-
- ospfv3IfTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3IfEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 Interface Table describes the
-             interfaces from the viewpoint of OSPFv3."
-         REFERENCE
-             "OSPF for IPv6, Appendix C.3, Router Interface
-             Parameters"
-         ::= { ospfv3Objects 7 }
-
- ospfv3IfEntry OBJECT-TYPE
-         SYNTAX          Ospfv3IfEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 Interface Entry describes one
-             interface from the viewpoint of OSPFv3.
-
-             The information in this table is persistent,
-             and when written, the entity SHOULD save the
-             change to non-volatile storage."
-         INDEX           { ospfv3IfIndex,
-                           ospfv3IfInstId }
-         ::= { ospfv3IfTable 1 }
-
- Ospfv3IfEntry ::= SEQUENCE {
-         ospfv3IfIndex
-                 InterfaceIndex,
-         ospfv3IfInstId
-                 Ospfv3IfInstIdTC,
-         ospfv3IfAreaId
-                 Ospfv3AreaIdTC,
-         ospfv3IfType
-                 INTEGER,
-         ospfv3IfAdminStatus
-                 Status,
-         ospfv3IfRtrPriority
-                 DesignatedRouterPriority,
-         ospfv3IfTransitDelay
-                 Ospfv3UpToRefreshIntervalTC,
-         ospfv3IfRetransInterval
-                 Ospfv3UpToRefreshIntervalTC,
-         ospfv3IfHelloInterval
-                 HelloRange,
-         ospfv3IfRtrDeadInterval
-                  Ospfv3DeadIntervalRangeTC,
-         ospfv3IfPollInterval
-                 Unsigned32,
-         ospfv3IfState
-                 INTEGER,
-         ospfv3IfDesignatedRouter
-                 Ospfv3RouterIdTC,
-         ospfv3IfBackupDesignatedRouter
-                 Ospfv3RouterIdTC,
-         ospfv3IfEvents
-                 Counter32,
-         ospfv3IfRowStatus
-                 RowStatus,
-         ospfv3IfDemand
-                 TruthValue,
-         ospfv3IfMetricValue
-                 Metric,
-         ospfv3IfLinkScopeLsaCount
-                 Gauge32,
-         ospfv3IfLinkLsaCksumSum
-                 Unsigned32,
-         ospfv3IfDemandNbrProbe
-                 TruthValue,
-         ospfv3IfDemandNbrProbeRetransLimit
-                 Unsigned32,
-         ospfv3IfDemandNbrProbeInterval
-                 Unsigned32,
-         ospfv3IfTEDisabled
-                 TruthValue,
-         ospfv3IfLinkLSASuppression
-                 TruthValue
-         }
-
- ospfv3IfIndex OBJECT-TYPE
-         SYNTAX          InterfaceIndex
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The interface index of this OSPFv3 interface.
-             It corresponds to the interface index of the
-             IPv6 interface on which OSPFv3 is configured."
-         ::= { ospfv3IfEntry 1 }
-
- ospfv3IfInstId OBJECT-TYPE
-         SYNTAX          Ospfv3IfInstIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Enables multiple interface instances of OSPFv3
-             to be run over a single link.  Each interface
-             instance would be assigned a separate ID.  This ID
-             has local link significance only."
-         ::= { ospfv3IfEntry 2 }
-
- ospfv3IfAreaId OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "A 32-bit integer uniquely identifying the area
-             to which the interface connects.  Area ID
-             0 is used for the OSPFv3 backbone."
-         DEFVAL          { 0 }
-         ::= { ospfv3IfEntry 3 }
-
- ospfv3IfType OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         broadcast(1),
-                         nbma(2),
-                         pointToPoint(3),
-                         pointToMultipoint(5)
-                         }
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 interface type."
-         ::= { ospfv3IfEntry 4 }
-
- ospfv3IfAdminStatus OBJECT-TYPE
-         SYNTAX          Status
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 interface's administrative status.
-             The value formed on the interface; the interface
-             will be advertised as an internal route to some
-             area.  The value 'disabled' denotes that the
-             interface is external to OSPFv3.
-
-             Note that a value of 'disabled' for the object
-             ospfv3AdminStatus will override a value of
-             'enabled' for the interface."
-         DEFVAL          { enabled }
-         ::= { ospfv3IfEntry 5 }
-
- ospfv3IfRtrPriority OBJECT-TYPE
-         SYNTAX          DesignatedRouterPriority
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The priority of this interface.  Used in
-             multi-access networks, this field is used in
-             the designated-router election algorithm.  The
-             value 0 signifies that the router is not
-             eligible to become the Designated Router on this
-             particular network.  In the event of a tie in
-             this value, routers will use their Router ID as
-             a tie breaker."
-         DEFVAL          { 1 }
-         ::= { ospfv3IfEntry 6 }
-
- ospfv3IfTransitDelay OBJECT-TYPE
-         SYNTAX          Ospfv3UpToRefreshIntervalTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The estimated number of seconds it takes to transmit
-             a Link State Update packet over this interface.  LSAs
-             contained in the update packet must have their age
-             incremented by this amount before transmission.  This
-             value should take into account the transmission and
-             propagation delays of the interface."
-         REFERENCE
-             "OSPF for IPv6, Appendix C.3, Router Interface
-             Parameters."
-         DEFVAL          { 1 }
-         ::= { ospfv3IfEntry 7 }
-
- ospfv3IfRetransInterval OBJECT-TYPE
-         SYNTAX          Ospfv3UpToRefreshIntervalTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The number of seconds between link state
-             advertisement retransmissions for adjacencies
-
-             belonging to this interface.  This value is
-             also used when retransmitting database
-             description and Link State Request packets."
-         DEFVAL          { 5 }
-         ::= { ospfv3IfEntry 8 }
-
- ospfv3IfHelloInterval OBJECT-TYPE
-         SYNTAX          HelloRange
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The length of time, in seconds, between the
-             Hello packets that the router sends on the
-             interface.  This value must be the same for all
-             routers attached to a common network."
-         DEFVAL          { 10 }
-         ::= { ospfv3IfEntry 9 }
-
- ospfv3IfRtrDeadInterval OBJECT-TYPE
-         SYNTAX          Ospfv3DeadIntervalRangeTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The number of seconds that a router's Hello
-             packets have not been seen before its
-             neighbors declare the router down on the interface.
-             This should be some multiple of the Hello interval.
-             This value must be the same for all routers attached
-             to a common network."
-         DEFVAL          { 40 }
-         ::= { ospfv3IfEntry 10 }
-
- ospfv3IfPollInterval OBJECT-TYPE
-         SYNTAX          Unsigned32
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The larger time interval, in seconds, between
-             the Hello packets sent to an inactive,
-             non-broadcast multi-access neighbor."
-         DEFVAL          { 120 }
-         ::= { ospfv3IfEntry 11 }
-
- ospfv3IfState OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         down(1),
-                         loopback(2),
-                         waiting(3),
-                         pointToPoint(4),
-                         designatedRouter(5),
-                         backupDesignatedRouter(6),
-                         otherDesignatedRouter(7),
-                         standby(8)
-                         }
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 interface state.  An interface may be
-             in standby state if there are multiple interfaces
-             on the link and another interface is active.  The
-             interface may be in Down state if the underlying
-             IPv6 interface is down or if the admin status is
-             'disabled' either globally or for the interface."
-         ::= { ospfv3IfEntry 12 }
-
- ospfv3IfDesignatedRouter OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The Router ID of the Designated Router."
-         ::= { ospfv3IfEntry 13 }
-
- ospfv3IfBackupDesignatedRouter OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The Router ID of the Backup Designated
-             Router."
-         ::= { ospfv3IfEntry 14 }
-
- ospfv3IfEvents OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of times this OSPFv3 interface has
-             changed its state or an error has occurred.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3IfEntry 15 }
-
-  ospfv3IfRowStatus OBJECT-TYPE
-         SYNTAX          RowStatus
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "This object permits management of the table by
-             facilitating actions such as row creation,
-             construction, and destruction.
-
-             The value of this object has no effect on
-             whether other objects in this conceptual row can be
-             modified."
-         ::= { ospfv3IfEntry 16 }
-
- ospfv3IfDemand OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "Indicates whether Demand OSPFv3 procedures
-             (Hello suppression to FULL neighbors and
-             setting the DoNotAge flag on propagated LSAs)
-             should be performed on this interface."
-         DEFVAL { false }
-         ::= { ospfv3IfEntry 17 }
-
- ospfv3IfMetricValue OBJECT-TYPE
-         SYNTAX          Metric
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The metric assigned to this interface.
-              The default value of the metric is
-              'Reference Bandwidth / ifSpeed'.  The value
-              of the reference bandwidth can be set
-              in the ospfv3ReferenceBandwidth object."
-         ::= { ospfv3IfEntry 18 }
-
-  ospfv3IfLinkScopeLsaCount OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The total number of Link-scope link state
-             advertisements in this link's link state
-             database."
-         ::= { ospfv3IfEntry 19 }
-
-  ospfv3IfLinkLsaCksumSum OBJECT-TYPE
-         SYNTAX          Unsigned32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit unsigned sum of the Link-scope link state
-             advertisements' LS checksums contained in this
-             link's link state database.  The sum can be used
-             to determine if there has been a change in a
-             router's link state database or to compare the
-             link state database of two routers."
-         ::= { ospfv3IfEntry 20 }
-
- ospfv3IfDemandNbrProbe OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-                "Indicates whether or not neighbor probing is
-                enabled to determine whether or not the neighbor
-                is inactive.  Neighbor probing is disabled by
-                default."
-         DEFVAL { false }
-         ::= { ospfv3IfEntry 21 }
-
-ospfv3IfDemandNbrProbeRetransLimit OBJECT-TYPE
-        SYNTAX       Unsigned32
-        MAX-ACCESS   read-create
-        STATUS       current
-        DESCRIPTION
-           "The number of consecutive LSA retransmissions before
-           the neighbor is deemed inactive and the neighbor
-           adjacency is brought down."
-        DEFVAL          { 10 }
-        ::= { ospfv3IfEntry 22}
-
-ospfv3IfDemandNbrProbeInterval OBJECT-TYPE
-        SYNTAX       Unsigned32
-        UNITS        "seconds"
-        MAX-ACCESS   read-create
-        STATUS       current
-        DESCRIPTION
-           "Defines how often the neighbor will be probed."
-        DEFVAL          { 120 }
-        ::= { ospfv3IfEntry 23 }
-
- ospfv3IfTEDisabled OBJECT-TYPE
-        SYNTAX          TruthValue
-        MAX-ACCESS      read-create
-        STATUS          current
-        DESCRIPTION
-           "Indicates whether or not traffic engineering
-           is disabled on the interface when traffic
-           engineering is enabled in the area where the
-           interface is attached.  The object is set
-           to the value true (1) to disable traffic engineering
-           on the interface.  Traffic engineering is enabled
-           by default on the interface when traffic engineering
-           is enabled in the area where the interface is
-           attached."
-        DEFVAL { false }
-        ::= { ospfv3IfEntry 24 }
-
- ospfv3IfLinkLSASuppression OBJECT-TYPE
-        SYNTAX          TruthValue
-        MAX-ACCESS      read-create
-        STATUS          current
-        DESCRIPTION
-           "Specifies whether or not link LSA origination is
-           suppressed for broadcast or NBMA interface types.
-           The object is set to value true (1) to suppress
-           the origination."
-        REFERENCE
-             "OSPF for IPv6, Appendix C.3, Router Interface
-                 Parameters"
-        DEFVAL { false }
-        ::= { ospfv3IfEntry 25 }
-
- -- OSPFv3 Virtual Interface Table
-
- ospfv3VirtIfTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3VirtIfEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Information about this router's virtual
-             interfaces that the OSPFv3 Process is configured
-             to carry on."
-         REFERENCE
-             "OSPF for IPv6, Appendix C.4, Virtual Link
-             Parameters"
-         ::= { ospfv3Objects 8 }
-
- ospfv3VirtIfEntry OBJECT-TYPE
-         SYNTAX          Ospfv3VirtIfEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Information about a single virtual interface.
-
-             The information in this table is persistent,
-             and when written, the entity SHOULD save the
-             change to non-volatile storage."
-         INDEX           { ospfv3VirtIfAreaId,
-                           ospfv3VirtIfNeighbor }
-         ::= { ospfv3VirtIfTable 1 }
-
- Ospfv3VirtIfEntry ::= SEQUENCE {
-         ospfv3VirtIfAreaId
-                 Ospfv3AreaIdTC,
-         ospfv3VirtIfNeighbor
-                 Ospfv3RouterIdTC,
-         ospfv3VirtIfIndex
-                 InterfaceIndex,
-         ospfv3VirtIfInstId
-                 Ospfv3IfInstIdTC,
-         ospfv3VirtIfTransitDelay
-                 Ospfv3UpToRefreshIntervalTC,
-         ospfv3VirtIfRetransInterval
-                 Ospfv3UpToRefreshIntervalTC,
-         ospfv3VirtIfHelloInterval
-                 HelloRange,
-         ospfv3VirtIfRtrDeadInterval
-                 Ospfv3DeadIntervalRangeTC,
-         ospfv3VirtIfState
-                 INTEGER,
-         ospfv3VirtIfEvents
-                 Counter32,
-         ospfv3VirtIfRowStatus
-                 RowStatus,
-         ospfv3VirtIfLinkScopeLsaCount
-                 Gauge32,
-         ospfv3VirtIfLinkLsaCksumSum
-                 Unsigned32
-         }
-
- ospfv3VirtIfAreaId OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The transit area that the virtual link
-             traverses.  By definition, this is not
-             Area 0."
-         ::= { ospfv3VirtIfEntry 1 }
-
- ospfv3VirtIfNeighbor OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Router ID of the virtual neighbor."
-         ::= { ospfv3VirtIfEntry 2 }
-
- ospfv3VirtIfIndex OBJECT-TYPE
-         SYNTAX          InterfaceIndex
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The local interface index assigned by the
-             OSPFv3 Process to this OSPFv3 virtual interface.
-             It is advertised in Hellos sent over the virtual
-             link and in the router's router-LSAs."
-         ::= { ospfv3VirtIfEntry 3 }
-
- ospfv3VirtIfInstId OBJECT-TYPE
-         SYNTAX          Ospfv3IfInstIdTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The local Interface Instance ID assigned by the
-             OSPFv3 Process to this OSPFv3 virtual interface."
-         ::= { ospfv3VirtIfEntry 4 }
-
- ospfv3VirtIfTransitDelay OBJECT-TYPE
-         SYNTAX          Ospfv3UpToRefreshIntervalTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The estimated number of seconds it takes to
-             transmit a Link State Update packet over this
-             interface."
-         DEFVAL          { 1 }
-         ::= { ospfv3VirtIfEntry 5 }
-
- ospfv3VirtIfRetransInterval OBJECT-TYPE
-         SYNTAX          Ospfv3UpToRefreshIntervalTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The number of seconds between link state
-             advertisement retransmissions for adjacencies
-             belonging to this interface.  This value is
-             also used when retransmitting database
-             description and Link State Request packets.  This
-             value should be well over the expected
-             round-trip time."
-         DEFVAL          { 5 }
-         ::= { ospfv3VirtIfEntry 6 }
-
- ospfv3VirtIfHelloInterval OBJECT-TYPE
-         SYNTAX          HelloRange
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The length of time, in seconds, between the
-             Hello packets that the router sends on the
-             interface.  This value must be the same for the
-             virtual neighbor."
-         DEFVAL          { 10 }
-         ::= { ospfv3VirtIfEntry 7 }
-
- ospfv3VirtIfRtrDeadInterval OBJECT-TYPE
-         SYNTAX          Ospfv3DeadIntervalRangeTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The number of seconds that a router's Hello
-             packets have not been seen before its
-             neighbors declare the router down.  This should
-             be some multiple of the Hello interval.  This
-             value must be the same for the virtual
-             neighbor."
-         DEFVAL          { 60 }
-         ::= { ospfv3VirtIfEntry 8 }
-
- ospfv3VirtIfState OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         down(1),
-                         pointToPoint(4)
-                         }
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "OSPF virtual interface states.  The same encoding
-             as the ospfV3IfTable is used."
-         ::= { ospfv3VirtIfEntry 9 }
-
- ospfv3VirtIfEvents OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of state changes or error events on
-             this virtual link.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3VirtIfEntry 10 }
-
- ospfv3VirtIfRowStatus OBJECT-TYPE
-         SYNTAX          RowStatus
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "This object permits management of the table by
-             facilitating actions such as row creation,
-             construction, and destruction.
-
-             The value of this object has no effect on
-             whether other objects in this conceptual row can be
-             modified."
-         ::= { ospfv3VirtIfEntry 11 }
-
- ospfv3VirtIfLinkScopeLsaCount OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The total number of Link-scope link state
-             advertisements in this virtual link's link state
-             database."
-         ::= { ospfv3VirtIfEntry 12 }
-
- ospfv3VirtIfLinkLsaCksumSum OBJECT-TYPE
-         SYNTAX          Unsigned32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit unsigned sum of the Link-scope link state
-             advertisements' LS checksums contained in this
-             virtual link's link state database.  The sum can be used
-             to determine if there has been a change in a
-             router's link state database or to compare the
-             link state database of two routers."
-         ::= { ospfv3VirtIfEntry 13 }
-
- -- OSPFv3 Neighbor Table
-
- ospfv3NbrTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3NbrEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A table describing all neighbors in the
-             locality of the OSPFv3 router."
-         REFERENCE
-             "OSPF Version 2, Section 10, The Neighbor Data
-             Structure"
-         ::= { ospfv3Objects 9 }
-
- ospfv3NbrEntry OBJECT-TYPE
-         SYNTAX          Ospfv3NbrEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The information regarding a single neighbor."
-         REFERENCE
-             "OSPF Version 2, Section 10, The Neighbor Data
-             Structure"
-         INDEX           { ospfv3NbrIfIndex,
-                           ospfv3NbrIfInstId,
-                           ospfv3NbrRtrId }
-         ::= { ospfv3NbrTable 1 }
-
- Ospfv3NbrEntry ::= SEQUENCE {
-         ospfv3NbrIfIndex
-                 InterfaceIndex,
-         ospfv3NbrIfInstId
-                 Ospfv3IfInstIdTC,
-         ospfv3NbrRtrId
-                 Ospfv3RouterIdTC,
-         ospfv3NbrAddressType
-                 InetAddressType,
-         ospfv3NbrAddress
-                 InetAddress,
-         ospfv3NbrOptions
-                 Integer32,
-         ospfv3NbrPriority
-                 DesignatedRouterPriority,
-         ospfv3NbrState
-                 INTEGER,
-         ospfv3NbrEvents
-                 Counter32,
-         ospfv3NbrLsRetransQLen
-                 Gauge32,
-         ospfv3NbrHelloSuppressed
-                 TruthValue,
-         ospfv3NbrIfId
-                 InterfaceIndex,
-         ospfv3NbrRestartHelperStatus
-                 INTEGER,
-         ospfv3NbrRestartHelperAge
-                 Ospfv3UpToRefreshIntervalTC,
-         ospfv3NbrRestartHelperExitReason
-                 INTEGER
-         }
-
- ospfv3NbrIfIndex OBJECT-TYPE
-         SYNTAX          InterfaceIndex
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Local Link ID of the link over which the
-              neighbor can be reached."
-         ::= { ospfv3NbrEntry 1 }
-
- ospfv3NbrIfInstId OBJECT-TYPE
-         SYNTAX          Ospfv3IfInstIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Interface instance over which the neighbor
-             can be reached.  This ID has local link
-             significance only."
-         ::= { ospfv3NbrEntry 2 }
-
- ospfv3NbrRtrId OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A 32-bit unsigned integer uniquely identifying the
-             neighboring router in the Autonomous System."
-         ::= { ospfv3NbrEntry 3 }
-
- ospfv3NbrAddressType OBJECT-TYPE
-         SYNTAX          InetAddressType
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The address type of ospfv3NbrAddress.  Only IPv6
-             addresses without zone index are expected."
-         ::= { ospfv3NbrEntry 4 }
-
- ospfv3NbrAddress OBJECT-TYPE
-         SYNTAX          InetAddress
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The IPv6 address of the neighbor associated with
-             the local link."
-         ::= { ospfv3NbrEntry 5 }
-
- ospfv3NbrOptions OBJECT-TYPE
-         SYNTAX          Integer32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "A bit mask corresponding to the neighbor's
-             options field."
-         REFERENCE
-             "OSPF for IPv6, Appendix A.2, The Options Field"
-         ::= { ospfv3NbrEntry 6 }
-
- ospfv3NbrPriority OBJECT-TYPE
-         SYNTAX          DesignatedRouterPriority
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The priority of this neighbor in the designated-
-             router election algorithm.  The value 0 signifies
-             that the neighbor is not eligible to become the
-             Designated Router on this particular network."
-         ::= { ospfv3NbrEntry 7 }
-
- ospfv3NbrState OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         down(1),
-                         attempt(2),
-                         init(3),
-                         twoWay(4),
-                         exchangeStart(5),
-                         exchange(6),
-                         loading(7),
-                         full(8)
-                         }
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The state of the relationship with this
-             neighbor."
-         REFERENCE
-             "OSPF Version 2, Section 10.1, Neighbor states"
-         ::= { ospfv3NbrEntry 8 }
-
- ospfv3NbrEvents OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of times this neighbor relationship
-             has changed state or an error has occurred.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3NbrEntry 9 }
-
- ospfv3NbrLsRetransQLen OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The current length of the retransmission
-             queue."
-         ::= { ospfv3NbrEntry 10 }
-
- ospfv3NbrHelloSuppressed OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "Indicates whether Hellos are being suppressed
-             to the neighbor."
-         ::= { ospfv3NbrEntry 11 }
-
- ospfv3NbrIfId OBJECT-TYPE
-         SYNTAX          InterfaceIndex
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The Interface ID that the neighbor advertises
-             in its Hello packets on this link, that is, the
-             neighbor's local interface index."
-         ::= { ospfv3NbrEntry 12 }
-
- ospfv3NbrRestartHelperStatus OBJECT-TYPE
-        SYNTAX       INTEGER { notHelping(1),
-                               helping(2)
-                             }
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-           "Indicates whether the router is acting
-           as a graceful restart helper for the neighbor."
-           ::= { ospfv3NbrEntry 13 }
-
- ospfv3NbrRestartHelperAge OBJECT-TYPE
-        SYNTAX       Ospfv3UpToRefreshIntervalTC
-        UNITS        "seconds"
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-           "Remaining time in current OSPF graceful restart
-           interval, if the router is acting as a restart
-           helper for the neighbor."
-        ::= { ospfv3NbrEntry 14 }
-
- ospfv3NbrRestartHelperExitReason OBJECT-TYPE
-        SYNTAX       INTEGER { none(1),
-                               inProgress(2),
-                               completed(3),
-                               timedOut(4),
-                               topologyChanged(5)
-                             }
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-           "Describes the outcome of the last attempt at acting
-           as a graceful restart helper for the neighbor.
-
-           none:            no restart has yet been attempted.
-           inProgress:      a restart attempt is currently underway.
-           completed:       the last restart completed successfully.
-           timedOut:        the last restart timed out.
-           topologyChanged: the last restart was aborted due to
-                            a topology change."
-     ::= { ospfv3NbrEntry 15 }
-
- -- OSPFv3 Configured Neighbor Table
-
- ospfv3CfgNbrTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3CfgNbrEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A table describing all configured neighbors.
-
-             The Configured Neighbors table just gives
-             OSPFv3 information for sending OSPFv3 packets
-             to potential neighbors and is typically used
-             on NBMA and Point-to-Multipoint networks.
-             Once a Hello is received from a neighbor in
-             the Configured Neighbor table, an entry for
-             that neighbor is created in the Neighbor table
-             and adjacency state is maintained there.
-             Neighbors on multi-access or Point-to-Point
-             networks can use multicast addressing, so only
-             Neighbor table entries are created for them."
-         REFERENCE
-             "OSPF Version 2, Section 10, The Neighbor Data
-             Structure"
-         ::= { ospfv3Objects 10 }
-
- ospfv3CfgNbrEntry OBJECT-TYPE
-         SYNTAX          Ospfv3CfgNbrEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The information regarding a single configured
-             neighbor.
-
-             The information in this table is persistent,
-             and when written, the entity SHOULD save the
-             change to non-volatile storage."
-         REFERENCE
-             "OSPF Version 2, Section 10, The Neighbor Data
-             Structure"
-         INDEX           { ospfv3CfgNbrIfIndex,
-                           ospfv3CfgNbrIfInstId,
-                           ospfv3CfgNbrAddressType,
-                           ospfv3CfgNbrAddress }
-         ::= { ospfv3CfgNbrTable 1 }
-
- Ospfv3CfgNbrEntry ::= SEQUENCE {
-         ospfv3CfgNbrIfIndex
-                 InterfaceIndex,
-         ospfv3CfgNbrIfInstId
-                 Ospfv3IfInstIdTC,
-         ospfv3CfgNbrAddressType
-                 InetAddressType,
-         ospfv3CfgNbrAddress
-                 InetAddress,
-         ospfv3CfgNbrPriority
-                 DesignatedRouterPriority,
-         ospfv3CfgNbrRowStatus
-                 RowStatus
-         }
-
- ospfv3CfgNbrIfIndex OBJECT-TYPE
-         SYNTAX          InterfaceIndex
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Local Link ID of the link over which the
-              neighbor can be reached."
-         ::= { ospfv3CfgNbrEntry 1 }
-
- ospfv3CfgNbrIfInstId OBJECT-TYPE
-         SYNTAX          Ospfv3IfInstIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Interface instance over which the neighbor
-             can be reached.  This ID has local link
-             significance only."
-         ::= { ospfv3CfgNbrEntry 2 }
-
- ospfv3CfgNbrAddressType OBJECT-TYPE
-         SYNTAX          InetAddressType
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The address type of ospfv3NbrAddress.  Only IPv6
-             addresses without zone index are expected."
-         ::= { ospfv3CfgNbrEntry 3 }
-
- ospfv3CfgNbrAddress OBJECT-TYPE
-         SYNTAX          InetAddress
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The IPv6 address of the neighbor associated with
-             the local link."
-         ::= { ospfv3CfgNbrEntry 4 }
-
- ospfv3CfgNbrPriority OBJECT-TYPE
-         SYNTAX          DesignatedRouterPriority
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "The priority of this neighbor in the designated-
-             router election algorithm.  The value 0 signifies
-             that the neighbor is not eligible to become the
-             Designated Router on this particular network."
-         DEFVAL          { 1 }
-         ::= { ospfv3CfgNbrEntry 5 }
-
- ospfv3CfgNbrRowStatus OBJECT-TYPE
-         SYNTAX          RowStatus
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "This object permits management of the table by
-             facilitating actions such as row creation,
-             construction, and destruction.
-
-             The value of this object has no effect on
-             whether other objects in this conceptual row can be
-             modified."
-         ::= { ospfv3CfgNbrEntry 6 }
-
- -- OSPFv3 Virtual Neighbor Table
-
- ospfv3VirtNbrTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3VirtNbrEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A table describing all virtual neighbors."
-         REFERENCE
-             "OSPF Version 2, Section 15, Virtual Links"
-         ::= { ospfv3Objects 11 }
-
- ospfv3VirtNbrEntry OBJECT-TYPE
-         SYNTAX          Ospfv3VirtNbrEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "Virtual neighbor information."
-         INDEX           { ospfv3VirtNbrArea,
-                           ospfv3VirtNbrRtrId }
-         ::= { ospfv3VirtNbrTable 1 }
-
- Ospfv3VirtNbrEntry ::= SEQUENCE {
-         ospfv3VirtNbrArea
-                 Ospfv3AreaIdTC,
-         ospfv3VirtNbrRtrId
-                 Ospfv3RouterIdTC,
-         ospfv3VirtNbrIfIndex
-                 InterfaceIndex,
-         ospfv3VirtNbrIfInstId
-                 Ospfv3IfInstIdTC,
-         ospfv3VirtNbrAddressType
-                 InetAddressType,
-         ospfv3VirtNbrAddress
-                 InetAddress,
-         ospfv3VirtNbrOptions
-                 Integer32,
-         ospfv3VirtNbrState
-                 INTEGER,
-         ospfv3VirtNbrEvents
-                 Counter32,
-         ospfv3VirtNbrLsRetransQLen
-                 Gauge32,
-         ospfv3VirtNbrHelloSuppressed
-                 TruthValue,
-         ospfv3VirtNbrIfId
-                 InterfaceIndex,
-         ospfv3VirtNbrRestartHelperStatus
-                 INTEGER,
-         ospfv3VirtNbrRestartHelperAge
-                 Ospfv3UpToRefreshIntervalTC,
-         ospfv3VirtNbrRestartHelperExitReason
-                 INTEGER
-         }
-
- ospfv3VirtNbrArea OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The transit area Identifier."
-         ::= { ospfv3VirtNbrEntry 1 }
-
- ospfv3VirtNbrRtrId OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A 32-bit integer uniquely identifying the
-             neighboring router in the Autonomous System."
-         ::= { ospfv3VirtNbrEntry 2 }
-
- ospfv3VirtNbrIfIndex OBJECT-TYPE
-         SYNTAX          InterfaceIndex
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The local Interface ID for the virtual link over
-             which the neighbor can be reached."
-         ::= { ospfv3VirtNbrEntry 3 }
-
- ospfv3VirtNbrIfInstId OBJECT-TYPE
-         SYNTAX          Ospfv3IfInstIdTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The interface instance for the virtual link over
-             which the neighbor can be reached."
-         ::= { ospfv3VirtNbrEntry 4 }
-
- ospfv3VirtNbrAddressType OBJECT-TYPE
-         SYNTAX          InetAddressType
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The address type of ospfv3VirtNbrAddress.  Only IPv6
-             addresses without zone index are expected."
-         ::= { ospfv3VirtNbrEntry 5 }
-
- ospfv3VirtNbrAddress OBJECT-TYPE
-         SYNTAX          InetAddress
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The IPv6 address advertised by this virtual neighbor.
-             It must be a global scope address."
-         ::= { ospfv3VirtNbrEntry 6 }
-
- ospfv3VirtNbrOptions OBJECT-TYPE
-         SYNTAX          Integer32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "A bit mask corresponding to the neighbor's options
-             field."
-         REFERENCE
-             "OSPF for IPv6, Appendix A.2, The Options Field"
-         ::= { ospfv3VirtNbrEntry 7 }
-
- ospfv3VirtNbrState OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         down(1),
-                         attempt(2),
-                         init(3),
-                         twoWay(4),
-                         exchangeStart(5),
-                         exchange(6),
-                         loading(7),
-                         full(8)
-                         }
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The state of the virtual neighbor relationship."
-         ::= { ospfv3VirtNbrEntry 8 }
-
- ospfv3VirtNbrEvents OBJECT-TYPE
-         SYNTAX          Counter32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The number of times this virtual link has
-             changed its state or an error has occurred.
-
-             Discontinuities in the value of this counter
-             can occur at re-initialization of the management
-             system and at other times as indicated by the
-             value of ospfv3DiscontinuityTime."
-         ::= { ospfv3VirtNbrEntry 9 }
-
- ospfv3VirtNbrLsRetransQLen OBJECT-TYPE
-         SYNTAX          Gauge32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The current length of the retransmission
-             queue."
-         ::= { ospfv3VirtNbrEntry 10 }
-
- ospfv3VirtNbrHelloSuppressed OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "Indicates whether Hellos are being suppressed
-             to the neighbor."
-         ::= { ospfv3VirtNbrEntry 11 }
-
- ospfv3VirtNbrIfId OBJECT-TYPE
-         SYNTAX          InterfaceIndex
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The Interface ID that the neighbor advertises
-             in its Hello packets on this virtual link, that is,
-             the neighbor's local Interface ID."
-         ::= { ospfv3VirtNbrEntry 12 }
-
-ospfv3VirtNbrRestartHelperStatus OBJECT-TYPE
-        SYNTAX       INTEGER { notHelping(1),
-                               helping(2)
-                             }
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-            "Indicates whether the router is acting
-            as a graceful restart helper for the neighbor."
-           ::= { ospfv3VirtNbrEntry 13 }
-
- ospfv3VirtNbrRestartHelperAge OBJECT-TYPE
-        SYNTAX       Ospfv3UpToRefreshIntervalTC
-        UNITS        "seconds"
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-            "Remaining time in the current OSPF graceful restart
-            interval, if the router is acting as a restart
-            helper for the neighbor."
-        ::= { ospfv3VirtNbrEntry 14 }
-
- ospfv3VirtNbrRestartHelperExitReason OBJECT-TYPE
-        SYNTAX       INTEGER { none(1),
-                               inProgress(2),
-                               completed(3),
-                               timedOut(4),
-                               topologyChanged(5)
-                             }
-        MAX-ACCESS   read-only
-        STATUS       current
-        DESCRIPTION
-            "Describes the outcome of the last attempt at acting
-            as a graceful restart helper for the neighbor.
-
-            none:            no restart has yet been attempted.
-            inProgress:      a restart attempt is currently underway.
-            completed:       the last restart completed successfully.
-            timedOut:        the last restart timed out.
-            topologyChanged: the last restart was aborted due to
-                             a topology change."
-     ::= { ospfv3VirtNbrEntry 15 }
-
- --
- -- The OSPFv3 Area Aggregate Table
- --
-
- ospfv3AreaAggregateTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3AreaAggregateEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Area Aggregate Table acts as an adjunct
-             to the Area Table.  It describes those address
-             aggregates that are configured to be propagated
-             from an area.  Its purpose is to reduce the amount
-             of information that is known beyond an area's
-             borders.
-
-             A range of IPv6 prefixes specified by a
-             prefix / prefix length pair.  Note that if
-             ranges are configured such that one range
-             subsumes another range, the most specific
-             match is the preferred one."
-         ::= { ospfv3Objects 12 }
-
- ospfv3AreaAggregateEntry OBJECT-TYPE
-         SYNTAX          Ospfv3AreaAggregateEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A single area aggregate entry.
-
-             Information in this table is persistent, and
-             when this object is written, the entity SHOULD
-             save the change to non-volatile storage."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         INDEX           { ospfv3AreaAggregateAreaID,
-                           ospfv3AreaAggregateAreaLsdbType,
-                           ospfv3AreaAggregatePrefixType,
-                           ospfv3AreaAggregatePrefix,
-                           ospfv3AreaAggregatePrefixLength }
-         ::= { ospfv3AreaAggregateTable 1 }
-
- Ospfv3AreaAggregateEntry ::= SEQUENCE {
-         ospfv3AreaAggregateAreaID
-                 Ospfv3AreaIdTC,
-         ospfv3AreaAggregateAreaLsdbType
-                 INTEGER,
-         ospfv3AreaAggregatePrefixType
-                 InetAddressType,
-         ospfv3AreaAggregatePrefix
-                 InetAddress,
-         ospfv3AreaAggregatePrefixLength
-                 InetAddressPrefixLength,
-         ospfv3AreaAggregateRowStatus
-                 RowStatus,
-         ospfv3AreaAggregateEffect
-                 INTEGER,
-         ospfv3AreaAggregateRouteTag
-                 Unsigned32
-         }
-
- ospfv3AreaAggregateAreaID OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The area the Address Aggregate is to be found
-             within."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         ::= { ospfv3AreaAggregateEntry 1 }
-
- ospfv3AreaAggregateAreaLsdbType OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         interAreaPrefixLsa(8195), -- 0x2003
-                         nssaExternalLsa(8199)     -- 0x2007
-                         }
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The type of the Address Aggregate.  This field
-             specifies the Area LSDB type that this Address
-             Aggregate applies to."
-         REFERENCE
-             "OSPF Version 2, Appendix A.4.1, The LSA header"
-         ::= { ospfv3AreaAggregateEntry 2 }
-
- ospfv3AreaAggregatePrefixType OBJECT-TYPE
-         SYNTAX          InetAddressType
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The prefix type of ospfv3AreaAggregatePrefix.  Only
-             IPv6 addresses are expected."
-         ::= { ospfv3AreaAggregateEntry 3 }
-
- ospfv3AreaAggregatePrefix OBJECT-TYPE
-         SYNTAX          InetAddress (SIZE (0..16))
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The IPv6 prefix."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         ::= { ospfv3AreaAggregateEntry 4 }
-
- ospfv3AreaAggregatePrefixLength OBJECT-TYPE
-         SYNTAX          InetAddressPrefixLength (3..128)
-         UNITS           "bits"
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The length of the prefix (in bits).  A prefix can
-             not be shorter than 3 bits."
-         REFERENCE
-             "OSPF Version 2, Appendix C.2, Area parameters"
-         ::= { ospfv3AreaAggregateEntry 5 }
-
- ospfv3AreaAggregateRowStatus OBJECT-TYPE
-         SYNTAX          RowStatus
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "This object permits management of the table by
-             facilitating actions such as row creation,
-             construction, and destruction.
-
-             The value of this object has no effect on
-             whether other objects in this conceptual row can be
-             modified."
-         ::= { ospfv3AreaAggregateEntry 6 }
-
- ospfv3AreaAggregateEffect OBJECT-TYPE
-         SYNTAX          INTEGER {
-                         advertiseMatching(1),
-                         doNotAdvertiseMatching(2)
-                         }
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "Prefixes subsumed by ranges will either trigger the
-             advertisement of the indicated aggregate
-             (advertiseMatching) or result in the prefix not
-             being advertised at all outside the area."
-         DEFVAL          { advertiseMatching }
-         ::= { ospfv3AreaAggregateEntry 7 }
-
- ospfv3AreaAggregateRouteTag OBJECT-TYPE
-         SYNTAX          Unsigned32
-         MAX-ACCESS      read-create
-         STATUS          current
-         DESCRIPTION
-             "This tag is advertised only in the summarized
-             As-External LSA when summarizing from NSSA-LSAs to
-             AS-External-LSAs."
-         DEFVAL         { 0 }
-         ::= { ospfv3AreaAggregateEntry 8 }
-
- -- OSPFv3 Link-Scope Link State Database, for virtual interfaces
-
- ospfv3VirtLinkLsdbTable OBJECT-TYPE
-         SYNTAX          SEQUENCE OF Ospfv3VirtLinkLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The OSPFv3 Process's Link-scope LSDB for virtual
-             interfaces.  The LSDB contains the Link-scope link
-             state advertisements from virtual interfaces."
-         ::= { ospfv3Objects 13 }
-
- ospfv3VirtLinkLsdbEntry OBJECT-TYPE
-         SYNTAX          Ospfv3VirtLinkLsdbEntry
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "A single Link-scope link state advertisement
-             for a virtual interface."
-         INDEX           { ospfv3VirtLinkLsdbIfAreaId,
-                           ospfv3VirtLinkLsdbIfNeighbor,
-                           ospfv3VirtLinkLsdbType,
-                           ospfv3VirtLinkLsdbRouterId,
-                           ospfv3VirtLinkLsdbLsid }
-         ::= { ospfv3VirtLinkLsdbTable 1 }
-
- Ospfv3VirtLinkLsdbEntry ::= SEQUENCE {
-         ospfv3VirtLinkLsdbIfAreaId
-                 Ospfv3AreaIdTC,
-         ospfv3VirtLinkLsdbIfNeighbor
-                 Ospfv3RouterIdTC,
-         ospfv3VirtLinkLsdbType
-                 Unsigned32,
-         ospfv3VirtLinkLsdbRouterId
-                 Ospfv3RouterIdTC,
-         ospfv3VirtLinkLsdbLsid
-                 Ospfv3LsIdTC,
-         ospfv3VirtLinkLsdbSequence
-                 Ospfv3LsaSequenceTC,
-         ospfv3VirtLinkLsdbAge
-                 Ospfv3LsaAgeTC,
-         ospfv3VirtLinkLsdbChecksum
-                 Integer32,
-         ospfv3VirtLinkLsdbAdvertisement
-                 OCTET STRING,
-         ospfv3VirtLinkLsdbTypeKnown
-                 TruthValue
-         }
-
- ospfv3VirtLinkLsdbIfAreaId OBJECT-TYPE
-         SYNTAX          Ospfv3AreaIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The transit area that the virtual link
-             traverses.  By definition, this is not
-             Area 0."
-         ::= { ospfv3VirtLinkLsdbEntry 1 }
-
- ospfv3VirtLinkLsdbIfNeighbor OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The Router ID of the virtual neighbor."
-         ::= { ospfv3VirtLinkLsdbEntry 2 }
-
- ospfv3VirtLinkLsdbType OBJECT-TYPE
-         SYNTAX          Unsigned32(0..'FFFFFFFF'h)
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The type of the link state advertisement.
-             Each link state type has a separate
-             advertisement format.  Link-scope LSAs unrecognized
-             by the router are also stored in this database."
-         ::= { ospfv3VirtLinkLsdbEntry 3 }
-
- ospfv3VirtLinkLsdbRouterId OBJECT-TYPE
-         SYNTAX          Ospfv3RouterIdTC
-         MAX-ACCESS      not-accessible
-         STATUS          current
-         DESCRIPTION
-             "The 32-bit number that uniquely identifies the
-             originating router in the Autonomous System."
-         REFERENCE
-             "OSPF Version 2, Appendix C.1, Global parameters"
-         ::= { ospfv3VirtLinkLsdbEntry 4 }
-
- ospfv3VirtLinkLsdbLsid OBJECT-TYPE
-         SYNTAX        Ospfv3LsIdTC
-         MAX-ACCESS    not-accessible
-         STATUS        current
-         DESCRIPTION
-             "The Link State ID is an LS type-specific field
-             containing a unique identifier;
-             it identifies the piece of the routing domain
-             that is being described by the advertisement.
-             In contrast to OSPFv2, the LSID has no
-             addressing semantics."
-         ::= { ospfv3VirtLinkLsdbEntry 5 }
-
- -- Note that the OSPF sequence number is a 32-bit signed
- -- integer.  It starts with the value '80000001'h
- -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h.
- -- Thus, a typical sequence number will be very negative.
-
- ospfv3VirtLinkLsdbSequence OBJECT-TYPE
-         SYNTAX          Ospfv3LsaSequenceTC
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The sequence number field is a signed 32-bit
-             integer.  It is used to detect old and duplicate
-             link state advertisements.  The space of
-             sequence numbers is linearly ordered.  The
-             larger the sequence number, the more recent the
-             advertisement."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.6, LS sequence
-             number"
-         ::= { ospfv3VirtLinkLsdbEntry 6 }
-
- ospfv3VirtLinkLsdbAge OBJECT-TYPE
-         SYNTAX          Ospfv3LsaAgeTC
-         UNITS           "seconds"
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the age of the link state
-             advertisement in seconds.  The high-order bit
-             of the LS age field is considered the DoNotAge
-             bit for support of on-demand circuits."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.1, LS age;
-              Extending OSPF to Support Demand Circuits,
-              Section 2.2, The LS age field."
-         ::= { ospfv3VirtLinkLsdbEntry 7 }
-
- ospfv3VirtLinkLsdbChecksum OBJECT-TYPE
-         SYNTAX          Integer32
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "This field is the checksum of the complete
-             contents of the advertisement, excepting the
-             age field.  The age field is excepted so that
-             an advertisement's age can be incremented
-             without updating the checksum.  The checksum
-             used is the same that is used for ISO
-             connectionless datagrams; it is commonly
-             referred to as the Fletcher checksum."
-         REFERENCE
-             "OSPF Version 2, Section 12.1.7, LS checksum"
-         ::= { ospfv3VirtLinkLsdbEntry 8 }
-
- ospfv3VirtLinkLsdbAdvertisement OBJECT-TYPE
-         SYNTAX          OCTET STRING (SIZE (1..65535))
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The entire link state advertisement, including
-             its header."
-         ::= { ospfv3VirtLinkLsdbEntry 9 }
-
- ospfv3VirtLinkLsdbTypeKnown OBJECT-TYPE
-         SYNTAX          TruthValue
-         MAX-ACCESS      read-only
-         STATUS          current
-         DESCRIPTION
-             "The value true (1) indicates that the LSA type is
-             recognized by this router."
-         ::= { ospfv3VirtLinkLsdbEntry 10 }
-
- -- The Ospfv3 Notification Table
-
- -- The Ospfv3 Notification Table records fields that are
- -- required for notifications.
-
- ospfv3NotificationEntry OBJECT IDENTIFIER
-         ::= { ospfv3Objects 14 }
-
- ospfv3ConfigErrorType OBJECT-TYPE
-     SYNTAX       INTEGER {
-                     badVersion(1),
-                     areaMismatch(2),
-                     unknownNbmaNbr(3), -- Router is DR eligible
-                     unknownVirtualNbr(4),
-                     helloIntervalMismatch(5),
-                     deadIntervalMismatch(6),
-                     optionMismatch(7),
-                     mtuMismatch(8),
-                     duplicateRouterId(9),
-                     noError(10) }
-     MAX-ACCESS   accessible-for-notify
-     STATUS   current
-     DESCRIPTION
-         "Potential types of configuration conflicts.
-         Used by the ospfv3ConfigError and
-         ospfv3ConfigVirtError notifications."
-     ::= { ospfv3NotificationEntry 1 }
-
- ospfv3PacketType OBJECT-TYPE
-     SYNTAX       INTEGER {
-                     hello(1),
-                     dbDescript(2),
-                     lsReq(3),
-                     lsUpdate(4),
-                     lsAck(5),
-                     nullPacket(6) }
-     MAX-ACCESS   accessible-for-notify
-     STATUS       current
-     DESCRIPTION
-         "OSPFv3 packet types."
-     ::= { ospfv3NotificationEntry 2 }
-
- ospfv3PacketSrc  OBJECT-TYPE
-     SYNTAX       InetAddressIPv6
-     MAX-ACCESS   accessible-for-notify
-     STATUS       current
-     DESCRIPTION
-         "The IPv6 address of an inbound packet that cannot
-         be identified by a neighbor instance.
-
-         Only IPv6 addresses without zone index are expected."
-     ::= { ospfv3NotificationEntry 3 }
-
- -- Notification Definitions
-
- -- The notifications need to be throttled so as to not overwhelm the
- -- management agent in case of rapid changes to the OSPFv3 module.
-
-ospfv3VirtIfStateChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId,  -- The originator of the notification
-               ospfv3VirtIfState  -- The new state
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3VirtIfStateChange notification signifies that
-         there has been a change in the state of an OSPFv3 virtual
-         interface.
-
-         This notification should be generated when the interface
-         state regresses (e.g., goes from Point-to-Point to Down)
-         or progresses to a terminal state (i.e., Point-to-Point)."
-     ::= { ospfv3Notifications 1 }
-
-ospfv3NbrStateChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-               ospfv3NbrState  -- The new state
-
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3NbrStateChange notification signifies that
-         there has been a change in the state of a
-         non-virtual OSPFv3 neighbor.  This notification should be
-         generated when the neighbor state regresses
-         (e.g., goes from Attempt or Full to 1-Way or
-         Down) or progresses to a terminal state (e.g.,
-         2-Way or Full).  When a neighbor transitions
-         from or to Full on non-broadcast multi-access
-         and broadcast networks, the notification should be
-         generated by the Designated Router.  A Designated
-         Router transitioning to Down will be noted by
-         ospfIfStateChange."
-     ::= { ospfv3Notifications 2 }
-
-ospfv3VirtNbrStateChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-               ospfv3VirtNbrState  -- The new state
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3VirtNbrStateChange notification signifies
-         that there has been a change in the state of an OSPFv3
-         virtual neighbor.  This notification should be generated
-         when the neighbor state regresses (e.g., goes
-         from Attempt or Full to 1-Way or Down) or
-         progresses to a terminal state (e.g., Full)."
-     ::= { ospfv3Notifications 3 }
-
-ospfv3IfConfigError NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-        ospfv3IfState,         -- State of the interface
-        ospfv3PacketSrc,       -- IPv6 address of source
-        ospfv3ConfigErrorType, -- Type of error
-        ospfv3PacketType       -- Type of packet
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3IfConfigError notification signifies that a
-         packet has been received on a non-virtual
-         interface from a router whose configuration
-         parameters conflict with this router's
-         configuration parameters.  Note that the event
-         optionMismatch should cause a notification only if it
-         prevents an adjacency from forming."
-     ::= { ospfv3Notifications 4 }
-
-ospfv3VirtIfConfigError NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-        ospfv3VirtIfState,     -- State of the interface
-        ospfv3ConfigErrorType, -- Type of error
-        ospfv3PacketType
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3VirtIfConfigError notification signifies that a
-         packet has been received on a virtual interface
-         from a router whose configuration parameters
-         conflict with this router's configuration
-         parameters.  Note that the event optionMismatch
-         should cause a notification only if it prevents an
-         adjacency from forming."
-     ::= { ospfv3Notifications 5 }
-
-ospfv3IfRxBadPacket NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-        ospfv3IfState,         -- State of the interface
-        ospfv3PacketSrc,       -- The source IPv6 address
-        ospfv3PacketType       -- Type of packet
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3IfRxBadPacket notification signifies that an
-         OSPFv3 packet that cannot be parsed has been received on a
-         non-virtual interface."
-     ::= { ospfv3Notifications 6 }
-
-ospfv3VirtIfRxBadPacket NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-       ospfv3VirtIfState,      -- State of the interface
-       ospfv3PacketType        -- Type of packet
-       }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3VirtIfRxBadPacket notification signifies
-         that an OSPFv3 packet that cannot be parsed has been
-         received on a virtual interface."
-     ::= { ospfv3Notifications 7 }
-
-ospfv3LsdbOverflow NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-        ospfv3ExtAreaLsdbLimit -- Limit on External LSAs
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3LsdbOverflow notification signifies that the
-         number of LSAs in the router's link state
-         database has exceeded ospfv3ExtAreaLsdbLimit."
-     ::= { ospfv3Notifications 8 }
-
-ospfv3LsdbApproachingOverflow NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-        ospfv3ExtAreaLsdbLimit
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3LsdbApproachingOverflow notification signifies
-         that the number of LSAs in the router's
-         link state database has exceeded ninety percent of
-         ospfv3ExtAreaLsdbLimit."
-     ::= { ospfv3Notifications 9 }
-
-ospfv3IfStateChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-        ospfv3IfState   -- The new state
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3IfStateChange notification signifies that there
-         has been a change in the state of a non-virtual
-         OSPFv3 interface.  This notification should be generated
-         when the interface state regresses (e.g., goes
-         from DR to Down) or progresses to a terminal
-         state (i.e., Point-to-Point, DR Other, DR, or
-         Backup)."
-     ::= { ospfv3Notifications 10 }
-
-ospfv3NssaTranslatorStatusChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-        ospfv3AreaNssaTranslatorState  -- new state
-        }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3NssaTranslatorStatusChange notification
-         indicates that there has been a change in the router's
-         ability to translate OSPFv3 NSSA LSAs into OSPFv3 External
-         LSAs.  This notification should be generated when the
-         Translator Status transitions from or to any defined
-         status on a per-area basis."
-     ::= { ospfv3Notifications 11 }
-
-ospfv3RestartStatusChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-               ospfv3RestartStatus,  -- new status
-               ospfv3RestartInterval,
-               ospfv3RestartExitReason
-             }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3RestartStatusChange notification signifies that
-         there has been a change in the graceful restart
-         state for the router.  This notification should be
-         generated when the router restart status
-         changes."
-     ::= { ospfv3Notifications 12 }
-
-ospfv3NbrRestartHelperStatusChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-               ospfv3NbrRestartHelperStatus,  -- new status
-               ospfv3NbrRestartHelperAge,
-               ospfv3NbrRestartHelperExitReason
-             }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3NbrRestartHelperStatusChange notification
-         signifies that there has been a change in the
-         graceful restart helper state for the neighbor.
-         This notification should be generated when the
-         neighbor restart helper status transitions for a neighbor."
-     ::= { ospfv3Notifications 13 }
-
-ospfv3VirtNbrRestartHelperStatusChange NOTIFICATION-TYPE
-     OBJECTS { ospfv3RouterId, -- The originator of the notification
-               ospfv3VirtNbrRestartHelperStatus,  -- new status
-               ospfv3VirtNbrRestartHelperAge,
-               ospfv3VirtNbrRestartHelperExitReason
-             }
-     STATUS       current
-     DESCRIPTION
-         "An ospfv3VirtNbrRestartHelperStatusChange
-         notification signifies that there has been a
-         change in the graceful restart helper state for
-         the virtual neighbor.  This notification should be
-         generated when the virtual neighbor restart helper status
-         transitions for a virtual neighbor."
-     ::= { ospfv3Notifications 14 }
-
- -- Conformance Information
-
- ospfv3Groups      OBJECT IDENTIFIER ::= { ospfv3Conformance 1 }
- ospfv3Compliances OBJECT IDENTIFIER ::= { ospfv3Conformance 2 }
-
- -- Compliance Statements
-
- ospfv3FullCompliance MODULE-COMPLIANCE
-         STATUS          current
-         DESCRIPTION     "The compliance statement"
-         MODULE          -- this module
-         MANDATORY-GROUPS {
-                         ospfv3BasicGroup,
-                         ospfv3AreaGroup,
-                         ospfv3IfGroup,
-                         ospfv3VirtIfGroup,
-                         ospfv3NbrGroup,
-                         ospfv3CfgNbrGroup,
-                         ospfv3VirtNbrGroup,
-                         ospfv3AreaAggregateGroup
-                         }
-
-         GROUP           ospfv3AsLsdbGroup
-         DESCRIPTION
-             "This group is required for OSPFv3 systems that
-             display their AS-scope link state database."
-
-         GROUP           ospfv3AreaLsdbGroup
-         DESCRIPTION
-             "This group is required for OSPFv3 systems that
-             display their Area-scope link state database."
-
-         GROUP           ospfv3LinkLsdbGroup
-         DESCRIPTION
-             "This group is required for OSPFv3 systems that
-             display their Link-scope link state database
-             for non-virtual interfaces."
-
-         GROUP           ospfv3VirtLinkLsdbGroup
-         DESCRIPTION
-             "This group is required for OSPFv3 systems that
-             display their Link-scope link state database
-             for virtual interfaces."
-
-         GROUP           ospfv3HostGroup
-         DESCRIPTION
-             "This group is required for OSPFv3 systems that
-             support attached hosts."
-
-         GROUP           ospfv3NotificationObjectGroup
-         DESCRIPTION
-             "This group is required for OSPFv3 systems that
-             support OSPFv3 notifications."
-
-         GROUP           ospfv3NotificationGroup
-         DESCRIPTION
-             "This group is required for OSPFv3 systems that
-             support OSPFv3 notifications."
-
-         OBJECT          ospfv3NbrAddressType
-         SYNTAX          InetAddressType { ipv6(2) }
-         DESCRIPTION
-             "An implementation is only required to support IPv6
-             address without zone index."
-
-         OBJECT          ospfv3NbrAddress
-         SYNTAX          InetAddress (SIZE (16))
-         DESCRIPTION
-             "An implementation is only required to support IPv6
-             address without zone index."
-
-         OBJECT          ospfv3VirtNbrAddressType
-         SYNTAX          InetAddressType { ipv6(2) }
-         DESCRIPTION
-             "An implementation is only required to support IPv6
-             address without zone index."
-
-         OBJECT          ospfv3VirtNbrAddress
-         SYNTAX          InetAddress (SIZE (16))
-         DESCRIPTION
-             "An implementation is only required to support IPv6
-             address without zone index."
-         ::= { ospfv3Compliances 1 }
-
-    ospfv3ReadOnlyCompliance MODULE-COMPLIANCE
-       STATUS     current
-       DESCRIPTION
-               "When this MIB module is implemented without
-               support for read-create (i.e., in read-only
-               mode), the implementation can claim read-only
-               compliance.  Such a device can then be monitored,
-               but cannot be configured with this MIB."
-
-       MODULE -- this module
-            MANDATORY-GROUPS {
-                    ospfv3BasicGroup,
-                    ospfv3AreaGroup,
-                    ospfv3IfGroup,
-                    ospfv3VirtIfGroup,
-                    ospfv3NbrGroup,
-                    ospfv3CfgNbrGroup,
-                    ospfv3VirtNbrGroup,
-                    ospfv3AreaAggregateGroup
-                    }
-
-       GROUP           ospfv3AsLsdbGroup
-       DESCRIPTION
-           "This group is required for OSPFv3 systems that
-           display their AS-scope link state database."
-
-       GROUP           ospfv3AreaLsdbGroup
-       DESCRIPTION
-           "This group is required for OSPFv3 systems that
-           display their Area-scope link state database."
-
-       GROUP           ospfv3LinkLsdbGroup
-       DESCRIPTION
-           "This group is required for OSPFv3 systems that
-           display their Link-scope link state database
-           for non-virtual interfaces."
-
-       GROUP           ospfv3VirtLinkLsdbGroup
-       DESCRIPTION
-           "This group is required for OSPFv3 systems that
-           display their Link-scope link state database
-           for virtual interfaces."
-
-       GROUP           ospfv3HostGroup
-       DESCRIPTION
-           "This group is required for OSPFv3 systems that
-           support attached hosts."
-
-       GROUP           ospfv3NotificationObjectGroup
-       DESCRIPTION
-           "This group is required for OSPFv3 systems that
-           support OSPFv3 notifications."
-
-       GROUP           ospfv3NotificationGroup
-       DESCRIPTION
-           "This group is required for OSPFv3 systems that
-           support OSPFv3 notifications."
-
-       OBJECT ospfv3RouterId
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AdminStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3ExtAreaLsdbLimit
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3ExitOverflowInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3DemandExtensions
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3ReferenceBandwidth
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3RestartSupport
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3RestartInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3RestartStrictLsaChecking
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3NotificationEnable
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3StubRouterAdvertisement
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaImportAsExtern
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaSummary
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaRowStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaStubMetric
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaNssaTranslatorRole
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaNssaTranslatorStabInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaStubMetricType
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaTEEnabled
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3HostMetric
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3HostRowStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3HostAreaID
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfAreaId
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfType
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfAdminStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfRtrPriority
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfTransitDelay
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfRetransInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfHelloInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfRtrDeadInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfPollInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfRowStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfDemand
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfMetricValue
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfDemandNbrProbe
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfDemandNbrProbeRetransLimit
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfDemandNbrProbeInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfTEDisabled
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3IfLinkLSASuppression
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3VirtIfTransitDelay
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3VirtIfRetransInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3VirtIfHelloInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3VirtIfRtrDeadInterval
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3VirtIfRowStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3CfgNbrPriority
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3CfgNbrRowStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaAggregateRowStatus
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaAggregateEffect
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-
-       OBJECT ospfv3AreaAggregateRouteTag
-       MIN-ACCESS read-only
-       DESCRIPTION
-            "Write access is not required."
-    ::= { ospfv3Compliances 2 }
-
- -- units of conformance
-
- ospfv3BasicGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3RouterId,
-                         ospfv3AdminStatus,
-                         ospfv3VersionNumber,
-                         ospfv3AreaBdrRtrStatus,
-                         ospfv3ASBdrRtrStatus,
-                         ospfv3AsScopeLsaCount,
-                         ospfv3AsScopeLsaCksumSum,
-                         ospfv3OriginateNewLsas,
-                         ospfv3RxNewLsas,
-                         ospfv3ExtLsaCount,
-                         ospfv3ExtAreaLsdbLimit,
-                         ospfv3ExitOverflowInterval,
-                         ospfv3DemandExtensions,
-                         ospfv3ReferenceBandwidth,
-                         ospfv3RestartSupport,
-                         ospfv3RestartInterval,
-                         ospfv3RestartStrictLsaChecking,
-                         ospfv3RestartStatus,
-                         ospfv3RestartAge,
-                         ospfv3RestartExitReason,
-                         ospfv3NotificationEnable,
-                         ospfv3StubRouterSupport,
-                         ospfv3StubRouterAdvertisement,
-                         ospfv3DiscontinuityTime,
-                         ospfv3RestartTime
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used for managing/monitoring
-             OSPFv3 global parameters."
-         ::= { ospfv3Groups 1 }
-
- ospfv3AreaGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3AreaImportAsExtern,
-                         ospfv3AreaSpfRuns,
-                         ospfv3AreaBdrRtrCount,
-                         ospfv3AreaAsBdrRtrCount,
-                         ospfv3AreaScopeLsaCount,
-                         ospfv3AreaScopeLsaCksumSum,
-                         ospfv3AreaSummary,
-                         ospfv3AreaRowStatus,
-                         ospfv3AreaStubMetric,
-                         ospfv3AreaNssaTranslatorRole,
-                         ospfv3AreaNssaTranslatorState,
-                         ospfv3AreaNssaTranslatorStabInterval,
-                         ospfv3AreaNssaTranslatorEvents,
-                         ospfv3AreaStubMetricType,
-                         ospfv3AreaTEEnabled
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used for OSPFv3 systems
-             supporting areas."
-         ::= { ospfv3Groups 2 }
-
- ospfv3AsLsdbGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3AsLsdbSequence,
-                         ospfv3AsLsdbAge,
-                         ospfv3AsLsdbChecksum,
-                         ospfv3AsLsdbAdvertisement,
-                         ospfv3AsLsdbTypeKnown
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used for OSPFv3 systems
-             that display their AS-scope link state database."
-         ::= { ospfv3Groups 3 }
-
- ospfv3AreaLsdbGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3AreaLsdbSequence,
-                         ospfv3AreaLsdbAge,
-                         ospfv3AreaLsdbChecksum,
-                         ospfv3AreaLsdbAdvertisement,
-                         ospfv3AreaLsdbTypeKnown
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used for OSPFv3 systems
-             that display their Area-scope link state database."
-         ::= { ospfv3Groups 4 }
-
- ospfv3LinkLsdbGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3LinkLsdbSequence,
-                         ospfv3LinkLsdbAge,
-                         ospfv3LinkLsdbChecksum,
-                         ospfv3LinkLsdbAdvertisement,
-                         ospfv3LinkLsdbTypeKnown
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used for OSPFv3 systems
-             that display their Link-scope link state database
-             for non-virtual interfaces."
-         ::= { ospfv3Groups 5 }
-
- ospfv3HostGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3HostMetric,
-                         ospfv3HostRowStatus,
-                         ospfv3HostAreaID
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used for OSPFv3 systems
-             that support attached hosts."
-         ::= { ospfv3Groups 6 }
-
- ospfv3IfGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3IfAreaId,
-                         ospfv3IfType,
-                         ospfv3IfAdminStatus,
-                         ospfv3IfRtrPriority,
-                         ospfv3IfTransitDelay,
-                         ospfv3IfRetransInterval,
-                         ospfv3IfHelloInterval,
-                         ospfv3IfRtrDeadInterval,
-                         ospfv3IfPollInterval,
-                         ospfv3IfState,
-                         ospfv3IfDesignatedRouter,
-                         ospfv3IfBackupDesignatedRouter,
-                         ospfv3IfEvents,
-                         ospfv3IfRowStatus,
-                         ospfv3IfDemand,
-                         ospfv3IfMetricValue,
-                         ospfv3IfLinkScopeLsaCount,
-                         ospfv3IfLinkLsaCksumSum,
-                         ospfv3IfDemandNbrProbe,
-                         ospfv3IfDemandNbrProbeRetransLimit,
-                         ospfv3IfDemandNbrProbeInterval,
-                         ospfv3IfTEDisabled,
-                         ospfv3IfLinkLSASuppression
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These interface objects are used for
-             managing/monitoring OSPFv3 interfaces."
-         ::= { ospfv3Groups 7 }
-
- ospfv3VirtIfGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3VirtIfIndex,
-                         ospfv3VirtIfInstId,
-                         ospfv3VirtIfTransitDelay,
-                         ospfv3VirtIfRetransInterval,
-                         ospfv3VirtIfHelloInterval,
-                         ospfv3VirtIfRtrDeadInterval,
-                         ospfv3VirtIfState,
-                         ospfv3VirtIfEvents,
-                         ospfv3VirtIfRowStatus,
-                         ospfv3VirtIfLinkScopeLsaCount,
-                         ospfv3VirtIfLinkLsaCksumSum
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These virtual interface objects are used for
-             managing/monitoring OSPFv3 virtual interfaces."
-         ::= { ospfv3Groups 8 }
-
- ospfv3NbrGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3NbrAddressType,
-                         ospfv3NbrAddress,
-                         ospfv3NbrOptions,
-                         ospfv3NbrPriority,
-                         ospfv3NbrState,
-                         ospfv3NbrEvents,
-                         ospfv3NbrLsRetransQLen,
-                         ospfv3NbrHelloSuppressed,
-                         ospfv3NbrIfId,
-                         ospfv3NbrRestartHelperStatus,
-                         ospfv3NbrRestartHelperAge,
-                         ospfv3NbrRestartHelperExitReason
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These neighbor objects are used for
-             managing/monitoring OSPFv3 neighbors."
-         ::= { ospfv3Groups 9 }
-
- ospfv3CfgNbrGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3CfgNbrPriority,
-                         ospfv3CfgNbrRowStatus
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These configured neighbor objects are used for
-             managing/monitoring OSPFv3-configured neighbors."
-         ::= { ospfv3Groups 10 }
-
- ospfv3VirtNbrGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3VirtNbrIfIndex,
-                         ospfv3VirtNbrIfInstId,
-                         ospfv3VirtNbrAddressType,
-                         ospfv3VirtNbrAddress,
-                         ospfv3VirtNbrOptions,
-                         ospfv3VirtNbrState,
-                         ospfv3VirtNbrEvents,
-                         ospfv3VirtNbrLsRetransQLen,
-                         ospfv3VirtNbrHelloSuppressed,
-                         ospfv3VirtNbrIfId,
-                         ospfv3VirtNbrRestartHelperStatus,
-                         ospfv3VirtNbrRestartHelperAge,
-                         ospfv3VirtNbrRestartHelperExitReason
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These virtual neighbor objects are used for
-             managing/monitoring OSPFv3 virtual neighbors."
-         ::= { ospfv3Groups 11 }
-
- ospfv3AreaAggregateGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3AreaAggregateRowStatus,
-                         ospfv3AreaAggregateEffect,
-                         ospfv3AreaAggregateRouteTag
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These area aggregate objects are required for
-             aggregating OSPFv3 prefixes for summarization
-             across areas."
-         ::= { ospfv3Groups 12 }
-
- ospfv3VirtLinkLsdbGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3VirtLinkLsdbSequence,
-                         ospfv3VirtLinkLsdbAge,
-                         ospfv3VirtLinkLsdbChecksum,
-                         ospfv3VirtLinkLsdbAdvertisement,
-                         ospfv3VirtLinkLsdbTypeKnown
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used for OSPFv3 systems
-             that display their Link-scope link state database
-             for virtual interfaces."
-         ::= { ospfv3Groups 13 }
-
- ospfv3NotificationObjectGroup OBJECT-GROUP
-         OBJECTS         {
-                         ospfv3ConfigErrorType,
-                         ospfv3PacketType,
-                         ospfv3PacketSrc
-                         }
-         STATUS          current
-         DESCRIPTION
-             "These objects are used to record notification
-             parameters."
-         ::= { ospfv3Groups 14 }
-
- ospfv3NotificationGroup NOTIFICATION-GROUP
-         NOTIFICATIONS   {
-                         ospfv3VirtIfStateChange,
-                         ospfv3NbrStateChange,
-                         ospfv3VirtNbrStateChange,
-                         ospfv3IfConfigError,
-                         ospfv3VirtIfConfigError,
-                         ospfv3IfRxBadPacket,
-                         ospfv3VirtIfRxBadPacket,
-                         ospfv3LsdbOverflow,
-                         ospfv3LsdbApproachingOverflow,
-                         ospfv3IfStateChange,
-                         ospfv3NssaTranslatorStatusChange,
-                         ospfv3RestartStatusChange,
-                         ospfv3NbrRestartHelperStatusChange,
-                         ospfv3VirtNbrRestartHelperStatusChange
-                         }
-         STATUS          current
-         DESCRIPTION
-             "This group is used for OSPFv3 notifications."
-         ::= { ospfv3Groups 15 }
-
- END
diff --git a/ospfd/OSPF-MIB.txt b/ospfd/OSPF-MIB.txt
deleted file mode 100644 (file)
index 217c1e5..0000000
+++ /dev/null
@@ -1,2723 +0,0 @@
-OSPF-MIB DEFINITIONS ::= BEGIN
-
-    IMPORTS
-            MODULE-IDENTITY, OBJECT-TYPE, Counter32, Gauge32,
-            Integer32, IpAddress
-                FROM SNMPv2-SMI
-            TEXTUAL-CONVENTION, TruthValue, RowStatus
-                FROM SNMPv2-TC
-            MODULE-COMPLIANCE, OBJECT-GROUP          FROM SNMPv2-CONF
-            mib-2                                    FROM RFC1213-MIB;
-
---  This MIB module uses the extended OBJECT-TYPE macro as
---  defined in [9].
-
-ospf MODULE-IDENTITY
-        LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995
-        ORGANIZATION "IETF OSPF Working Group"
-        CONTACT-INFO
-       "       Fred Baker
-       Postal: Cisco Systems
-               519 Lado Drive
-               Santa Barbara, California 93111
-       Tel:    +1 805 681 0115
-       E-Mail: fred@cisco.com
-
-               Rob Coltun
-       Postal: RainbowBridge Communications
-       Tel:    (301) 340-9416
-       E-Mail: rcoltun@rainbow-bridge.com"
-    DESCRIPTION
-       "The MIB module to describe the OSPF Version 2
-       Protocol"
-    ::= { mib-2 14 }
-
---  The Area ID, in OSPF, has the same format as an IP Address,
---  but has the function of defining a summarization point for
---  Link State Advertisements
-
-AreaID ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "An OSPF Area Identifier."
-    SYNTAX      IpAddress
-
-
---  The Router ID, in OSPF, has the same format as an IP Address,
---  but identifies the router independent of its IP Address.
-
-RouterID ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "A OSPF Router Identifier."
-    SYNTAX      IpAddress
-
-
---  The OSPF Metric is defined as an unsigned value in the range
-
-Metric ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "The OSPF Internal Metric."
-    SYNTAX      Integer32 (0..'FFFF'h)
-
-BigMetric ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "The OSPF External Metric."
-    SYNTAX      Integer32 (0..'FFFFFF'h)
-
---  Status Values
-
-Status ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "The status of an interface: 'enabled' indicates that
-       it is willing to communicate with other OSPF Routers,
-       while 'disabled' indicates that it is not."
-    SYNTAX      INTEGER { enabled (1), disabled (2) }
-
---  Time Durations measured in seconds
-
-PositiveInteger ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "A positive integer. Values in excess are precluded as
-       unnecessary and prone to interoperability issues."
-    SYNTAX      Integer32 (0..'7FFFFFFF'h)
-
-HelloRange ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "The range of intervals on which hello messages are
-       exchanged."
-    SYNTAX      Integer32 (1..'FFFF'h)
-
-UpToMaxAge ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "The values that one might find or configure for
-       variables bounded by the maximum age of an LSA."
-    SYNTAX      Integer32 (0..3600)
-
-
---  The range of ifIndex
-
-InterfaceIndex ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "The range of ifIndex."
-    SYNTAX      Integer32
-
-
---  Potential Priorities for the Designated Router Election
-
-DesignatedRouterPriority ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "The values defined for the priority of a system for
-       becoming the designated router."
-    SYNTAX      Integer32 (0..'FF'h)
-
-TOSType ::= TEXTUAL-CONVENTION
-    STATUS      current
-    DESCRIPTION
-       "Type of Service is defined as a mapping to the IP Type of
-       Service Flags as defined in the IP Forwarding Table MIB
-
-       +-----+-----+-----+-----+-----+-----+-----+-----+
-       |                 |                       |     |
-       |   PRECEDENCE    |    TYPE OF SERVICE    |  0  |
-       |                 |                       |     |
-       +-----+-----+-----+-----+-----+-----+-----+-----+
-
-                IP TOS                IP TOS
-           Field     Policy      Field     Policy
-
-           Contents    Code      Contents    Code
-           0 0 0 0  ==>   0      0 0 0 1  ==>   2
-           0 0 1 0  ==>   4      0 0 1 1  ==>   6
-           0 1 0 0  ==>   8      0 1 0 1  ==>  10
-           0 1 1 0  ==>  12      0 1 1 1  ==>  14
-           1 0 0 0  ==>  16      1 0 0 1  ==>  18
-           1 0 1 0  ==>  20      1 0 1 1  ==>  22
-           1 1 0 0  ==>  24      1 1 0 1  ==>  26
-           1 1 1 0  ==>  28      1 1 1 1  ==>  30
-
-       The remaining values are left for future definition."
-    SYNTAX      Integer32 (0..30)
-
-
---  OSPF General Variables
-
---      These parameters apply globally to the Router's
---      OSPF Process.
-
-ospfGeneralGroup OBJECT IDENTIFIER ::= { ospf 1 }
-
-
-    ospfRouterId OBJECT-TYPE
-        SYNTAX   RouterID
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "A  32-bit  integer  uniquely  identifying  the
-           router in the Autonomous System.
-
-           By  convention,  to  ensure  uniqueness,   this
-           should  default  to  the  value  of  one of the
-           router's IP interface addresses."
-       REFERENCE
-          "OSPF Version 2, C.1 Global parameters"
-      ::= { ospfGeneralGroup 1 }
-
-
-    ospfAdminStat OBJECT-TYPE
-        SYNTAX   Status
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "The  administrative  status  of  OSPF  in  the
-           router.   The  value 'enabled' denotes that the
-           OSPF Process is active on at least  one  inter-
-           face;  'disabled'  disables  it  on  all inter-
-           faces."
-       ::= { ospfGeneralGroup 2 }
-
-    ospfVersionNumber OBJECT-TYPE
-        SYNTAX   INTEGER    { version2 (2) }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The current version number of the OSPF  proto-
-           col is 2."
-       REFERENCE
-          "OSPF Version 2, Title"
-      ::= { ospfGeneralGroup 3 }
-
-
-    ospfAreaBdrRtrStatus OBJECT-TYPE
-        SYNTAX   TruthValue
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "A flag to note whether this router is an  area
-           border router."
-       REFERENCE
-          "OSPF Version 2, Section 3 Splitting the AS into
-          Areas"
-      ::= { ospfGeneralGroup 4 }
-
-
-    ospfASBdrRtrStatus OBJECT-TYPE
-        SYNTAX   TruthValue
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "A flag to note whether this router is  config-
-           ured as an Autonomous System border router."
-       REFERENCE
-          "OSPF Version 2, Section 3.3  Classification  of
-          routers"
-      ::= { ospfGeneralGroup 5 }
-
-    ospfExternLsaCount OBJECT-TYPE
-        SYNTAX   Gauge32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of external (LS type 5)  link-state
-           advertisements in the link-state database."
-       REFERENCE
-          "OSPF Version 2, Appendix A.4.5 AS external link
-          advertisements"
-      ::= { ospfGeneralGroup 6 }
-
-
-    ospfExternLsaCksumSum OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The 32-bit unsigned sum of the LS checksums of
-           the  external  link-state  advertisements  con-
-           tained in the link-state  database.   This  sum
-           can  be  used  to determine if there has been a
-           change in a router's link state  database,  and
-           to  compare  the  link-state  database  of  two
-           routers."
-       ::= { ospfGeneralGroup 7 }
-
-
-    ospfTOSSupport OBJECT-TYPE
-        SYNTAX   TruthValue
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "The router's support for type-of-service rout-
-           ing."
-       REFERENCE
-          "OSPF Version 2,  Appendix  F.1.2  Optional  TOS
-          support"
-      ::= { ospfGeneralGroup 8 }
-
-    ospfOriginateNewLsas OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of  new  link-state  advertisements
-           that  have been originated.  This number is in-
-           cremented each time the router originates a new
-           LSA."
-       ::= { ospfGeneralGroup 9 }
-
-
-    ospfRxNewLsas OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of  link-state  advertisements  re-
-           ceived  determined  to  be  new instantiations.
-           This number does not include  newer  instantia-
-           tions  of self-originated link-state advertise-
-           ments."
-       ::= { ospfGeneralGroup 10 }
-
-    ospfExtLsdbLimit OBJECT-TYPE
-        SYNTAX   Integer32 (-1..'7FFFFFFF'h)
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "The  maximum   number   of   non-default   AS-
-           external-LSAs entries that can be stored in the
-           link-state database.  If the value is -1,  then
-           there is no limit.
-
-           When the number of non-default AS-external-LSAs
-           in   a  router's  link-state  database  reaches
-           ospfExtLsdbLimit, the router  enters  Overflow-
-           State.   The   router  never  holds  more  than
-           ospfExtLsdbLimit  non-default  AS-external-LSAs
-           in  its  database. OspfExtLsdbLimit MUST be set
-           identically in all routers attached to the OSPF
-           backbone  and/or  any regular OSPF area. (i.e.,
-           OSPF stub areas and NSSAs are excluded)."
-       DEFVAL { -1 }
-       ::= { ospfGeneralGroup 11 }
-
-    ospfMulticastExtensions OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "A Bit Mask indicating whether  the  router  is
-           forwarding  IP  multicast  (Class  D) datagrams
-           based on the algorithms defined in  the  Multi-
-           cast Extensions to OSPF.
-
-           Bit 0, if set, indicates that  the  router  can
-           forward  IP multicast datagrams in the router's
-           directly attached areas (called intra-area mul-
-           ticast routing).
-
-           Bit 1, if set, indicates that  the  router  can
-           forward  IP  multicast  datagrams  between OSPF
-           areas (called inter-area multicast routing).
-
-           Bit 2, if set, indicates that  the  router  can
-           forward  IP  multicast  datagrams between Auto-
-           nomous Systems (called inter-AS multicast rout-
-           ing).
-
-           Only certain combinations of bit  settings  are
-           allowed,  namely: 0 (no multicast forwarding is
-           enabled), 1 (intra-area multicasting  only),  3
-           (intra-area  and  inter-area  multicasting),  5
-           (intra-area and inter-AS  multicasting)  and  7
-           (multicasting  everywhere). By default, no mul-
-           ticast forwarding is enabled."
-       DEFVAL { 0 }
-       ::= { ospfGeneralGroup 12 }
-
-    ospfExitOverflowInterval OBJECT-TYPE
-        SYNTAX   PositiveInteger
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "The number of  seconds  that,  after  entering
-           OverflowState,  a  router will attempt to leave
-           OverflowState. This allows the router to  again
-           originate  non-default  AS-external-LSAs.  When
-           set to 0, the router will not  leave  Overflow-
-           State until restarted."
-       DEFVAL { 0 }
-       ::= { ospfGeneralGroup 13 }
-
-
-    ospfDemandExtensions OBJECT-TYPE
-        SYNTAX   TruthValue
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "The router's support for demand routing."
-       REFERENCE
-          "OSPF Version 2, Appendix on Demand Routing"
-      ::= { ospfGeneralGroup 14 }
-
-
---      The OSPF Area Data Structure contains information
---      regarding the various areas. The interfaces and
---      virtual links are configured as part of these areas.
---      Area 0.0.0.0, by definition, is the Backbone Area
-
-
-    ospfAreaTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfAreaEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "Information describing the configured  parame-
-           ters  and cumulative statistics of the router's
-           attached areas."
-       REFERENCE
-          "OSPF Version 2, Section 6  The Area Data Struc-
-          ture"
-      ::= { ospf 2 }
-
-
-    ospfAreaEntry OBJECT-TYPE
-        SYNTAX   OspfAreaEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "Information describing the configured  parame-
-           ters  and  cumulative  statistics of one of the
-           router's attached areas."
-       INDEX { ospfAreaId }
-       ::= { ospfAreaTable 1 }
-
-OspfAreaEntry ::=
-    SEQUENCE {
-        ospfAreaId
-            AreaID,
-        ospfAuthType
-            Integer32,
-        ospfImportAsExtern
-            INTEGER,
-        ospfSpfRuns
-            Counter32,
-        ospfAreaBdrRtrCount
-            Gauge32,
-        ospfAsBdrRtrCount
-            Gauge32,
-        ospfAreaLsaCount
-            Gauge32,
-        ospfAreaLsaCksumSum
-            Integer32,
-        ospfAreaSummary
-            INTEGER,
-        ospfAreaStatus
-            RowStatus
-              }
-
-    ospfAreaId OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "A 32-bit integer uniquely identifying an area.
-           Area ID 0.0.0.0 is used for the OSPF backbone."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfAreaEntry 1 }
-
-
-    ospfAuthType OBJECT-TYPE
-        SYNTAX   Integer32
-                    -- none (0),
-                    -- simplePassword (1)
-                    -- md5 (2)
-                    -- reserved for specification by IANA (> 2)
-        MAX-ACCESS   read-create
-        STATUS   obsolete
-        DESCRIPTION
-           "The authentication type specified for an area.
-           Additional authentication types may be assigned
-           locally on a per Area basis."
-       REFERENCE
-          "OSPF Version 2, Appendix E Authentication"
-      DEFVAL { 0 }        -- no authentication, by default
-      ::= { ospfAreaEntry 2 }
-
-    ospfImportAsExtern OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    importExternal (1),
-                    importNoExternal (2),
-                    importNssa (3)
-                  }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The area's support for importing  AS  external
-           link- state advertisements."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      DEFVAL { importExternal }
-      ::= { ospfAreaEntry 3 }
-
-
-    ospfSpfRuns OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of times that the intra-area  route
-           table  has  been  calculated  using this area's
-           link-state database.  This  is  typically  done
-           using Dijkstra's algorithm."
-       ::= { ospfAreaEntry 4 }
-
-
-    ospfAreaBdrRtrCount OBJECT-TYPE
-        SYNTAX   Gauge32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The total number of area border routers reach-
-           able within this area.  This is initially zero,
-           and is calculated in each SPF Pass."
-       ::= { ospfAreaEntry 5 }
-
-    ospfAsBdrRtrCount OBJECT-TYPE
-        SYNTAX   Gauge32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The total number of Autonomous  System  border
-           routers  reachable  within  this area.  This is
-           initially zero, and is calculated in  each  SPF
-           Pass."
-       ::= { ospfAreaEntry 6 }
-
-
-    ospfAreaLsaCount OBJECT-TYPE
-        SYNTAX   Gauge32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The total number of link-state  advertisements
-           in  this  area's link-state database, excluding
-           AS External LSA's."
-       ::= { ospfAreaEntry 7 }
-
-
-    ospfAreaLsaCksumSum OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The 32-bit unsigned sum of the link-state  ad-
-           vertisements'  LS  checksums  contained in this
-           area's link-state database.  This sum  excludes
-           external (LS type 5) link-state advertisements.
-           The sum can be used to determine if  there  has
-           been  a  change  in a router's link state data-
-           base, and to compare the link-state database of
-           two routers."
-       DEFVAL   { 0 }
-       ::= { ospfAreaEntry 8 }
-
-    ospfAreaSummary OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    noAreaSummary (1),
-                    sendAreaSummary (2)
-                  }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The variable ospfAreaSummary controls the  im-
-           port  of  summary LSAs into stub areas.  It has
-           no effect on other areas.
-
-           If it is noAreaSummary, the router will neither
-           originate  nor  propagate summary LSAs into the
-           stub area.  It will rely entirely  on  its  de-
-           fault route.
-
-           If it is sendAreaSummary, the router will  both
-           summarize and propagate summary LSAs."
-       DEFVAL   { noAreaSummary }
-       ::= { ospfAreaEntry 9 }
-
-
-    ospfAreaStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfAreaEntry 10 }
-
-
---  OSPF Area Default Metric Table
-
---      The OSPF Area Default Metric Table describes the metrics
---      that a default Area Border Router will advertise into a
---      Stub area.
-
-
-    ospfStubAreaTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfStubAreaEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The set of metrics that will be advertised  by
-           a default Area Border Router into a stub area."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2, Area Parameters"
-      ::= { ospf 3 }
-
-
-    ospfStubAreaEntry OBJECT-TYPE
-        SYNTAX   OspfStubAreaEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The metric for a given Type  of  Service  that
-           will  be  advertised  by  a default Area Border
-           Router into a stub area."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2, Area Parameters"
-      INDEX { ospfStubAreaId, ospfStubTOS }
-      ::= { ospfStubAreaTable 1 }
-
-OspfStubAreaEntry ::=
-    SEQUENCE {
-        ospfStubAreaId
-            AreaID,
-        ospfStubTOS
-            TOSType,
-        ospfStubMetric
-            BigMetric,
-        ospfStubStatus
-            RowStatus,
-        ospfStubMetricType
-            INTEGER
-              }
-
-    ospfStubAreaId OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The 32 bit identifier for the Stub  Area.   On
-           creation,  this  can  be  derived  from the in-
-           stance."
-       ::= { ospfStubAreaEntry 1 }
-
-
-    ospfStubTOS OBJECT-TYPE
-        SYNTAX   TOSType
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The  Type  of  Service  associated  with   the
-           metric.   On creation, this can be derived from
-           the instance."
-       ::= { ospfStubAreaEntry 2 }
-
-
-    ospfStubMetric OBJECT-TYPE
-        SYNTAX   BigMetric
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The metric value applied at the indicated type
-           of  service.  By default, this equals the least
-           metric at the type of service among the  inter-
-           faces to other areas."
-       ::= { ospfStubAreaEntry 3 }
-
-
-    ospfStubStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfStubAreaEntry 4 }
-
-    ospfStubMetricType OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    ospfMetric (1),                -- OSPF Metric
-                    comparableCost (2),        -- external type 1
-                    nonComparable  (3)        -- external type 2
-                  }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the type of metric  ad-
-           vertised as a default route."
-       DEFVAL   { ospfMetric }
-       ::= { ospfStubAreaEntry 5 }
-
---  OSPF Link State Database
-
---      The Link State Database contains the Link State
---      Advertisements from throughout the areas that the
---      device is attached to.
-
-
-    ospfLsdbTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfLsdbEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The OSPF Process's Link State Database."
-       REFERENCE
-          "OSPF Version 2, Section 12  Link  State  Adver-
-          tisements"
-      ::= { ospf 4 }
-
-
-    ospfLsdbEntry OBJECT-TYPE
-        SYNTAX   OspfLsdbEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A single Link State Advertisement."
-       INDEX { ospfLsdbAreaId, ospfLsdbType,
-               ospfLsdbLsid, ospfLsdbRouterId }
-       ::= { ospfLsdbTable 1 }
-
-OspfLsdbEntry ::=
-    SEQUENCE {
-        ospfLsdbAreaId
-            AreaID,
-        ospfLsdbType
-            INTEGER,
-        ospfLsdbLsid
-            IpAddress,
-        ospfLsdbRouterId
-            RouterID,
-        ospfLsdbSequence
-            Integer32,
-        ospfLsdbAge
-            Integer32,
-        ospfLsdbChecksum
-            Integer32,
-        ospfLsdbAdvertisement
-            OCTET STRING
-              }
-    ospfLsdbAreaId OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The 32 bit identifier of the Area  from  which
-           the LSA was received."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfLsdbEntry 1 }
-
--- External Link State Advertisements are permitted
--- for backward compatibility, but should be displayed in
--- the ospfExtLsdbTable rather than here.
-
-    ospfLsdbType OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    routerLink (1),
-                    networkLink (2),
-                    summaryLink (3),
-                    asSummaryLink (4),
-                    asExternalLink (5), -- but see ospfExtLsdbTable
-                    multicastLink (6),
-                    nssaExternalLink (7)
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The type  of  the  link  state  advertisement.
-           Each  link state type has a separate advertise-
-           ment format."
-       REFERENCE
-          "OSPF Version 2, Appendix A.4.1 The  Link  State
-          Advertisement header"
-      ::= { ospfLsdbEntry 2 }
-
-    ospfLsdbLsid OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Link State ID is an LS Type Specific field
-           containing either a Router ID or an IP Address;
-           it identifies the piece of the  routing  domain
-           that is being described by the advertisement."
-       REFERENCE
-          "OSPF Version 2, Section 12.1.4 Link State ID"
-      ::= { ospfLsdbEntry 3 }
-    ospfLsdbRouterId OBJECT-TYPE
-        SYNTAX   RouterID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The 32 bit number that uniquely identifies the
-           originating router in the Autonomous System."
-       REFERENCE
-          "OSPF Version 2, Appendix C.1 Global parameters"
-      ::= { ospfLsdbEntry 4 }
-
---  Note that the OSPF Sequence Number is a 32 bit signed
---  integer.  It starts with the value '80000001'h,
---  or -'7FFFFFFF'h, and increments until '7FFFFFFF'h
---  Thus, a typical sequence number will be very negative.
-
-    ospfLsdbSequence OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The sequence number field is a  signed  32-bit
-           integer.   It  is used to detect old and dupli-
-           cate link state advertisements.  The  space  of
-           sequence  numbers  is  linearly  ordered.   The
-           larger the sequence number the more recent  the
-           advertisement."
-       REFERENCE
-          "OSPF Version  2,  Section  12.1.6  LS  sequence
-          number"
-      ::= { ospfLsdbEntry 5 }
-
-
-    ospfLsdbAge OBJECT-TYPE
-        SYNTAX   Integer32    -- Should be 0..MaxAge
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "This field is the age of the link state adver-
-           tisement in seconds."
-       REFERENCE
-          "OSPF Version 2, Section 12.1.1 LS age"
-      ::= { ospfLsdbEntry 6 }
-
-    ospfLsdbChecksum OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "This field is the  checksum  of  the  complete
-           contents  of  the  advertisement, excepting the
-           age field.  The age field is excepted  so  that
-           an   advertisement's  age  can  be  incremented
-           without updating the  checksum.   The  checksum
-           used  is  the same that is used for ISO connec-
-           tionless datagrams; it is commonly referred  to
-           as the Fletcher checksum."
-       REFERENCE
-          "OSPF Version 2, Section 12.1.7 LS checksum"
-      ::= { ospfLsdbEntry 7 }
-
-
-    ospfLsdbAdvertisement OBJECT-TYPE
-        SYNTAX   OCTET STRING (SIZE (1..65535))
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The entire Link State Advertisement, including
-           its header."
-       REFERENCE
-          "OSPF Version 2, Section 12  Link  State  Adver-
-          tisements"
-      ::= { ospfLsdbEntry 8 }
-
-
---  Address Range Table
-
---      The Address Range Table acts as an adjunct to the Area
---      Table; It describes those Address Range Summaries that
---      are configured to be propagated from an Area to reduce
---      the amount of information about it which is known beyond
---      its borders.
-
-    ospfAreaRangeTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfAreaRangeEntry
-        MAX-ACCESS   not-accessible
-        STATUS   obsolete
-        DESCRIPTION
-           "A range if IP addresses  specified  by  an  IP
-           address/IP  network  mask  pair.   For example,
-           class B address range of X.X.X.X with a network
-           mask  of  255.255.0.0 includes all IP addresses
-           from X.X.0.0 to X.X.255.255"
-       REFERENCE
-          "OSPF Version 2, Appendix C.2  Area parameters"
-      ::= { ospf 5 }
-    ospfAreaRangeEntry OBJECT-TYPE
-        SYNTAX   OspfAreaRangeEntry
-        MAX-ACCESS   not-accessible
-        STATUS   obsolete
-        DESCRIPTION
-           "A range if IP addresses  specified  by  an  IP
-           address/IP  network  mask  pair.   For example,
-           class B address range of X.X.X.X with a network
-           mask  of  255.255.0.0 includes all IP addresses
-           from X.X.0.0 to X.X.255.255"
-       REFERENCE
-          "OSPF Version 2, Appendix C.2  Area parameters"
-      INDEX { ospfAreaRangeAreaId, ospfAreaRangeNet }
-      ::= { ospfAreaRangeTable 1 }
-
-OspfAreaRangeEntry ::=
-    SEQUENCE {
-        ospfAreaRangeAreaId
-            AreaID,
-        ospfAreaRangeNet
-            IpAddress,
-        ospfAreaRangeMask
-            IpAddress,
-        ospfAreaRangeStatus
-            RowStatus,
-        ospfAreaRangeEffect
-            INTEGER
-              }
-
-    ospfAreaRangeAreaId OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   obsolete
-        DESCRIPTION
-           "The Area the Address  Range  is  to  be  found
-           within."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfAreaRangeEntry 1 }
-
-
-    ospfAreaRangeNet OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   obsolete
-        DESCRIPTION
-           "The IP Address of the Net or Subnet  indicated
-           by the range."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfAreaRangeEntry 2 }
-
-
-    ospfAreaRangeMask OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-create
-        STATUS   obsolete
-        DESCRIPTION
-           "The Subnet Mask that pertains to  the  Net  or
-           Subnet."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfAreaRangeEntry 3 }
-
-    ospfAreaRangeStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   obsolete
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfAreaRangeEntry 4 }
-
-
-    ospfAreaRangeEffect OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    advertiseMatching (1),
-                    doNotAdvertiseMatching (2)
-                  }
-        MAX-ACCESS   read-create
-        STATUS   obsolete
-        DESCRIPTION
-           "Subnets subsumed by ranges either trigger  the
-           advertisement  of the indicated summary (adver-
-           tiseMatching), or result in  the  subnet's  not
-           being advertised at all outside the area."
-       DEFVAL   { advertiseMatching }
-       ::= { ospfAreaRangeEntry 5 }
-
-
-
---  OSPF Host Table
-
---      The Host/Metric Table indicates what hosts are directly
---      attached to the Router, and what metrics and types of
---      service should be advertised for them.
-
-    ospfHostTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfHostEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The list of Hosts, and their metrics, that the
-           router will advertise as host routes."
-       REFERENCE
-          "OSPF Version 2, Appendix C.6  Host route param-
-          eters"
-      ::= { ospf 6 }
-
-
-    ospfHostEntry OBJECT-TYPE
-        SYNTAX   OspfHostEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A metric to be advertised, for a given type of
-           service, when a given host is reachable."
-       INDEX { ospfHostIpAddress, ospfHostTOS }
-       ::= { ospfHostTable 1 }
-
-OspfHostEntry ::=
-    SEQUENCE {
-        ospfHostIpAddress
-            IpAddress,
-        ospfHostTOS
-            TOSType,
-        ospfHostMetric
-            Metric,
-        ospfHostStatus
-            RowStatus,
-        ospfHostAreaID
-            AreaID
-              }
-
-    ospfHostIpAddress OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP Address of the Host."
-       REFERENCE
-          "OSPF Version 2, Appendix C.6 Host route parame-
-          ters"
-      ::= { ospfHostEntry 1 }
-
-
-    ospfHostTOS OBJECT-TYPE
-        SYNTAX   TOSType
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Type of Service of the route being config-
-           ured."
-       REFERENCE
-          "OSPF Version 2, Appendix C.6 Host route parame-
-          ters"
-      ::= { ospfHostEntry 2 }
-
-
-    ospfHostMetric OBJECT-TYPE
-        SYNTAX   Metric
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The Metric to be advertised."
-       REFERENCE
-          "OSPF Version 2, Appendix C.6 Host route parame-
-          ters"
-      ::= { ospfHostEntry 3 }
-
-    ospfHostStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfHostEntry 4 }
-
-
-    ospfHostAreaID OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Area the Host Entry is to be found within.
-           By  default, the area that a subsuming OSPF in-
-           terface is in, or 0.0.0.0"
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfHostEntry 5 }
-
-
---  OSPF Interface Table
-
---      The OSPF Interface Table augments the ipAddrTable
---             with OSPF specific information.
-
-    ospfIfTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfIfEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The OSPF Interface Table describes the  inter-
-           faces from the viewpoint of OSPF."
-       REFERENCE
-          "OSPF Version 2, Appendix C.3  Router  interface
-          parameters"
-      ::= { ospf 7 }
-
-
-    ospfIfEntry OBJECT-TYPE
-        SYNTAX   OspfIfEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The OSPF Interface Entry describes one  inter-
-           face from the viewpoint of OSPF."
-       INDEX { ospfIfIpAddress, ospfAddressLessIf }
-       ::= { ospfIfTable 1 }
-
-OspfIfEntry ::=
-    SEQUENCE {
-        ospfIfIpAddress
-            IpAddress,
-        ospfAddressLessIf
-            Integer32,
-        ospfIfAreaId
-            AreaID,
-        ospfIfType
-            INTEGER,
-        ospfIfAdminStat
-            Status,
-        ospfIfRtrPriority
-            DesignatedRouterPriority,
-        ospfIfTransitDelay
-            UpToMaxAge,
-        ospfIfRetransInterval
-            UpToMaxAge,
-        ospfIfHelloInterval
-            HelloRange,
-        ospfIfRtrDeadInterval
-            PositiveInteger,
-        ospfIfPollInterval
-            PositiveInteger,
-        ospfIfState
-            INTEGER,
-        ospfIfDesignatedRouter
-            IpAddress,
-        ospfIfBackupDesignatedRouter
-            IpAddress,
-        ospfIfEvents
-            Counter32,
-        ospfIfAuthType
-            INTEGER,
-        ospfIfAuthKey
-            OCTET STRING,
-        ospfIfStatus
-            RowStatus,
-        ospfIfMulticastForwarding
-            INTEGER,
-        ospfIfDemand
-            TruthValue
-              }
-
-    ospfIfIpAddress OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP address of this OSPF interface."
-       ::= { ospfIfEntry 1 }
-
-    ospfAddressLessIf OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "For the purpose of easing  the  instancing  of
-           addressed   and  addressless  interfaces;  This
-           variable takes the value 0 on  interfaces  with
-           IP  Addresses,  and  the corresponding value of
-           ifIndex for interfaces having no IP Address."
-       ::= { ospfIfEntry 2 }
-    ospfIfAreaId OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "A 32-bit integer uniquely identifying the area
-           to  which  the  interface  connects.   Area  ID
-           0.0.0.0 is used for the OSPF backbone."
-       DEFVAL   { '00000000'H }    -- 0.0.0.0
-       ::= { ospfIfEntry 3 }
-
-    ospfIfType OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    broadcast (1),
-                    nbma (2),
-                    pointToPoint (3),
-                    pointToMultipoint (5)
-                  }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The OSPF interface type.
-
-           By way of a default, this field may be intuited
-           from the corresponding value of ifType.  Broad-
-           cast LANs, such as  Ethernet  and  IEEE  802.5,
-           take  the  value  'broadcast', X.25 and similar
-           technologies take the value 'nbma',  and  links
-           that  are  definitively point to point take the
-           value 'pointToPoint'."
-       ::= { ospfIfEntry 4 }
-
-
-    ospfIfAdminStat OBJECT-TYPE
-        SYNTAX   Status
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The OSPF  interface's  administrative  status.
-           The  value formed on the interface, and the in-
-           terface will be advertised as an internal route
-           to  some  area.   The  value 'disabled' denotes
-           that the interface is external to OSPF."
-       DEFVAL { enabled }
-       ::= { ospfIfEntry 5 }
-
-    ospfIfRtrPriority OBJECT-TYPE
-        SYNTAX   DesignatedRouterPriority
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The  priority  of  this  interface.   Used  in
-           multi-access  networks,  this  field is used in
-           the designated router election algorithm.   The
-           value 0 signifies that the router is not eligi-
-           ble to become the  designated  router  on  this
-           particular  network.   In the event of a tie in
-           this value, routers will use their Router ID as
-           a tie breaker."
-       DEFVAL { 1 }
-       ::= { ospfIfEntry 6 }
-
-
-    ospfIfTransitDelay OBJECT-TYPE
-        SYNTAX   UpToMaxAge
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The estimated number of seconds  it  takes  to
-           transmit  a  link state update packet over this
-           interface."
-       DEFVAL { 1 }
-       ::= { ospfIfEntry 7 }
-
-
-    ospfIfRetransInterval OBJECT-TYPE
-        SYNTAX   UpToMaxAge
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The number of seconds between  link-state  ad-
-           vertisement  retransmissions,  for  adjacencies
-           belonging to this  interface.   This  value  is
-           also used when retransmitting database descrip-
-           tion and link-state request packets."
-       DEFVAL { 5 }
-       ::= { ospfIfEntry 8 }
-
-
-    ospfIfHelloInterval OBJECT-TYPE
-        SYNTAX   HelloRange
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The length of time, in  seconds,  between  the
-           Hello  packets that the router sends on the in-
-           terface.  This value must be the same  for  all
-           routers attached to a common network."
-       DEFVAL { 10 }
-       ::= { ospfIfEntry 9 }
-
-
-    ospfIfRtrDeadInterval OBJECT-TYPE
-        SYNTAX   PositiveInteger
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The number of seconds that  a  router's  Hello
-           packets  have  not been seen before it's neigh-
-           bors declare the router down.  This  should  be
-           some  multiple  of  the  Hello  interval.  This
-           value must be the same for all routers attached
-           to a common network."
-       DEFVAL { 40 }
-       ::= { ospfIfEntry 10 }
-
-
-    ospfIfPollInterval OBJECT-TYPE
-        SYNTAX   PositiveInteger
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The larger time interval, in seconds,  between
-           the  Hello  packets  sent  to  an inactive non-
-           broadcast multi- access neighbor."
-       DEFVAL { 120 }
-       ::= { ospfIfEntry 11 }
-
-
-    ospfIfState OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    down (1),
-                    loopback (2),
-                    waiting (3),
-                    pointToPoint (4),
-                    designatedRouter (5),
-                    backupDesignatedRouter (6),
-                    otherDesignatedRouter (7)
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The OSPF Interface State."
-       DEFVAL { down }
-       ::= { ospfIfEntry 12 }
-
-
-    ospfIfDesignatedRouter OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP Address of the Designated Router."
-       DEFVAL   { '00000000'H }    -- 0.0.0.0
-       ::= { ospfIfEntry 13 }
-
-
-    ospfIfBackupDesignatedRouter OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The  IP  Address  of  the  Backup   Designated
-           Router."
-       DEFVAL   { '00000000'H }    -- 0.0.0.0
-       ::= { ospfIfEntry 14 }
-
-    ospfIfEvents OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of times this  OSPF  interface  has
-           changed its state, or an error has occurred."
-       ::= { ospfIfEntry 15 }
-
-
-    ospfIfAuthKey OBJECT-TYPE
-        SYNTAX   OCTET STRING (SIZE (0..256))
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The Authentication Key.  If the Area's Author-
-           ization  Type  is  simplePassword,  and the key
-           length is shorter than 8 octets, the agent will
-           left adjust and zero fill to 8 octets.
-
-           Note that unauthenticated  interfaces  need  no
-           authentication key, and simple password authen-
-           tication cannot use a key of more  than  8  oc-
-           tets.  Larger keys are useful only with authen-
-           tication mechanisms not specified in this docu-
-           ment.
-
-           When read, ospfIfAuthKey always returns an  Oc-
-           tet String of length zero."
-       REFERENCE
-          "OSPF Version 2, Section 9  The  Interface  Data
-          Structure"
-      DEFVAL   { '0000000000000000'H }    -- 0.0.0.0.0.0.0.0
-      ::= { ospfIfEntry 16 }
-
-    ospfIfStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfIfEntry 17 }
-
-
-    ospfIfMulticastForwarding OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                            blocked (1),        -- no multicast forwarding
-                            multicast (2),        -- using multicast address
-                            unicast (3)        -- to each OSPF neighbor
-                  }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The way multicasts should  forwarded  on  this
-           interface;  not  forwarded,  forwarded  as data
-           link multicasts, or forwarded as data link uni-
-           casts.   Data link multicasting is not meaning-
-           ful on point to point and NBMA interfaces,  and
-           setting ospfMulticastForwarding to 0 effective-
-           ly disables all multicast forwarding."
-       DEFVAL { blocked }
-       ::= { ospfIfEntry 18 }
-
-
-    ospfIfDemand OBJECT-TYPE
-        SYNTAX   TruthValue
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "Indicates whether Demand OSPF procedures (hel-
-           lo suppression to FULL neighbors and setting the
-           DoNotAge flag on proogated LSAs) should be per-
-           formed on this interface."
-       DEFVAL { false }
-       ::= { ospfIfEntry 19 }
-
-
-    ospfIfAuthType OBJECT-TYPE
-        SYNTAX   INTEGER (0..255)
-                    -- none (0),
-                    -- simplePassword (1)
-                    -- md5 (2)
-                    -- reserved for specification by IANA (> 2)
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The authentication type specified for  an  in-
-           terface.   Additional  authentication types may
-           be assigned locally."
-       REFERENCE
-          "OSPF Version 2, Appendix E Authentication"
-      DEFVAL { 0 }        -- no authentication, by default
-      ::= { ospfIfEntry 20 }
-
-
---  OSPF Interface Metric Table
-
---      The Metric Table describes the metrics to be advertised
---      for a specified interface at the various types of service.
---      As such, this table is an adjunct of the OSPF Interface
---      Table.
-
--- Types of service, as defined by RFC 791, have the ability
--- to request low delay, high bandwidth, or reliable linkage.
-
--- For the purposes of this specification, the measure of
--- bandwidth
-
---      Metric = 10^8 / ifSpeed
-
--- is the default value.  For multiple link interfaces, note
--- that ifSpeed is the sum of the individual link speeds.
--- This yields a number having the following typical values:
-
---      Network Type/bit rate   Metric
-
---      >= 100 MBPS                 1
---      Ethernet/802.3             10
---      E1                         48
---      T1 (ESF)                   65
---       64 KBPS                 1562
---       56 KBPS                 1785
---       19.2 KBPS               5208
---        9.6 KBPS              10416
-
--- Routes that are not specified use the default (TOS 0) metric
-
-    ospfIfMetricTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfIfMetricEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The TOS metrics for  a  non-virtual  interface
-           identified by the interface index."
-       REFERENCE
-          "OSPF Version 2, Appendix C.3  Router  interface
-          parameters"
-      ::= { ospf 8 }
-
-    ospfIfMetricEntry OBJECT-TYPE
-        SYNTAX   OspfIfMetricEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A particular TOS metric for a non-virtual  in-
-           terface identified by the interface index."
-       REFERENCE
-          "OSPF Version 2, Appendix C.3  Router  interface
-          parameters"
-      INDEX { ospfIfMetricIpAddress,
-  ospfIfMetricAddressLessIf,
-  ospfIfMetricTOS }
-      ::= { ospfIfMetricTable 1 }
-
-OspfIfMetricEntry ::=
-    SEQUENCE {
-        ospfIfMetricIpAddress
-            IpAddress,
-        ospfIfMetricAddressLessIf
-            Integer32,
-        ospfIfMetricTOS
-            TOSType,
-        ospfIfMetricValue
-            Metric,
-        ospfIfMetricStatus
-            RowStatus
-              }
-
-    ospfIfMetricIpAddress OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP address of this OSPF interface.  On row
-           creation,  this  can  be  derived  from the in-
-           stance."
-       ::= { ospfIfMetricEntry 1 }
-
-    ospfIfMetricAddressLessIf OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "For the purpose of easing  the  instancing  of
-           addressed   and  addressless  interfaces;  This
-           variable takes the value 0 on  interfaces  with
-           IP  Addresses, and the value of ifIndex for in-
-           terfaces having no IP Address.   On  row  crea-
-           tion, this can be derived from the instance."
-       ::= { ospfIfMetricEntry 2 }
-
-
-    ospfIfMetricTOS OBJECT-TYPE
-        SYNTAX   TOSType
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The type of service metric  being  referenced.
-           On  row  creation, this can be derived from the
-           instance."
-       ::= { ospfIfMetricEntry 3 }
-
-
-    ospfIfMetricValue OBJECT-TYPE
-        SYNTAX   Metric
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The metric of using this type  of  service  on
-           this interface.  The default value of the TOS 0
-           Metric is 10^8 / ifSpeed."
-       ::= { ospfIfMetricEntry 4 }
-
-    ospfIfMetricStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfIfMetricEntry 5 }
-
-
---  OSPF Virtual Interface Table
-
---      The Virtual Interface Table describes the virtual
---      links that the OSPF Process is configured to
---      carry on.
-
-    ospfVirtIfTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfVirtIfEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "Information about this router's virtual inter-
-           faces."
-       REFERENCE
-          "OSPF Version  2,  Appendix  C.4   Virtual  link
-          parameters"
-      ::= { ospf 9 }
-
-
-    ospfVirtIfEntry OBJECT-TYPE
-        SYNTAX   OspfVirtIfEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "Information about a single Virtual Interface."
-       INDEX { ospfVirtIfAreaId, ospfVirtIfNeighbor }
-       ::= { ospfVirtIfTable 1 }
-
-OspfVirtIfEntry ::=
-    SEQUENCE {
-        ospfVirtIfAreaId
-            AreaID,
-        ospfVirtIfNeighbor
-            RouterID,
-        ospfVirtIfTransitDelay
-            UpToMaxAge,
-        ospfVirtIfRetransInterval
-            UpToMaxAge,
-        ospfVirtIfHelloInterval
-            HelloRange,
-        ospfVirtIfRtrDeadInterval
-            PositiveInteger,
-        ospfVirtIfState
-            INTEGER,
-        ospfVirtIfEvents
-            Counter32,
-        ospfVirtIfAuthType
-            INTEGER,
-        ospfVirtIfAuthKey
-            OCTET STRING,
-        ospfVirtIfStatus
-            RowStatus
-              }
-
-    ospfVirtIfAreaId OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The  Transit  Area  that  the   Virtual   Link
-           traverses.  By definition, this is not 0.0.0.0"
-       ::= { ospfVirtIfEntry 1 }
-
-
-    ospfVirtIfNeighbor OBJECT-TYPE
-        SYNTAX   RouterID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Router ID of the Virtual Neighbor."
-       ::= { ospfVirtIfEntry 2 }
-
-
-    ospfVirtIfTransitDelay OBJECT-TYPE
-        SYNTAX   UpToMaxAge
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The estimated number of seconds  it  takes  to
-           transmit  a link- state update packet over this
-           interface."
-       DEFVAL { 1 }
-       ::= { ospfVirtIfEntry 3 }
-
-
-    ospfVirtIfRetransInterval OBJECT-TYPE
-        SYNTAX   UpToMaxAge
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The number of seconds between  link-state  ad-
-           vertisement  retransmissions,  for  adjacencies
-           belonging to this  interface.   This  value  is
-           also used when retransmitting database descrip-
-           tion  and  link-state  request  packets.   This
-           value  should  be well over the expected round-
-           trip time."
-       DEFVAL { 5 }
-       ::= { ospfVirtIfEntry 4 }
-
-
-    ospfVirtIfHelloInterval OBJECT-TYPE
-        SYNTAX   HelloRange
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The length of time, in  seconds,  between  the
-           Hello  packets that the router sends on the in-
-           terface.  This value must be the same  for  the
-           virtual neighbor."
-       DEFVAL { 10 }
-       ::= { ospfVirtIfEntry 5 }
-
-
-    ospfVirtIfRtrDeadInterval OBJECT-TYPE
-        SYNTAX   PositiveInteger
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The number of seconds that  a  router's  Hello
-           packets  have  not been seen before it's neigh-
-           bors declare the router down.  This  should  be
-           some  multiple  of  the  Hello  interval.  This
-           value must be the same for the  virtual  neigh-
-           bor."
-       DEFVAL { 60 }
-       ::= { ospfVirtIfEntry 6 }
-
-
-    ospfVirtIfState OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    down (1),            -- these use the same encoding
-                    pointToPoint (4)     -- as the ospfIfTable
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "OSPF virtual interface states."
-       DEFVAL   { down }
-       ::= { ospfVirtIfEntry 7 }
-
-
-    ospfVirtIfEvents OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of state changes or error events on
-           this Virtual Link"
-       ::= { ospfVirtIfEntry 8 }
-
-
-    ospfVirtIfAuthKey OBJECT-TYPE
-        SYNTAX   OCTET STRING (SIZE(0..256))
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "If Authentication Type is simplePassword,  the
-           device  will left adjust and zero fill to 8 oc-
-           tets.
-
-           Note that unauthenticated  interfaces  need  no
-           authentication key, and simple password authen-
-           tication cannot use a key of more  than  8  oc-
-           tets.  Larger keys are useful only with authen-
-           tication mechanisms not specified in this docu-
-           ment.
-
-           When  read,  ospfVifAuthKey  always  returns  a
-           string of length zero."
-       REFERENCE
-          "OSPF Version 2, Section 9  The  Interface  Data
-          Structure"
-      DEFVAL   { '0000000000000000'H }    -- 0.0.0.0.0.0.0.0
-      ::= { ospfVirtIfEntry 9 }
-
-
-    ospfVirtIfStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfVirtIfEntry 10 }
-
-
-    ospfVirtIfAuthType OBJECT-TYPE
-        SYNTAX   INTEGER (0..255)
-                    -- none (0),
-                    -- simplePassword (1)
-                    -- md5 (2)
-                    -- reserved for specification by IANA (> 2)
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The authentication type specified for a virtu-
-           al  interface.  Additional authentication types
-           may be assigned locally."
-       REFERENCE
-          "OSPF Version 2, Appendix E Authentication"
-      DEFVAL { 0 }        -- no authentication, by default
-      ::= { ospfVirtIfEntry 11 }
-
-
---  OSPF Neighbor Table
-
---      The OSPF Neighbor Table describes all neighbors in
---      the locality of the subject router.
-
-    ospfNbrTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfNbrEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A table of non-virtual neighbor information."
-       REFERENCE
-          "OSPF Version 2, Section 10  The  Neighbor  Data
-          Structure"
-      ::= { ospf 10 }
-
-
-    ospfNbrEntry OBJECT-TYPE
-        SYNTAX   OspfNbrEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The information regarding a single neighbor."
-       REFERENCE
-          "OSPF Version 2, Section 10  The  Neighbor  Data
-          Structure"
-      INDEX { ospfNbrIpAddr, ospfNbrAddressLessIndex }
-      ::= { ospfNbrTable 1 }
-
-OspfNbrEntry ::=
-    SEQUENCE {
-        ospfNbrIpAddr
-            IpAddress,
-        ospfNbrAddressLessIndex
-            InterfaceIndex,
-        ospfNbrRtrId
-            RouterID,
-        ospfNbrOptions
-            Integer32,
-        ospfNbrPriority
-            DesignatedRouterPriority,
-        ospfNbrState
-            INTEGER,
-        ospfNbrEvents
-            Counter32,
-        ospfNbrLsRetransQLen
-            Gauge32,
-        ospfNbmaNbrStatus
-            RowStatus,
-        ospfNbmaNbrPermanence
-            INTEGER,
-        ospfNbrHelloSuppressed
-            TruthValue
-              }
-
-    ospfNbrIpAddr OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP address this neighbor is using  in  its
-           IP  Source  Address.  Note that, on addressless
-           links, this will not be 0.0.0.0,  but  the  ad-
-           dress of another of the neighbor's interfaces."
-       ::= { ospfNbrEntry 1 }
-
-
-    ospfNbrAddressLessIndex OBJECT-TYPE
-        SYNTAX   InterfaceIndex
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "On an interface having an  IP  Address,  zero.
-           On  addressless  interfaces,  the corresponding
-           value of ifIndex in the Internet Standard  MIB.
-           On  row  creation, this can be derived from the
-           instance."
-       ::= { ospfNbrEntry 2 }
-
-
-    ospfNbrRtrId OBJECT-TYPE
-        SYNTAX   RouterID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "A 32-bit integer (represented as a type  IpAd-
-           dress)  uniquely  identifying  the  neighboring
-           router in the Autonomous System."
-       DEFVAL   { '00000000'H }    -- 0.0.0.0
-       ::= { ospfNbrEntry 3 }
-
-
-    ospfNbrOptions OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "A Bit Mask corresponding to the neighbor's op-
-           tions field.
-
-           Bit 0, if set, indicates that the  system  will
-           operate  on  Type of Service metrics other than
-           TOS 0.  If zero, the neighbor will  ignore  all
-           metrics except the TOS 0 metric.
-
-           Bit 1, if set, indicates  that  the  associated
-           area  accepts and operates on external informa-
-           tion; if zero, it is a stub area.
-
-           Bit 2, if set, indicates that the system is ca-
-           pable  of routing IP Multicast datagrams; i.e.,
-           that it implements the Multicast Extensions  to
-           OSPF.
-
-           Bit 3, if set, indicates  that  the  associated
-           area  is  an  NSSA.  These areas are capable of
-           carrying type 7 external advertisements,  which
-           are  translated into type 5 external advertise-
-           ments at NSSA borders."
-       REFERENCE
-          "OSPF Version 2, Section 12.1.2 Options"
-      DEFVAL { 0 }
-      ::= { ospfNbrEntry 4 }
-
-
-    ospfNbrPriority OBJECT-TYPE
-        SYNTAX   DesignatedRouterPriority
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The priority of this neighbor in the designat-
-           ed router election algorithm.  The value 0 sig-
-           nifies that the neighbor is not eligible to be-
-           come  the  designated router on this particular
-           network."
-       DEFVAL { 1 }
-       ::= { ospfNbrEntry 5 }
-
-
-    ospfNbrState OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    down (1),
-                    attempt (2),
-                    init (3),
-                    twoWay (4),
-                    exchangeStart (5),
-                    exchange (6),
-                    loading (7),
-                    full (8)
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The State of the relationship with this Neigh-
-           bor."
-       REFERENCE
-          "OSPF Version 2, Section 10.1 Neighbor States"
-      DEFVAL   { down }
-      ::= { ospfNbrEntry 6 }
-
-
-    ospfNbrEvents OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of times this neighbor relationship
-           has changed state, or an error has occurred."
-       ::= { ospfNbrEntry 7 }
-
-
-    ospfNbrLsRetransQLen OBJECT-TYPE
-        SYNTAX   Gauge32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The  current  length  of  the   retransmission
-           queue."
-       ::= { ospfNbrEntry 8 }
-
-
-    ospfNbmaNbrStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfNbrEntry 9 }
-
-
-    ospfNbmaNbrPermanence OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    dynamic (1),        -- learned through protocol
-                    permanent (2)       -- configured address
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.   'dynamic'  and  'permanent' refer to how
-           the neighbor became known."
-       DEFVAL { permanent }
-       ::= { ospfNbrEntry 10 }
-
-
-    ospfNbrHelloSuppressed OBJECT-TYPE
-        SYNTAX   TruthValue
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "Indicates whether Hellos are being  suppressed
-           to the neighbor"
-       ::= { ospfNbrEntry 11 }
-
-
---  OSPF Virtual Neighbor Table
-
---      This table describes all virtual neighbors.
---      Since Virtual Links are configured in the
---      virtual interface table, this table is read-only.
-
-    ospfVirtNbrTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfVirtNbrEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A table of virtual neighbor information."
-       REFERENCE
-          "OSPF Version 2, Section 15  Virtual Links"
-      ::= { ospf 11 }
-
-
-    ospfVirtNbrEntry OBJECT-TYPE
-        SYNTAX   OspfVirtNbrEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "Virtual neighbor information."
-       INDEX { ospfVirtNbrArea, ospfVirtNbrRtrId }
-       ::= { ospfVirtNbrTable 1 }
-
-OspfVirtNbrEntry ::=
-    SEQUENCE {
-        ospfVirtNbrArea
-            AreaID,
-        ospfVirtNbrRtrId
-            RouterID,
-        ospfVirtNbrIpAddr
-            IpAddress,
-        ospfVirtNbrOptions
-            Integer32,
-        ospfVirtNbrState
-            INTEGER,
-        ospfVirtNbrEvents
-            Counter32,
-        ospfVirtNbrLsRetransQLen
-            Gauge32,
-        ospfVirtNbrHelloSuppressed
-                TruthValue
-              }
-
-    ospfVirtNbrArea OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Transit Area Identifier."
-       ::= { ospfVirtNbrEntry 1 }
-
-
-    ospfVirtNbrRtrId OBJECT-TYPE
-        SYNTAX   RouterID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "A  32-bit  integer  uniquely  identifying  the
-           neighboring router in the Autonomous System."
-       ::= { ospfVirtNbrEntry 2 }
-
-
-    ospfVirtNbrIpAddr OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP address this Virtual  Neighbor  is  us-
-           ing."
-       ::= { ospfVirtNbrEntry 3 }
-
-
-    ospfVirtNbrOptions OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "A Bit Mask corresponding to the neighbor's op-
-           tions field.
-
-           Bit 1, if set, indicates that the  system  will
-           operate  on  Type of Service metrics other than
-           TOS 0.  If zero, the neighbor will  ignore  all
-           metrics except the TOS 0 metric.
-
-           Bit 2, if set, indicates  that  the  system  is
-           Network  Multicast  capable; ie, that it imple-
-           ments OSPF Multicast Routing."
-       ::= { ospfVirtNbrEntry 4 }
-    ospfVirtNbrState OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    down (1),
-                    attempt (2),
-                    init (3),
-                    twoWay (4),
-                    exchangeStart (5),
-                    exchange (6),
-                    loading (7),
-                    full (8)
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The state of the  Virtual  Neighbor  Relation-
-           ship."
-       ::= { ospfVirtNbrEntry 5 }
-
-
-    ospfVirtNbrEvents OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of  times  this  virtual  link  has
-           changed its state, or an error has occurred."
-       ::= { ospfVirtNbrEntry 6 }
-
-
-    ospfVirtNbrLsRetransQLen OBJECT-TYPE
-        SYNTAX   Gauge32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The  current  length  of  the   retransmission
-           queue."
-       ::= { ospfVirtNbrEntry 7 }
-
-
-    ospfVirtNbrHelloSuppressed OBJECT-TYPE
-        SYNTAX   TruthValue
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "Indicates whether Hellos are being  suppressed
-           to the neighbor"
-       ::= { ospfVirtNbrEntry 8 }
-
---  OSPF Link State Database, External
-
---      The Link State Database contains the Link State
---      Advertisements from throughout the areas that the
---      device is attached to.
-
---             This table is identical to the OSPF LSDB Table in
---      format, but contains only External Link State
---             Advertisements.  The purpose is to allow external
---      LSAs to be displayed once for the router rather
---      than once in each non-stub area.
-
-    ospfExtLsdbTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfExtLsdbEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "The OSPF Process's Links State Database."
-       REFERENCE
-          "OSPF Version 2, Section 12  Link  State  Adver-
-          tisements"
-      ::= { ospf 12 }
-
-
-    ospfExtLsdbEntry OBJECT-TYPE
-        SYNTAX   OspfExtLsdbEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A single Link State Advertisement."
-       INDEX { ospfExtLsdbType, ospfExtLsdbLsid, ospfExtLsdbRouterId }
-       ::= { ospfExtLsdbTable 1 }
-
-OspfExtLsdbEntry ::=
-    SEQUENCE {
-        ospfExtLsdbType
-            INTEGER,
-        ospfExtLsdbLsid
-            IpAddress,
-        ospfExtLsdbRouterId
-            RouterID,
-        ospfExtLsdbSequence
-            Integer32,
-        ospfExtLsdbAge
-            Integer32,
-        ospfExtLsdbChecksum
-            Integer32,
-        ospfExtLsdbAdvertisement
-            OCTET STRING
-              }
-
-    ospfExtLsdbType OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    asExternalLink (5)
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The type  of  the  link  state  advertisement.
-           Each  link state type has a separate advertise-
-           ment format."
-       REFERENCE
-          "OSPF Version 2, Appendix A.4.1 The  Link  State
-          Advertisement header"
-      ::= { ospfExtLsdbEntry 1 }
-
-
-    ospfExtLsdbLsid OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Link State ID is an LS Type Specific field
-           containing either a Router ID or an IP Address;
-           it identifies the piece of the  routing  domain
-           that is being described by the advertisement."
-       REFERENCE
-          "OSPF Version 2, Section 12.1.4 Link State ID"
-      ::= { ospfExtLsdbEntry 2 }
-
-
-    ospfExtLsdbRouterId OBJECT-TYPE
-        SYNTAX   RouterID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The 32 bit number that uniquely identifies the
-           originating router in the Autonomous System."
-       REFERENCE
-          "OSPF Version 2, Appendix C.1 Global parameters"
-      ::= { ospfExtLsdbEntry 3 }
-
---  Note that the OSPF Sequence Number is a 32 bit signed
---  integer.  It starts with the value '80000001'h,
---  or -'7FFFFFFF'h, and increments until '7FFFFFFF'h
---  Thus, a typical sequence number will be very negative.
-    ospfExtLsdbSequence OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The sequence number field is a  signed  32-bit
-           integer.   It  is used to detect old and dupli-
-           cate link state advertisements.  The  space  of
-           sequence  numbers  is  linearly  ordered.   The
-           larger the sequence number the more recent  the
-           advertisement."
-       REFERENCE
-          "OSPF Version  2,  Section  12.1.6  LS  sequence
-          number"
-      ::= { ospfExtLsdbEntry 4 }
-
-
-    ospfExtLsdbAge OBJECT-TYPE
-        SYNTAX   Integer32    -- Should be 0..MaxAge
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "This field is the age of the link state adver-
-           tisement in seconds."
-       REFERENCE
-          "OSPF Version 2, Section 12.1.1 LS age"
-      ::= { ospfExtLsdbEntry 5 }
-
-
-    ospfExtLsdbChecksum OBJECT-TYPE
-        SYNTAX   Integer32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "This field is the  checksum  of  the  complete
-           contents  of  the  advertisement, excepting the
-           age field.  The age field is excepted  so  that
-           an   advertisement's  age  can  be  incremented
-           without updating the  checksum.   The  checksum
-           used  is  the same that is used for ISO connec-
-           tionless datagrams; it is commonly referred  to
-           as the Fletcher checksum."
-       REFERENCE
-          "OSPF Version 2, Section 12.1.7 LS checksum"
-      ::= { ospfExtLsdbEntry 6 }
-
-
-    ospfExtLsdbAdvertisement OBJECT-TYPE
-        SYNTAX   OCTET STRING (SIZE(36))
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The entire Link State Advertisement, including
-           its header."
-       REFERENCE
-          "OSPF Version 2, Section 12  Link  State  Adver-
-          tisements"
-      ::= { ospfExtLsdbEntry 7 }
-
-
---  OSPF Use of the CIDR Route Table
-
-ospfRouteGroup           OBJECT IDENTIFIER ::= { ospf 13 }
-
--- The IP Forwarding Table defines a number of objects for use by
--- the routing protocol to externalize its information.  Most of
--- the variables (ipForwardDest, ipForwardMask, ipForwardPolicy,
--- ipForwardNextHop, ipForwardIfIndex, ipForwardType,
--- ipForwardProto, ipForwardAge, and ipForwardNextHopAS) are
--- defined there.
-
--- Those that leave some discretion are defined here.
-
--- ipCidrRouteProto is, of course, ospf (13).
-
--- ipCidrRouteAge is the time since the route was first calculated,
--- as opposed to the time since the last SPF run.
-
--- ipCidrRouteInfo is an OBJECT IDENTIFIER for use by the routing
--- protocol.  The following values shall be found there depending
--- on the way the route was calculated.
-
-ospfIntraArea      OBJECT IDENTIFIER ::= { ospfRouteGroup 1 }
-ospfInterArea      OBJECT IDENTIFIER ::= { ospfRouteGroup 2 }
-ospfExternalType1  OBJECT IDENTIFIER ::= { ospfRouteGroup 3 }
-ospfExternalType2  OBJECT IDENTIFIER ::= { ospfRouteGroup 4 }
-
--- ipCidrRouteMetric1 is, by definition, the primary routing
--- metric.  Therefore, it should be the metric that route
--- selection is based on.  For intra-area and inter-area routes,
--- it is an OSPF metric.  For External Type 1 (comparable value)
--- routes, it is an OSPF metric plus the External Metric.  For
--- external Type 2 (non-comparable value) routes, it is the
--- external metric.
-
--- ipCidrRouteMetric2 is, by definition, a secondary routing
--- metric.  Therefore, it should be the metric that breaks a tie
--- among routes having equal metric1 values and the same
--- calculation rule.  For intra-area, inter-area routes, and
--- External Type 1 (comparable value) routes, it is unused.  For
--- external Type 2 (non-comparable value) routes, it is the metric
--- to the AS border router.
-
--- ipCidrRouteMetric3, ipCidrRouteMetric4, and ipCidrRouteMetric5 are
--- unused.
-
---
---      The OSPF Area Aggregate Table
---
---      This table replaces the OSPF Area Summary Table, being an
---      extension of that for CIDR routers.
-
-    ospfAreaAggregateTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF OspfAreaAggregateEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A range of IP addresses  specified  by  an  IP
-           address/IP  network  mask  pair.   For example,
-           class B address range of X.X.X.X with a network
-           mask  of  255.255.0.0 includes all IP addresses
-           from X.X.0.0  to  X.X.255.255.   Note  that  if
-           ranges  are configured such that one range sub-
-           sumes  another  range  (e.g.,   10.0.0.0   mask
-           255.0.0.0  and  10.1.0.0 mask 255.255.0.0), the
-           most specific match is the preferred one."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2  Area parameters"
-      ::= { ospf 14 }
-
-
-    ospfAreaAggregateEntry OBJECT-TYPE
-        SYNTAX   OspfAreaAggregateEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A range of IP addresses  specified  by  an  IP
-           address/IP  network  mask  pair.   For example,
-           class B address range of X.X.X.X with a network
-           mask  of  255.255.0.0 includes all IP addresses
-           from X.X.0.0  to  X.X.255.255.   Note  that  if
-           ranges are range configured such that one range
-           subsumes another  range  (e.g.,  10.0.0.0  mask
-           255.0.0.0  and  10.1.0.0 mask 255.255.0.0), the
-           most specific match is the preferred one."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2  Area parameters"
-      INDEX { ospfAreaAggregateAreaID, ospfAreaAggregateLsdbType,
-              ospfAreaAggregateNet, ospfAreaAggregateMask }
-      ::= { ospfAreaAggregateTable 1 }
-
-
-OspfAreaAggregateEntry ::=
-    SEQUENCE {
-        ospfAreaAggregateAreaID
-            AreaID,
-        ospfAreaAggregateLsdbType
-            INTEGER,
-        ospfAreaAggregateNet
-            IpAddress,
-        ospfAreaAggregateMask
-            IpAddress,
-        ospfAreaAggregateStatus
-            RowStatus,
-        ospfAreaAggregateEffect
-            INTEGER
-              }
-
-    ospfAreaAggregateAreaID OBJECT-TYPE
-        SYNTAX   AreaID
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Area the Address Aggregate is to be  found
-           within."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfAreaAggregateEntry 1 }
-
-
-    ospfAreaAggregateLsdbType OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    summaryLink (3),
-                    nssaExternalLink (7)
-                  }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The type of the Address Aggregate.  This field
-           specifies  the  Lsdb type that this Address Ag-
-           gregate applies to."
-       REFERENCE
-          "OSPF Version 2, Appendix A.4.1 The  Link  State
-          Advertisement header"
-      ::= { ospfAreaAggregateEntry 2 }
-
-
-    ospfAreaAggregateNet OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP Address of the Net or Subnet  indicated
-           by the range."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfAreaAggregateEntry 3 }
-
-
-    ospfAreaAggregateMask OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The Subnet Mask that pertains to  the  Net  or
-           Subnet."
-       REFERENCE
-          "OSPF Version 2, Appendix C.2 Area parameters"
-      ::= { ospfAreaAggregateEntry 4 }
-
-
-    ospfAreaAggregateStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable displays the status of  the  en-
-           try.  Setting it to 'invalid' has the effect of
-           rendering it inoperative.  The internal  effect
-           (row removal) is implementation dependent."
-       ::= { ospfAreaAggregateEntry 5 }
-
-
-    ospfAreaAggregateEffect OBJECT-TYPE
-        SYNTAX   INTEGER    {
-                    advertiseMatching (1),
-                    doNotAdvertiseMatching (2)
-                  }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "Subnets subsumed by ranges either trigger  the
-           advertisement  of  the indicated aggregate (ad-
-           vertiseMatching), or result in the subnet's not
-           being advertised at all outside the area."
-       DEFVAL   { advertiseMatching }
-       ::= { ospfAreaAggregateEntry 6 }
-
-
--- conformance information
-
-ospfConformance OBJECT IDENTIFIER ::= { ospf 15 }
-
-ospfGroups      OBJECT IDENTIFIER ::= { ospfConformance 1 }
-ospfCompliances OBJECT IDENTIFIER ::= { ospfConformance 2 }
-
--- compliance statements
-
-    ospfCompliance MODULE-COMPLIANCE
-        STATUS  current
-        DESCRIPTION
-           "The compliance statement "
-       MODULE  -- this module
-       MANDATORY-GROUPS {
-                    ospfBasicGroup,
-                    ospfAreaGroup,
-                    ospfStubAreaGroup,
-                    ospfIfGroup,
-                    ospfIfMetricGroup,
-                    ospfVirtIfGroup,
-                    ospfNbrGroup,
-                    ospfVirtNbrGroup,
-                    ospfAreaAggregateGroup
-           }
-       ::= { ospfCompliances 1 }
-
-
--- units of conformance
-
-    ospfBasicGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfRouterId,
-                    ospfAdminStat,
-                    ospfVersionNumber,
-                    ospfAreaBdrRtrStatus,
-                    ospfASBdrRtrStatus,
-                    ospfExternLsaCount,
-                    ospfExternLsaCksumSum,
-                    ospfTOSSupport,
-                    ospfOriginateNewLsas,
-                    ospfRxNewLsas,
-                    ospfExtLsdbLimit,
-                    ospfMulticastExtensions,
-                    ospfExitOverflowInterval,
-                    ospfDemandExtensions
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required for OSPF systems."
-       ::= { ospfGroups 1 }
-
-
-    ospfAreaGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfAreaId,
-                    ospfImportAsExtern,
-                    ospfSpfRuns,
-                    ospfAreaBdrRtrCount,
-                    ospfAsBdrRtrCount,
-                    ospfAreaLsaCount,
-                    ospfAreaLsaCksumSum,
-                    ospfAreaSummary,
-                    ospfAreaStatus
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required  for  OSPF  systems
-           supporting areas."
-       ::= { ospfGroups 2 }
-
-
-    ospfStubAreaGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfStubAreaId,
-                    ospfStubTOS,
-                    ospfStubMetric,
-                    ospfStubStatus,
-                    ospfStubMetricType
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required  for  OSPF  systems
-           supporting stub areas."
-       ::= { ospfGroups 3 }
-
-
-    ospfLsdbGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfLsdbAreaId,
-                    ospfLsdbType,
-                    ospfLsdbLsid,
-                    ospfLsdbRouterId,
-                    ospfLsdbSequence,
-                    ospfLsdbAge,
-                    ospfLsdbChecksum,
-                    ospfLsdbAdvertisement
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required  for  OSPF  systems
-           that display their link state database."
-       ::= { ospfGroups 4 }
-
-
-    ospfAreaRangeGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfAreaRangeAreaId,
-                    ospfAreaRangeNet,
-                    ospfAreaRangeMask,
-                    ospfAreaRangeStatus,
-                    ospfAreaRangeEffect
-        }
-        STATUS  obsolete
-        DESCRIPTION
-           "These objects are required for  non-CIDR  OSPF
-           systems that support multiple areas."
-       ::= { ospfGroups 5 }
-
-
-    ospfHostGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfHostIpAddress,
-                    ospfHostTOS,
-                    ospfHostMetric,
-                    ospfHostStatus,
-                    ospfHostAreaID
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required  for  OSPF  systems
-           that support attached hosts."
-       ::= { ospfGroups 6 }
-
-
-    ospfIfGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfIfIpAddress,
-                    ospfAddressLessIf,
-                    ospfIfAreaId,
-                    ospfIfType,
-                    ospfIfAdminStat,
-                    ospfIfRtrPriority,
-                    ospfIfTransitDelay,
-                    ospfIfRetransInterval,
-                    ospfIfHelloInterval,
-                    ospfIfRtrDeadInterval,
-                    ospfIfPollInterval,
-                    ospfIfState,
-                    ospfIfDesignatedRouter,
-                    ospfIfBackupDesignatedRouter,
-                    ospfIfEvents,
-                    ospfIfAuthType,
-                    ospfIfAuthKey,
-                    ospfIfStatus,
-                    ospfIfMulticastForwarding,
-                    ospfIfDemand
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required for OSPF systems."
-       ::= { ospfGroups 7 }
-
-
-    ospfIfMetricGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfIfMetricIpAddress,
-                    ospfIfMetricAddressLessIf,
-                    ospfIfMetricTOS,
-                    ospfIfMetricValue,
-                    ospfIfMetricStatus
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required for OSPF systems."
-       ::= { ospfGroups 8 }
-
-
-    ospfVirtIfGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfVirtIfAreaId,
-                    ospfVirtIfNeighbor,
-                    ospfVirtIfTransitDelay,
-                    ospfVirtIfRetransInterval,
-                    ospfVirtIfHelloInterval,
-                    ospfVirtIfRtrDeadInterval,
-                    ospfVirtIfState,
-                    ospfVirtIfEvents,
-                    ospfVirtIfAuthType,
-                    ospfVirtIfAuthKey,
-                    ospfVirtIfStatus
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required for OSPF systems."
-       ::= { ospfGroups 9 }
-
-
-    ospfNbrGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfNbrIpAddr,
-                    ospfNbrAddressLessIndex,
-                    ospfNbrRtrId,
-                    ospfNbrOptions,
-                    ospfNbrPriority,
-                    ospfNbrState,
-                    ospfNbrEvents,
-                    ospfNbrLsRetransQLen,
-                    ospfNbmaNbrStatus,
-                    ospfNbmaNbrPermanence,
-                    ospfNbrHelloSuppressed
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required for OSPF systems."
-       ::= { ospfGroups 10 }
-
-
-    ospfVirtNbrGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfVirtNbrArea,
-                    ospfVirtNbrRtrId,
-                    ospfVirtNbrIpAddr,
-                    ospfVirtNbrOptions,
-                    ospfVirtNbrState,
-                    ospfVirtNbrEvents,
-                    ospfVirtNbrLsRetransQLen,
-                    ospfVirtNbrHelloSuppressed
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required for OSPF systems."
-       ::= { ospfGroups 11 }
-
-
-    ospfExtLsdbGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfExtLsdbType,
-                    ospfExtLsdbLsid,
-                    ospfExtLsdbRouterId,
-                    ospfExtLsdbSequence,
-                    ospfExtLsdbAge,
-                    ospfExtLsdbChecksum,
-                    ospfExtLsdbAdvertisement
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required  for  OSPF  systems
-           that display their link state database."
-       ::= { ospfGroups 12 }
-
-
-    ospfAreaAggregateGroup    OBJECT-GROUP
-        OBJECTS {
-                    ospfAreaAggregateAreaID,
-                    ospfAreaAggregateLsdbType,
-                    ospfAreaAggregateNet,
-                    ospfAreaAggregateMask,
-                    ospfAreaAggregateStatus,
-                    ospfAreaAggregateEffect
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required for OSPF systems."
-       ::= { ospfGroups 13 }
-
-END
diff --git a/ospfd/OSPF-TRAP-MIB.txt b/ospfd/OSPF-TRAP-MIB.txt
deleted file mode 100644 (file)
index 8a3ab99..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-OSPF-TRAP-MIB DEFINITIONS ::= BEGIN
-
-    IMPORTS
-            MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, IpAddress
-                FROM SNMPv2-SMI
-            MODULE-COMPLIANCE, OBJECT-GROUP
-                FROM SNMPv2-CONF
-            ospfRouterId, ospfIfIpAddress, ospfAddressLessIf, ospfIfState,
-            ospfVirtIfAreaId, ospfVirtIfNeighbor, ospfVirtIfState,
-            ospfNbrIpAddr, ospfNbrAddressLessIndex, ospfNbrRtrId,
-            ospfNbrState, ospfVirtNbrArea, ospfVirtNbrRtrId, ospfVirtNbrState,
-            ospfLsdbType, ospfLsdbLsid, ospfLsdbRouterId, ospfLsdbAreaId,
-            ospfExtLsdbLimit, ospf
-                FROM OSPF-MIB;
-
-    ospfTrap MODULE-IDENTITY
-           LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995
-           ORGANIZATION "IETF OSPF Working Group"
-           CONTACT-INFO
-           "                      Fred Baker
-           Postal:                Cisco Systems
-                                  519 Lado Drive
-                                  Santa Barbara, California 93111
-           Tel:                   +1 805 681 0115
-           E-Mail:                fred@cisco.com
-
-                                  Rob Coltun
-           Postal:                RainbowBridge Communications
-           Tel:                   (301) 340-9416
-           E-Mail:                rcoltun@rainbow-bridge.com"
-       DESCRIPTION
-          "The MIB module to describe traps for  the  OSPF
-          Version 2 Protocol."
-      ::= { ospf 16 }
-
--- Trap Support Objects
-
---         The following are support objects for the OSPF traps.
-
-ospfTrapControl OBJECT IDENTIFIER ::= { ospfTrap 1 }
-ospfTraps OBJECT IDENTIFIER ::= { ospfTrap 2 }
-
-    ospfSetTrap OBJECT-TYPE
-        SYNTAX   OCTET STRING (SIZE(4))
-        MAX-ACCESS   read-write
-        STATUS   current
-        DESCRIPTION
-           "A four-octet string serving as a bit  map  for
-           the trap events defined by the OSPF traps. This
-           object is used to enable and  disable  specific
-           OSPF   traps   where  a  1  in  the  bit  field
-           represents enabled.  The right-most bit  (least
-           significant) represents trap 0."
-       ::= { ospfTrapControl 1 }
-
-
-    ospfConfigErrorType OBJECT-TYPE
-        SYNTAX   INTEGER   {
-                    badVersion (1),
-                    areaMismatch (2),
-                    unknownNbmaNbr (3), -- Router is Dr eligible
-                    unknownVirtualNbr (4),
-                    authTypeMismatch(5),
-                    authFailure (6),
-                    netMaskMismatch (7),
-                    helloIntervalMismatch (8),
-                    deadIntervalMismatch (9),
-                    optionMismatch (10) }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "Potential types  of  configuration  conflicts.
-           Used  by the ospfConfigError and ospfConfigVir-
-           tError traps."
-   ::= { ospfTrapControl 2 }
-
-
-    ospfPacketType OBJECT-TYPE
-        SYNTAX   INTEGER   {
-                    hello (1),
-                    dbDescript (2),
-                    lsReq (3),
-                    lsUpdate (4),
-                    lsAck (5) }
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "OSPF packet types."
-   ::= { ospfTrapControl 3 }
-
-
-    ospfPacketSrc OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP address of an inbound packet that  can-
-           not be identified by a neighbor instance."
-       ::= { ospfTrapControl 4 }
-
-
--- Traps
-
-
-    ospfIfStateChange NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfIfIpAddress,
-                    ospfAddressLessIf,
-                    ospfIfState   -- The new state
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfIfStateChange trap signifies that there
-           has been a change in the state of a non-virtual
-           OSPF interface. This trap should  be  generated
-           when  the interface state regresses (e.g., goes
-           from Dr to Down) or progresses  to  a  terminal
-           state  (i.e.,  Point-to-Point, DR Other, Dr, or
-           Backup)."
-   ::= { ospfTraps 16 }
-
-
-    ospfVirtIfStateChange NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfVirtIfAreaId,
-                    ospfVirtIfNeighbor,
-                    ospfVirtIfState  -- The new state
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfIfStateChange trap signifies that there
-           has  been a change in the state of an OSPF vir-
-           tual interface.
-           This trap should be generated when  the  inter-
-           face  state  regresses  (e.g., goes from Point-
-           to-Point to Down) or progresses to  a  terminal
-           state (i.e., Point-to-Point)."
-   ::= { ospfTraps 1 }
-
-
-    ospfNbrStateChange NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfNbrIpAddr,
-                    ospfNbrAddressLessIndex,
-                    ospfNbrRtrId,
-                    ospfNbrState  -- The new state
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An  ospfNbrStateChange  trap  signifies   that
-           there  has been a change in the state of a non-
-           virtual OSPF neighbor.   This  trap  should  be
-           generated  when  the  neighbor  state regresses
-           (e.g., goes from Attempt or Full  to  1-Way  or
-           Down)  or progresses to a terminal state (e.g.,
-           2-Way or Full).  When an  neighbor  transitions
-           from  or  to Full on non-broadcast multi-access
-           and broadcast networks, the trap should be gen-
-           erated  by the designated router.  A designated
-           router transitioning to Down will be  noted  by
-           ospfIfStateChange."
-   ::= { ospfTraps 2 }
-
-
-    ospfVirtNbrStateChange NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfVirtNbrArea,
-                    ospfVirtNbrRtrId,
-                    ospfVirtNbrState  -- The new state
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfIfStateChange trap signifies that there
-           has  been a change in the state of an OSPF vir-
-           tual neighbor.  This trap should  be  generated
-           when  the  neighbor state regresses (e.g., goes
-           from Attempt or  Full  to  1-Way  or  Down)  or
-           progresses to a terminal state (e.g., Full)."
-   ::= { ospfTraps 3 }
-    ospfIfConfigError NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfIfIpAddress,
-                    ospfAddressLessIf,
-                    ospfPacketSrc,  -- The source IP address
-                    ospfConfigErrorType, -- Type of error
-                    ospfPacketType
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfIfConfigError  trap  signifies  that  a
-           packet  has  been received on a non-virtual in-
-           terface  from  a  router  whose   configuration
-           parameters  conflict  with this router's confi-
-           guration parameters.  Note that the  event  op-
-           tionMismatch  should  cause  a  trap only if it
-           prevents an adjacency from forming."
-                  ::= { ospfTraps 4 }
-
-
-    ospfVirtIfConfigError NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfVirtIfAreaId,
-                    ospfVirtIfNeighbor,
-                    ospfConfigErrorType, -- Type of error
-                    ospfPacketType
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfConfigError trap signifies that a pack-
-           et  has  been  received  on a virtual interface
-           from a router  whose  configuration  parameters
-           conflict   with   this  router's  configuration
-           parameters.  Note that the event optionMismatch
-           should  cause a trap only if it prevents an ad-
-           jacency from forming."
-   ::= { ospfTraps 5 }
-
-
-    ospfIfAuthFailure NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfIfIpAddress,
-                    ospfAddressLessIf,
-                    ospfPacketSrc,  -- The source IP address
-                    ospfConfigErrorType, -- authTypeMismatch or
-                                         -- authFailure
-                    ospfPacketType
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfIfAuthFailure  trap  signifies  that  a
-           packet  has  been received on a non-virtual in-
-           terface from a router whose authentication  key
-           or  authentication  type  conflicts  with  this
-           router's authentication key  or  authentication
-           type."
-   ::= { ospfTraps 6 }
-
-
-    ospfVirtIfAuthFailure NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfVirtIfAreaId,
-                    ospfVirtIfNeighbor,
-                    ospfConfigErrorType, -- authTypeMismatch or
-                                         -- authFailure
-                    ospfPacketType
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfVirtIfAuthFailure trap signifies that a
-           packet has been received on a virtual interface
-           from a router whose authentication key  or  au-
-           thentication  type conflicts with this router's
-           authentication key or authentication type."
-   ::= { ospfTraps 7 }
-
-
-    ospfIfRxBadPacket NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfIfIpAddress,
-                    ospfAddressLessIf,
-                    ospfPacketSrc,  -- The source IP address
-                    ospfPacketType
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfIfRxBadPacket trap  signifies  that  an
-           OSPF  packet has been received on a non-virtual
-           interface that cannot be parsed."
-   ::= { ospfTraps 8 }
-
-    ospfVirtIfRxBadPacket NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfVirtIfAreaId,
-                    ospfVirtIfNeighbor,
-                    ospfPacketType
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfRxBadPacket trap signifies that an OSPF
-           packet has been received on a virtual interface
-           that cannot be parsed."
-   ::= { ospfTraps 9 }
-
-
-    ospfTxRetransmit NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfIfIpAddress,
-                    ospfAddressLessIf,
-                    ospfNbrRtrId, -- Destination
-                    ospfPacketType,
-                    ospfLsdbType,
-                    ospfLsdbLsid,
-                    ospfLsdbRouterId
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfTxRetransmit  trap  signifies  than  an
-           OSPF  packet  has  been retransmitted on a non-
-           virtual interface.  All packets that may be re-
-           transmitted  are associated with an LSDB entry.
-           The LS type, LS ID, and Router ID are  used  to
-           identify the LSDB entry."
-   ::= { ospfTraps 10 }
-
-
-    ospfVirtIfTxRetransmit NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfVirtIfAreaId,
-                    ospfVirtIfNeighbor,
-                    ospfPacketType,
-                    ospfLsdbType,
-                    ospfLsdbLsid,
-                    ospfLsdbRouterId
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfTxRetransmit  trap  signifies  than  an
-           OSPF packet has been retransmitted on a virtual
-           interface.  All packets that may be retransmit-
-           ted  are  associated with an LSDB entry. The LS
-           type, LS ID, and Router ID are used to identify
-           the LSDB entry."
-   ::= { ospfTraps 11 }
-
-
-    ospfOriginateLsa NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfLsdbAreaId,  -- 0.0.0.0 for AS Externals
-                    ospfLsdbType,
-                    ospfLsdbLsid,
-                    ospfLsdbRouterId
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfOriginateLsa trap signifies that a  new
-           LSA  has  been originated by this router.  This
-           trap should not be invoked for simple refreshes
-           of  LSAs  (which happesn every 30 minutes), but
-           instead will only be invoked  when  an  LSA  is
-           (re)originated due to a topology change.  Addi-
-           tionally, this trap does not include LSAs  that
-           are  being  flushed  because  they have reached
-           MaxAge."
-   ::= { ospfTraps 12 }
-
-
-    ospfMaxAgeLsa NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfLsdbAreaId,  -- 0.0.0.0 for AS Externals
-                    ospfLsdbType,
-                    ospfLsdbLsid,
-                    ospfLsdbRouterId
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfMaxAgeLsa trap signifies  that  one  of
-           the LSA in the router's link-state database has
-           aged to MaxAge."
-   ::= { ospfTraps 13 }
-
-
-    ospfLsdbOverflow NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfExtLsdbLimit
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfLsdbOverflow trap  signifies  that  the
-           number of LSAs in the router's link-state data-
-           base has exceeded ospfExtLsdbLimit."
-   ::= { ospfTraps 14 }
-
-
-    ospfLsdbApproachingOverflow NOTIFICATION-TYPE
-        OBJECTS {
-                    ospfRouterId, -- The originator of the trap
-                    ospfExtLsdbLimit
-                  }
-        STATUS             current
-        DESCRIPTION
-           "An ospfLsdbApproachingOverflow trap  signifies
-           that  the  number of LSAs in the router's link-
-           state database has exceeded ninety  percent  of
-           ospfExtLsdbLimit."
-   ::= { ospfTraps 15 }
-
-
--- conformance information
-
-ospfTrapConformance OBJECT IDENTIFIER ::= { ospfTrap 3 }
-
-ospfTrapGroups      OBJECT IDENTIFIER ::= { ospfTrapConformance 1 }
-ospfTrapCompliances OBJECT IDENTIFIER ::= { ospfTrapConformance 2 }
-
--- compliance statements
-
-    ospfTrapCompliance MODULE-COMPLIANCE
-        STATUS  current
-        DESCRIPTION
-           "The compliance statement "
-       MODULE  -- this module
-       MANDATORY-GROUPS { ospfTrapControlGroup }
-
-
-        GROUP       ospfTrapControlGroup
-        DESCRIPTION
-           "This group is optional but recommended for all
-           OSPF systems"
-       ::= { ospfTrapCompliances 1 }
-
-
--- units of conformance
-
-    ospfTrapControlGroup    OBJECT-GROUP
-        OBJECTS {
-                           ospfSetTrap,
-                           ospfConfigErrorType,
-                           ospfPacketType,
-                           ospfPacketSrc
-        }
-        STATUS  current
-        DESCRIPTION
-           "These objects are required  to  control  traps
-           from OSPF systems."
-       ::= { ospfTrapGroups 1 }
-
-
-END
index 16347f1c5bbfe730c98bf148f23d09bd869f5786..3efc219fcb8c38063bd46152636f178f939bb5ed 100644 (file)
@@ -2530,8 +2530,8 @@ DEFUN (show_ip_ospf_mpls_te_link,
        "Interface name\n")
 {
        struct vrf *vrf;
-       int idx_interface = 5;
-       struct interface *ifp;
+       int idx_interface = 0;
+       struct interface *ifp = NULL;
        struct listnode *node;
        char *vrf_name = NULL;
        bool all_vrf;
@@ -2543,7 +2543,7 @@ DEFUN (show_ip_ospf_mpls_te_link,
                vrf_name = argv[idx_vrf + 1]->arg;
                all_vrf = strmatch(vrf_name, "all");
        }
-
+       argv_find(argv, argc, "INTERFACE", &idx_interface);
        /* vrf input is provided could be all or specific vrf*/
        if (vrf_name) {
                if (all_vrf) {
@@ -2557,32 +2557,31 @@ DEFUN (show_ip_ospf_mpls_te_link,
                        return CMD_SUCCESS;
                }
                ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-               if (ospf == NULL || !ospf->oi_running)
-                       return CMD_SUCCESS;
-               vrf = vrf_lookup_by_id(ospf->vrf_id);
-               FOR_ALL_INTERFACES (vrf, ifp)
-                       show_mpls_te_link_sub(vty, ifp);
+       } else
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+       if (ospf == NULL || !ospf->oi_running)
                return CMD_SUCCESS;
-       }
-       /* Show All Interfaces. */
-       if (argc == 5) {
-               for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-                       if (!ospf->oi_running)
-                               continue;
-                       vrf = vrf_lookup_by_id(ospf->vrf_id);
-                       FOR_ALL_INTERFACES (vrf, ifp)
-                               show_mpls_te_link_sub(vty, ifp);
+
+       vrf = vrf_lookup_by_id(ospf->vrf_id);
+       if (!vrf)
+               return CMD_SUCCESS;
+       if (idx_interface) {
+               ifp = if_lookup_by_name(
+                                       argv[idx_interface]->arg,
+                                       ospf->vrf_id);
+               if (ifp == NULL) {
+                       vty_out(vty, "No such interface name in vrf %s\n",
+                               vrf->name);
+                       return CMD_SUCCESS;
                }
        }
-       /* Interface name is specified. */
-       else {
-               ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg);
-               if (ifp == NULL)
-                       vty_out(vty, "No such interface name\n");
-               else
+       if (!ifp) {
+               FOR_ALL_INTERFACES (vrf, ifp)
                        show_mpls_te_link_sub(vty, ifp);
+               return CMD_SUCCESS;
        }
 
+       show_mpls_te_link_sub(vty, ifp);
        return CMD_SUCCESS;
 }
 
index 67f5c7e8902558d40d1d00ed9b5ca2b98b64c5f1..fb08833b61148626abee8ecb020dd9eca6b8d023 100644 (file)
@@ -4687,7 +4687,7 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
 
        ospf_show_vrf_name(ospf, vty, json, use_vrf);
 
-       ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
+       ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
        if (!ifp) {
                if (use_json)
                        json_object_boolean_true_add(json, "noSuchIface");
@@ -4717,34 +4717,50 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
 
 DEFUN (show_ip_ospf_neighbor_int,
        show_ip_ospf_neighbor_int_cmd,
-       "show ip ospf neighbor IFNAME [json]",
+       "show ip ospf [vrf <NAME>] neighbor IFNAME [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
        "Neighbor list\n"
        "Interface name\n"
        JSON_STR)
 {
        struct ospf *ospf;
-       int idx_ifname = 4;
+       int idx_ifname = 0;
+       int idx_vrf = 0;
        bool uj = use_json(argc, argv);
-       struct listnode *node = NULL;
        int ret = CMD_SUCCESS;
        struct interface *ifp = NULL;
+       char *vrf_name = NULL;
+       vrf_id_t vrf_id = VRF_DEFAULT;
+       struct vrf *vrf = NULL;
+
+       if (argv_find(argv, argc, "vrf", &idx_vrf))
+               vrf_name = argv[idx_vrf + 1]->arg;
+       if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
+               vrf_name = NULL;
+       if (vrf_name) {
+               vrf = vrf_lookup_by_name(vrf_name);
+               if (vrf)
+                       vrf_id = vrf->vrf_id;
+       }
+       ospf = ospf_lookup_by_vrf_id(vrf_id);
+
+       if (!ospf || !ospf->oi_running)
+               return ret;
 
        if (!uj)
                show_ip_ospf_neighbour_header(vty);
 
-       ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
-       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-               if (!ospf->oi_running)
-                       continue;
-               if (!ifp || ifp->vrf_id != ospf->vrf_id)
-                       continue;
-               ret = show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname,
-                                                      argv, uj, 0);
-       }
+       argv_find(argv, argc, "IFNAME", &idx_ifname);
 
+       ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
+       if (!ifp)
+               return ret;
+
+       ret = show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname,
+                                              argv, uj, 0);
        return ret;
 }
 
@@ -5576,7 +5592,7 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
                        vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
        }
 
-       ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
+       ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
        if (!ifp) {
                if (!use_json)
                        vty_out(vty, "No such interface.\n");
@@ -10648,28 +10664,45 @@ static void ospf_interface_clear(struct interface *ifp)
 
 DEFUN (clear_ip_ospf_interface,
        clear_ip_ospf_interface_cmd,
-       "clear ip ospf interface [IFNAME]",
+       "clear ip ospf [vrf <NAME>] interface [IFNAME]",
        CLEAR_STR
        IP_STR
        "OSPF information\n"
+       VRF_CMD_HELP_STR
        "Interface information\n"
        "Interface name\n")
 {
-       int idx_ifname = 4;
+       int idx_ifname = 0;
+       int idx_vrf = 0;
        struct interface *ifp;
        struct listnode *node;
        struct ospf *ospf = NULL;
+       char *vrf_name = NULL;
+       vrf_id_t vrf_id = VRF_DEFAULT;
+       struct vrf *vrf = NULL;
 
-       if (argc == 4) /* Clear all the ospfv2 interfaces. */
-       {
+       if (argv_find(argv, argc, "vrf", &idx_vrf))
+               vrf_name = argv[idx_vrf + 1]->arg;
+       if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
+               vrf_name = NULL;
+       if (vrf_name) {
+               vrf = vrf_lookup_by_name(vrf_name);
+               if (vrf)
+                       vrf_id = vrf->vrf_id;
+       }
+       if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
+               /* Clear all the ospfv2 interfaces. */
                for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-                       struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
+                       if (vrf_id != ospf->vrf_id)
+                               continue;
+                       if (!vrf)
+                               vrf = vrf_lookup_by_id(ospf->vrf_id);
                        FOR_ALL_INTERFACES (vrf, ifp)
                                ospf_interface_clear(ifp);
                }
        } else {
                /* Interface name is specified. */
-               ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
+               ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
                if (ifp == NULL)
                        vty_out(vty, "No such interface name\n");
                else
index 83074b5ac018f8c8f2d6a0c152b3cde4e0671bdd..3ad1b870b4b7b01f8ac4b24fe4e52aaa180ad47d 100644 (file)
@@ -108,6 +108,4 @@ ospfd_ospfd_snmp_la_LIBADD = lib/libfrrsnmp.la
 
 EXTRA_DIST += \
        ospfd/ChangeLog.opaque.txt \
-       ospfd/OSPF-MIB.txt \
-       ospfd/OSPF-TRAP-MIB.txt \
        # end
index c301a1c23a5de4d8f9fa85eb5ae1f6704fb26595..7f3ff36df9db6620072310ff217ad35d7da9719f 100644 (file)
@@ -35,7 +35,7 @@
 # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
 #
 watchfrr_enable=yes
-watchfrr_options=("-b_" "-r/usr/lib/frr/frr_restart_%s" "-s/usr/lib/frr/frr_start_%s" "-k/usr/lib/frr/frr_stop_%s")
+watchfrr_options="-r '/usr/lib/frr/frr restart %s' -s '/usr/lib/frr/frr start %s' -k '/usr/lib/frr/frr stop %s'"
 #
 zebra=no
 bgpd=no
index 47a92eed32cc67fb651ad610d81968abbb2ce82f..b59656adcd84d39977aeb534df566640c7f3c49a 100755 (executable)
@@ -107,22 +107,28 @@ check_daemon()
 # The Frr daemons creates the pidfile when starting.
 start()
 {
+    local dmn inst
+    dmn="$1"
+    inst="$2"
+
     ulimit -n $MAX_FDS > /dev/null 2> /dev/null
-    if [ "$1" = "watchfrr" ]; then
+    if [ "$dmn" = "watchfrr" ]; then
 
         # We may need to restart watchfrr if new daemons are added and/or
         # removed
-        if started "$1" ; then
+        if started "$dmn" ; then
             stop watchfrr
         else
             # Echo only once. watchfrr is printed in the stop above
-            echo -n " $1"
+            echo -n " $dmn"
         fi
 
         if [ -e /var/run/frr/watchfrr.started ] ; then
             rm /var/run/frr/watchfrr.started
         fi
-        daemon --pidfile=`pidfile $1` "$D_PATH/$1" -d "${watchfrr_options[@]}"
+        # redhat /etc/init.d/functions daemon() re-expands args :(
+        # eval "set - $watchfrr_options"
+        daemon --pidfile=`pidfile $dmn` "$D_PATH/$dmn" -d "$watchfrr_options"
         RETVAL=$?
         [ $RETVAL -ne 0 ] && break
         for i in `seq 1 10`;
@@ -135,25 +141,25 @@ start()
             fi
         done
         RETVAL=1
-    elif [ -n "$2" ]; then
-        echo -n " $1-$2"
-        if ! check_daemon $1 $2 ; then
+    elif [ -n "$inst" ]; then
+        echo -n " $dmn-$inst"
+        if ! check_daemon $dmn $inst ; then
             echo -n " (binary does not exist)"
             return;
         fi
-        daemon --pidfile=`pidfile $1-$2` "$D_PATH/$1" -d `eval echo "$""$1""_options"` -n "$2"
+        daemon --pidfile=`pidfile $dmn-$inst` "$D_PATH/$dmn" -d `eval echo "$""$dmn""_options"` -n "$inst"
         RETVAL=$?
     else
-        echo -n " $1 "
-        if ! check_daemon $1; then
+        echo -n " $dmn "
+        if ! check_daemon $dmn; then
             echo " (binary does not exist)"
             return;
         fi
-        daemon --pidfile=`pidfile $1` "$D_PATH/$1" -d `eval echo "$""$1""_options"`
+        daemon --pidfile=`pidfile $dmn` "$D_PATH/$dmn" -d `eval echo "$""$dmn""_options"`
         RETVAL=$?
     fi
     echo
-    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$1
+    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$dmn
     return $RETVAL
 }
 
@@ -223,11 +229,9 @@ start_watchfrr()
     fi
 
     # Check variable type
-    if ! declare -p watchfrr_options | grep -q '^declare \-a'; then
-        echo
-        echo "ERROR: The variable watchfrr_options from /etc/frr/daemons must be a BASH array!"
-        echo "ERROR: Please convert config file and restart!"
-        exit 1
+    if declare -p watchfrr_options | grep -q '^declare \-a'; then
+        # old array support
+        watchfrr_options="${watchfrr_options[@]}"
     fi
 
     # Which daemons have been started?
@@ -241,13 +245,13 @@ start_watchfrr()
                     eval "inst_disable=\${${daemon_name}_${inst}}"
                     if [ -z ${inst_disable} ] || [ ${inst_disable} != 0 ]; then
                         if check_daemon $daemon_name $inst; then
-                            watchfrr_options+=("${daemon_name}-${inst}")
+                            watchfrr_options="$watchfrr_options ${daemon_name}-${inst}"
                         fi
                     fi
                 done
             else
                 if check_daemon $daemon_name; then
-                    watchfrr_options+=($daemon_name)
+                    watchfrr_options="$watchfrr_options $daemon_name"
                 fi
             fi
             found_one=1
index d2da06faa6e90bbcf8e5426445bf7f7ad70fe38c..7a6344aa4c797830b393e394a47b53e4b14136d6 100644 (file)
@@ -637,6 +637,9 @@ fi
 %config(noreplace) %{_sysconfdir}/pam.d/frr
 %config(noreplace) %{_sysconfdir}/logrotate.d/frr
 %{_sbindir}/frr-reload
+%{_sbindir}/frrcommon.sh
+%{_sbindir}/frrinit.sh
+%{_sbindir}/watchfrr.sh
 
 
 %files contrib
diff --git a/ripd/RIPv2-MIB.txt b/ripd/RIPv2-MIB.txt
deleted file mode 100644 (file)
index 6c92fb5..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-   RIPv2-MIB DEFINITIONS ::= BEGIN
-
-   IMPORTS
-       MODULE-IDENTITY, OBJECT-TYPE, Counter32,
-       TimeTicks, IpAddress                     FROM SNMPv2-SMI
-       TEXTUAL-CONVENTION, RowStatus            FROM SNMPv2-TC
-       MODULE-COMPLIANCE, OBJECT-GROUP          FROM SNMPv2-CONF
-       mib-2                                    FROM RFC1213-MIB;
-
-   --  This MIB module uses the extended OBJECT-TYPE macro as
-   --  defined in [9].
-
-   rip2  MODULE-IDENTITY
-           LAST-UPDATED "9407272253Z"      -- Wed Jul 27 22:53:04 PDT 1994
-           ORGANIZATION "IETF RIP-II Working Group"
-           CONTACT-INFO
-          "       Fred Baker
-          Postal: Cisco Systems
-                  519 Lado Drive
-                  Santa Barbara, California 93111
-          Tel:    +1 805 681 0115
-          E-Mail: fbaker@cisco.com
-
-          Postal: Gary Malkin
-                  Xylogics, Inc.
-                  53 Third Avenue
-                  Burlington, MA  01803
-
-          Phone:  (617) 272-8140
-          EMail:  gmalkin@Xylogics.COM"
-      DESCRIPTION
-         "The MIB module to describe the RIP2 Version 2 Protocol"
-     ::= { mib-2 23 }
-
- --  RIP-2 Management Information Base
-
- -- the RouteTag type represents the contents of the
- -- Route Domain field in the packet header or route entry.
- -- The use of the Route Domain is deprecated.
-
- RouteTag ::= TEXTUAL-CONVENTION
-     STATUS      current
-     DESCRIPTION
-        "the RouteTag type represents the contents of the Route Domain
-        field in the packet header or route entry"
-    SYNTAX      OCTET STRING (SIZE (2))
-
---4.1 Global Counters
-
---      The RIP-2 Globals Group.
---      Implementation of this group is mandatory for systems
---      which implement RIP-2.
-
--- These counters are intended to facilitate debugging quickly
--- changing routes or failing neighbors
-
-rip2Globals OBJECT IDENTIFIER ::= { rip2 1 }
-
-    rip2GlobalRouteChanges OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of route changes made to the IP Route
-           Database by RIP.  This does not include the refresh
-           of a route's age."
-       ::= { rip2Globals 1 }
-
-    rip2GlobalQueries OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of responses sent to RIP queries
-           from other systems."
-       ::= { rip2Globals 2 }
-
---4.2 RIP Interface Tables
-
---  RIP Interfaces Groups
---  Implementation of these Groups is mandatory for systems
---  which implement RIP-2.
-
--- The RIP Interface Status Table.
-
-    rip2IfStatTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF Rip2IfStatEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A list of subnets which require separate
-           status monitoring in RIP."
-       ::= { rip2 2 }
-
-   rip2IfStatEntry OBJECT-TYPE
-       SYNTAX   Rip2IfStatEntry
-       MAX-ACCESS   not-accessible
-       STATUS   current
-       DESCRIPTION
-          "A Single Routing Domain in a single Subnet."
-      INDEX { rip2IfStatAddress }
-      ::= { rip2IfStatTable 1 }
-
-    Rip2IfStatEntry ::=
-        SEQUENCE {
-            rip2IfStatAddress
-                IpAddress,
-            rip2IfStatRcvBadPackets
-                Counter32,
-            rip2IfStatRcvBadRoutes
-                Counter32,
-            rip2IfStatSentUpdates
-                Counter32,
-            rip2IfStatStatus
-                RowStatus
-    }
-
-    rip2IfStatAddress OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP Address of this system on the indicated
-           subnet. For unnumbered interfaces, the value 0.0.0.N,
-           where the least significant 24 bits (N) is the ifIndex
-           for the IP Interface in network byte order."
-       ::= { rip2IfStatEntry 1 }
-
-    rip2IfStatRcvBadPackets OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of RIP response packets received by
-           the RIP process which were subsequently discarded
-           for any reason (e.g. a version 0 packet, or an
-           unknown command type)."
-       ::= { rip2IfStatEntry 2 }
-
-    rip2IfStatRcvBadRoutes OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of routes, in valid RIP packets,
-           which were ignored for any reason (e.g. unknown
-           address family, or invalid metric)."
-       ::= { rip2IfStatEntry 3 }
-
-    rip2IfStatSentUpdates OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of triggered RIP updates actually
-           sent on this interface.  This explicitly does
-           NOT include full updates sent containing new
-           information."
-       ::= { rip2IfStatEntry 4 }
-
-    rip2IfStatStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "Writing invalid has the effect of deleting
-           this interface."
-       ::= { rip2IfStatEntry 5 }
-
--- The RIP Interface Configuration Table.
-
-    rip2IfConfTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF Rip2IfConfEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A list of subnets which require separate
-           configuration in RIP."
-       ::= { rip2 3 }
-
-   rip2IfConfEntry OBJECT-TYPE
-       SYNTAX   Rip2IfConfEntry
-       MAX-ACCESS   not-accessible
-       STATUS   current
-       DESCRIPTION
-          "A Single Routing Domain in a single Subnet."
-      INDEX { rip2IfConfAddress }
-      ::= { rip2IfConfTable 1 }
-
-    Rip2IfConfEntry ::=
-        SEQUENCE {
-            rip2IfConfAddress
-                IpAddress,
-            rip2IfConfDomain
-                RouteTag,
-            rip2IfConfAuthType
-                INTEGER,
-            rip2IfConfAuthKey
-                OCTET STRING (SIZE(0..16)),
-            rip2IfConfSend
-                INTEGER,
-            rip2IfConfReceive
-                INTEGER,
-            rip2IfConfDefaultMetric
-                INTEGER,
-            rip2IfConfStatus
-                RowStatus,
-            rip2IfConfSrcAddress
-                IpAddress
-    }
-
-    rip2IfConfAddress OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP Address of this system on the indicated
-           subnet.  For unnumbered interfaces, the value 0.0.0.N,
-           where the least significant 24 bits (N) is the ifIndex
-           for the IP Interface in network byte order."
-       ::= { rip2IfConfEntry 1 }
-
-    rip2IfConfDomain OBJECT-TYPE
-        SYNTAX   RouteTag
-        MAX-ACCESS   read-create
-        STATUS   obsolete
-        DESCRIPTION
-           "Value inserted into the Routing Domain field
-           of all RIP packets sent on this interface."
-       DEFVAL { '0000'h }
-       ::= { rip2IfConfEntry 2 }
-
-    rip2IfConfAuthType OBJECT-TYPE
-        SYNTAX   INTEGER {
-                    noAuthentication (1),
-                    simplePassword (2),
-                    md5 (3)
-                 }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The type of Authentication used on this
-           interface."
-       DEFVAL { noAuthentication }
-       ::= { rip2IfConfEntry 3 }
-
-    rip2IfConfAuthKey OBJECT-TYPE
-        SYNTAX   OCTET STRING (SIZE(0..16))
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The value to be used as the Authentication Key
-           whenever the corresponding instance of
-           rip2IfConfAuthType has a value other than
-           noAuthentication.  A modification of the corresponding
-           instance of rip2IfConfAuthType does not modify
-           the rip2IfConfAuthKey value.  If a string shorter
-           than 16 octets is supplied, it will be left-
-           justified and padded to 16 octets, on the right,
-           with nulls (0x00).
-
-           Reading this object always results in an  OCTET
-           STRING of length zero; authentication may not
-           be bypassed by reading the MIB object."
-       DEFVAL { ''h }
-       ::= { rip2IfConfEntry 4 }
-
-    rip2IfConfSend OBJECT-TYPE
-        SYNTAX   INTEGER {
-                    doNotSend (1),
-                    ripVersion1 (2),
-                    rip1Compatible (3),
-                    ripVersion2 (4),
-                    ripV1Demand (5),
-                    ripV2Demand (6)
-                 }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "What the router sends on this interface.
-           ripVersion1 implies sending RIP updates compliant
-           with  RFC  1058.   rip1Compatible implies
-           broadcasting RIP-2 updates using RFC 1058 route
-           subsumption rules.  ripVersion2 implies
-           multicasting RIP-2 updates.  ripV1Demand indicates
-           the use of Demand RIP on a WAN interface under RIP
-           Version 1 rules.  ripV2Demand indicates the use of
-           Demand RIP on a WAN interface under Version 2 rules."
-       DEFVAL { rip1Compatible }
-       ::= { rip2IfConfEntry 5 }
-
-    rip2IfConfReceive OBJECT-TYPE
-        SYNTAX   INTEGER {
-                    rip1 (1),
-                    rip2 (2),
-                    rip1OrRip2 (3),
-                    doNotRecieve (4)
-                 }
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This indicates which version of RIP updates
-           are to be accepted.  Note that rip2 and
-           rip1OrRip2 implies reception of multicast
-           packets."
-       DEFVAL { rip1OrRip2 }
-       ::= { rip2IfConfEntry 6 }
-
-    rip2IfConfDefaultMetric OBJECT-TYPE
-        SYNTAX   INTEGER ( 0..15 )
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "This variable indicates the metric that is to
-           be used for the default route entry in RIP updates
-           originated on this interface.  A value of zero
-           indicates that no default route should be
-           originated; in this case, a default route via
-           another router may be propagated."
-       ::= { rip2IfConfEntry 7 }
-
-    rip2IfConfStatus OBJECT-TYPE
-        SYNTAX   RowStatus
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "Writing invalid has  the  effect  of  deleting
-           this interface."
-       ::= { rip2IfConfEntry 8 }
-
-    rip2IfConfSrcAddress OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-create
-        STATUS   current
-        DESCRIPTION
-           "The IP Address this system will use as a source
-            address on this interface.  If it is a numbered
-            interface, this MUST be the same value as
-            rip2IfConfAddress.  On unnumbered interfaces,
-            it must be the value of rip2IfConfAddress for
-            some interface on the system."
-       ::= { rip2IfConfEntry 9 }
-
---4.3 Peer Table
-
---  Peer Table
-
---      The RIP Peer Group
---      Implementation of this Group is Optional
-
---      This group provides information about active peer
---      relationships intended to assist in debugging.  An
---      active peer is a router from which a valid RIP
---      updated has been heard in the last 180 seconds.
-
-    rip2PeerTable OBJECT-TYPE
-        SYNTAX   SEQUENCE OF Rip2PeerEntry
-        MAX-ACCESS   not-accessible
-        STATUS   current
-        DESCRIPTION
-           "A list of RIP Peers."
-       ::= { rip2 4 }
-
-   rip2PeerEntry OBJECT-TYPE
-       SYNTAX   Rip2PeerEntry
-       MAX-ACCESS   not-accessible
-       STATUS   current
-       DESCRIPTION
-          "Information regarding a single routing peer."
-      INDEX { rip2PeerAddress, rip2PeerDomain }
-      ::= { rip2PeerTable 1 }
-
-    Rip2PeerEntry ::=
-        SEQUENCE {
-            rip2PeerAddress
-                IpAddress,
-            rip2PeerDomain
-                RouteTag,
-            rip2PeerLastUpdate
-                TimeTicks,
-            rip2PeerVersion
-                INTEGER,
-            rip2PeerRcvBadPackets
-                Counter32,
-            rip2PeerRcvBadRoutes
-                Counter32
-            }
-
-    rip2PeerAddress OBJECT-TYPE
-        SYNTAX   IpAddress
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The IP Address that the peer is using as its source
-            address.  Note that on an unnumbered link, this may
-            not be a member of any subnet on the system."
-       ::= { rip2PeerEntry 1 }
-
-    rip2PeerDomain OBJECT-TYPE
-        SYNTAX   RouteTag
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The value in the Routing Domain field  in  RIP
-           packets received from the peer.  As domain suuport
-           is deprecated, this must be zero."
-       ::= { rip2PeerEntry 2 }
-
-    rip2PeerLastUpdate OBJECT-TYPE
-        SYNTAX   TimeTicks
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The value of sysUpTime when the most recent
-           RIP update was received from this system."
-       ::= { rip2PeerEntry 3 }
-
-    rip2PeerVersion OBJECT-TYPE
-        SYNTAX   INTEGER ( 0..255 )
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The RIP version number in the header of the
-           last RIP packet received."
-       ::= { rip2PeerEntry 4 }
-
-    rip2PeerRcvBadPackets OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of RIP response packets from this
-           peer discarded as invalid."
-       ::= { rip2PeerEntry 5 }
-
-
-    rip2PeerRcvBadRoutes OBJECT-TYPE
-        SYNTAX   Counter32
-        MAX-ACCESS   read-only
-        STATUS   current
-        DESCRIPTION
-           "The number of routes from this peer that were
-           ignored because the entry format was invalid."
-       ::= { rip2PeerEntry 6 }
-
--- conformance information
-
-rip2Conformance OBJECT IDENTIFIER ::= { rip2 5 }
-
-rip2Groups      OBJECT IDENTIFIER ::= { rip2Conformance 1 }
-rip2Compliances OBJECT IDENTIFIER ::= { rip2Conformance 2 }
-
--- compliance statements
-rip2Compliance MODULE-COMPLIANCE
-    STATUS  current
-    DESCRIPTION
-       "The compliance statement "
-    MODULE  -- this module
-    MANDATORY-GROUPS {
-                 rip2GlobalGroup,
-                 rip2IfStatGroup,
-                 rip2IfConfGroup,
-                 rip2PeerGroup
-        }
-    GROUP       rip2GlobalGroup
-    DESCRIPTION
-       "This group defines global controls for RIP-II systems."
-    GROUP       rip2IfStatGroup
-    DESCRIPTION
-       "This group defines interface statistics for RIP-II systems."
-    GROUP       rip2IfConfGroup
-    DESCRIPTION
-       "This group defines interface configuration for RIP-II systems."
-    GROUP       rip2PeerGroup
-    DESCRIPTION
-       "This group defines peer information for RIP-II systems."
-    ::= { rip2Compliances 1 }
-
--- units of conformance
-
-rip2GlobalGroup    OBJECT-GROUP
-    OBJECTS {
-                rip2GlobalRouteChanges,
-                rip2GlobalQueries
-    }
-    STATUS  current
-    DESCRIPTION
-       "This group defines global controls for RIP-II systems."
-    ::= { rip2Groups 1 }
-rip2IfStatGroup    OBJECT-GROUP
-    OBJECTS {
-            rip2IfStatAddress,
-            rip2IfStatRcvBadPackets,
-            rip2IfStatRcvBadRoutes,
-            rip2IfStatSentUpdates,
-            rip2IfStatStatus
-    }
-    STATUS  current
-    DESCRIPTION
-       "This group defines interface statistics for RIP-II systems."
-    ::= { rip2Groups 2 }
-rip2IfConfGroup    OBJECT-GROUP
-    OBJECTS {
-            rip2IfConfAddress,
-            rip2IfConfAuthType,
-            rip2IfConfAuthKey,
-            rip2IfConfSend,
-            rip2IfConfReceive,
-            rip2IfConfDefaultMetric,
-            rip2IfConfStatus,
-            rip2IfConfSrcAddress
-    }
-    STATUS  current
-    DESCRIPTION
-       "This group defines interface configuration for RIP-II systems."
-    ::= { rip2Groups 3 }
-rip2PeerGroup    OBJECT-GROUP
-    OBJECTS {
-            rip2PeerAddress,
-            rip2PeerDomain,
-            rip2PeerLastUpdate,
-            rip2PeerVersion,
-            rip2PeerRcvBadPackets,
-            rip2PeerRcvBadRoutes
-    }
-    STATUS  current
-    DESCRIPTION
-       "This group defines peer information for RIP-II systems."
-    ::= { rip2Groups 4 }
-END
index e0e5d95895c970cbe2d322f0d5f8d507ead4cfb1..5bb81ef157c2f1a10da77634e89a7ab22cbebd1c 100644 (file)
@@ -210,7 +210,8 @@ DEFPY (rip_distance_source,
 {
        if (!no) {
                nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
-               nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY, NULL);
+               nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
+                                     distance_str);
                nb_cli_enqueue_change(vty, "./access-list",
                                      acl ? NB_OP_MODIFY : NB_OP_DELETE, acl);
        } else
index 2ce289e38f62a4c984e3d771fe979a0b5a09b251..3356d99c2ab8651b522ec61a870c575c663a7e21 100644 (file)
@@ -204,13 +204,6 @@ static int config_write_debug(struct vty *vty)
        return write;
 }
 
-void rip_debug_reset(void)
-{
-       rip_debug_event = 0;
-       rip_debug_packet = 0;
-       rip_debug_zebra = 0;
-}
-
 void rip_debug_init(void)
 {
        rip_debug_event = 0;
index c3b15d2e1524d2bf93a8fe66e52bc1385df73662..3d819ccd0ba325ae5fa0d458f2df026e5def3f64 100644 (file)
@@ -47,6 +47,5 @@ extern unsigned long rip_debug_packet;
 extern unsigned long rip_debug_zebra;
 
 extern void rip_debug_init(void);
-extern void rip_debug_reset(void);
 
 #endif /* _ZEBRA_RIP_DEBUG_H */
index 3d11ba1464043d6b2dec292cd457e8d316a4c862..96b1cd89387d0a5ab30b0385a66d6104da47b11c 100644 (file)
@@ -531,15 +531,6 @@ static void rip_interface_reset(struct rip_interface *ri)
        rip_interface_clean(ri);
 }
 
-void rip_interfaces_reset(void)
-{
-       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
-       struct interface *ifp;
-
-       FOR_ALL_INTERFACES (vrf, ifp)
-               rip_interface_reset(ifp->info);
-}
-
 int rip_if_down(struct interface *ifp)
 {
        struct route_node *rp;
index 421b0afe389e22f0fbb0c26ced2d8086d4230883..4e445bd46df4bddab4cc14b084d4551a44b99506 100644 (file)
@@ -170,6 +170,7 @@ static int ripd_instance_distance_source_create(enum nb_event event,
                return NB_OK;
 
        yang_dnode_get_ipv4p(&prefix, dnode, "./prefix");
+       apply_mask_ipv4(&prefix);
 
        /* Get RIP distance node. */
        rn = route_node_get(rip_distance_table, (struct prefix *)&prefix);
@@ -317,6 +318,7 @@ static int ripd_instance_network_create(enum nb_event event,
                return NB_OK;
 
        yang_dnode_get_ipv4p(&p, dnode, NULL);
+       apply_mask_ipv4((struct prefix_ipv4 *)&p);
 
        return rip_enable_network_add(&p);
 }
@@ -330,6 +332,7 @@ static int ripd_instance_network_delete(enum nb_event event,
                return NB_OK;
 
        yang_dnode_get_ipv4p(&p, dnode, NULL);
+       apply_mask_ipv4((struct prefix_ipv4 *)&p);
 
        return rip_enable_network_delete(&p);
 }
@@ -605,10 +608,9 @@ ripd_instance_redistribute_route_map_delete(enum nb_event event,
 
        type = yang_dnode_get_enum(dnode, "../protocol");
 
-       if (rip->route_map[type].name) {
-               free(rip->route_map[type].name);
-               rip->route_map[type].name = NULL;
-       }
+       free(rip->route_map[type].name);
+       rip->route_map[type].name = NULL;
+       rip->route_map[type].map = NULL;
 
        return NB_OK;
 }
@@ -667,6 +669,7 @@ static int ripd_instance_static_route_create(enum nb_event event,
                return NB_OK;
 
        yang_dnode_get_ipv4p(&p, dnode, NULL);
+       apply_mask_ipv4(&p);
 
        memset(&nh, 0, sizeof(nh));
        nh.type = NEXTHOP_TYPE_IPV4;
@@ -685,6 +688,7 @@ static int ripd_instance_static_route_delete(enum nb_event event,
                return NB_OK;
 
        yang_dnode_get_ipv4p(&p, dnode, NULL);
+       apply_mask_ipv4(&p);
 
        rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
 
index b69b2466d5c9c61c0de95170a9ce0252e97318ad..b34f944c9e62ab23069c8cdcca84293789c9dd2f 100644 (file)
@@ -517,11 +517,6 @@ static struct route_map_rule_cmd route_set_tag_cmd = {
 #define MATCH_STR "Match values from routing table\n"
 #define SET_STR "Set values in destination routing protocol\n"
 
-void rip_route_map_reset()
-{
-       ;
-}
-
 /* Route-map init */
 void rip_route_map_init()
 {
index 20f543a2588981b91bf8fe5faa34a9da4b0202cf..fff8681775a8c997f94b37272956d7b063cb6fae 100644 (file)
@@ -147,11 +147,6 @@ static int rip_zebra_read_route(int command, struct zclient *zclient,
        return 0;
 }
 
-void rip_zclient_reset(void)
-{
-       zclient_reset(zclient);
-}
-
 void rip_redistribute_conf_update(int type)
 {
        zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
index 4a6765308e59d541cbfe773e0c4835a6501091cc..59a883225768ed5d10861c3cd36894b4d55ff5ee 100644 (file)
@@ -3364,8 +3364,8 @@ void rip_clean(void)
                        if (rip->route_map[i].name)
                                free(rip->route_map[i].name);
 
-               XFREE(MTYPE_ROUTE_TABLE, rip->table);
-               XFREE(MTYPE_ROUTE_TABLE, rip->neighbor);
+               route_table_finish(rip->table);
+               route_table_finish(rip->neighbor);
 
                XFREE(MTYPE_RIP, rip);
                rip = NULL;
index d4fb230a20a504e6331cf9f22302c80f50305e6f..91fab2a7a2e3d63b190b8be002db5c88f25e1393 100644 (file)
@@ -376,17 +376,14 @@ extern void rip_init(void);
 extern void rip_clean(void);
 extern void rip_clean_network(void);
 extern void rip_interfaces_clean(void);
-extern void rip_interfaces_reset(void);
 extern int rip_passive_nondefault_set(const char *ifname);
 extern int rip_passive_nondefault_unset(const char *ifname);
 extern void rip_passive_nondefault_clean(void);
 extern void rip_if_init(void);
 extern void rip_if_down_all(void);
 extern void rip_route_map_init(void);
-extern void rip_route_map_reset(void);
 extern void rip_zclient_init(struct thread_master *);
 extern void rip_zclient_stop(void);
-extern void rip_zclient_reset(void);
 extern int if_check_address(struct in_addr addr);
 extern int rip_create(int socket);
 
index ed74047ccef933f11f7b61fc8ab09caec9d2badf..1c2f8d64c8fda43a736645a6969e80280aaeefdf 100644 (file)
@@ -9,9 +9,6 @@ dist_examples_DATA += ripd/ripd.conf.sample
 vtysh_scan += \
        $(top_srcdir)/ripd/rip_cli.c \
        $(top_srcdir)/ripd/rip_debug.c \
-       $(top_srcdir)/ripd/rip_interface.c \
-       $(top_srcdir)/ripd/rip_offset.c \
-       $(top_srcdir)/ripd/rip_zebra.c \
        $(top_srcdir)/ripd/ripd.c \
        # end
 
@@ -59,5 +56,3 @@ ripd_ripd_snmp_la_SOURCES = ripd/rip_snmp.c
 ripd_ripd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
 ripd_ripd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
 ripd_ripd_snmp_la_LIBADD = lib/libfrrsnmp.la
-
-EXTRA_DIST += ripd/RIPv2-MIB.txt
diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c
new file mode 100644 (file)
index 0000000..a187e80
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ * Copyright (C) 2018 NetDEF, Inc.
+ *                    Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "if.h"
+#include "vrf.h"
+#include "log.h"
+#include "prefix.h"
+#include "command.h"
+#include "northbound_cli.h"
+#include "libfrr.h"
+
+#include "ripngd/ripngd.h"
+#include "ripngd/ripng_cli.h"
+#ifndef VTYSH_EXTRACT_PL
+#include "ripngd/ripng_cli_clippy.c"
+#endif
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance
+ */
+DEFPY_NOSH (router_ripng,
+       router_ripng_cmd,
+       "router ripng",
+       "Enable a routing process\n"
+       "Make RIPng instance command\n")
+{
+       int ret;
+
+       nb_cli_enqueue_change(vty, "/frr-ripngd:ripngd/instance", NB_OP_CREATE,
+                             NULL);
+
+       ret = nb_cli_apply_changes(vty, NULL);
+       if (ret == CMD_SUCCESS)
+               VTY_PUSH_XPATH(RIPNG_NODE, "/frr-ripngd:ripngd/instance");
+
+       return ret;
+}
+
+DEFPY (no_router_ripng,
+       no_router_ripng_cmd,
+       "no router ripng",
+       NO_STR
+       "Enable a routing process\n"
+       "Make RIPng instance command\n")
+{
+       nb_cli_enqueue_change(vty, "/frr-ripngd:ripngd/instance", NB_OP_DELETE,
+                             NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode,
+                        bool show_defaults)
+{
+       vty_out(vty, "!\n");
+       vty_out(vty, "router ripng\n");
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
+ */
+DEFPY (ripng_allow_ecmp,
+       ripng_allow_ecmp_cmd,
+       "[no] allow-ecmp",
+       NO_STR
+       "Allow Equal Cost MultiPath\n")
+{
+       nb_cli_enqueue_change(vty, "./allow-ecmp", NB_OP_MODIFY,
+                             no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_allow_ecmp(struct vty *vty, struct lyd_node *dnode,
+                              bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+
+       vty_out(vty, " allow-ecmp\n");
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/default-information-originate
+ */
+DEFPY (ripng_default_information_originate,
+       ripng_default_information_originate_cmd,
+       "[no] default-information originate",
+       NO_STR
+       "Default route information\n"
+       "Distribute default route\n")
+{
+       nb_cli_enqueue_change(vty, "./default-information-originate",
+                             NB_OP_MODIFY, no ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_default_information_originate(struct vty *vty,
+                                                 struct lyd_node *dnode,
+                                                 bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no");
+
+       vty_out(vty, " default-information originate\n");
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/default-metric
+ */
+DEFPY (ripng_default_metric,
+       ripng_default_metric_cmd,
+       "default-metric (1-16)",
+       "Set a metric of redistribute routes\n"
+       "Default metric\n")
+{
+       nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY,
+                             default_metric_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY (no_ripng_default_metric,
+       no_ripng_default_metric_cmd,
+       "no default-metric [(1-16)]",
+       NO_STR
+       "Set a metric of redistribute routes\n"
+       "Default metric\n")
+{
+       nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_default_metric(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       vty_out(vty, " default-metric %s\n",
+               yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/network
+ */
+DEFPY (ripng_network_prefix,
+       ripng_network_prefix_cmd,
+       "[no] network X:X::X:X/M",
+       NO_STR
+       "RIPng enable on specified interface or network.\n"
+       "IPv6 network\n")
+{
+       nb_cli_enqueue_change(vty, "./network",
+                             no ? NB_OP_DELETE : NB_OP_CREATE, network_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_network_prefix(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/interface
+ */
+DEFPY (ripng_network_if,
+       ripng_network_if_cmd,
+       "[no] network WORD",
+       NO_STR
+       "RIPng enable on specified interface or network.\n"
+       "Interface name\n")
+{
+       nb_cli_enqueue_change(vty, "./interface",
+                             no ? NB_OP_DELETE : NB_OP_CREATE, network);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_network_interface(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
+{
+       vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/offset-list
+ */
+DEFPY (ripng_offset_list,
+       ripng_offset_list_cmd,
+       "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]",
+       NO_STR
+       "Modify RIPng metric\n"
+       "Access-list name\n"
+       "For incoming updates\n"
+       "For outgoing updates\n"
+       "Metric value\n"
+       "Interface to match\n")
+{
+       if (!no) {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl);
+               nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
+                                     metric_str);
+       } else
+               nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+
+       return nb_cli_apply_changes(
+               vty, "./offset-list[interface='%s'][direction='%s']",
+               ifname ? ifname : "*", direction);
+}
+
+void cli_show_ripng_offset_list(struct vty *vty, struct lyd_node *dnode,
+                               bool show_defaults)
+{
+       const char *interface;
+
+       interface = yang_dnode_get_string(dnode, "./interface");
+
+       vty_out(vty, " offset-list %s %s %s",
+               yang_dnode_get_string(dnode, "./access-list"),
+               yang_dnode_get_string(dnode, "./direction"),
+               yang_dnode_get_string(dnode, "./metric"));
+       if (!strmatch(interface, "*"))
+               vty_out(vty, " %s", interface);
+       vty_out(vty, "\n");
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/passive-interface
+ */
+DEFPY (ripng_passive_interface,
+       ripng_passive_interface_cmd,
+       "[no] passive-interface IFNAME",
+       NO_STR
+       "Suppress routing updates on an interface\n"
+       "Interface name\n")
+{
+       nb_cli_enqueue_change(vty, "./passive-interface",
+                             no ? NB_OP_DELETE : NB_OP_CREATE, ifname);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_passive_interface(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
+{
+       vty_out(vty, " passive-interface %s\n",
+               yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/redistribute
+ */
+DEFPY (ripng_redistribute,
+       ripng_redistribute_cmd,
+       "[no] redistribute " FRR_REDIST_STR_RIPNGD "$protocol [{metric (0-16)|route-map WORD}]",
+       NO_STR
+       REDIST_STR
+       FRR_REDIST_HELP_STR_RIPNGD
+       "Metric\n"
+       "Metric value\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+{
+       if (!no) {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./route-map",
+                                     route_map ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     route_map);
+               nb_cli_enqueue_change(vty, "./metric",
+                                     metric_str ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     metric_str);
+       } else
+               nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+
+       return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']",
+                                   protocol);
+}
+
+void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode,
+                                bool show_defaults)
+{
+       vty_out(vty, " redistribute %s",
+               yang_dnode_get_string(dnode, "./protocol"));
+       if (yang_dnode_exists(dnode, "./metric"))
+               vty_out(vty, " metric %s",
+                       yang_dnode_get_string(dnode, "./metric"));
+       if (yang_dnode_exists(dnode, "./route-map"))
+               vty_out(vty, " route-map %s",
+                       yang_dnode_get_string(dnode, "./route-map"));
+       vty_out(vty, "\n");
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/static-route
+ */
+DEFPY (ripng_route,
+       ripng_route_cmd,
+       "[no] route X:X::X:X/M",
+       NO_STR
+       "Static route setup\n"
+       "Set static RIPng route announcement\n")
+{
+       nb_cli_enqueue_change(vty, "./static-route",
+                             no ? NB_OP_DELETE : NB_OP_CREATE, route_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_route(struct vty *vty, struct lyd_node *dnode,
+                         bool show_defaults)
+{
+       vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/aggregate-addres
+ */
+DEFPY (ripng_aggregate_address,
+       ripng_aggregate_address_cmd,
+       "[no] aggregate-address X:X::X:X/M",
+       NO_STR
+       "Set aggregate RIPng route announcement\n"
+       "Aggregate network\n")
+{
+       nb_cli_enqueue_change(vty, "./aggregate-address",
+                             no ? NB_OP_DELETE : NB_OP_CREATE,
+                             aggregate_address_str);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ripng_aggregate_address(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
+{
+       vty_out(vty, " aggregate-address %s\n",
+               yang_dnode_get_string(dnode, NULL));
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers
+ */
+DEFPY (ripng_timers,
+       ripng_timers_cmd,
+       "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage",
+       "RIPng timers setup\n"
+       "Basic timer\n"
+       "Routing table update timer value in second. Default is 30.\n"
+       "Routing information timeout timer. Default is 180.\n"
+       "Garbage collection timer. Default is 120.\n")
+{
+       nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY,
+                             update_str);
+       nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY,
+                             timeout_str);
+       nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY,
+                             garbage_str);
+
+       return nb_cli_apply_changes(vty, "./timers");
+}
+
+DEFPY (no_ripng_timers,
+       no_ripng_timers_cmd,
+       "no timers basic [(1-65535) (1-65535) (1-65535)]",
+       NO_STR
+       "RIPng timers setup\n"
+       "Basic timer\n"
+       "Routing table update timer value in second. Default is 30.\n"
+       "Routing information timeout timer. Default is 180.\n"
+       "Garbage collection timer. Default is 120.\n")
+{
+       nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL);
+       nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL);
+       nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, "./timers");
+}
+
+void cli_show_ripng_timers(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       vty_out(vty, " timers basic %s %s %s\n",
+               yang_dnode_get_string(dnode, "./update-interval"),
+               yang_dnode_get_string(dnode, "./holddown-interval"),
+               yang_dnode_get_string(dnode, "./flush-interval"));
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
+ */
+DEFPY (ipv6_ripng_split_horizon,
+       ipv6_ripng_split_horizon_cmd,
+       "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]",
+       NO_STR
+       IPV6_STR
+       "Routing Information Protocol\n"
+       "Perform split horizon\n"
+       "With poisoned-reverse\n")
+{
+       const char *value;
+
+       if (no)
+               value = "disabled";
+       else if (poisoned_reverse)
+               value = "poison-reverse";
+       else
+               value = "simple";
+
+       nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
+
+       return nb_cli_apply_changes(vty, "./frr-ripngd:ripng");
+}
+
+void cli_show_ipv6_ripng_split_horizon(struct vty *vty, struct lyd_node *dnode,
+                                      bool show_defaults)
+{
+       int value;
+
+       value = yang_dnode_get_enum(dnode, NULL);
+       switch (value) {
+       case RIPNG_NO_SPLIT_HORIZON:
+               vty_out(vty, " no ipv6 ripng split-horizon\n");
+               break;
+       case RIPNG_SPLIT_HORIZON:
+               vty_out(vty, " ipv6 ripng split-horizon\n");
+               break;
+       case RIPNG_SPLIT_HORIZON_POISONED_REVERSE:
+               vty_out(vty, " ipv6 ripng split-horizon poisoned-reverse\n");
+               break;
+       }
+}
+
+/*
+ * XPath: /frr-ripngd:clear-ripng-route
+ */
+DEFPY (clear_ipv6_rip,
+       clear_ipv6_rip_cmd,
+       "clear ipv6 ripng",
+       CLEAR_STR
+       IPV6_STR
+       "Clear IPv6 RIP database\n")
+{
+       return nb_cli_rpc("/frr-ripngd:clear-ripng-route", NULL, NULL);
+}
+
+void ripng_cli_init(void)
+{
+       install_element(CONFIG_NODE, &router_ripng_cmd);
+       install_element(CONFIG_NODE, &no_router_ripng_cmd);
+
+       install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
+       install_element(RIPNG_NODE, &ripng_default_information_originate_cmd);
+       install_element(RIPNG_NODE, &ripng_default_metric_cmd);
+       install_element(RIPNG_NODE, &no_ripng_default_metric_cmd);
+       install_element(RIPNG_NODE, &ripng_network_prefix_cmd);
+       install_element(RIPNG_NODE, &ripng_network_if_cmd);
+       install_element(RIPNG_NODE, &ripng_offset_list_cmd);
+       install_element(RIPNG_NODE, &ripng_passive_interface_cmd);
+       install_element(RIPNG_NODE, &ripng_redistribute_cmd);
+       install_element(RIPNG_NODE, &ripng_route_cmd);
+       install_element(RIPNG_NODE, &ripng_aggregate_address_cmd);
+       install_element(RIPNG_NODE, &ripng_timers_cmd);
+       install_element(RIPNG_NODE, &no_ripng_timers_cmd);
+
+       install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd);
+
+       install_element(ENABLE_NODE, &clear_ipv6_rip_cmd);
+}
diff --git a/ripngd/ripng_cli.h b/ripngd/ripng_cli.h
new file mode 100644 (file)
index 0000000..d95747e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ * Copyright (C) 2018 NetDEF, Inc.
+ *                    Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_RIPNG_CLI_H_
+#define _FRR_RIPNG_CLI_H_
+
+extern void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults);
+extern void cli_show_ripng_allow_ecmp(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults);
+extern void cli_show_ripng_default_information_originate(struct vty *vty,
+                                                        struct lyd_node *dnode,
+                                                        bool show_defaults);
+extern void cli_show_ripng_default_metric(struct vty *vty,
+                                         struct lyd_node *dnode,
+                                         bool show_defaults);
+extern void cli_show_ripng_network_prefix(struct vty *vty,
+                                         struct lyd_node *dnode,
+                                         bool show_defaults);
+extern void cli_show_ripng_network_interface(struct vty *vty,
+                                            struct lyd_node *dnode,
+                                            bool show_defaults);
+extern void cli_show_ripng_offset_list(struct vty *vty, struct lyd_node *dnode,
+                                      bool show_defaults);
+extern void cli_show_ripng_passive_interface(struct vty *vty,
+                                            struct lyd_node *dnode,
+                                            bool show_defaults);
+extern void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode,
+                                       bool show_defaults);
+extern void cli_show_ripng_route(struct vty *vty, struct lyd_node *dnode,
+                                bool show_defaults);
+extern void cli_show_ripng_aggregate_address(struct vty *vty,
+                                            struct lyd_node *dnode,
+                                            bool show_defaults);
+extern void cli_show_ripng_timers(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults);
+extern void cli_show_ipv6_ripng_split_horizon(struct vty *vty,
+                                             struct lyd_node *dnode,
+                                             bool show_defaults);
+
+#endif /* _FRR_RIPNG_CLI_H_ */
index c8cad23addfbc2161bfd7b9e0166cbee416c0467..c56ff126271bcbb0d06a0d9ac0c094e7e3ca837c 100644 (file)
@@ -207,13 +207,6 @@ static int config_write_debug(struct vty *vty)
        return write;
 }
 
-void ripng_debug_reset()
-{
-       ripng_debug_event = 0;
-       ripng_debug_packet = 0;
-       ripng_debug_zebra = 0;
-}
-
 void ripng_debug_init()
 {
        ripng_debug_event = 0;
index 8124a1a0c93e6ff295206359293d2f82b293ea5b..81cb0f9c7ef78124d6d10216fa67b05901e38937 100644 (file)
@@ -45,6 +45,5 @@ extern unsigned long ripng_debug_packet;
 extern unsigned long ripng_debug_zebra;
 
 extern void ripng_debug_init(void);
-extern void ripng_debug_reset(void);
 
 #endif /* _ZEBRA_RIPNG_DEBUG_H */
index a1d25f29619574383cf75503d3a6d85ac12fcaa3..4d14fbab649290301604d853d2173e7782560426 100644 (file)
@@ -36,6 +36,7 @@
 #include "privs.h"
 #include "vrf.h"
 #include "lib_errors.h"
+#include "northbound_cli.h"
 
 #include "ripngd/ripngd.h"
 #include "ripngd/ripng_debug.h"
@@ -323,37 +324,6 @@ void ripng_interface_clean(void)
        }
 }
 
-void ripng_interface_reset(void)
-{
-       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
-       struct interface *ifp;
-       struct ripng_interface *ri;
-
-       FOR_ALL_INTERFACES (vrf, ifp) {
-               ri = ifp->info;
-
-               ri->enable_network = 0;
-               ri->enable_interface = 0;
-               ri->running = 0;
-
-               ri->split_horizon = RIPNG_NO_SPLIT_HORIZON;
-               ri->split_horizon_default = RIPNG_NO_SPLIT_HORIZON;
-
-               ri->list[RIPNG_FILTER_IN] = NULL;
-               ri->list[RIPNG_FILTER_OUT] = NULL;
-
-               ri->prefix[RIPNG_FILTER_IN] = NULL;
-               ri->prefix[RIPNG_FILTER_OUT] = NULL;
-
-               if (ri->t_wakeup) {
-                       thread_cancel(ri->t_wakeup);
-                       ri->t_wakeup = NULL;
-               }
-
-               ri->passive = 0;
-       }
-}
-
 static void ripng_apply_address_add(struct connected *ifc)
 {
        struct prefix_ipv6 address;
@@ -543,7 +513,7 @@ static int ripng_enable_network_lookup2(struct connected *connected)
 }
 
 /* Add RIPng enable network. */
-static int ripng_enable_network_add(struct prefix *p)
+int ripng_enable_network_add(struct prefix *p)
 {
        struct agg_node *node;
 
@@ -551,18 +521,18 @@ static int ripng_enable_network_add(struct prefix *p)
 
        if (node->info) {
                agg_unlock_node(node);
-               return -1;
+               return NB_ERR_INCONSISTENCY;
        } else
                node->info = (void *)1;
 
        /* XXX: One should find a better solution than a generic one */
        ripng_enable_apply_all();
 
-       return 1;
+       return NB_OK;
 }
 
 /* Delete RIPng enable network. */
-static int ripng_enable_network_delete(struct prefix *p)
+int ripng_enable_network_delete(struct prefix *p)
 {
        struct agg_node *node;
 
@@ -576,9 +546,10 @@ static int ripng_enable_network_delete(struct prefix *p)
                /* Unlock lookup lock. */
                agg_unlock_node(node);
 
-               return 1;
+               return NB_OK;
        }
-       return -1;
+
+       return NB_ERR_INCONSISTENCY;
 }
 
 /* Lookup function. */
@@ -595,30 +566,30 @@ static int ripng_enable_if_lookup(const char *ifname)
 }
 
 /* Add interface to ripng_enable_if. */
-static int ripng_enable_if_add(const char *ifname)
+int ripng_enable_if_add(const char *ifname)
 {
        int ret;
 
        ret = ripng_enable_if_lookup(ifname);
        if (ret >= 0)
-               return -1;
+               return NB_ERR_INCONSISTENCY;
 
        vector_set(ripng_enable_if, strdup(ifname));
 
        ripng_enable_apply_all();
 
-       return 1;
+       return NB_OK;
 }
 
 /* Delete interface from ripng_enable_if. */
-static int ripng_enable_if_delete(const char *ifname)
+int ripng_enable_if_delete(const char *ifname)
 {
        int index;
        char *str;
 
        index = ripng_enable_if_lookup(ifname);
        if (index < 0)
-               return -1;
+               return NB_ERR_INCONSISTENCY;
 
        str = vector_slot(ripng_enable_if, index);
        free(str);
@@ -626,7 +597,7 @@ static int ripng_enable_if_delete(const char *ifname)
 
        ripng_enable_apply_all();
 
-       return 1;
+       return NB_OK;
 }
 
 /* Wake up interface. */
@@ -830,26 +801,26 @@ static void ripng_passive_interface_apply_all(void)
 }
 
 /* Passive interface. */
-static int ripng_passive_interface_set(struct vty *vty, const char *ifname)
+int ripng_passive_interface_set(const char *ifname)
 {
        if (ripng_passive_interface_lookup(ifname) >= 0)
-               return CMD_WARNING_CONFIG_FAILED;
+               return NB_ERR_INCONSISTENCY;
 
        vector_set(Vripng_passive_interface, strdup(ifname));
 
        ripng_passive_interface_apply_all();
 
-       return CMD_SUCCESS;
+       return NB_OK;
 }
 
-static int ripng_passive_interface_unset(struct vty *vty, const char *ifname)
+int ripng_passive_interface_unset(const char *ifname)
 {
        int i;
        char *str;
 
        i = ripng_passive_interface_lookup(ifname);
        if (i < 0)
-               return CMD_WARNING_CONFIG_FAILED;
+               return NB_ERR_INCONSISTENCY;
 
        str = vector_slot(Vripng_passive_interface, i);
        free(str);
@@ -857,7 +828,7 @@ static int ripng_passive_interface_unset(struct vty *vty, const char *ifname)
 
        ripng_passive_interface_apply_all();
 
-       return CMD_SUCCESS;
+       return NB_OK;
 }
 
 /* Free all configured RIP passive-interface settings. */
@@ -875,7 +846,7 @@ void ripng_passive_interface_clean(void)
 }
 
 /* Write RIPng enable network and interface to the vty. */
-int ripng_network_write(struct vty *vty, int config_mode)
+int ripng_network_write(struct vty *vty)
 {
        unsigned int i;
        const char *ifname;
@@ -887,8 +858,7 @@ int ripng_network_write(struct vty *vty, int config_mode)
             node = agg_route_next(node))
                if (node->info) {
                        struct prefix *p = &node->p;
-                       vty_out(vty, "%s%s/%d\n",
-                               config_mode ? " network " : "    ",
+                       vty_out(vty, "    %s/%d\n",
                                inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
                                p->prefixlen);
                }
@@ -896,148 +866,11 @@ int ripng_network_write(struct vty *vty, int config_mode)
        /* Write enable interface. */
        for (i = 0; i < vector_active(ripng_enable_if); i++)
                if ((ifname = vector_slot(ripng_enable_if, i)) != NULL)
-                       vty_out(vty, "%s%s\n",
-                               config_mode ? " network " : "    ", ifname);
-
-       /* Write passive interface. */
-       if (config_mode)
-               for (i = 0; i < vector_active(Vripng_passive_interface); i++)
-                       if ((ifname = vector_slot(Vripng_passive_interface, i))
-                           != NULL)
-                               vty_out(vty, " passive-interface %s\n", ifname);
+                       vty_out(vty, "    %s\n", ifname);
 
        return 0;
 }
 
-/* RIPng enable on specified interface or matched network. */
-DEFUN (ripng_network,
-       ripng_network_cmd,
-       "network IF_OR_ADDR",
-       "RIPng enable on specified interface or network.\n"
-       "Interface or address\n")
-{
-       int idx_if_or_addr = 1;
-       int ret;
-       struct prefix p;
-
-       ret = str2prefix(argv[idx_if_or_addr]->arg, &p);
-
-       /* Given string is IPv6 network or interface name. */
-       if (ret)
-               ret = ripng_enable_network_add(&p);
-       else
-               ret = ripng_enable_if_add(argv[idx_if_or_addr]->arg);
-
-       if (ret < 0) {
-               vty_out(vty, "There is same network configuration %s\n",
-                       argv[idx_if_or_addr]->arg);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return CMD_SUCCESS;
-}
-
-/* RIPng enable on specified interface or matched network. */
-DEFUN (no_ripng_network,
-       no_ripng_network_cmd,
-       "no network IF_OR_ADDR",
-       NO_STR
-       "RIPng enable on specified interface or network.\n"
-       "Interface or address\n")
-{
-       int idx_if_or_addr = 2;
-       int ret;
-       struct prefix p;
-
-       ret = str2prefix(argv[idx_if_or_addr]->arg, &p);
-
-       /* Given string is interface name. */
-       if (ret)
-               ret = ripng_enable_network_delete(&p);
-       else
-               ret = ripng_enable_if_delete(argv[idx_if_or_addr]->arg);
-
-       if (ret < 0) {
-               vty_out(vty, "can't find network %s\n",
-                       argv[idx_if_or_addr]->arg);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_ripng_split_horizon,
-       ipv6_ripng_split_horizon_cmd,
-       "ipv6 ripng split-horizon",
-       IPV6_STR
-       "Routing Information Protocol\n"
-       "Perform split horizon\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct ripng_interface *ri;
-
-       ri = ifp->info;
-
-       ri->split_horizon = RIPNG_SPLIT_HORIZON;
-       return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_ripng_split_horizon_poisoned_reverse,
-       ipv6_ripng_split_horizon_poisoned_reverse_cmd,
-       "ipv6 ripng split-horizon poisoned-reverse",
-       IPV6_STR
-       "Routing Information Protocol\n"
-       "Perform split horizon\n"
-       "With poisoned-reverse\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct ripng_interface *ri;
-
-       ri = ifp->info;
-
-       ri->split_horizon = RIPNG_SPLIT_HORIZON_POISONED_REVERSE;
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_ripng_split_horizon,
-       no_ipv6_ripng_split_horizon_cmd,
-       "no ipv6 ripng split-horizon [poisoned-reverse]",
-       NO_STR
-       IPV6_STR
-       "Routing Information Protocol\n"
-       "Perform split horizon\n"
-       "With poisoned-reverse\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct ripng_interface *ri;
-
-       ri = ifp->info;
-
-       ri->split_horizon = RIPNG_NO_SPLIT_HORIZON;
-       return CMD_SUCCESS;
-}
-
-DEFUN (ripng_passive_interface,
-       ripng_passive_interface_cmd,
-       "passive-interface IFNAME",
-       "Suppress routing updates on an interface\n"
-       "Interface name\n")
-{
-       int idx_ifname = 1;
-       return ripng_passive_interface_set(vty, argv[idx_ifname]->arg);
-}
-
-DEFUN (no_ripng_passive_interface,
-       no_ripng_passive_interface_cmd,
-       "no passive-interface IFNAME",
-       NO_STR
-       "Suppress routing updates on an interface\n"
-       "Interface name\n")
-{
-       int idx_ifname = 2;
-       return ripng_passive_interface_unset(vty, argv[idx_ifname]->arg);
-}
-
 static struct ripng_interface *ri_new(void)
 {
        struct ripng_interface *ri;
@@ -1047,8 +880,8 @@ static struct ripng_interface *ri_new(void)
           Relay or SMDS is enabled, the default value for split-horizon is
           off.  But currently Zebra does detect Frame Relay or SMDS
           interface.  So all interface is set to split horizon.  */
-       ri->split_horizon_default = RIPNG_SPLIT_HORIZON;
-       ri->split_horizon = ri->split_horizon_default;
+       ri->split_horizon =
+               yang_get_default_enum("%s/split-horizon", RIPNG_IFACE);
 
        return ri;
 }
@@ -1072,44 +905,22 @@ static int interface_config_write(struct vty *vty)
 {
        struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
        struct interface *ifp;
-       struct ripng_interface *ri;
        int write = 0;
 
        FOR_ALL_INTERFACES (vrf, ifp) {
-               ri = ifp->info;
+               struct lyd_node *dnode;
 
-               /* Do not display the interface if there is no
-                * configuration about it.
-                **/
-               if ((!ifp->desc)
-                   && (ri->split_horizon == ri->split_horizon_default))
+               dnode = yang_dnode_get(
+                       running_config->dnode,
+                       "/frr-interface:lib/interface[name='%s'][vrf='%s']",
+                       ifp->name, vrf->name);
+               if (dnode == NULL)
                        continue;
 
-               vty_frame(vty, "interface %s\n", ifp->name);
-               if (ifp->desc)
-                       vty_out(vty, " description %s\n", ifp->desc);
-
-               /* Split horizon. */
-               if (ri->split_horizon != ri->split_horizon_default) {
-                       switch (ri->split_horizon) {
-                       case RIPNG_SPLIT_HORIZON:
-                               vty_out(vty, " ipv6 ripng split-horizon\n");
-                               break;
-                       case RIPNG_SPLIT_HORIZON_POISONED_REVERSE:
-                               vty_out(vty,
-                                       " ipv6 ripng split-horizon poisoned-reverse\n");
-                               break;
-                       case RIPNG_NO_SPLIT_HORIZON:
-                       default:
-                               vty_out(vty, " no ipv6 ripng split-horizon\n");
-                               break;
-                       }
-               }
-
-               vty_endframe(vty, "!\n");
-
-               write++;
+               write = 1;
+               nb_cli_show_dnode_cmds(vty, dnode, false);
        }
+
        return write;
 }
 
@@ -1137,14 +948,4 @@ void ripng_if_init()
        /* Install interface node. */
        install_node(&interface_node, interface_config_write);
        if_cmd_init();
-
-       install_element(RIPNG_NODE, &ripng_network_cmd);
-       install_element(RIPNG_NODE, &no_ripng_network_cmd);
-       install_element(RIPNG_NODE, &ripng_passive_interface_cmd);
-       install_element(RIPNG_NODE, &no_ripng_passive_interface_cmd);
-
-       install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd);
-       install_element(INTERFACE_NODE,
-                       &ipv6_ripng_split_horizon_poisoned_reverse_cmd);
-       install_element(INTERFACE_NODE, &no_ipv6_ripng_split_horizon_cmd);
 }
index 98df7ef12d89111708b456b7a8fa8d2905d55e3c..10e19efe77f6962fc39cea79f2378adcb0a52f1c 100644 (file)
@@ -72,13 +72,9 @@ static struct frr_daemon_info ripngd_di;
 static void sighup(void)
 {
        zlog_info("SIGHUP received");
-       ripng_clean();
-       ripng_reset();
 
        /* Reload config file. */
        vty_read_config(NULL, ripngd_di.config_file, config_default);
-
-       /* Try to return to normal operation. */
 }
 
 /* SIGINT handler. */
@@ -120,6 +116,7 @@ struct quagga_signal_t ripng_signals[] = {
 
 static const struct frr_yang_module_info *ripngd_yang_modules[] = {
        &frr_interface_info,
+       &frr_ripngd_info,
 };
 
 FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT,
@@ -177,6 +174,7 @@ int main(int argc, char **argv)
 
        /* RIPngd inits. */
        ripng_init();
+       ripng_cli_init();
        zebra_init(master);
        ripng_peer_init();
 
diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c
new file mode 100644 (file)
index 0000000..7993714
--- /dev/null
@@ -0,0 +1,1001 @@
+/*
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ * Copyright (C) 2018 NetDEF, Inc.
+ *                    Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "if.h"
+#include "vrf.h"
+#include "log.h"
+#include "prefix.h"
+#include "table.h"
+#include "command.h"
+#include "routemap.h"
+#include "agg_table.h"
+#include "northbound.h"
+#include "libfrr.h"
+
+#include "ripngd/ripngd.h"
+#include "ripngd/ripng_route.h"
+#include "ripngd/ripng_cli.h"
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance
+ */
+static int ripngd_instance_create(enum nb_event event,
+                                 const struct lyd_node *dnode,
+                                 union nb_resource *resource)
+{
+       int socket;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               break;
+       case NB_EV_PREPARE:
+               socket = ripng_make_socket();
+               if (socket < 0)
+                       return NB_ERR_RESOURCE;
+               resource->fd = socket;
+               break;
+       case NB_EV_ABORT:
+               socket = resource->fd;
+               close(socket);
+               break;
+       case NB_EV_APPLY:
+               socket = resource->fd;
+               ripng_create(socket);
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int ripngd_instance_delete(enum nb_event event,
+                                 const struct lyd_node *dnode)
+{
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng_clean();
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
+ */
+static int ripngd_instance_allow_ecmp_modify(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->ecmp = yang_dnode_get_bool(dnode, NULL);
+       if (!ripng->ecmp)
+               ripng_ecmp_disable();
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/default-information-originate
+ */
+static int ripngd_instance_default_information_originate_modify(
+       enum nb_event event, const struct lyd_node *dnode,
+       union nb_resource *resource)
+{
+       bool default_information;
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       default_information = yang_dnode_get_bool(dnode, NULL);
+       str2prefix_ipv6("::/0", &p);
+       if (default_information) {
+               ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT,
+                                      &p, 0, NULL, 0);
+       } else {
+               ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG,
+                                         RIPNG_ROUTE_DEFAULT, &p, 0);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/default-metric
+ */
+static int ripngd_instance_default_metric_modify(enum nb_event event,
+                                                const struct lyd_node *dnode,
+                                                union nb_resource *resource)
+{
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->default_metric = yang_dnode_get_uint8(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/network
+ */
+static int ripngd_instance_network_create(enum nb_event event,
+                                         const struct lyd_node *dnode,
+                                         union nb_resource *resource)
+{
+       struct prefix p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6((struct prefix_ipv6 *)&p);
+
+       return ripng_enable_network_add(&p);
+}
+
+static int ripngd_instance_network_delete(enum nb_event event,
+                                         const struct lyd_node *dnode)
+{
+       struct prefix p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6((struct prefix_ipv6 *)&p);
+
+       return ripng_enable_network_delete(&p);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/interface
+ */
+static int ripngd_instance_interface_create(enum nb_event event,
+                                           const struct lyd_node *dnode,
+                                           union nb_resource *resource)
+{
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_enable_if_add(ifname);
+}
+
+static int ripngd_instance_interface_delete(enum nb_event event,
+                                           const struct lyd_node *dnode)
+{
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_enable_if_delete(ifname);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/offset-list
+ */
+static int ripngd_instance_offset_list_create(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       const char *ifname;
+       struct ripng_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, "./interface");
+
+       offset = ripng_offset_list_new(ifname);
+       yang_dnode_set_entry(dnode, offset);
+
+       return NB_OK;
+}
+
+static int ripngd_instance_offset_list_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       int direct;
+       struct ripng_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "./direction");
+
+       offset = yang_dnode_get_entry(dnode, true);
+       if (offset->direct[direct].alist_name) {
+               free(offset->direct[direct].alist_name);
+               offset->direct[direct].alist_name = NULL;
+       }
+       if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL
+           && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name == NULL)
+               ripng_offset_list_del(offset);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list
+ */
+static int
+ripngd_instance_offset_list_access_list_modify(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       int direct;
+       struct ripng_offset_list *offset;
+       const char *alist_name;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "../direction");
+       alist_name = yang_dnode_get_string(dnode, NULL);
+
+       offset = yang_dnode_get_entry(dnode, true);
+       if (offset->direct[direct].alist_name)
+               free(offset->direct[direct].alist_name);
+       offset->direct[direct].alist_name = strdup(alist_name);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/offset-list/metric
+ */
+static int
+ripngd_instance_offset_list_metric_modify(enum nb_event event,
+                                         const struct lyd_node *dnode,
+                                         union nb_resource *resource)
+{
+       int direct;
+       uint8_t metric;
+       struct ripng_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "../direction");
+       metric = yang_dnode_get_uint8(dnode, NULL);
+
+       offset = yang_dnode_get_entry(dnode, true);
+       offset->direct[direct].metric = metric;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/passive-interface
+ */
+static int
+ripngd_instance_passive_interface_create(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_passive_interface_set(ifname);
+}
+
+static int
+ripngd_instance_passive_interface_delete(enum nb_event event,
+                                        const struct lyd_node *dnode)
+{
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_passive_interface_unset(ifname);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/redistribute
+ */
+static int ripngd_instance_redistribute_create(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       return NB_OK;
+}
+
+static int ripngd_instance_redistribute_delete(enum nb_event event,
+                                              const struct lyd_node *dnode)
+{
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "./protocol");
+
+       ripng_redistribute_conf_delete(type);
+
+       return NB_OK;
+}
+
+static void
+ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode)
+{
+       int type;
+
+       type = yang_dnode_get_enum(dnode, "./protocol");
+       ripng_redistribute_conf_update(type);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
+ */
+static int
+ripngd_instance_redistribute_route_map_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       int type;
+       const char *rmap_name;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+       rmap_name = yang_dnode_get_string(dnode, NULL);
+
+       if (ripng->route_map[type].name)
+               free(ripng->route_map[type].name);
+       ripng->route_map[type].name = strdup(rmap_name);
+       ripng->route_map[type].map = route_map_lookup_by_name(rmap_name);
+
+       return NB_OK;
+}
+
+static int
+ripngd_instance_redistribute_route_map_delete(enum nb_event event,
+                                             const struct lyd_node *dnode)
+{
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+
+       free(ripng->route_map[type].name);
+       ripng->route_map[type].name = NULL;
+       ripng->route_map[type].map = NULL;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/redistribute/metric
+ */
+static int
+ripngd_instance_redistribute_metric_modify(enum nb_event event,
+                                          const struct lyd_node *dnode,
+                                          union nb_resource *resource)
+{
+       int type;
+       uint8_t metric;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+       metric = yang_dnode_get_uint8(dnode, NULL);
+
+       ripng->route_map[type].metric_config = true;
+       ripng->route_map[type].metric = metric;
+
+       return NB_OK;
+}
+
+static int
+ripngd_instance_redistribute_metric_delete(enum nb_event event,
+                                          const struct lyd_node *dnode)
+{
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+
+       ripng->route_map[type].metric_config = false;
+       ripng->route_map[type].metric = 0;
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/static-route
+ */
+static int ripngd_instance_static_route_create(enum nb_event event,
+                                              const struct lyd_node *dnode,
+                                              union nb_resource *resource)
+{
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0,
+                              NULL, 0);
+
+       return NB_OK;
+}
+
+static int ripngd_instance_static_route_delete(enum nb_event event,
+                                              const struct lyd_node *dnode)
+{
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/aggregate-address
+ */
+static int
+ripngd_instance_aggregate_address_create(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_aggregate_add((struct prefix *)&p);
+
+       return NB_OK;
+}
+
+static int
+ripngd_instance_aggregate_address_delete(enum nb_event event,
+                                        const struct lyd_node *dnode)
+{
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_aggregate_delete((struct prefix *)&p);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers
+ */
+static void ripngd_instance_timers_apply_finish(const struct lyd_node *dnode)
+{
+       /* Reset update timer thread. */
+       ripng_event(RIPNG_UPDATE_EVENT, 0);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
+ */
+static int
+ripngd_instance_timers_flush_interval_modify(enum nb_event event,
+                                            const struct lyd_node *dnode,
+                                            union nb_resource *resource)
+{
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->garbage_time = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval
+ */
+static int
+ripngd_instance_timers_holddown_interval_modify(enum nb_event event,
+                                               const struct lyd_node *dnode,
+                                               union nb_resource *resource)
+{
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->timeout_time = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers/update-interval
+ */
+static int
+ripngd_instance_timers_update_interval_modify(enum nb_event event,
+                                             const struct lyd_node *dnode,
+                                             union nb_resource *resource)
+{
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->update_time = yang_dnode_get_uint16(dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor
+ */
+static const void *
+ripngd_state_neighbors_neighbor_get_next(const void *parent_list_entry,
+                                        const void *list_entry)
+{
+       struct listnode *node;
+
+       if (list_entry == NULL)
+               node = listhead(peer_list);
+       else
+               node = listnextnode((struct listnode *)list_entry);
+
+       return node;
+}
+
+static int ripngd_state_neighbors_neighbor_get_keys(const void *list_entry,
+                                                   struct yang_list_keys *keys)
+{
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       keys->num = 1;
+       (void)inet_ntop(AF_INET6, &peer->addr, keys->key[0],
+                       sizeof(keys->key[0]));
+
+       return NB_OK;
+}
+
+static const void *
+ripngd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
+                                            const struct yang_list_keys *keys)
+{
+       struct in6_addr address;
+       struct ripng_peer *peer;
+       struct listnode *node;
+
+       yang_str2ipv6(keys->key[0], &address);
+
+       for (ALL_LIST_ELEMENTS_RO(peer_list, node, peer)) {
+               if (IPV6_ADDR_SAME(&peer->addr, &address))
+                       return node;
+       }
+
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/address
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_address_get_elem(const char *xpath,
+                                                const void *list_entry)
+{
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       return yang_data_new_ipv6(xpath, &peer->addr);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/last-update
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
+                                                    const void *list_entry)
+{
+       /* TODO: yang:date-and-time is tricky */
+       return NULL;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       return yang_data_new_uint32(xpath, peer->recv_badpackets);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd
+ */
+static struct yang_data *
+ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
+                                                        const void *list_entry)
+{
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       return yang_data_new_uint32(xpath, peer->recv_badroutes);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route
+ */
+static const void *
+ripngd_state_routes_route_get_next(const void *parent_list_entry,
+                                  const void *list_entry)
+{
+       struct agg_node *rn;
+
+       if (ripng == NULL)
+               return NULL;
+
+       if (list_entry == NULL)
+               rn = agg_route_top(ripng->table);
+       else
+               rn = agg_route_next((struct agg_node *)list_entry);
+       while (rn && rn->info == NULL)
+               rn = agg_route_next(rn);
+
+       return rn;
+}
+
+static int ripngd_state_routes_route_get_keys(const void *list_entry,
+                                             struct yang_list_keys *keys)
+{
+       const struct agg_node *rn = list_entry;
+
+       keys->num = 1;
+       (void)prefix2str(&rn->p, keys->key[0], sizeof(keys->key[0]));
+
+       return NB_OK;
+}
+
+static const void *
+ripngd_state_routes_route_lookup_entry(const void *parent_list_entry,
+                                      const struct yang_list_keys *keys)
+{
+       struct prefix prefix;
+       struct agg_node *rn;
+
+       yang_str2ipv6p(keys->key[0], &prefix);
+
+       rn = agg_node_lookup(ripng->table, &prefix);
+       if (!rn || !rn->info)
+               return NULL;
+
+       agg_unlock_node(rn);
+
+       return rn;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/prefix
+ */
+static struct yang_data *
+ripngd_state_routes_route_prefix_get_elem(const char *xpath,
+                                         const void *list_entry)
+{
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_ipv6p(xpath, &rinfo->rp->p);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/next-hop
+ */
+static struct yang_data *
+ripngd_state_routes_route_next_hop_get_elem(const char *xpath,
+                                           const void *list_entry)
+{
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_ipv6(xpath, &rinfo->nexthop);
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/interface
+ */
+static struct yang_data *
+ripngd_state_routes_route_interface_get_elem(const char *xpath,
+                                            const void *list_entry)
+{
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_string(
+               xpath, ifindex2ifname(rinfo->ifindex, VRF_DEFAULT));
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/state/routes/route/metric
+ */
+static struct yang_data *
+ripngd_state_routes_route_metric_get_elem(const char *xpath,
+                                         const void *list_entry)
+{
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_uint8(xpath, rinfo->metric);
+}
+
+/*
+ * XPath: /frr-ripngd:clear-ripng-route
+ */
+static int clear_ripng_route_rpc(const char *xpath, const struct list *input,
+                                struct list *output)
+{
+       struct agg_node *rp;
+       struct ripng_info *rinfo;
+       struct list *list;
+       struct listnode *listnode;
+
+       /* Clear received RIPng routes */
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) {
+               list = rp->info;
+               if (list == NULL)
+                       continue;
+
+               for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
+                       if (!ripng_route_rte(rinfo))
+                               continue;
+
+                       if (CHECK_FLAG(rinfo->flags, RIPNG_RTF_FIB))
+                               ripng_zebra_ipv6_delete(rp);
+                       break;
+               }
+
+               if (rinfo) {
+                       RIPNG_TIMER_OFF(rinfo->t_timeout);
+                       RIPNG_TIMER_OFF(rinfo->t_garbage_collect);
+                       listnode_delete(list, rinfo);
+                       ripng_info_free(rinfo);
+               }
+
+               if (list_isempty(list)) {
+                       list_delete(&list);
+                       rp->info = NULL;
+                       agg_unlock_node(rp);
+               }
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
+ */
+static int
+lib_interface_ripng_split_horizon_modify(enum nb_event event,
+                                        const struct lyd_node *dnode,
+                                        union nb_resource *resource)
+{
+       struct interface *ifp;
+       struct ripng_interface *ri;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifp = yang_dnode_get_entry(dnode, true);
+       ri = ifp->info;
+       ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
+
+       return NB_OK;
+}
+
+/* clang-format off */
+const struct frr_yang_module_info frr_ripngd_info = {
+       .name = "frr-ripngd",
+       .nodes = {
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance",
+                       .cbs.create = ripngd_instance_create,
+                       .cbs.delete = ripngd_instance_delete,
+                       .cbs.cli_show = cli_show_router_ripng,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/allow-ecmp",
+                       .cbs.modify = ripngd_instance_allow_ecmp_modify,
+                       .cbs.cli_show = cli_show_ripng_allow_ecmp,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/default-information-originate",
+                       .cbs.modify = ripngd_instance_default_information_originate_modify,
+                       .cbs.cli_show = cli_show_ripng_default_information_originate,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/default-metric",
+                       .cbs.modify = ripngd_instance_default_metric_modify,
+                       .cbs.cli_show = cli_show_ripng_default_metric,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/network",
+                       .cbs.create = ripngd_instance_network_create,
+                       .cbs.delete = ripngd_instance_network_delete,
+                       .cbs.cli_show = cli_show_ripng_network_prefix,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/interface",
+                       .cbs.create = ripngd_instance_interface_create,
+                       .cbs.delete = ripngd_instance_interface_delete,
+                       .cbs.cli_show = cli_show_ripng_network_interface,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/offset-list",
+                       .cbs.create = ripngd_instance_offset_list_create,
+                       .cbs.delete = ripngd_instance_offset_list_delete,
+                       .cbs.cli_show = cli_show_ripng_offset_list,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/offset-list/access-list",
+                       .cbs.modify = ripngd_instance_offset_list_access_list_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/offset-list/metric",
+                       .cbs.modify = ripngd_instance_offset_list_metric_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/passive-interface",
+                       .cbs.create = ripngd_instance_passive_interface_create,
+                       .cbs.delete = ripngd_instance_passive_interface_delete,
+                       .cbs.cli_show = cli_show_ripng_passive_interface,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/redistribute",
+                       .cbs.create = ripngd_instance_redistribute_create,
+                       .cbs.delete = ripngd_instance_redistribute_delete,
+                       .cbs.apply_finish = ripngd_instance_redistribute_apply_finish,
+                       .cbs.cli_show = cli_show_ripng_redistribute,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/redistribute/route-map",
+                       .cbs.modify = ripngd_instance_redistribute_route_map_modify,
+                       .cbs.delete = ripngd_instance_redistribute_route_map_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/redistribute/metric",
+                       .cbs.modify = ripngd_instance_redistribute_metric_modify,
+                       .cbs.delete = ripngd_instance_redistribute_metric_delete,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/static-route",
+                       .cbs.create = ripngd_instance_static_route_create,
+                       .cbs.delete = ripngd_instance_static_route_delete,
+                       .cbs.cli_show = cli_show_ripng_route,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/aggregate-address",
+                       .cbs.create = ripngd_instance_aggregate_address_create,
+                       .cbs.delete = ripngd_instance_aggregate_address_delete,
+                       .cbs.cli_show = cli_show_ripng_aggregate_address,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers",
+                       .cbs.apply_finish = ripngd_instance_timers_apply_finish,
+                       .cbs.cli_show = cli_show_ripng_timers,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers/flush-interval",
+                       .cbs.modify = ripngd_instance_timers_flush_interval_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers/holddown-interval",
+                       .cbs.modify = ripngd_instance_timers_holddown_interval_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers/update-interval",
+                       .cbs.modify = ripngd_instance_timers_update_interval_modify,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor",
+                       .cbs.get_next = ripngd_state_neighbors_neighbor_get_next,
+                       .cbs.get_keys = ripngd_state_neighbors_neighbor_get_keys,
+                       .cbs.lookup_entry = ripngd_state_neighbors_neighbor_lookup_entry,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/address",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_address_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/last-update",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_last_update_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd",
+                       .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route",
+                       .cbs.get_next = ripngd_state_routes_route_get_next,
+                       .cbs.get_keys = ripngd_state_routes_route_get_keys,
+                       .cbs.lookup_entry = ripngd_state_routes_route_lookup_entry,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/prefix",
+                       .cbs.get_elem = ripngd_state_routes_route_prefix_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/next-hop",
+                       .cbs.get_elem = ripngd_state_routes_route_next_hop_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/interface",
+                       .cbs.get_elem = ripngd_state_routes_route_interface_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/state/routes/route/metric",
+                       .cbs.get_elem = ripngd_state_routes_route_metric_get_elem,
+               },
+               {
+                       .xpath = "/frr-ripngd:clear-ripng-route",
+                       .cbs.rpc = clear_ripng_route_rpc,
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-ripngd:ripng/split-horizon",
+                       .cbs.modify = lib_interface_ripng_split_horizon_modify,
+                       .cbs.cli_show = cli_show_ipv6_ripng_split_horizon,
+               },
+               {
+                       .xpath = NULL,
+               },
+       }
+};
index 32b81b54802bf911d8c2c4c3d15f6cd48c2c045c..278df758924164116f9a21c7f48f0a4af5416cca 100644 (file)
 
 #include "ripngd/ripngd.h"
 
-#define RIPNG_OFFSET_LIST_IN  0
-#define RIPNG_OFFSET_LIST_OUT 1
-#define RIPNG_OFFSET_LIST_MAX 2
-
-struct ripng_offset_list {
-       char *ifname;
-
-       struct {
-               char *alist_name;
-               /* struct access_list *alist; */
-               int metric;
-       } direct[RIPNG_OFFSET_LIST_MAX];
-};
-
 static struct list *ripng_offset_list_master;
 
-static int strcmp_safe(const char *s1, const char *s2)
-{
-       if (s1 == NULL && s2 == NULL)
-               return 0;
-       if (s1 == NULL)
-               return -1;
-       if (s2 == NULL)
-               return 1;
-       return strcmp(s1, s2);
-}
+#define OFFSET_LIST_IN_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name)
+#define OFFSET_LIST_IN_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].metric)
+
+#define OFFSET_LIST_OUT_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
+#define OFFSET_LIST_OUT_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric)
 
-static struct ripng_offset_list *ripng_offset_list_new(void)
+struct ripng_offset_list *ripng_offset_list_new(const char *ifname)
 {
        struct ripng_offset_list *new;
 
        new = XCALLOC(MTYPE_RIPNG_OFFSET_LIST,
                      sizeof(struct ripng_offset_list));
+       new->ifname = strdup(ifname);
+       listnode_add_sort(ripng_offset_list_master, new);
+
        return new;
 }
 
-static void ripng_offset_list_free(struct ripng_offset_list *offset)
+void ripng_offset_list_del(struct ripng_offset_list *offset)
 {
+       listnode_delete(ripng_offset_list_master, offset);
+       if (OFFSET_LIST_IN_NAME(offset))
+               free(OFFSET_LIST_IN_NAME(offset));
+       if (OFFSET_LIST_OUT_NAME(offset))
+               free(OFFSET_LIST_OUT_NAME(offset));
+       free(offset->ifname);
        XFREE(MTYPE_RIPNG_OFFSET_LIST, offset);
 }
 
-static struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname)
+struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname)
 {
        struct ripng_offset_list *offset;
        struct listnode *node, *nnode;
 
        for (ALL_LIST_ELEMENTS(ripng_offset_list_master, node, nnode, offset)) {
-               if (strcmp_safe(offset->ifname, ifname) == 0)
+               if (strcmp(offset->ifname, ifname) == 0)
                        return offset;
        }
        return NULL;
 }
 
-static struct ripng_offset_list *ripng_offset_list_get(const char *ifname)
-{
-       struct ripng_offset_list *offset;
-
-       offset = ripng_offset_list_lookup(ifname);
-       if (offset)
-               return offset;
-
-       offset = ripng_offset_list_new();
-       if (ifname)
-               offset->ifname = strdup(ifname);
-       listnode_add_sort(ripng_offset_list_master, offset);
-
-       return offset;
-}
-
-static int ripng_offset_list_set(struct vty *vty, const char *alist,
-                                const char *direct_str, const char *metric_str,
-                                const char *ifname)
-{
-       int direct;
-       int metric;
-       struct ripng_offset_list *offset;
-
-       /* Check direction. */
-       if (strncmp(direct_str, "i", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_IN;
-       else if (strncmp(direct_str, "o", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_OUT;
-       else {
-               vty_out(vty, "Invalid direction: %s\n", direct_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Check metric. */
-       metric = atoi(metric_str);
-       if (metric < 0 || metric > 16) {
-               vty_out(vty, "Invalid metric: %s\n", metric_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Get offset-list structure with interface name. */
-       offset = ripng_offset_list_get(ifname);
-
-       if (offset->direct[direct].alist_name)
-               free(offset->direct[direct].alist_name);
-       offset->direct[direct].alist_name = strdup(alist);
-       offset->direct[direct].metric = metric;
-
-       return CMD_SUCCESS;
-}
-
-static int ripng_offset_list_unset(struct vty *vty, const char *alist,
-                                  const char *direct_str,
-                                  const char *metric_str, const char *ifname)
-{
-       int direct;
-       int metric;
-       struct ripng_offset_list *offset;
-
-       /* Check direction. */
-       if (strncmp(direct_str, "i", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_IN;
-       else if (strncmp(direct_str, "o", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_OUT;
-       else {
-               vty_out(vty, "Invalid direction: %s\n", direct_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Check metric. */
-       metric = atoi(metric_str);
-       if (metric < 0 || metric > 16) {
-               vty_out(vty, "Invalid metric: %s\n", metric_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Get offset-list structure with interface name. */
-       offset = ripng_offset_list_lookup(ifname);
-
-       if (offset) {
-               if (offset->direct[direct].alist_name)
-                       free(offset->direct[direct].alist_name);
-               offset->direct[direct].alist_name = NULL;
-
-               if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL
-                   && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name
-                              == NULL) {
-                       listnode_delete(ripng_offset_list_master, offset);
-                       if (offset->ifname)
-                               free(offset->ifname);
-                       ripng_offset_list_free(offset);
-               }
-       } else {
-               vty_out(vty, "Can't find offset-list\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       return CMD_SUCCESS;
-}
-
-#define OFFSET_LIST_IN_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name)
-#define OFFSET_LIST_IN_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].metric)
-
-#define OFFSET_LIST_OUT_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
-#define OFFSET_LIST_OUT_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric)
-
 /* If metric is modifed return 1. */
 int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
                               uint8_t *metric)
@@ -214,7 +98,7 @@ int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
                return 0;
        }
        /* Look up offset-list without interface name. */
-       offset = ripng_offset_list_lookup(NULL);
+       offset = ripng_offset_list_lookup("*");
        if (offset && OFFSET_LIST_IN_NAME(offset)) {
                alist = access_list_lookup(AFI_IP6,
                                           OFFSET_LIST_IN_NAME(offset));
@@ -253,7 +137,7 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
        }
 
        /* Look up offset-list without interface name. */
-       offset = ripng_offset_list_lookup(NULL);
+       offset = ripng_offset_list_lookup("*");
        if (offset && OFFSET_LIST_OUT_NAME(offset)) {
                alist = access_list_lookup(AFI_IP6,
                                           OFFSET_LIST_OUT_NAME(offset));
@@ -269,95 +153,10 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
        return 0;
 }
 
-DEFUN (ripng_offset_list,
-       ripng_offset_list_cmd,
-       "offset-list WORD <in|out> (0-16)",
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n")
-{
-       int idx_word = 1;
-       int idx_in_out = 2;
-       int idx_number = 3;
-       return ripng_offset_list_set(vty, argv[idx_word]->arg,
-                                    argv[idx_in_out]->arg,
-                                    argv[idx_number]->arg, NULL);
-}
-
-DEFUN (ripng_offset_list_ifname,
-       ripng_offset_list_ifname_cmd,
-       "offset-list WORD <in|out> (0-16) IFNAME",
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n"
-       "Interface to match\n")
-{
-       int idx_word = 1;
-       int idx_in_out = 2;
-       int idx_number = 3;
-       int idx_ifname = 4;
-       return ripng_offset_list_set(
-               vty, argv[idx_word]->arg, argv[idx_in_out]->arg,
-               argv[idx_number]->arg, argv[idx_ifname]->arg);
-}
-
-DEFUN (no_ripng_offset_list,
-       no_ripng_offset_list_cmd,
-       "no offset-list WORD <in|out> (0-16)",
-       NO_STR
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n")
-{
-       int idx_word = 2;
-       int idx_in_out = 3;
-       int idx_number = 4;
-       return ripng_offset_list_unset(vty, argv[idx_word]->arg,
-                                      argv[idx_in_out]->arg,
-                                      argv[idx_number]->arg, NULL);
-}
-
-DEFUN (no_ripng_offset_list_ifname,
-       no_ripng_offset_list_ifname_cmd,
-       "no offset-list WORD <in|out> (0-16) IFNAME",
-       NO_STR
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n"
-       "Interface to match\n")
-{
-       int idx_word = 2;
-       int idx_in_out = 3;
-       int idx_number = 4;
-       int idx_ifname = 5;
-       return ripng_offset_list_unset(
-               vty, argv[idx_word]->arg, argv[idx_in_out]->arg,
-               argv[idx_number]->arg, argv[idx_ifname]->arg);
-}
-
 static int offset_list_cmp(struct ripng_offset_list *o1,
                           struct ripng_offset_list *o2)
 {
-       return strcmp_safe(o1->ifname, o2->ifname);
-}
-
-static void offset_list_del(struct ripng_offset_list *offset)
-{
-       if (OFFSET_LIST_IN_NAME(offset))
-               free(OFFSET_LIST_IN_NAME(offset));
-       if (OFFSET_LIST_OUT_NAME(offset))
-               free(OFFSET_LIST_OUT_NAME(offset));
-       if (offset->ifname)
-               free(offset->ifname);
-       ripng_offset_list_free(offset);
+       return strcmp(o1->ifname, o2->ifname);
 }
 
 void ripng_offset_init(void)
@@ -365,12 +164,7 @@ void ripng_offset_init(void)
        ripng_offset_list_master = list_new();
        ripng_offset_list_master->cmp =
                (int (*)(void *, void *))offset_list_cmp;
-       ripng_offset_list_master->del = (void (*)(void *))offset_list_del;
-
-       install_element(RIPNG_NODE, &ripng_offset_list_cmd);
-       install_element(RIPNG_NODE, &ripng_offset_list_ifname_cmd);
-       install_element(RIPNG_NODE, &no_ripng_offset_list_cmd);
-       install_element(RIPNG_NODE, &no_ripng_offset_list_ifname_cmd);
+       ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del;
 }
 
 void ripng_offset_clean(void)
@@ -380,45 +174,5 @@ void ripng_offset_clean(void)
        ripng_offset_list_master = list_new();
        ripng_offset_list_master->cmp =
                (int (*)(void *, void *))offset_list_cmp;
-       ripng_offset_list_master->del = (void (*)(void *))offset_list_del;
-}
-
-int config_write_ripng_offset_list(struct vty *vty)
-{
-       struct listnode *node, *nnode;
-       struct ripng_offset_list *offset;
-
-       for (ALL_LIST_ELEMENTS(ripng_offset_list_master, node, nnode, offset)) {
-               if (!offset->ifname) {
-                       if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name)
-                               vty_out(vty, " offset-list %s in %d\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .metric);
-                       if (offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
-                               vty_out(vty, " offset-list %s out %d\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .metric);
-               } else {
-                       if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name)
-                               vty_out(vty, " offset-list %s in %d %s\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .metric,
-                                       offset->ifname);
-                       if (offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
-                               vty_out(vty, " offset-list %s out %d %s\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .metric,
-                                       offset->ifname);
-               }
-       }
-
-       return 0;
+       ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del;
 }
index a18332516e4bd71f41f0f9bcc4872e736ceefac4..9a9e346a5931c33f0684e0f756f1778cd763da83 100644 (file)
@@ -337,12 +337,6 @@ static struct route_map_rule_cmd route_set_tag_cmd = {
 #define MATCH_STR "Match values from routing table\n"
 #define SET_STR "Set values in destination routing protocol\n"
 
-void ripng_route_map_reset()
-{
-       /* XXX ??? */
-       ;
-}
-
 void ripng_route_map_init()
 {
        route_map_init();
index f2b69c85a796ae54d59f841fbf63288d35be0395..e3f42edf51266ddf6cafb1a401ca06482349fbdc 100644 (file)
@@ -141,26 +141,19 @@ static int ripng_zebra_read_route(int command, struct zclient *zclient,
        return 0;
 }
 
-void ripng_zclient_reset(void)
+void ripng_redistribute_conf_update(int type)
 {
-       zclient_reset(zclient);
+       zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
+                            VRF_DEFAULT);
 }
 
-static int ripng_redistribute_unset(int type)
+void ripng_redistribute_conf_delete(int type)
 {
-
-       if (!vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT))
-               return CMD_SUCCESS;
-
-       vrf_bitmap_set(zclient->redist[AFI_IP6][type], VRF_DEFAULT);
-
        if (zclient->sock > 0)
                zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
                                        AFI_IP6, type, 0, VRF_DEFAULT);
 
        ripng_redistribute_withdraw(type);
-
-       return CMD_SUCCESS;
 }
 
 int ripng_redistribute_check(int type)
@@ -168,206 +161,25 @@ int ripng_redistribute_check(int type)
        return vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT);
 }
 
-static void ripng_redistribute_metric_set(int type, int metric)
-{
-       ripng->route_map[type].metric_config = 1;
-       ripng->route_map[type].metric = metric;
-}
-
-static int ripng_redistribute_metric_unset(int type)
-{
-       ripng->route_map[type].metric_config = 0;
-       ripng->route_map[type].metric = 0;
-       return 0;
-}
-
-static void ripng_redistribute_routemap_set(int type, const char *name)
-{
-       if (ripng->route_map[type].name)
-               free(ripng->route_map[type].name);
-
-       ripng->route_map[type].name = strdup(name);
-       ripng->route_map[type].map = route_map_lookup_by_name(name);
-}
-
-static void ripng_redistribute_routemap_unset(int type)
-{
-       if (ripng->route_map[type].name)
-               free(ripng->route_map[type].name);
-
-       ripng->route_map[type].name = NULL;
-       ripng->route_map[type].map = NULL;
-}
-
-/* Redistribution types */
-static struct {
-       int type;
-       int str_min_len;
-       const char *str;
-} redist_type[] = {{ZEBRA_ROUTE_KERNEL, 1, "kernel"},
-                  {ZEBRA_ROUTE_CONNECT, 1, "connected"},
-                  {ZEBRA_ROUTE_STATIC, 1, "static"},
-                  {ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
-                  {ZEBRA_ROUTE_BGP, 2, "bgp"},
-                  {ZEBRA_ROUTE_VNC, 1, "vnc"},
-                  {0, 0, NULL}};
-
 void ripng_redistribute_clean()
 {
-       int i;
-
-       for (i = 0; redist_type[i].str; i++) {
-               if (vrf_bitmap_check(
-                           zclient->redist[AFI_IP6][redist_type[i].type],
-                           VRF_DEFAULT)) {
-                       if (zclient->sock > 0)
-                               zebra_redistribute_send(
-                                       ZEBRA_REDISTRIBUTE_DELETE, zclient,
-                                       AFI_IP6, redist_type[i].type, 0,
-                                       VRF_DEFAULT);
-
-                       vrf_bitmap_unset(
-                               zclient->redist[AFI_IP6][redist_type[i].type],
-                               VRF_DEFAULT);
-
-                       /* Remove the routes from RIPng table. */
-                       ripng_redistribute_withdraw(redist_type[i].type);
-               }
-       }
-}
-
-DEFUN (ripng_redistribute_type,
-       ripng_redistribute_type_cmd,
-       "redistribute " FRR_REDIST_STR_RIPNGD,
-       "Redistribute\n"
-       FRR_REDIST_HELP_STR_RIPNGD)
-{
-       int type;
-
-       char *proto = argv[argc - 1]->text;
-       type = proto_redistnum(AFI_IP6, proto);
-
-       if (type < 0) {
-               vty_out(vty, "Invalid type %s\n", proto);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
-                            VRF_DEFAULT);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ripng_redistribute_type,
-       no_ripng_redistribute_type_cmd,
-       "no redistribute " FRR_REDIST_STR_RIPNGD " [metric (0-16)] [route-map WORD]",
-       NO_STR
-       "Redistribute\n"
-       FRR_REDIST_HELP_STR_RIPNGD
-       "Metric\n"
-       "Metric value\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
-{
-       int type;
-
-       char *proto = argv[2]->text;
-       type = proto_redistnum(AFI_IP6, proto);
-
-       if (type < 0) {
-               vty_out(vty, "Invalid type %s\n", proto);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       ripng_redistribute_metric_unset(type);
-       ripng_redistribute_routemap_unset(type);
-       return ripng_redistribute_unset(type);
-}
-
-
-DEFUN (ripng_redistribute_type_metric,
-       ripng_redistribute_type_metric_cmd,
-       "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16)",
-       "Redistribute\n"
-       FRR_REDIST_HELP_STR_RIPNGD
-       "Metric\n"
-       "Metric value\n")
-{
-       int idx_protocol = 1;
-       int idx_number = 3;
-       int type;
-       int metric;
-
-       metric = atoi(argv[idx_number]->arg);
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-
-       if (type < 0) {
-               vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       ripng_redistribute_metric_set(type, metric);
-       zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
-                            VRF_DEFAULT);
-       return CMD_SUCCESS;
-}
-
-DEFUN (ripng_redistribute_type_routemap,
-       ripng_redistribute_type_routemap_cmd,
-       "redistribute " FRR_REDIST_STR_RIPNGD " route-map WORD",
-       "Redistribute\n"
-       FRR_REDIST_HELP_STR_RIPNGD
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
-{
-       int idx_protocol = 1;
-       int idx_word = 3;
-       int type;
-
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
+       for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+               if (!vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT))
+                       continue;
 
-       if (type < 0) {
-               vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+               if (zclient->sock > 0)
+                       zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE,
+                                               zclient, AFI_IP6, i, 0,
+                                               VRF_DEFAULT);
 
-       ripng_redistribute_routemap_set(type, argv[idx_word]->text);
-       zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
-                            VRF_DEFAULT);
-       return CMD_SUCCESS;
-}
+               vrf_bitmap_unset(zclient->redist[AFI_IP6][i], VRF_DEFAULT);
 
-DEFUN (ripng_redistribute_type_metric_routemap,
-       ripng_redistribute_type_metric_routemap_cmd,
-       "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16) route-map WORD",
-       "Redistribute\n"
-       FRR_REDIST_HELP_STR_RIPNGD
-       "Metric\n"
-       "Metric value\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
-{
-       int idx_protocol = 1;
-       int idx_number = 3;
-       int idx_word = 5;
-       int type;
-       int metric;
-
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-       metric = atoi(argv[idx_number]->arg);
-
-       if (type < 0) {
-               vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text);
-               return CMD_WARNING_CONFIG_FAILED;
+               /* Remove the routes from RIP table. */
+               ripng_redistribute_withdraw(i);
        }
-
-       ripng_redistribute_metric_set(type, metric);
-       ripng_redistribute_routemap_set(type, argv[idx_word]->text);
-       zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
-                            VRF_DEFAULT);
-       return CMD_SUCCESS;
 }
 
-void ripng_redistribute_write(struct vty *vty, int config_mode)
+void ripng_redistribute_write(struct vty *vty)
 {
        int i;
 
@@ -377,31 +189,7 @@ void ripng_redistribute_write(struct vty *vty, int config_mode)
                                         VRF_DEFAULT))
                        continue;
 
-               if (!config_mode) {
-                       vty_out(vty, "    %s", zebra_route_string(i));
-                       continue;
-               }
-
-               if (ripng->route_map[i].metric_config) {
-                       if (ripng->route_map[i].name)
-                               vty_out(vty,
-                                       " redistribute %s metric %d route-map %s\n",
-                                       zebra_route_string(i),
-                                       ripng->route_map[i].metric,
-                                       ripng->route_map[i].name);
-                       else
-                               vty_out(vty, " redistribute %s metric %d\n",
-                                       zebra_route_string(i),
-                                       ripng->route_map[i].metric);
-               } else {
-                       if (ripng->route_map[i].name)
-                               vty_out(vty, " redistribute %s route-map %s\n",
-                                       zebra_route_string(i),
-                                       ripng->route_map[i].name);
-                       else
-                               vty_out(vty, " redistribute %s\n",
-                                       zebra_route_string(i));
-               }
+               vty_out(vty, "    %s", zebra_route_string(i));
        }
 }
 
@@ -426,14 +214,6 @@ void zebra_init(struct thread_master *master)
        zclient->interface_address_delete = ripng_interface_address_delete;
        zclient->redistribute_route_add = ripng_zebra_read_route;
        zclient->redistribute_route_del = ripng_zebra_read_route;
-
-       /* Install command elements to ripng node */
-       install_element(RIPNG_NODE, &ripng_redistribute_type_cmd);
-       install_element(RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
-       install_element(RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
-       install_element(RIPNG_NODE,
-                       &ripng_redistribute_type_metric_routemap_cmd);
-       install_element(RIPNG_NODE, &no_ripng_redistribute_type_cmd);
 }
 
 void ripng_zebra_stop(void)
index 2cbbbae7f547faf5f29d2413802f519e6fdbc522..4ec9209da7670ed3f19efce2b50076da901f0673 100644 (file)
@@ -36,6 +36,7 @@
 #include "if_rmap.h"
 #include "privs.h"
 #include "lib_errors.h"
+#include "northbound_cli.h"
 
 #include "ripngd/ripngd.h"
 #include "ripngd/ripng_route.h"
@@ -65,7 +66,7 @@ struct ripng_nexthop {
        struct in6_addr address;
 };
 
-static int ripng_route_rte(struct ripng_info *rinfo)
+int ripng_route_rte(struct ripng_info *rinfo)
 {
        return (rinfo->type == ZEBRA_ROUTE_RIPNG
                && rinfo->sub_type == RIPNG_ROUTE_RTE);
@@ -87,7 +88,7 @@ void ripng_info_free(struct ripng_info *rinfo)
 }
 
 /* Create ripng socket. */
-static int ripng_make_socket(void)
+int ripng_make_socket(void)
 {
        int ret;
        int sock;
@@ -1778,7 +1779,7 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
 }
 
 /* Create new RIPng instance and set it to global variable. */
-static int ripng_create(void)
+int ripng_create(int socket)
 {
        /* ripng should be NULL. */
        assert(ripng == NULL);
@@ -1788,10 +1789,15 @@ static int ripng_create(void)
 
        /* Default version and timer values. */
        ripng->version = RIPNG_V1;
-       ripng->update_time = RIPNG_UPDATE_TIMER_DEFAULT;
-       ripng->timeout_time = RIPNG_TIMEOUT_TIMER_DEFAULT;
-       ripng->garbage_time = RIPNG_GARBAGE_TIMER_DEFAULT;
-       ripng->default_metric = RIPNG_DEFAULT_METRIC_DEFAULT;
+       ripng->update_time = yang_get_default_uint32(
+               "%s/timers/update-interval", RIPNG_INSTANCE);
+       ripng->timeout_time = yang_get_default_uint32(
+               "%s/timers/holddown-interval", RIPNG_INSTANCE);
+       ripng->garbage_time = yang_get_default_uint32(
+               "%s/timers/flush-interval", RIPNG_INSTANCE);
+       ripng->default_metric =
+               yang_get_default_uint8("%s/default-metric", RIPNG_INSTANCE);
+       ripng->ecmp = yang_get_default_bool("%s/allow-ecmp", RIPNG_INSTANCE);
 
        /* Make buffer.  */
        ripng->ibuf = stream_new(RIPNG_MAX_PACKET_SIZE * 5);
@@ -1799,13 +1805,9 @@ static int ripng_create(void)
 
        /* Initialize RIPng routig table. */
        ripng->table = agg_table_init();
-       ripng->route = agg_table_init();
-       ripng->aggregate = agg_table_init();
 
        /* Make socket. */
-       ripng->sock = ripng_make_socket();
-       if (ripng->sock < 0)
-               return ripng->sock;
+       ripng->sock = socket;
 
        /* Threads. */
        ripng_event(RIPNG_READ, ripng->sock);
@@ -2060,12 +2062,12 @@ DEFUN (show_ipv6_ripng_status,
                return CMD_SUCCESS;
 
        vty_out(vty, "Routing Protocol is \"RIPng\"\n");
-       vty_out(vty, "  Sending updates every %ld seconds with +/-50%%,",
+       vty_out(vty, "  Sending updates every %u seconds with +/-50%%,",
                ripng->update_time);
        vty_out(vty, " next due in %lu seconds\n",
                thread_timer_remain_second(ripng->t_update));
-       vty_out(vty, "  Timeout after %ld seconds,", ripng->timeout_time);
-       vty_out(vty, " garbage collect after %ld seconds\n",
+       vty_out(vty, "  Timeout after %u seconds,", ripng->timeout_time);
+       vty_out(vty, " garbage collect after %u seconds\n",
                ripng->garbage_time);
 
        /* Filtering status show. */
@@ -2077,7 +2079,7 @@ DEFUN (show_ipv6_ripng_status,
 
        /* Redistribute information. */
        vty_out(vty, "  Redistributing:");
-       ripng_redistribute_write(vty, 0);
+       ripng_redistribute_write(vty);
        vty_out(vty, "\n");
 
        vty_out(vty, "  Default version control: send version %d,",
@@ -2099,7 +2101,7 @@ DEFUN (show_ipv6_ripng_status,
        }
 
        vty_out(vty, "  Routing for Networks:\n");
-       ripng_network_write(vty, 0);
+       ripng_network_write(vty);
 
        vty_out(vty, "  Routing Information Sources:\n");
        vty_out(vty,
@@ -2109,245 +2111,6 @@ DEFUN (show_ipv6_ripng_status,
        return CMD_SUCCESS;
 }
 
-DEFUN (clear_ipv6_rip,
-       clear_ipv6_rip_cmd,
-       "clear ipv6 ripng",
-       CLEAR_STR
-       IPV6_STR
-       "Clear IPv6 RIP database\n")
-{
-       struct agg_node *rp;
-       struct ripng_info *rinfo;
-       struct list *list;
-       struct listnode *listnode;
-
-       /* Clear received RIPng routes */
-       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) {
-               list = rp->info;
-               if (list == NULL)
-                       continue;
-
-               for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
-                       if (!ripng_route_rte(rinfo))
-                               continue;
-
-                       if (CHECK_FLAG(rinfo->flags, RIPNG_RTF_FIB))
-                               ripng_zebra_ipv6_delete(rp);
-                       break;
-               }
-
-               if (rinfo) {
-                       RIPNG_TIMER_OFF(rinfo->t_timeout);
-                       RIPNG_TIMER_OFF(rinfo->t_garbage_collect);
-                       listnode_delete(list, rinfo);
-                       ripng_info_free(rinfo);
-               }
-
-               if (list_isempty(list)) {
-                       list_delete(&list);
-                       rp->info = NULL;
-                       agg_unlock_node(rp);
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN_NOSH (router_ripng,
-       router_ripng_cmd,
-       "router ripng",
-       "Enable a routing process\n"
-       "Make RIPng instance command\n")
-{
-       int ret;
-
-       vty->node = RIPNG_NODE;
-
-       if (!ripng) {
-               ret = ripng_create();
-
-               /* Notice to user we couldn't create RIPng. */
-               if (ret < 0) {
-                       zlog_warn("can't create RIPng");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_router_ripng,
-       no_router_ripng_cmd,
-       "no router ripng",
-       NO_STR
-       "Enable a routing process\n"
-       "Make RIPng instance command\n")
-{
-       if (ripng)
-               ripng_clean();
-       return CMD_SUCCESS;
-}
-
-DEFUN (ripng_route,
-       ripng_route_cmd,
-       "route IPV6ADDR",
-       "Static route setup\n"
-       "Set static RIPng route announcement\n")
-{
-       int idx_ipv6addr = 1;
-       int ret;
-       struct prefix_ipv6 p;
-       struct agg_node *rp;
-
-       ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg,
-                             (struct prefix_ipv6 *)&p);
-       if (ret <= 0) {
-               vty_out(vty, "Malformed address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       apply_mask_ipv6(&p);
-
-       rp = agg_node_get(ripng->route, (struct prefix *)&p);
-       if (rp->info) {
-               vty_out(vty, "There is already same static route.\n");
-               agg_unlock_node(rp);
-               return CMD_WARNING;
-       }
-       rp->info = (void *)1;
-
-       ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0,
-                              NULL, 0);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ripng_route,
-       no_ripng_route_cmd,
-       "no route IPV6ADDR",
-       NO_STR
-       "Static route setup\n"
-       "Delete static RIPng route announcement\n")
-{
-       int idx_ipv6addr = 2;
-       int ret;
-       struct prefix_ipv6 p;
-       struct agg_node *rp;
-
-       ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg,
-                             (struct prefix_ipv6 *)&p);
-       if (ret <= 0) {
-               vty_out(vty, "Malformed address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       apply_mask_ipv6(&p);
-
-       rp = agg_node_lookup(ripng->route, (struct prefix *)&p);
-       if (!rp) {
-               vty_out(vty, "Can't find static route.\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0);
-       agg_unlock_node(rp);
-
-       rp->info = NULL;
-       agg_unlock_node(rp);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (ripng_aggregate_address,
-       ripng_aggregate_address_cmd,
-       "aggregate-address X:X::X:X/M",
-       "Set aggregate RIPng route announcement\n"
-       "Aggregate network\n")
-{
-       int idx_ipv6_prefixlen = 1;
-       int ret;
-       struct prefix p;
-       struct agg_node *node;
-
-       ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg,
-                             (struct prefix_ipv6 *)&p);
-       if (ret <= 0) {
-               vty_out(vty, "Malformed address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Check aggregate alredy exist or not. */
-       node = agg_node_get(ripng->aggregate, &p);
-       if (node->info) {
-               vty_out(vty, "There is already same aggregate route.\n");
-               agg_unlock_node(node);
-               return CMD_WARNING;
-       }
-       node->info = (void *)1;
-
-       ripng_aggregate_add(&p);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ripng_aggregate_address,
-       no_ripng_aggregate_address_cmd,
-       "no aggregate-address X:X::X:X/M",
-       NO_STR
-       "Delete aggregate RIPng route announcement\n"
-       "Aggregate network\n")
-{
-       int idx_ipv6_prefixlen = 2;
-       int ret;
-       struct prefix p;
-       struct agg_node *rn;
-
-       ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg,
-                             (struct prefix_ipv6 *)&p);
-       if (ret <= 0) {
-               vty_out(vty, "Malformed address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       rn = agg_node_lookup(ripng->aggregate, &p);
-       if (!rn) {
-               vty_out(vty, "Can't find aggregate route.\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       agg_unlock_node(rn);
-       rn->info = NULL;
-       agg_unlock_node(rn);
-
-       ripng_aggregate_delete(&p);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (ripng_default_metric,
-       ripng_default_metric_cmd,
-       "default-metric (1-16)",
-       "Set a metric of redistribute routes\n"
-       "Default metric\n")
-{
-       int idx_number = 1;
-       if (ripng) {
-               ripng->default_metric = atoi(argv[idx_number]->arg);
-       }
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ripng_default_metric,
-       no_ripng_default_metric_cmd,
-       "no default-metric [(1-16)]",
-       NO_STR
-       "Set a metric of redistribute routes\n"
-       "Default metric\n")
-{
-       if (ripng) {
-               ripng->default_metric = RIPNG_DEFAULT_METRIC_DEFAULT;
-       }
-       return CMD_SUCCESS;
-}
-
-
 #if 0
 /* RIPng update timer setup. */
 DEFUN (ripng_update_timer,
@@ -2451,58 +2214,6 @@ DEFUN (no_ripng_garbage_timer,
 }
 #endif /* 0 */
 
-DEFUN (ripng_timers,
-       ripng_timers_cmd,
-       "timers basic (0-65535) (0-65535) (0-65535)",
-       "RIPng timers setup\n"
-       "Basic timer\n"
-       "Routing table update timer value in second. Default is 30.\n"
-       "Routing information timeout timer. Default is 180.\n"
-       "Garbage collection timer. Default is 120.\n")
-{
-       int idx_number = 2;
-       int idx_number_2 = 3;
-       int idx_number_3 = 4;
-       unsigned long update;
-       unsigned long timeout;
-       unsigned long garbage;
-
-       update = strtoul(argv[idx_number]->arg, NULL, 10);
-       timeout = strtoul(argv[idx_number_2]->arg, NULL, 10);
-       garbage = strtoul(argv[idx_number_3]->arg, NULL, 10);
-
-       /* Set each timer value. */
-       ripng->update_time = update;
-       ripng->timeout_time = timeout;
-       ripng->garbage_time = garbage;
-
-       /* Reset update timer thread. */
-       ripng_event(RIPNG_UPDATE_EVENT, 0);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ripng_timers,
-       no_ripng_timers_cmd,
-       "no timers basic [(0-65535) (0-65535) (0-65535)]",
-       NO_STR
-       "RIPng timers setup\n"
-       "Basic timer\n"
-       "Routing table update timer value in second. Default is 30.\n"
-       "Routing information timeout timer. Default is 180.\n"
-       "Garbage collection timer. Default is 120.\n")
-{
-       /* Set each timer value to the default. */
-       ripng->update_time = RIPNG_UPDATE_TIMER_DEFAULT;
-       ripng->timeout_time = RIPNG_TIMEOUT_TIMER_DEFAULT;
-       ripng->garbage_time = RIPNG_GARBAGE_TIMER_DEFAULT;
-
-       /* Reset update timer thread. */
-       ripng_event(RIPNG_UPDATE_EVENT, 0);
-
-       return CMD_SUCCESS;
-}
-
 #if 0
 DEFUN (show_ipv6_protocols,
        show_ipv6_protocols_cmd,
@@ -2530,48 +2241,8 @@ DEFUN (show_ipv6_protocols,
 }
 #endif
 
-/* Please be carefull to use this command. */
-DEFUN (ripng_default_information_originate,
-       ripng_default_information_originate_cmd,
-       "default-information originate",
-       "Default route information\n"
-       "Distribute default route\n")
-{
-       struct prefix_ipv6 p;
-
-       if (!ripng->default_information) {
-               ripng->default_information = 1;
-
-               str2prefix_ipv6("::/0", &p);
-               ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT,
-                                      &p, 0, NULL, 0);
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ripng_default_information_originate,
-       no_ripng_default_information_originate_cmd,
-       "no default-information originate",
-       NO_STR
-       "Default route information\n"
-       "Distribute default route\n")
-{
-       struct prefix_ipv6 p;
-
-       if (ripng->default_information) {
-               ripng->default_information = 0;
-
-               str2prefix_ipv6("::/0", &p);
-               ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG,
-                                         RIPNG_ROUTE_DEFAULT, &p, 0);
-       }
-
-       return CMD_SUCCESS;
-}
-
 /* Update ECMP routes to zebra when ECMP is disabled. */
-static void ripng_ecmp_disable(void)
+void ripng_ecmp_disable(void)
 {
        struct agg_node *rp;
        struct ripng_info *rinfo, *tmp_rinfo;
@@ -2608,109 +2279,24 @@ static void ripng_ecmp_disable(void)
                }
 }
 
-DEFUN (ripng_allow_ecmp,
-       ripng_allow_ecmp_cmd,
-       "allow-ecmp",
-       "Allow Equal Cost MultiPath\n")
-{
-       if (ripng->ecmp) {
-               vty_out(vty, "ECMP is already enabled.\n");
-               return CMD_WARNING;
-       }
-
-       ripng->ecmp = 1;
-       zlog_info("ECMP is enabled.");
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ripng_allow_ecmp,
-       no_ripng_allow_ecmp_cmd,
-       "no allow-ecmp",
-       NO_STR
-       "Allow Equal Cost MultiPath\n")
-{
-       if (!ripng->ecmp) {
-               vty_out(vty, "ECMP is already disabled.\n");
-               return CMD_WARNING;
-       }
-
-       ripng->ecmp = 0;
-       zlog_info("ECMP is disabled.");
-       ripng_ecmp_disable();
-       return CMD_SUCCESS;
-}
-
 /* RIPng configuration write function. */
 static int ripng_config_write(struct vty *vty)
 {
-       int ripng_network_write(struct vty *, int);
-       void ripng_redistribute_write(struct vty *, int);
+       struct lyd_node *dnode;
        int write = 0;
-       struct agg_node *rp;
-
-       if (ripng) {
 
-               /* RIPng router. */
-               vty_out(vty, "router ripng\n");
-
-               if (ripng->default_information)
-                       vty_out(vty, " default-information originate\n");
-
-               ripng_network_write(vty, 1);
-
-               /* RIPng default metric configuration */
-               if (ripng->default_metric != RIPNG_DEFAULT_METRIC_DEFAULT)
-                       vty_out(vty, " default-metric %d\n",
-                               ripng->default_metric);
-
-               ripng_redistribute_write(vty, 1);
-
-               /* RIP offset-list configuration. */
-               config_write_ripng_offset_list(vty);
-
-               /* RIPng aggregate routes. */
-               for (rp = agg_route_top(ripng->aggregate); rp;
-                    rp = agg_route_next(rp))
-                       if (rp->info != NULL)
-                               vty_out(vty, " aggregate-address %s/%d\n",
-                                       inet6_ntoa(rp->p.u.prefix6),
-                                       rp->p.prefixlen);
-
-               /* ECMP configuration. */
-               if (ripng->ecmp)
-                       vty_out(vty, " allow-ecmp\n");
-
-               /* RIPng static routes. */
-               for (rp = agg_route_top(ripng->route); rp;
-                    rp = agg_route_next(rp))
-                       if (rp->info != NULL)
-                               vty_out(vty, " route %s/%d\n",
-                                       inet6_ntoa(rp->p.u.prefix6),
-                                       rp->p.prefixlen);
-
-               /* RIPng timers configuration. */
-               if (ripng->update_time != RIPNG_UPDATE_TIMER_DEFAULT
-                   || ripng->timeout_time != RIPNG_TIMEOUT_TIMER_DEFAULT
-                   || ripng->garbage_time != RIPNG_GARBAGE_TIMER_DEFAULT) {
-                       vty_out(vty, " timers basic %ld %ld %ld\n",
-                               ripng->update_time, ripng->timeout_time,
-                               ripng->garbage_time);
-               }
-#if 0
-      if (ripng->update_time != RIPNG_UPDATE_TIMER_DEFAULT)
-       vty_out (vty, " update-timer %d\n", ripng->update_time);
-      if (ripng->timeout_time != RIPNG_TIMEOUT_TIMER_DEFAULT)
-       vty_out (vty, " timeout-timer %d\n", ripng->timeout_time);
-      if (ripng->garbage_time != RIPNG_GARBAGE_TIMER_DEFAULT)
-       vty_out (vty, " garbage-timer %d\n", ripng->garbage_time);
-#endif /* 0 */
+       dnode = yang_dnode_get(running_config->dnode,
+                              "/frr-ripngd:ripngd/instance");
+       if (dnode) {
+               nb_cli_show_dnode_cmds(vty, dnode, false);
 
-               write += config_write_distribute(vty);
+               config_write_distribute(vty);
 
-               write += config_write_if_rmap(vty);
+               config_write_if_rmap(vty);
 
-               write++;
+               write = 1;
        }
+
        return write;
 }
 
@@ -2855,29 +2441,11 @@ void ripng_clean()
                        ripng->sock = -1;
                }
 
-               /* Static RIPng route configuration. */
-               for (rp = agg_route_top(ripng->route); rp;
-                    rp = agg_route_next(rp))
-                       if (rp->info) {
-                               rp->info = NULL;
-                               agg_unlock_node(rp);
-                       }
-
-               /* RIPng aggregated prefixes */
-               for (rp = agg_route_top(ripng->aggregate); rp;
-                    rp = agg_route_next(rp))
-                       if (rp->info) {
-                               rp->info = NULL;
-                               agg_unlock_node(rp);
-                       }
-
                for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                        if (ripng->route_map[i].name)
                                free(ripng->route_map[i].name);
 
-               XFREE(MTYPE_ROUTE_TABLE, ripng->table);
-               XFREE(MTYPE_ROUTE_TABLE, ripng->route);
-               XFREE(MTYPE_ROUTE_TABLE, ripng->aggregate);
+               agg_table_finish(ripng->table);
 
                stream_free(ripng->ibuf);
                stream_free(ripng->obuf);
@@ -2893,25 +2461,6 @@ void ripng_clean()
        ripng_redistribute_clean();
 }
 
-/* Reset all values to the default settings. */
-void ripng_reset()
-{
-       /* Call ripd related reset functions. */
-       ripng_debug_reset();
-       ripng_route_map_reset();
-
-       /* Call library reset functions. */
-       vty_reset();
-       access_list_reset();
-       prefix_list_reset();
-
-       distribute_list_reset();
-
-       ripng_interface_reset();
-
-       ripng_zclient_reset();
-}
-
 static void ripng_if_rmap_update(struct if_rmap *if_rmap)
 {
        struct interface *ifp;
@@ -2987,22 +2536,8 @@ void ripng_init()
        install_element(VIEW_NODE, &show_ipv6_ripng_cmd);
        install_element(VIEW_NODE, &show_ipv6_ripng_status_cmd);
 
-       install_element(ENABLE_NODE, &clear_ipv6_rip_cmd);
-
-       install_element(CONFIG_NODE, &router_ripng_cmd);
-       install_element(CONFIG_NODE, &no_router_ripng_cmd);
-
        install_default(RIPNG_NODE);
-       install_element(RIPNG_NODE, &ripng_route_cmd);
-       install_element(RIPNG_NODE, &no_ripng_route_cmd);
-       install_element(RIPNG_NODE, &ripng_aggregate_address_cmd);
-       install_element(RIPNG_NODE, &no_ripng_aggregate_address_cmd);
-
-       install_element(RIPNG_NODE, &ripng_default_metric_cmd);
-       install_element(RIPNG_NODE, &no_ripng_default_metric_cmd);
 
-       install_element(RIPNG_NODE, &ripng_timers_cmd);
-       install_element(RIPNG_NODE, &no_ripng_timers_cmd);
 #if 0
   install_element (VIEW_NODE, &show_ipv6_protocols_cmd);
   install_element (RIPNG_NODE, &ripng_update_timer_cmd);
@@ -3013,13 +2548,6 @@ void ripng_init()
   install_element (RIPNG_NODE, &no_ripng_garbage_timer_cmd);
 #endif /* 0 */
 
-       install_element(RIPNG_NODE, &ripng_default_information_originate_cmd);
-       install_element(RIPNG_NODE,
-                       &no_ripng_default_information_originate_cmd);
-
-       install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
-       install_element(RIPNG_NODE, &no_ripng_allow_ecmp_cmd);
-
        ripng_if_init();
        ripng_debug_init();
 
index 1095a33494e71d49946be5581df0f11fa37f8480..5b32374ace87238f08127ea0a80c941ba628ce02 100644 (file)
 #define RIPNG_METRIC_NEXTHOP          0xff
 #define RIPNG_GROUP              "ff02::9"
 
-/* RIPng timers. */
-#define RIPNG_UPDATE_TIMER_DEFAULT      30
-#define RIPNG_TIMEOUT_TIMER_DEFAULT    180
-#define RIPNG_GARBAGE_TIMER_DEFAULT    120
-
 /* RIPng peer timeout value. */
 #define RIPNG_PEER_TIMER_DEFAULT       180
 
@@ -77,9 +72,6 @@
 #define RIPNG_DEFAULT_ACCEPT_NONE        1
 #define RIPNG_DEFAULT_ACCEPT             2
 
-/* Default value for "default-metric" command. */
-#define RIPNG_DEFAULT_METRIC_DEFAULT     1
-
 /* For max RTE calculation. */
 #ifndef IPV6_HDRLEN
 #define IPV6_HDRLEN 40
 #define IFMINMTU    576
 #endif /* IFMINMTU */
 
+/* YANG paths */
+#define RIPNG_INSTANCE "/frr-ripngd:ripngd/instance"
+#define RIPNG_IFACE    "/frr-interface:lib/interface/frr-ripngd:ripng"
+
 /* RIPng structure. */
 struct ripng {
        /* RIPng socket. */
@@ -97,12 +93,11 @@ struct ripng {
        /* RIPng Parameters.*/
        uint8_t command;
        uint8_t version;
-       unsigned long update_time;
-       unsigned long timeout_time;
-       unsigned long garbage_time;
+       uint16_t update_time;
+       uint16_t timeout_time;
+       uint16_t garbage_time;
        int max_mtu;
-       int default_metric;
-       int default_information;
+       uint8_t default_metric;
 
        /* Input/output buffer of RIPng. */
        struct stream *ibuf;
@@ -111,12 +106,6 @@ struct ripng {
        /* RIPng routing information base. */
        struct agg_table *table;
 
-       /* RIPng only static route information. */
-       struct agg_table *route;
-
-       /* RIPng aggregate route information. */
-       struct agg_table *aggregate;
-
        /* RIPng threads. */
        struct thread *t_read;
        struct thread *t_write;
@@ -130,14 +119,14 @@ struct ripng {
        struct thread *t_triggered_interval;
 
        /* RIPng ECMP flag */
-       unsigned int ecmp;
+       bool ecmp;
 
        /* For redistribute route map. */
        struct {
                char *name;
                struct route_map *map;
-               int metric_config;
-               uint32_t metric;
+               bool metric_config;
+               uint8_t metric;
        } route_map[ZEBRA_ROUTE_MAX];
 };
 
@@ -247,7 +236,6 @@ struct ripng_interface {
 
        /* Split horizon flag. */
        split_horizon_policy_t split_horizon;
-       split_horizon_policy_t split_horizon_default;
 
 /* For filter type slot. */
 #define RIPNG_FILTER_IN  0
@@ -325,30 +313,46 @@ enum ripng_event {
                }                                                              \
        } while (0)
 
+#define RIPNG_OFFSET_LIST_IN  0
+#define RIPNG_OFFSET_LIST_OUT 1
+#define RIPNG_OFFSET_LIST_MAX 2
+
+struct ripng_offset_list {
+       char *ifname;
+
+       struct {
+               char *alist_name;
+               /* struct access_list *alist; */
+               uint8_t metric;
+       } direct[RIPNG_OFFSET_LIST_MAX];
+};
+
 /* Extern variables. */
 extern struct ripng *ripng;
+extern struct list *peer_list;
 extern struct zebra_privs_t ripngd_privs;
 extern struct thread_master *master;
 
 /* Prototypes. */
 extern void ripng_init(void);
-extern void ripng_reset(void);
 extern void ripng_clean(void);
 extern void ripng_clean_network(void);
 extern void ripng_interface_clean(void);
-extern void ripng_interface_reset(void);
+extern int ripng_enable_network_add(struct prefix *p);
+extern int ripng_enable_network_delete(struct prefix *p);
+extern int ripng_enable_if_add(const char *ifname);
+extern int ripng_enable_if_delete(const char *ifname);
+extern int ripng_passive_interface_set(const char *ifname);
+extern int ripng_passive_interface_unset(const char *ifname);
 extern void ripng_passive_interface_clean(void);
 extern void ripng_if_init(void);
 extern void ripng_route_map_init(void);
-extern void ripng_route_map_reset(void);
 extern void ripng_terminate(void);
 /* zclient_init() is done by ripng_zebra.c:zebra_init() */
 extern void zebra_init(struct thread_master *);
 extern void ripng_zebra_stop(void);
-extern void ripng_zclient_reset(void);
-extern void ripng_offset_init(void);
-
-extern int config_write_ripng_offset_list(struct vty *);
+extern void ripng_redistribute_conf_update(int type);
+extern void ripng_redistribute_conf_delete(int type);
 
 extern void ripng_peer_init(void);
 extern void ripng_peer_update(struct sockaddr_in6 *, uint8_t);
@@ -358,12 +362,18 @@ extern void ripng_peer_display(struct vty *);
 extern struct ripng_peer *ripng_peer_lookup(struct in6_addr *);
 extern struct ripng_peer *ripng_peer_lookup_next(struct in6_addr *);
 
+extern struct ripng_offset_list *ripng_offset_list_new(const char *ifname);
+extern void ripng_offset_list_del(struct ripng_offset_list *offset);
+extern struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname);
+extern struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname);
 extern int ripng_offset_list_apply_in(struct prefix_ipv6 *, struct interface *,
                                      uint8_t *);
 extern int ripng_offset_list_apply_out(struct prefix_ipv6 *, struct interface *,
                                       uint8_t *);
+extern void ripng_offset_init(void);
 extern void ripng_offset_clean(void);
 
+extern int ripng_route_rte(struct ripng_info *rinfo);
 extern struct ripng_info *ripng_info_new(void);
 extern void ripng_info_free(struct ripng_info *rinfo);
 extern void ripng_event(enum ripng_event, int);
@@ -374,6 +384,7 @@ extern void ripng_redistribute_delete(int, int, struct prefix_ipv6 *,
                                      ifindex_t);
 extern void ripng_redistribute_withdraw(int type);
 
+extern void ripng_ecmp_disable(void);
 extern void ripng_distribute_update_interface(struct interface *);
 extern void ripng_if_rmap_update_interface(struct interface *);
 
@@ -382,7 +393,7 @@ extern void ripng_zebra_ipv6_delete(struct agg_node *node);
 
 extern void ripng_redistribute_clean(void);
 extern int ripng_redistribute_check(int);
-extern void ripng_redistribute_write(struct vty *, int);
+extern void ripng_redistribute_write(struct vty *);
 
 extern int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p,
                           struct in6_addr *nexthop, uint16_t tag,
@@ -406,10 +417,16 @@ extern int ripng_interface_address_add(int command, struct zclient *,
 extern int ripng_interface_address_delete(int command, struct zclient *,
                                          zebra_size_t, vrf_id_t);
 
-extern int ripng_network_write(struct vty *, int);
+extern int ripng_create(int socket);
+extern int ripng_make_socket(void);
+extern int ripng_network_write(struct vty *);
 
 extern struct ripng_info *ripng_ecmp_add(struct ripng_info *);
 extern struct ripng_info *ripng_ecmp_replace(struct ripng_info *);
 extern struct ripng_info *ripng_ecmp_delete(struct ripng_info *);
 
+/* Northbound. */
+extern void ripng_cli_init(void);
+extern const struct frr_yang_module_info frr_ripngd_info;
+
 #endif /* _ZEBRA_RIPNG_RIPNGD_H */
index 8f834a1d297d5200fd4b711a90b7264d6fbf5bc2..d401e9bbf6cfa586b1d32ee174f95b93df2254a8 100644 (file)
@@ -6,21 +6,21 @@ if RIPNGD
 noinst_LIBRARIES += ripngd/libripng.a
 sbin_PROGRAMS += ripngd/ripngd
 vtysh_scan += \
+       $(top_srcdir)/ripngd/ripng_cli.c \
        $(top_srcdir)/ripngd/ripng_debug.c \
-       $(top_srcdir)/ripngd/ripng_interface.c \
-       $(top_srcdir)/ripngd/ripng_offset.c \
-       $(top_srcdir)/ripngd/ripng_zebra.c \
        $(top_srcdir)/ripngd/ripngd.c \
        # end
 man8 += $(MANBUILD)/ripngd.8
 endif
 
 ripngd_libripng_a_SOURCES = \
+       ripngd/ripng_cli.c \
        ripngd/ripng_debug.c \
        ripngd/ripng_interface.c \
        ripngd/ripng_memory.c \
        ripngd/ripng_nexthop.c \
        ripngd/ripng_offset.c \
+       ripngd/ripng_northbound.c \
        ripngd/ripng_peer.c \
        ripngd/ripng_route.c \
        ripngd/ripng_routemap.c \
@@ -28,7 +28,11 @@ ripngd_libripng_a_SOURCES = \
        ripngd/ripngd.c \
        # end
 
+ripngd/ripng_cli_clippy.c: $(CLIPPY_DEPS)
+ripngd/ripng_cli.$(OBJEXT): ripngd/ripng_cli_clippy.c
+
 noinst_HEADERS += \
+       ripngd/ripng_cli.h \
        ripngd/ripng_debug.h \
        ripngd/ripng_memory.h \
        ripngd/ripng_nexthop.h \
@@ -40,5 +44,8 @@ ripngd_ripngd_LDADD = ripngd/libripng.a lib/libfrr.la @LIBCAP@
 ripngd_ripngd_SOURCES = \
        ripngd/ripng_main.c \
        # end
+nodist_ripngd_ripngd_SOURCES = \
+       yang/frr-ripngd.yang.c \
+       # end
 
 dist_examples_DATA += ripngd/ripngd.conf.sample
index 2fbc686e1e81dc5135e5ac8b6b59e391e4edd076..78016dc9cefe544dfde53ab6bdb3ac386e95e640 100644 (file)
@@ -1384,10 +1384,10 @@ static void bgp_startup(void)
                 LOG_DAEMON);
        zprivs_preinit(&bgpd_privs);
        zprivs_init(&bgpd_privs);
-       yang_init();
-       nb_init(NULL, 0);
 
        master = thread_master_create(NULL);
+       yang_init();
+       nb_init(master, NULL, 0);
        bgp_master_init(master);
        bgp_option_set(BGP_OPT_NO_LISTEN);
        vrf_init(NULL, NULL, NULL, NULL, NULL);
index 9e34a7c255ba45f9345b3b2978190941bbe343ee..768cf296ad407c1e50ca71c7c41645922cdff883 100644 (file)
@@ -156,7 +156,7 @@ int main(int argc, char **argv)
        vty_init(master);
        memory_init();
        yang_init();
-       nb_init(NULL, 0);
+       nb_init(master, NULL, 0);
 
        /* OSPF vty inits. */
        test_vty_init();
index 04f1e3253d0b625e5eec58647054561dcdb33da0..393b58874571310f3690f7e18dd5cd47dbee286e 100644 (file)
@@ -80,11 +80,12 @@ int main(int argc, char **argv)
        /* Library inits. */
        cmd_init(1);
        cmd_hostname_set("test");
+       cmd_domainname_set("test.domain");
 
        vty_init(master);
        memory_init();
        yang_init();
-       nb_init(NULL, 0);
+       nb_init(master, NULL, 0);
 
        test_init(argc, argv);
 
index af8f9ce56afd5ab7274685e8494fe9dd6a859bdb..8f9959cc47ded6ded34e46cc1c8dc62d42a11370 100644 (file)
@@ -311,6 +311,7 @@ frr version @PACKAGE_VERSION@
 frr defaults @DFLT_NAME@\r
 !\r
 hostname test\r
+domainname test.domain\r
 !\r
 !\r
 !\r
@@ -327,6 +328,7 @@ frr version @PACKAGE_VERSION@
 frr defaults @DFLT_NAME@\r
 !\r
 hostname foohost\r
+domainname test.domain\r
 !\r
 !\r
 !\r
index 74816ece8c54c32a62610cd6c5411de4c76cf6bf..ba46bdcea9dbd8336d6a0fdf8e4d1c19013dde4c 100644 (file)
@@ -143,7 +143,7 @@ static void test_init(void)
 
        cmd_init(1);
        yang_init();
-       nb_init(NULL, 0);
+       nb_init(master, NULL, 0);
 
        install_node(&bgp_node, NULL);
        install_node(&rip_node, NULL);
index a9a89ee491a40759ff314e02f0c29142323219a3..7cd622854e886806746ec4eb2352bae020f93a33 100644 (file)
@@ -153,39 +153,6 @@ frr_test_module_vrfs_vrf_routes_route_get_next(const void *parent_list_entry,
        return node;
 }
 
-static int
-frr_test_module_vrfs_vrf_routes_route_get_keys(const void *list_entry,
-                                              struct yang_list_keys *keys)
-{
-       const struct troute *route;
-
-       route = listgetdata((struct listnode *)list_entry);
-
-       keys->num = 1;
-       (void)prefix2str(&route->prefix, keys->key[0], sizeof(keys->key[0]));
-
-       return NB_OK;
-}
-
-static const void *frr_test_module_vrfs_vrf_routes_route_lookup_entry(
-       const void *parent_list_entry, const struct yang_list_keys *keys)
-{
-       const struct tvrf *vrf;
-       const struct troute *route;
-       struct listnode *node;
-       struct prefix prefix;
-
-       yang_str2ipv4p(keys->key[0], &prefix);
-
-       vrf = listgetdata((struct listnode *)parent_list_entry);
-       for (ALL_LIST_ELEMENTS_RO(vrf->routes, node, route)) {
-               if (prefix_same((struct prefix *)&route->prefix, &prefix))
-                       return node;
-       }
-
-       return NULL;
-}
-
 /*
  * XPath: /frr-test-module:frr-test-module/vrfs/vrf/routes/route/prefix
  */
@@ -276,8 +243,6 @@ const struct frr_yang_module_info frr_test_module_info = {
                {
                        .xpath = "/frr-test-module:frr-test-module/vrfs/vrf/routes/route",
                        .cbs.get_next = frr_test_module_vrfs_vrf_routes_route_get_next,
-                       .cbs.get_keys = frr_test_module_vrfs_vrf_routes_route_get_keys,
-                       .cbs.lookup_entry = frr_test_module_vrfs_vrf_routes_route_lookup_entry,
                },
                {
                        .xpath = "/frr-test-module:frr-test-module/vrfs/vrf/routes/route/prefix",
@@ -449,7 +414,7 @@ int main(int argc, char **argv)
        vty_init(master);
        memory_init();
        yang_init();
-       nb_init(modules, array_size(modules));
+       nb_init(master, modules, array_size(modules));
 
        /* Create artificial data. */
        create_data(num_vrfs, num_interfaces, num_routes);
diff --git a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv4-post6.1.ref b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv4-post6.1.ref
new file mode 100644 (file)
index 0000000..d36d045
--- /dev/null
@@ -0,0 +1,9 @@
+BGP table version is 1, local router ID is 192.168.0.1, vrf id 0
+Default local pref 100, local AS 100
+Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+               i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+   Network          Next Hop            Metric LocPrf Weight Path
+*> 192.168.0.0/24   0.0.0.0                  0         32768 i
diff --git a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_post6.1.ref b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_post6.1.ref
new file mode 100644 (file)
index 0000000..de91b24
--- /dev/null
@@ -0,0 +1,9 @@
+BGP table version is 1, local router ID is 192.168.0.1, vrf id 0
+Default local pref 100, local AS 100
+Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+               i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+   Network          Next Hop            Metric LocPrf Weight Path
+*> fc00::/64        ::                       0         32768 i
diff --git a/tests/topotests/bgp-vrf-route-leak-basic/r1/bgpd.conf b/tests/topotests/bgp-vrf-route-leak-basic/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..626c268
--- /dev/null
@@ -0,0 +1,14 @@
+hostname r1
+
+router bgp 99 vrf DONNA
+  address-family ipv4 unicast
+    redistribute connected
+    import vrf EVA
+  !
+!
+router bgp 99 vrf EVA
+  address-family ipv4 unicast
+    redistribute connected
+    import vrf DONNA
+  !
+!
\ No newline at end of file
diff --git a/tests/topotests/bgp-vrf-route-leak-basic/r1/zebra.conf b/tests/topotests/bgp-vrf-route-leak-basic/r1/zebra.conf
new file mode 100644 (file)
index 0000000..3503855
--- /dev/null
@@ -0,0 +1,18 @@
+hostname r1
+
+int dummy1
+  ip address 10.0.0.1/24
+  no shut
+!
+int dummy2
+  ip address 10.0.1.1/24
+  no shut
+!
+int dummy3
+  ip address 10.0.2.1/24
+  no shut
+!
+int dummy4
+  ip address 10.0.3.1/24
+  no shut
+!
diff --git a/tests/topotests/bgp-vrf-route-leak-basic/setup_vrfs b/tests/topotests/bgp-vrf-route-leak-basic/setup_vrfs
new file mode 100644 (file)
index 0000000..fb67953
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+ip link add DONNA type vrf table 1001
+ip link add EVA type vrf table 1002
+
+ip link add dummy1 type dummy
+ip link add dummy2 type dummy
+ip link add dummy3 type dummy
+ip link add dummy4 type dummy
+
+ip link set dummy1 master DONNA
+ip link set dummy2 master EVA
+ip link set dummy3 master DONNA
+ip link set dummy4 master EVA
+
+
diff --git a/tests/topotests/bgp-vrf-route-leak-basic/test_bgp.py b/tests/topotests/bgp-vrf-route-leak-basic/test_bgp.py
new file mode 100644 (file)
index 0000000..b0d6040
--- /dev/null
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+
+#
+# test_bgp.py
+#
+# Copyright (c) 2018 Cumulus Networks, Inc.
+#                    Donald Sharp
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND Cumulus Networks DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_bgp.py: Test basic vrf route leaking
+"""
+
+import json
+import os
+import sys
+import pytest
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+from mininet.topo import Topo
+
+
+class BGPVRFTopo(Topo):
+    def build(self, *_args, **_opts):
+        "Build function"
+        tgen = get_topogen(self)
+
+        for routern in range(1, 2):
+            tgen.add_router('r{}'.format(routern))
+
+def setup_module(mod):
+    "Sets up the pytest environment"
+    tgen = Topogen(BGPVRFTopo, mod.__name__)
+    tgen.start_topology()
+
+    # For all registered routers, load the zebra configuration file
+    for rname, router in tgen.routers().iteritems():
+        router.run("/bin/bash {}/setup_vrfs".format(CWD))
+        router.load_config(
+            TopoRouter.RD_ZEBRA,
+            os.path.join(CWD, '{}/zebra.conf'.format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BGP,
+            os.path.join(CWD, '{}/bgpd.conf'.format(rname))
+        )
+
+    # After loading the configurations, this function loads configured daemons.
+    tgen.start_router()
+    #tgen.mininet_cli()
+
+def teardown_module(mod):
+    "Teardown the pytest environment"
+    tgen = get_topogen()
+
+    # This function tears down the whole topology.
+    tgen.stop_topology()
+
+def test_vrf_route_leak():
+    logger.info("Ensure that routes are leaked back and forth")
+    tgen = get_topogen()
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    r1 = tgen.gears['r1']
+
+    donna = r1.vtysh_cmd("show ip route vrf DONNA json", isjson=True)
+    route0 = donna["10.0.0.0/24"][0]
+    assert route0['protocol'] == "connected"
+    route1 = donna["10.0.1.0/24"][0]
+    assert route1['protocol'] == "bgp"
+    assert route1['selected'] == True
+    nhop = route1['nexthops'][0]
+    assert nhop['fib'] == True
+    route2 = donna["10.0.2.0/24"][0]
+    assert route2['protocol'] == "connected"
+    route3 = donna["10.0.3.0/24"][0]
+    assert route3['protocol'] == "bgp"
+    assert route3['selected'] == True
+    nhop = route3['nexthops'][0]
+    assert nhop['fib'] == True
+    eva = r1.vtysh_cmd("show ip route vrf EVA json", isjson=True)
+    route0 = eva["10.0.0.0/24"][0]
+    assert route0['protocol'] == "bgp"
+    assert route0['selected'] == True
+    nhop = route0['nexthops'][0]
+    assert nhop['fib'] == True
+    route1 = eva["10.0.1.0/24"][0]
+    assert route1['protocol'] == "connected"
+    route2 = eva["10.0.2.0/24"][0]
+    assert route2['protocol'] == "bgp"
+    assert route2['selected'] == True
+    nhop = route2['nexthops'][0]
+    assert nhop['fib'] == True
+    route3 = eva["10.0.3.0/24"][0]
+    assert route3['protocol'] == "connected"
+    #tgen.mininet_cli()
+
+def test_memory_leak():
+    "Run the memory leak test and report results."
+    tgen = get_topogen()
+    if not tgen.is_memleak_enabled():
+        pytest.skip('Memory leak test/report is disabled')
+
+    tgen.report_memory_leaks()
+
+
+if __name__ == '__main__':
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index 274eceaf0ffa467f55b37cc696d1e9557d0c61b6..cb08db531454a92f09630d03eca7f3d7300e480e 100644 (file)
@@ -7,7 +7,7 @@ log monitor notifications
 log commands
 log file bgpd.log
 
-router bgp 5228
+router bgp 5228 vrf ce4-cust2
    bgp router-id 99.0.0.4
    neighbor 192.168.2.1 remote-as 5228
    neighbor 192.168.2.1 update-source 192.168.2.2
index bfd8ba84356f6a145ad5d30a8187ee9844c35d2b..e55c9e779a965782c11d013cf2405645d7ead9df 100644 (file)
@@ -2,7 +2,7 @@ log file zebra.log
 !
 hostname ce4
 !
-interface lo
+interface ce4-cust2
  ip address 99.0.0.4/32
 !
 interface ce4-eth0
index 596701cee2bf12838befc9039709afeead47c21d..31e23faededae782ce136eca4c444c23fa677b91 100644 (file)
@@ -196,7 +196,18 @@ def ltemplatePreRouterStartHook():
         for intf in intfs:
             cc.doCmd(tgen, rtr, 'echo 1 > /proc/sys/net/mpls/conf/{}/input'.format(intf))
         logger.info('setup {0} vrf {0}-cust2, {0}-eth5. enabled mpls input.'.format(rtr))
-    if cc.getOutput() != 3:
+    #put ce4-eth0 into a VRF (no default instance!)
+    rtrs = ['ce4']
+    cmds = ['ip link add {0}-cust2 type vrf table 20',
+            'ip ru add oif {0}-cust2 table 20',
+            'ip ru add iif {0}-cust2 table 20',
+            'ip link set dev {0}-cust2 up',
+            'sysctl -w net.ipv4.udp_l3mdev_accept={}'.format(l3mdev_accept)]
+    for rtr in rtrs:
+        for cmd in cmds:
+            cc.doCmd(tgen, rtr, cmd.format(rtr))
+        cc.doCmd(tgen, rtr, 'ip link set dev {0}-eth0 master {0}-cust2'.format(rtr))
+    if cc.getOutput() != 4:
         InitSuccess = False
         logger.info('Unexpected output seen ({} times, tests will be skipped'.format(cc.getOutput()))
     else:
index 1dfd22f6bdc51ae1de14bc22974d7d35fe4c0bb1..28ecfeec5ac37030c34ee2769994f3d884e818fe 100644 (file)
@@ -2,7 +2,7 @@ from lutil import luCommand
 luCommand('ce1','vtysh -c "show bgp summary"',' 00:0','wait','Adjacencies up',180)
 luCommand('ce2','vtysh -c "show bgp summary"',' 00:0','wait','Adjacencies up')
 luCommand('ce3','vtysh -c "show bgp summary"',' 00:0','wait','Adjacencies up')
-luCommand('ce4','vtysh -c "show bgp summary"',' 00:0','wait','Adjacencies up')
+luCommand('ce4','vtysh -c "show bgp vrf all summary"',' 00:0','wait','Adjacencies up',180)
 luCommand('r1','ping 2.2.2.2 -c 1',' 0. packet loss','wait','PE->P2 (loopback) ping',60)
 luCommand('r3','ping 2.2.2.2 -c 1',' 0. packet loss','wait','PE->P2 (loopback) ping',60)
 luCommand('r4','ping 2.2.2.2 -c 1',' 0. packet loss','wait','PE->P2 (loopback) ping',60)
index 174666a075b8845ed73d2532a52248d740087270..9827a9e2c118347448eb88ebdc2fa933c5e64934 100644 (file)
@@ -31,13 +31,14 @@ if ret != False and found != None:
 
     luCommand('ce1', 'ping 99.0.0.4 -I 99.0.0.1 -c 1',
        ' 0. packet loss','wait','CE->CE (loopback) ping - l3vpn+zebra case')
-    luCommand('ce4', 'ping 99.0.0.1 -I 99.0.0.4 -c 1',
-       ' 0. packet loss','wait','CE->CE (loopback) ping - l3vpn+zebra case')
+    #skip due to VRF weirdness
+    #luCommand('ce4', 'ping 99.0.0.1 -I 99.0.0.4 -c 1',
+    #  ' 0. packet loss','wait','CE->CE (loopback) ping - l3vpn+zebra case')
 
     luCommand('ce1', 'ping 99.0.0.4 -I 99.0.0.1 -c 1',
        ' 0. packet loss','wait','CE->CE (loopback) ping')
-    luCommand('ce4', 'ping 99.0.0.1 -I 99.0.0.4 -c 1',
-       ' 0. packet loss','wait','CE->CE (loopback) ping')
+    #luCommand('ce4', 'ping 99.0.0.1 -I 99.0.0.4 -c 1',
+    #  ' 0. packet loss','wait','CE->CE (loopback) ping')
 
     luCommand('r3', 'ip -M route show', '103', 'pass', 'MPLS->VRF route installed')
     luCommand('ce2', 'ping 99.0.0.3 -I 99.0.0.2 -c 1',
index 6239f77a8224c0ff20596734b20d466273da9c32..778d504040faaa862e00aa29cf40a2338c6531ab 100644 (file)
@@ -1,4 +1,12 @@
 from lutil import luCommand
+
+rtrs = ['r1', 'r3', 'r4', 'ce1', 'ce2', 'ce3', 'ce4']
+for rtr in rtrs:
+    luCommand(rtr,'sysctl net.ipv4.tcp_l3mdev_accept',' = \d*','none','')
+    found = luLast()
+    luCommand(rtr,'ss -aep',':bgp','pass','IPv4:bgp, l3mdev%s' % found.group(0))
+    luCommand(rtr,'ss -aep',':.:bgp','pass','IPv6:bgp')
+
 rtrs = ['r1', 'r3', 'r4']
 for rtr in rtrs:
     luCommand(rtr, 'ip link show type vrf {}-cust1'.format(rtr),'cust1: .*UP,LOWER_UP','pass','VRF cust1 up')
@@ -11,4 +19,6 @@ rtrs = ['ce1', 'ce2', 'ce3']
 for rtr in rtrs:
     luCommand(rtr, 'ip route show','192.168...0/24 dev ce.-eth0','pass','CE interface route')
     luCommand(rtr,'ping 192.168.1.1 -c 1',' 0. packet loss','wait','CE->PE ping')
-luCommand('ce4','ping 192.168.2.1 -c 1',' 0. packet loss','wait','CE4->PE4 ping')
+luCommand('ce4', 'ip link show type vrf ce4-cust2','cust2: .*UP,LOWER_UP','pass','VRF cust2 up')
+luCommand('ce4', 'ip route show vrf ce4-cust2','192.168...0/24 dev ce.-eth0','pass','CE interface route')
+luCommand('ce4','ping 192.168.2.1 -c 1 -I ce4-cust2',' 0. packet loss','wait','CE4->PE4 ping')
index 7b2387bd0b61905cfa23b94bfa40e3ea5b3c9439..e47ea5f2cdda82f1d7287586835d97583d0d016d 100644 (file)
@@ -37,7 +37,7 @@ want = [
     {'p':'5.4.3.0/24', 'n':'99.0.0.4'},
     {'p':'99.0.0.4/32', 'n':'0.0.0.0'},
 ]
-bgpribRequireUnicastRoutes('ce4','ipv4','','Cust 4 routes in ce1',want)
+bgpribRequireUnicastRoutes('ce4','ipv4','ce4-cust2','Cust 4 routes in ce1',want)
 
 
 ########################################################################
@@ -307,12 +307,12 @@ want = [
 ]
 bgpribRequireUnicastRoutes('ce3','ipv4','','Cust 1 routes from remote',want)
 
-luCommand('ce4','vtysh -c "show bgp ipv4 uni"','10 routes and 10','wait','Local and remote routes', 10)
+luCommand('ce4','vtysh -c "show bgp vrf ce4-cust2 ipv4 uni"','10 routes and 10','wait','Local and remote routes', 10)
 want = [
     {'p':'5.1.0.0/24', 'n':'192.168.2.1'},
     {'p':'5.1.1.0/24', 'n':'192.168.2.1'},
     {'p':'5.1.2.0/24', 'n':'192.168.2.1'},
     {'p':'5.1.3.0/24', 'n':'192.168.2.1'},
 ]
-bgpribRequireUnicastRoutes('ce4','ipv4','','Cust 2 routes from remote',want)
+bgpribRequireUnicastRoutes('ce4','ipv4','ce4-cust2','Cust 2 routes from remote',want)
 
diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1-post6.1.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1-post6.1.ref
new file mode 100644 (file)
index 0000000..2cf8748
--- /dev/null
@@ -0,0 +1,42 @@
+BGP table version is XXX, local router ID is 172.30.1.1, vrf id -
+Default local pref 100, local AS 100
+Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+               i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+   Network          Next Hop            Metric LocPrf Weight Path
+*  10.0.1.0/24      172.16.1.5                             0 65005 i
+*                   172.16.1.2                             0 65002 i
+*>                  172.16.1.1                             0 65001 i
+*> 10.101.0.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.1.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.2.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.3.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.4.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.5.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.6.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.7.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.8.0/24    172.16.1.1             100              0 65001 i
+*> 10.101.9.0/24    172.16.1.1             100              0 65001 i
+*> 10.102.0.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.1.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.2.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.3.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.4.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.5.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.6.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.7.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.8.0/24    172.16.1.2             100              0 65002 i
+*> 10.102.9.0/24    172.16.1.2             100              0 65002 i
+*> 10.105.0.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.1.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.2.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.3.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.4.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.5.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.6.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.7.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.8.0/24    172.16.1.5             100              0 65005 i
+*> 10.105.9.0/24    172.16.1.5             100              0 65005 i
+*> 172.20.0.0/28    0.0.0.0                  0          32768 i
diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2-post6.1.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2-post6.1.ref
new file mode 100644 (file)
index 0000000..9d1b948
--- /dev/null
@@ -0,0 +1,31 @@
+BGP table version is XXX, local router ID is 172.30.1.1, vrf id -
+Default local pref 100, local AS 100
+Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+               i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+   Network          Next Hop            Metric LocPrf Weight Path
+*  10.0.1.0/24      172.16.1.4                             0 65004 i
+*>                  172.16.1.3                             0 65003 i
+*> 10.103.0.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.1.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.2.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.3.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.4.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.5.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.6.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.7.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.8.0/24    172.16.1.3             100              0 65003 i
+*> 10.103.9.0/24    172.16.1.3             100              0 65003 i
+*> 10.104.0.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.1.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.2.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.3.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.4.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.5.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.6.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.7.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.8.0/24    172.16.1.4             100              0 65004 i
+*> 10.104.9.0/24    172.16.1.4             100              0 65004 i
+*> 172.20.0.0/28    0.0.0.0               9999          32768 100 100 100 100 100 i
diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3-post6.1.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3-post6.1.ref
new file mode 100644 (file)
index 0000000..8b66fa6
--- /dev/null
@@ -0,0 +1,42 @@
+BGP table version is XXX, local router ID is 172.30.1.1, vrf id -
+Default local pref 100, local AS 100
+Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+               i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+   Network          Next Hop            Metric LocPrf Weight Path
+*  10.0.1.0/24      172.16.1.8                             0 65008 i
+*                   172.16.1.7                             0 65007 i
+*>                  172.16.1.6                             0 65006 i
+*> 10.106.0.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.1.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.2.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.3.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.4.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.5.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.6.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.7.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.8.0/24    172.16.1.6             100              0 65006 i
+*> 10.106.9.0/24    172.16.1.6             100              0 65006 i
+*> 10.107.0.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.1.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.2.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.3.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.4.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.5.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.6.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.7.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.8.0/24    172.16.1.7             100              0 65007 i
+*> 10.107.9.0/24    172.16.1.7             100              0 65007 i
+*> 10.108.0.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.1.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.2.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.3.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.4.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.5.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.6.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.7.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.8.0/24    172.16.1.8             100              0 65008 i
+*> 10.108.9.0/24    172.16.1.8             100              0 65008 i
+*> 172.20.0.0/28    0.0.0.0                  0          32768 i
index cdc41fad5250d0c5df929d162446b96717140ff3..2b40994cf61ff9e9a2f698baf32c45dd53cbcf46 100644 (file)
@@ -10,19 +10,15 @@ Your current user needs to have access to the Docker daemon. Alternatively
 you can run these commands as root.
 
 ```console
-make topotests-build
 make topotests
 ```
 
-The first command will build a docker image with all the dependencies needed
-to run the topotests.
-
-The second command will spawn an instance of this image, compile FRR inside
+This command will pull the most recent topotests image from dockerhub, compile FRR inside
 of it, and run the topotests.
 
 ## Advanced Usage
 
-Internally, the topotests make target uses a shell script to spawn the docker
+Internally, the topotests make target uses a shell script to pull the image and spawn the docker
 container.
 
 There are several environment variables which can be used to modify the behavior
@@ -55,3 +51,22 @@ And to compile FRR but drop into a shell instead of running pytest:
 ```console
 ./tests/topotests/docker/frr-topotests.sh /bin/bash
 ```
+
+## Development
+
+The docker image just includes all the components to run the topotests, but not the topotests
+themselves. So if you just want to write tests and don't want to make changes to the environment
+provided by the docker image. You don't need to build your own docker image if you do not want to.
+
+When developing new tests, there is one caveat though: The startup script of the container will
+run a `git-clean` on its copy of the FRR tree to avoid any pollution of the container with build
+artefacts from the host. This will also result in your newly written tests being unavailable in the
+container unless at least added to the index with `git-add`.
+
+If you do want to test changes to the docker image, you can locally build the image and run the tests
+without pulling from the registry using the following commands:
+
+```console
+make topotests-build
+TOPOTEST_PULL=0 make topotests
+```
index 8e93ed31ff57f04a677363bc33a8e6968d328848..6d8bea00022d93ad9b39083cdce5fa32368102be 100755 (executable)
@@ -61,6 +61,9 @@ if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then
        TOPOTEST_OPTIONS        These options are appended to the docker-run
                                command for starting the tests.
 
+       TOPOTEST_PULL           If set to 0, don't try to pull the most recent
+                               version of the docker image from dockerhub.
+
        TOPOTEST_SANITIZER      Controls whether to use the address sanitizer.
                                Enabled by default, set to 0 to disable.
 
@@ -132,6 +135,10 @@ if [ -z "$TOPOTEST_BUILDCACHE" ]; then
                || docker volume create "${TOPOTEST_BUILDCACHE}"
 fi
 
+if [ "${TOPOTEST_PULL:-1}" = "1" ]; then
+       docker pull frrouting/frr:topotests-latest
+fi
+
 set -- --rm -i \
        -v "$TOPOTEST_LOGS:/tmp" \
        -v "$TOPOTEST_FRR:/root/host-frr:ro" \
index 8ec1511e1031d43193f6aae456f4fa5847c14fbc..5a8103664392f2281a3f7cbcdf31732a013b28b0 100644 (file)
@@ -123,7 +123,16 @@ class BgpRib:
                 return
             luResult(target, True, title, logstr)
        rib = json.loads(ret)
-       table = rib['routes']
+        try:
+           table = rib['routes']
+        # KeyError: 'routes' probably means missing/bad VRF
+        except KeyError as err:
+           if vrf != '':
+                errstr = '-script ERROR: check if wrong vrf (%s)' % (vrf)
+            else:
+                errstr = '-script ERROR: check if vrf missing'
+           luResult(target, False, title + errstr, logstr)
+           return
        for want in wantroutes:
            if not self.routes_include_wanted(table,want,debug):
                luResult(target, False, title, logstr)
index 25edfe032455968a1011ebc4e7b0bd3bda29789c..8688a13aef16b8f0dfcd0508aa9b22f252a1f692 100644 (file)
@@ -908,7 +908,7 @@ class TopoExaBGP(TopoHost):
 
 # Disable linter branch warning. It is expected to have these here.
 # pylint: disable=R0912
-def diagnose_env():
+def diagnose_env_linux():
     """
     Run diagnostics in the running environment. Returns `True` when everything
     is ok, otherwise `False`.
@@ -1066,3 +1066,14 @@ def diagnose_env():
     logger.removeHandler(fhandler)
 
     return ret
+
+def diagnose_env_freebsd():
+    return True
+
+def diagnose_env():
+    if sys.platform.startswith("linux"):
+        return diagnose_env_linux()
+    elif sys.platform.startswith("freebsd"):
+        return diagnose_env_freebsd()
+
+    return False
index f25b066288710c3fc91d19aff05e54826797c2d2..c7f405fac22d960f9b5f5dddd0a89b1ea76b2e3f 100644 (file)
@@ -336,7 +336,7 @@ def normalize_text(text):
 
     return text
 
-def module_present(module, load=True):
+def module_present_linux(module, load):
     """
     Returns whether `module` is present.
 
@@ -352,6 +352,15 @@ def module_present(module, load=True):
     else:
         return True
 
+def module_present_freebsd(module, load):
+    return True
+
+def module_present(module, load=True):
+    if sys.platform.startswith("linux"):
+        return module_present_linux(module, load)
+    elif sys.platform.startswith("freebsd"):
+        return module_present_freebsd(module, load)
+
 def version_cmp(v1, v2):
     """
     Compare two version strings and returns:
@@ -622,7 +631,7 @@ class Router(Node):
         self.daemons = {'zebra': 0, 'ripd': 0, 'ripngd': 0, 'ospfd': 0,
                         'ospf6d': 0, 'isisd': 0, 'bgpd': 0, 'pimd': 0,
                         'ldpd': 0, 'eigrpd': 0, 'nhrpd': 0, 'staticd': 0,
-                        'bfdd': 0}
+                        'bfdd': 0, 'sharpd': 0}
         self.daemons_options = {'zebra': ''}
         self.reportCores = True
         self.version = None
@@ -863,7 +872,6 @@ class Router(Node):
             ))
             self.waitOutput()
             logger.debug('{}: {} staticd started'.format(self, self.routertype))
-            sleep(1, '{}: waiting for staticd to start'.format(self.name))
        # Fix Link-Local Addresses
         # Somehow (on Mininet only), Zebra removes the IPv6 Link-Local addresses on start. Fix this
         self.cmd('for i in `ls /sys/class/net/` ; do mac=`cat /sys/class/net/$i/address`; IFS=\':\'; set $mac; unset IFS; ip address add dev $i scope link fe80::$(printf %02x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6/64; done')
index c23322c4c67ab2ba314f650f5e4bfd0fa0d3b1d1..85dae7fd36f0fd42b68dfd71825b8d58d20f4055 100644 (file)
@@ -3,3 +3,6 @@
 /gen_yang_deviations
 /permutations
 /ssd
+/watchfrr.sh
+/frrinit.sh
+/frrcommon.sh
index 547a4b21370e4ca01157eb49855545b1045d5b4f..77e6e9a3301fc79e0d53d62f0b6862f100b94539 100755 (executable)
@@ -5886,27 +5886,6 @@ sub process {
                             "unchecked sscanf return value\n" . "$here\n$stat_real\n");
                }
 
-# check for simple sscanf that should be kstrto<foo>
-               if ($^V && $^V ge 5.10.0 &&
-                   defined $stat &&
-                   $line =~ /\bsscanf\b/) {
-                       my $lc = $stat =~ tr@\n@@;
-                       $lc = $lc + $linenr;
-                       my $stat_real = raw_line($linenr, 0);
-                       for (my $count = $linenr + 1; $count <= $lc; $count++) {
-                               $stat_real = $stat_real . "\n" . raw_line($count, 0);
-                       }
-                       if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
-                               my $format = $6;
-                               my $count = $format =~ tr@%@%@;
-                               if ($count == 1 &&
-                                   $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
-                                       WARN("SSCANF_TO_KSTRTO",
-                                            "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
-                               }
-                       }
-               }
-
 # check for new externs in .h files.
                if ($realfile =~ /\.h$/ &&
                    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
@@ -6177,12 +6156,6 @@ sub process {
                             "consider using a completion\n" . $herecurr);
                }
 
-# recommend kstrto* over simple_strto* and strict_strto*
-               if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
-                       WARN("CONSIDER_KSTRTO",
-                            "$1 is obsolete, use k$3 instead\n" . $herecurr);
-               }
-
 # check for __initcall(), use device_initcall() explicitly or more appropriate function please
                if ($line =~ /^.\s*__initcall\s*\(/) {
                        WARN("USE_DEVICE_INITCALL",
diff --git a/tools/etc/default/frr b/tools/etc/default/frr
deleted file mode 100644 (file)
index 693fa63..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-MAX_INSTANCES=5
-MAX_FDS=1024
-ZEBRA_OPTIONS="-s 16777216 -A 127.0.0.1"
-BGPD_OPTIONS="-A 127.0.0.1"
-OSPFD_OPTIONS="-A 127.0.0.1"
-OSPF6D_OPTIONS="-A ::1"
-RIPD_OPTIONS="-A 127.0.0.1"
-RIPNGD_OPTIONS="-A ::1"
-ISISD_OPTIONS="-A 127.0.0.1"
-EIGRP_OPTIONS="-A 127.0.0.1"
index 1514082e9033886915a44cb06b797d44b3ae329a..2d56fe1b988b272082c3c034d335296f2f6c30de 100644 (file)
@@ -1,11 +1,5 @@
 # This file tells the frr package which daemons to start.
 #
-# Entries are in the format: <daemon>=(yes|no|priority)
-#   0, "no"  = disabled
-#   1, "yes" = highest priority
-#   2 .. 10  = lower priorities
-# Read /usr/share/doc/frr/README.Debian for details.
-#
 # Sample configurations for these daemons can be found in
 # /usr/share/doc/frr/examples/.
 #
 # When using "vtysh" such a config file is also needed. It should be owned by
 # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
 #
-# The watchfrr daemon is always started. Per default in monitoring-only but
-# that can be changed via /etc/frr/daemons.conf.
+# The watchfrr and zebra daemons are always started.
 #
-zebra=no
 bgpd=no
 ospfd=no
 ospf6d=no
@@ -37,3 +29,37 @@ sharpd=no
 pbrd=no
 bfdd=no
 fabricd=no
+
+#
+# If this option is set the /etc/init.d/frr script automatically loads
+# the config via "vtysh -b" when the servers are started.
+# Check /etc/pam.d/frr if you intend to use "vtysh"!
+#
+vtysh_enable=yes
+zebra_options="  -A 127.0.0.1 -s 90000000"
+bgpd_options="   -A 127.0.0.1"
+ospfd_options="  -A 127.0.0.1"
+ospf6d_options=" -A ::1"
+ripd_options="   -A 127.0.0.1"
+ripngd_options=" -A ::1"
+isisd_options="  -A 127.0.0.1"
+pimd_options="   -A 127.0.0.1"
+ldpd_options="   -A 127.0.0.1"
+nhrpd_options="  -A 127.0.0.1"
+eigrpd_options=" -A 127.0.0.1"
+babeld_options=" -A 127.0.0.1"
+sharpd_options=" -A 127.0.0.1"
+pbrd_options="   -A 127.0.0.1"
+staticd_options="-A 127.0.0.1"
+bfdd_options="   -A 127.0.0.1"
+fabricd_options="-A 127.0.0.1"
+
+# The list of daemons to watch is automatically generated by the init script.
+watchfrr_options="-r '/usr/lib/frr/watchfrr.sh restart %s' -s '/usr/lib/frr/watchfrr.sh start %s' -k '/usr/lib/frr/watchfrr.sh stop %s'"
+
+# for debugging purposes, you can specify a "wrap" command to start instead
+# of starting the daemon directly, e.g. to use valgrind on ospfd:
+#   ospfd_wrap="/usr/bin/valgrind"
+# or you can use "all_wrap" for all daemons, e.g. to use perf record:
+#   all_wrap="/usr/bin/perf record --call-graph -"
+# the normal daemon command is added to this at the end.
index 94221301eb92226097edcfea4a8cd5697fe855d3..70b96a98007e37498b5daf1a1822067f3bd36ccd 100644 (file)
@@ -1,33 +1 @@
-#
-# If this option is set the /etc/init.d/frr script automatically loads
-# the config via "vtysh -b" when the servers are started.
-# Check /etc/pam.d/frr if you intend to use "vtysh"!
-#
-vtysh_enable=yes
-zebra_options="  -s 90000000 --daemon -A 127.0.0.1"
-bgpd_options="   --daemon -A 127.0.0.1"
-ospfd_options="  --daemon -A 127.0.0.1"
-ospf6d_options=" --daemon -A ::1"
-ripd_options="   --daemon -A 127.0.0.1"
-ripngd_options=" --daemon -A ::1"
-isisd_options="  --daemon -A 127.0.0.1"
-pimd_options="  --daemon -A 127.0.0.1"
-ldpd_options="  --daemon -A 127.0.0.1"
-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"
-staticd_options="  --daemon -A 127.0.0.1"
-bfdd_options="  --daemon -A 127.0.0.1"
-fabricd_options="  --daemon -A 127.0.0.1"
-
-# The list of daemons to watch is automatically generated by the init script.
-watchfrr_enable=yes
-
-watchfrr_options=(-d -r /usr/lib/frr/frrbBrestartbB%s -s /usr/lib/frr/frrbBstartbB%s -k /usr/lib/frr/frrbBstopbB%s -b bB)
-
-# If valgrind_enable is 'yes' the frr daemons will be started via valgrind.
-# The use case for doing so is tracking down memory leaks, etc in frr.
-valgrind_enable=no
-valgrind=/usr/bin/valgrind
+# this file is deprecated, please use "daemons" instead.
index 80ceb00891f14e0a82a9b654418a06776a066bd9..e0ab9cb6f3145aa4098ca352b6ed36c08dcddc31 100644 (file)
@@ -1,2 +1 @@
 service integrated-vtysh-config
-username cumulus nopassword
index 3b41b57d682e4d2f218e1c6ac32fdca2a068ad9c..c48c8b97ad07b46e19ba12d405a04efe87b49038 100755 (executable)
@@ -974,8 +974,8 @@ def compare_context_objects(newconf, running):
                 delete_bgpd = True
                 lines_to_del.append((running_ctx_keys, None))
 
-            # We cannot do 'no interface' in FRR, and so deal with it
-            elif running_ctx_keys[0].startswith('interface'):
+            # We cannot do 'no interface' or 'no vrf' in FRR, and so deal with it
+            elif running_ctx_keys[0].startswith('interface') or running_ctx_keys[0].startswith('vrf'):
                 for line in running_ctx.lines:
                     lines_to_del.append((running_ctx_keys, line))
 
index ec383bc5a0d6d72728b5f0edafffaf8c746cd672..a443191fd04122893ee200870f22b4f16440220b 100755 (executable)
@@ -115,41 +115,45 @@ check_daemon()
 # The Frr daemons creates the pidfile when starting.
 start()
 {
-       ulimit -n $MAX_FDS
-       if [ "$1" = "watchfrr" ]; then
+       local dmn inst
+       dmn="$1"
+       inst="$2"
+
+       ulimit -n $MAX_FDS > /dev/null 2> /dev/null
+       if [ "$dmn" = "watchfrr" ]; then
 
                # We may need to restart watchfrr if new daemons are added and/or
                # removed
-               if started "$1" ; then
+               if started "$dmn" ; then
                        stop watchfrr
                else
                        # Echo only once. watchfrr is printed in the stop above
-                       echo -n " $1"
+                       echo -n " $dmn"
                fi
 
-
+               eval "set - $watchfrr_options"
                ${SSD} \
                        --start \
-                       --pidfile=`pidfile $1` \
-                       --exec "$D_PATH/$1" \
+                       --pidfile=`pidfile $dmn` \
+                       --exec "$D_PATH/$dmn" \
                        -- \
-                       "${watchfrr_options[@]}"
+                       "$@"
 
-       elif [ -n "$2" ]; then
-               echo -n " $1-$2"
-               if ! check_daemon $1 $2 ; then
+       elif [ -n "$inst" ]; then
+               echo -n " $dmn-$inst"
+               if ! check_daemon $dmn $inst ; then
                        echo -n " (binary does not exist)"
                        return;
                fi
 
                ${SSD} \
                        --start \
-                       --pidfile=`pidfile $1-$2` \
-                       --exec "$D_PATH/$1" \
+                       --pidfile=`pidfile $dmn-$inst` \
+                       --exec "$D_PATH/$dmn" \
                        -- \
-                       `eval echo "$""$1""_options"` -n "$2"
+                       `eval echo "$""$dmn""_options"` -n "$inst"
        else
-               if ! check_daemon $1; then
+               if ! check_daemon $dmn; then
                        echo -n " (binary does not exist)"
                        return;
                fi
@@ -157,22 +161,22 @@ start()
                if [ "$valgrind_enable" = "yes" ]; then
                        ${SSD} \
                                --start \
-                               --pidfile=`pidfile $1` \
+                               --pidfile=`pidfile $dmn` \
                                --exec "$valgrind" \
-                               -- --trace-children=no --leak-check=full --log-file=/var/log/frr/$1-valgrind.log $D_PATH/$1 \
-                               `eval echo "$""$1""_options"`
+                               -- --trace-children=no --leak-check=full --log-file=/var/log/frr/$dmn-valgrind.log $D_PATH/$dmn \
+                               `eval echo "$""$dmn""_options"`
                else
                        ${SSD} \
                                --start \
-                               --pidfile=`pidfile $1` \
-                               --exec "$D_PATH/$1" \
+                               --pidfile=`pidfile $dmn` \
+                               --exec "$D_PATH/$dmn" \
                                -- \
-                               `eval echo "$""$1""_options"`
+                               `eval echo "$""$dmn""_options"`
                fi
        fi
 
        # Start the staticd automatically
-       if [ "$1" = "zebra" ]; then
+       if [ "$dmn" = "zebra" ]; then
                echo -n "starting staticd since zebra is running"
                if ! check_daemon staticd ; then
                        echo -n " (binary does not exist)"
@@ -269,11 +273,9 @@ start_watchfrr()
        fi
 
        # Check variable type
-       if ! declare -p watchfrr_options | grep -q '^declare \-a'; then
-               echo
-               echo "ERROR: The variable watchfrr_options from /etc/frr/debian.cnf must be a BASH array!"
-               echo "ERROR: Please convert config file and restart!"
-               exit 1
+       if declare -p watchfrr_options | grep -q '^declare \-a'; then
+               # old array support
+               watchfrr_options="${watchfrr_options[@]}"
        fi
 
        # Which daemons have been started?
@@ -287,13 +289,13 @@ start_watchfrr()
                                        eval "inst_disable=\${${daemon_name}_${inst}}"
                                        if [ -z ${inst_disable} ] || [ ${inst_disable} != 0 ]; then
                                                if check_daemon $daemon_name $inst; then
-                                                       watchfrr_options+=("${daemon_name}-${inst}")
+                                                       watchfrr_options="$watchfrr_options ${daemon_name}-${inst}"
                                                fi
                                        fi
                                done
                        else
                                if check_daemon $daemon_name; then
-                                       watchfrr_options+=($daemon_name)
+                                       watchfrr_options="$watchfrr_options $daemon_name"
                                fi
                        fi
                        found_one=1
index 5f44274ec313f032c62e0d62edfee1e508ae23c8..c7568593b36d22c6dbcddc07ca8e2f9c644de47a 100644 (file)
@@ -1,11 +1,11 @@
 [Unit]
 Description=FRRouting
+Documentation=https://frrouting.readthedocs.io/en/latest/setup.html
 After=networking.service
 OnFailure=heartbeat-failed@%n.service
 
 [Service]
 Nice=-5
-EnvironmentFile=/etc/default/frr
 Type=forking
 NotifyAccess=all
 StartLimitInterval=3m
@@ -15,8 +15,9 @@ WatchdogSec=60s
 RestartSec=5
 Restart=on-abnormal
 LimitNOFILE=1024
-ExecStart=/usr/lib/frr/frr start
-ExecStop=/usr/lib/frr/frr stop
-ExecReload=/usr/lib/frr/frr-reload
+ExecStart=/usr/lib/frr/frrinit.sh start
+ExecStop=/usr/lib/frr/frrinit.sh stop
+ExecReload=/usr/lib/frr/frrinit.sh reload
+
 [Install]
 WantedBy=network-online.target
diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in
new file mode 100644 (file)
index 0000000..fa2fdc9
--- /dev/null
@@ -0,0 +1,321 @@
+#!/bin/sh
+#
+# This is a "library" of sorts for use by the other FRR shell scripts.  It
+# has most of the daemon start/stop logic, but expects the following shell
+# functions/commands to be provided by the "calling" script:
+#
+#   log_success_msg
+#   log_warning_msg
+#   log_failure_msg
+#
+# (coincidentally, these are LSB standard functions.)
+#
+# Sourcing this file in a shell script will load FRR config variables but
+# not perform any action.  Note there is an "exit 1" if the main config
+# file does not exist.
+#
+# This script should be installed in  @CFG_SBIN@/frrcommon.sh
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+D_PATH="@CFG_SBIN@" # /usr/lib/frr
+C_PATH="@CFG_SYSCONF@" # /etc/frr
+V_PATH="@CFG_STATE@" # /var/run/frr
+VTYSH="@vtysh_bin@" # /usr/bin/vtysh
+FRR_USER="@enable_user@" # frr
+FRR_GROUP="@enable_group@" # frr
+FRR_VTY_GROUP="@enable_vty_group@" # frrvty
+
+# ORDER MATTERS FOR $DAEMONS!
+# - keep zebra first
+# - watchfrr does NOT belong in this list
+
+DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd"
+RELOAD_SCRIPT="$D_PATH/frr-reload.py"
+
+#
+# general helpers
+#
+
+debug() {
+       [ -n "$watchfrr_debug" ] || return 0
+
+       printf '%s %s(%s):' "`date +%Y-%m-%dT%H:%M:%S.%N`" "$0" $$ >&2
+       # this is to show how arguments are split regarding whitespace & co.
+       # (e.g. for use with `debug "message" "$@"`)
+       while [ $# -gt 0 ]; do
+               printf ' "%s"' "$1" >&2
+               shift
+       done
+       printf '\n' >&2
+}
+
+chownfrr() {
+       [ -n "$FRR_USER" ] && chown "$FRR_USER" "$1"
+       [ -n "$FRR_GROUP" ] && chgrp "$FRR_GROUP" "$1"
+}
+
+vtysh_b () {
+       [ "$1" = "watchfrr" ] && return 0
+       [ -r "$C_PATH/frr.conf" ] || return 0
+       if [ -n "$1" ]; then
+               "$VTYSH" -b -n -d "$1"
+       else
+               "$VTYSH" -b -n
+       fi
+}
+
+daemon_inst() {
+       # note this sets global variables ($dmninst, $daemon, $inst)
+       dmninst="$1"
+       daemon="${dmninst%:*}"
+       inst=""
+       [ "$daemon" != "$dmninst" ] && inst="${dmninst#*:}"
+}
+
+daemon_list() {
+       # note $1 and $2 specify names for global variables to be set
+       local enabled disabled evar dvar
+       enabled=""
+       disabled=""
+       evar="$1"
+       dvar="$2"
+
+       for daemon in $DAEMONS; do
+               eval cfg=\$$daemon
+               eval inst=\$${daemon}_instances
+               [ "$daemon" = zebra -o "$daemon" = staticd ] && cfg=yes
+               if [ -n "$cfg" -a "$cfg" != "no" -a "$cfg" != "0" ]; then
+                       debug "$daemon enabled"
+                       enabled="$enabled $daemon"
+                       if [ -n "$inst" ]; then
+                               debug "$daemon multi-instance $inst"
+                               for i in $inst; do
+                                       enabled="$enabled $daemon:$inst"
+                               done
+                       fi
+               else
+                       debug "$daemon disabled"
+                       disabled="$disabled $daemon"
+               fi
+       done
+
+       enabled="${enabled# }"
+       disabled="${disabled# }"
+       [ -z "$evar" ] && echo "$enabled"
+       [ -n "$evar" ] && eval $evar="\"$enabled\""
+       [ -n "$dvar" ] && eval $dvar="\"$disabled\""
+}
+
+#
+# individual daemon management
+#
+
+daemon_prep() {
+       local daemon inst cfg
+       daemon="$1"
+       inst="$2"
+       [ "$daemon" = "watchfrr" ] && return 0
+       [ -x "$D_PATH/$daemon" ] || {
+               log_failure_msg "cannot start $daemon${inst:+ (instance $inst)}: daemon binary not installed\n"
+               return 1
+       }
+       [ -r "$C_PATH/frr.conf" ] && return 0
+
+       cfg="$C_PATH/$daemon${inst:+-$inst}.conf"
+       if [ ! -r "$cfg" ]; then
+               touch "$cfg"
+               chownfrr "$cfg"
+       fi
+       return 0
+}
+
+daemon_start() {
+       local dmninst daemon inst args instopt wrap bin
+       daemon_inst "$1"
+
+       ulimit -n $MAX_FDS > /dev/null 2> /dev/null
+       daemon_prep "$daemon" "$inst" || return 1
+       if test ! -d "$V_PATH"; then
+               mkdir -p "$V_PATH"
+               chown frr "$V_PATH"
+       fi
+
+       eval wrap="\$${daemon}_wrap"
+       bin="$D_PATH/$daemon"
+       instopt="${inst:+-n $inst}"
+       eval args="\$${daemon}_options"
+
+       if eval "$all_wrap $wrap $bin -d $instopt $args"; then
+               log_success_msg "Started $dmninst"
+               vtysh_b "$daemon"
+       else
+               log_failure_msg "Failed to start $dmninst!"
+       fi
+}
+
+daemon_stop() {
+       local dmninst daemon inst pidfile vtyfile pid cnt fail
+       daemon_inst "$1"
+
+       pidfile="$V_PATH/$daemon${inst:+-$inst}.pid"
+       vtyfile="$V_PATH/$daemon${inst:+-$inst}.vty"
+
+       [ -r "$pidfile" ] || fail="pid file not found"
+       [ -z "$fail" ] && pid="`cat \"$pidfile\"`"
+       [ -z "$fail" -a -z "$pid" ] && fail="pid file is empty"
+       [ -n "$fail" ] || kill -0 "$pid" 2>/dev/null || fail="pid $pid not running"
+
+       if [ -n "$fail" ]; then
+               log_failure_msg "Cannot stop $dmninst: $fail"
+               return 1
+       fi
+
+       debug "kill -2 $pid"
+       kill -2 "$pid"
+       cnt=1200
+       while kill -0 "$pid" 2>/dev/null; do
+               sleep .1
+               [ $(( cnt -= 1 )) -gt 0 ] || break
+       done
+       if kill -0 "$pid" 2>/dev/null; then
+               log_failure_msg "Failed to stop $dmninst, pid $pid still running"
+               still_running=1
+               return 1
+       else
+               log_success_msg "Stopped $dmninst"
+               rm -f "$pidfile"
+               return 0
+       fi
+}
+
+daemon_status() {
+       local dmninst daemon inst pidfile pid fail
+       daemon_inst "$1"
+
+       pidfile="$V_PATH/$daemon${inst:+-$inst}.pid"
+
+       [ -r "$pidfile" ] || return 3
+       pid="`cat \"$pidfile\"`"
+       [ -z "$pid" ] && return 1
+       kill -0 "$pid" 2>/dev/null || return 1
+       return 0
+}
+
+print_status() {
+       daemon_status "$1"
+       rv=$?
+       if [ "$rv" -eq 0 ]; then
+               log_success_msg "Status of $1: running"
+       else
+               log_failure_msg "Status of $1: FAILED"
+       fi
+       return $rv
+}
+
+#
+# all-daemon commands
+#
+
+all_start() {
+       daemon_list daemons
+       for dmninst in $daemons; do
+               daemon_start "$dmninst"
+       done
+}
+
+all_stop() {
+       local pids reversed
+
+       daemon_list daemons disabled
+       [ "$1" = "--reallyall" ] && daemons="$daemons $disabled"
+
+       reversed=""
+       for dmninst in $daemons; do
+               reversed="$dmninst $reversed"
+       done
+
+       for dmninst in $reversed; do
+               daemon_stop "$dmninst" &
+               pids="$pids $!"
+       done
+       for pid in $pids; do
+               wait $pid
+       done
+}
+
+all_status() {
+       local fail
+
+       daemon_list daemons
+       fail=0
+       for dmninst in $daemons; do
+               print_status "$dmninst" || fail=1
+       done
+       return $fail
+}
+
+#
+# config sourcing
+#
+
+load_old_config() {
+       oldcfg="$1"
+       [ -r "$oldcfg" ] || return 0
+       [ -s "$oldcfg" ] || return 0
+       grep -v '^[[:blank:]]*\(#\|$\)' "$oldcfg" > /dev/null || return 0
+
+       log_warning_msg "Reading deprecated $oldcfg.  Please move its settings to $C_PATH/daemons and remove it."
+
+       # save off settings from daemons for the OR below
+       for dmn in $DAEMONS; do eval "_new_$dmn=\${$dmn:-no}"; done
+
+       . "$oldcfg"
+
+       # OR together the daemon enabling options between config files
+       for dmn in $DAEMONS; do eval "test \$_new_$dmn != no && $dmn=\$_new_$dmn; unset _new_$dmn"; done
+}
+
+[ -r "$C_PATH/daemons" ] || {
+       log_failure_msg "cannot run $@: $C_PATH/daemons does not exist\n"
+       exit 1
+}
+. "$C_PATH/daemons"
+
+load_old_config "$C_PATH/daemons.conf"
+load_old_config "/etc/default/frr"
+load_old_config "/etc/sysconfig/frr"
+
+#
+# other defaults and dispatch
+#
+
+frrcommon_main() {
+       local cmd
+
+       debug "frrcommon_main" "$@"
+
+       cmd="$1"
+       shift
+
+       if [ "$1" = "all" -o -z "$1" ]; then
+               case "$cmd" in
+               start)  all_start;;
+               stop)   all_stop;;
+               restart)
+                       all_stop
+                       all_start
+                       ;;
+               *)      $cmd "$@";;
+               esac
+       else
+               case "$cmd" in
+               start)  daemon_start "$@";;
+               stop)   daemon_stop "$@";;
+               restart)
+                       daemon_stop "$@"
+                       daemon_start "$@"
+                       ;;
+               *)      $cmd "$@";;
+               esac
+       fi
+}
diff --git a/tools/frrinit.sh.in b/tools/frrinit.sh.in
new file mode 100644 (file)
index 0000000..3dddf5b
--- /dev/null
@@ -0,0 +1,90 @@
+#!/bin/sh
+#
+### BEGIN INIT INFO
+# Provides: frr
+# Required-Start: $local_fs $network $remote_fs $syslog
+# Required-Stop: $local_fs $network $remote_fs $syslog
+# Default-Start:  2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: start and stop the FRR routing suite
+# Description: FRR is a routing suite for IP routing protocols like
+#              BGP, OSPF, RIP and others. This script contols the main
+#              "watchfrr" daemon.
+### END INIT INFO
+#
+# This is the main init script for FRR.  It mostly wraps frrcommon.sh which
+# provides the actual functions to start/stop/restart things.
+#
+
+if [ -r "/lib/lsb/init-functions" ]; then
+       . /lib/lsb/init-functions
+else
+       log_success_msg() {
+               echo "$@"
+       }
+       log_warning_msg() {
+               echo "$@" >&2
+       }
+       log_failure_msg() {
+               echo "$@" >&2
+       }
+fi
+
+self="`dirname $0`"
+if [ -r "$self/frrcommon.sh" ]; then
+       . "$self/frrcommon.sh"
+else
+       . "@CFG_SBIN@/frrcommon.sh"
+fi
+
+case "$1" in
+start)
+       daemon_list daemons
+       watchfrr_options="$watchfrr_options $daemons"
+       daemon_start watchfrr
+       ;;
+stop)
+       daemon_stop watchfrr
+       all_stop --reallyall
+       exit ${still_running:-0}
+       ;;
+
+restart|force-reload)
+       daemon_stop watchfrr
+       all_stop --reallyall
+
+       daemon_list daemons
+       watchfrr_options="$watchfrr_options $daemons"
+       daemon_start watchfrr
+       ;;
+
+status)
+       fail=0
+       print_status watchfrr || fail=1
+       all_status || fail=1
+       exit $fail
+       ;;
+
+reload)
+       if [ ! -x "$RELOAD_SCRIPT" ]; then
+               log_failure_msg "The frr-pythontools package is required for reload functionality."
+               exit 1
+       fi
+
+       # restart watchfrr to pick up added daemons.
+       # NB: This will NOT cause the other daemons to be restarted.
+       daemon_list daemons
+       watchfrr_options="$watchfrr_options $daemons"
+       daemon_stop watchfrr && \
+               daemon_start watchfrr
+
+       NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}"
+       [ ! -r $NEW_CONFIG_FILE ] && log_failure_msg "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1
+       "$RELOAD_SCRIPT" --reload "$NEW_CONFIG_FILE"
+       exit $?
+       ;;
+
+*)
+       log_failure_msg "Unknown command: $1" >&2
+       exit 1
+esac
index 2e68dfee09506f160d5fc988f72972b14e7020fd..ff41fe2c63ce684deb5c68df47d467e2fbce2ab3 100644 (file)
@@ -13,6 +13,10 @@ sbin_SCRIPTS += \
        tools/frr-reload \
        tools/frr-reload.py \
        tools/frr \
+       \
+       tools/frrcommon.sh \
+       tools/frrinit.sh \
+       tools/watchfrr.sh \
        # end
 
 tools_permutations_SOURCES = tools/permutations.c
diff --git a/tools/watchfrr.sh.in b/tools/watchfrr.sh.in
new file mode 100644 (file)
index 0000000..3051d91
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# This is NOT the init script!  This is the watchfrr start/stop/restart
+# command handler, passed to watchfrr with the -s/-r/-k commands.  It is used
+# internally by watchfrr to start the protocol daemons with the appropriate
+# options.
+#
+# This script should be installed in  @CFG_SBIN@/watchfrr.sh
+
+log_success_msg() {
+       :
+}
+
+log_warning_msg() {
+       echo "$@" >&2
+       [ -x /usr/bin/logger ] && echo "$@" \
+               | /usr/bin/logger -t watchfrr.sh -p daemon.warn
+}
+
+log_failure_msg() {
+       echo "$@" >&2
+       [ -x /usr/bin/logger ] && echo "$@" \
+               | /usr/bin/logger -t watchfrr.sh -p daemon.err
+}
+
+self="`dirname $0`"
+if [ -r "$self/frrcommon.sh" ]; then
+       . "$self/frrcommon.sh"
+else
+       . "@CFG_SBIN@/frrcommon.sh"
+fi
+
+frrcommon_main "$@"
index f57a4d9ddf0aee1e36b3ae5b2d6c7e49b835f0a7..2327f2b46d7e04219518ab89d5d7fe849d307db9 100644 (file)
@@ -104,7 +104,7 @@ static int vty_close_pager(struct vty *vty)
        return 0;
 }
 
-void vtysh_pager_init(void)
+static void vtysh_pager_envdef(void)
 {
        char *pager_defined;
 
@@ -2881,52 +2881,58 @@ DEFUN (vtysh_copy_running_config,
        return vtysh_write_memory(self, vty, argc, argv);
 }
 
+DEFUN (vtysh_terminal_paginate,
+       vtysh_terminal_paginate_cmd,
+       "[no] terminal paginate",
+       NO_STR
+       "Set terminal line parameters\n"
+       "Use pager for output scrolling\n")
+{
+       free(vtysh_pager_name);
+       vtysh_pager_name = NULL;
+
+       if (strcmp(argv[0]->text, "no"))
+               vtysh_pager_envdef();
+       return CMD_SUCCESS;
+}
+
 DEFUN (vtysh_terminal_length,
        vtysh_terminal_length_cmd,
-       "terminal length (0-512)",
+       "[no] terminal length (0-4294967295)",
+       NO_STR
        "Set terminal line parameters\n"
        "Set number of lines on a screen\n"
-       "Number of lines on screen (0 for no pausing)\n")
+       "Number of lines on screen (0 for no pausing, nonzero to use pager)\n")
 {
        int idx_number = 2;
-       int lines;
-       char *endptr = NULL;
-       char default_pager[10];
+       unsigned long lines;
 
-       lines = strtol(argv[idx_number]->arg, &endptr, 10);
-       if (lines < 0 || lines > 512 || *endptr != '\0') {
-               vty_out(vty, "length is malformed\n");
-               return CMD_WARNING;
-       }
+       free(vtysh_pager_name);
+       vtysh_pager_name = NULL;
 
-       if (vtysh_pager_name) {
-               free(vtysh_pager_name);
-               vtysh_pager_name = NULL;
+       if (!strcmp(argv[0]->text, "no") || !strcmp(argv[1]->text, "no")) {
+               /* "terminal no length" = use VTYSH_PAGER */
+               vtysh_pager_envdef();
+               return CMD_SUCCESS;
        }
 
+       lines = strtoul(argv[idx_number]->arg, NULL, 10);
        if (lines != 0) {
-               snprintf(default_pager, 10, "more -%i", lines);
-               vtysh_pager_name = strdup(default_pager);
+               vty_out(vty,
+                       "%% The \"terminal length\" command is deprecated and its value is ignored.\n"
+                       "%% Please use \"terminal paginate\" instead with OS TTY length handling.\n");
+               vtysh_pager_envdef();
        }
 
        return CMD_SUCCESS;
 }
 
-DEFUN (vtysh_terminal_no_length,
+ALIAS_DEPRECATED(vtysh_terminal_length,
        vtysh_terminal_no_length_cmd,
        "terminal no length",
        "Set terminal line parameters\n"
        NO_STR
        "Set number of lines on a screen\n")
-{
-       if (vtysh_pager_name) {
-               free(vtysh_pager_name);
-               vtysh_pager_name = NULL;
-       }
-
-       vtysh_pager_init();
-       return CMD_SUCCESS;
-}
 
 DEFUN (vtysh_show_daemons,
        vtysh_show_daemons_cmd,
@@ -3805,6 +3811,7 @@ void vtysh_init_vty(void)
        /* "write memory" command. */
        install_element(ENABLE_NODE, &vtysh_write_memory_cmd);
 
+       install_element(VIEW_NODE, &vtysh_terminal_paginate_cmd);
        install_element(VIEW_NODE, &vtysh_terminal_length_cmd);
        install_element(VIEW_NODE, &vtysh_terminal_no_length_cmd);
        install_element(VIEW_NODE, &vtysh_show_daemons_cmd);
index 430b117c50a68b45c64ce54135873dd057b4e801..eb69a20b839615837e247f13f2565674533a05a1 100644 (file)
@@ -98,8 +98,6 @@ void vtysh_config_dump(void);
 
 void vtysh_config_init(void);
 
-void vtysh_pager_init(void);
-
 void suid_on(void);
 void suid_off(void);
 
index 777eed7b5d136495b78f6668ac13dc3705549923..2e4510a45a876be3442567017e82e3e6bf356ad9 100644 (file)
@@ -675,8 +675,6 @@ int main(int argc, char **argv, char **env)
                        exit(0);
        }
 
-       vtysh_pager_init();
-
        vtysh_readline_init();
 
        vty_hello(vty);
index e32bf3359bb580e454163c38fe7f7d87912d7ce9..e28da6db8c2deb31cddb0b98c57cb007a6cca1ff 100644 (file)
@@ -65,6 +65,7 @@ static bool watch_only = false;
 
 typedef enum {
        PHASE_NONE = 0,
+       PHASE_INIT,
        PHASE_STOPS_PENDING,
        PHASE_WAITING_DOWN,
        PHASE_ZEBRA_RESTART_PENDING,
@@ -72,7 +73,8 @@ typedef enum {
 } restart_phase_t;
 
 static const char *phase_str[] = {
-       "None",
+       "Idle",
+       "Startup",
        "Stop jobs running",
        "Waiting for other daemons to come down",
        "Zebra restart job running",
@@ -112,7 +114,7 @@ static struct global_state {
        int numpids;
        int numdown; /* # of daemons that are not UP or UNRESPONSIVE */
 } gs = {
-       .phase = PHASE_NONE,
+       .phase = PHASE_INIT,
        .vtydir = frr_vtydir,
        .period = 1000 * DEFAULT_PERIOD,
        .timeout = DEFAULT_TIMEOUT,
@@ -177,6 +179,7 @@ static int try_connect(struct daemon *dmn);
 static int wakeup_send_echo(struct thread *t_wakeup);
 static void try_restart(struct daemon *dmn);
 static void phase_check(void);
+static void restart_done(struct daemon *dmn);
 
 static const char *progname;
 static void printhelp(FILE *target)
@@ -333,6 +336,7 @@ static void sigchild(void)
        const char *name;
        const char *what;
        struct restart_info *restart;
+       struct daemon *dmn;
 
        switch (child = waitpid(-1, &status, WNOHANG)) {
        case -1:
@@ -378,9 +382,18 @@ static void sigchild(void)
                        zlog_warn(
                                "%s %s process %d exited with non-zero status %d",
                                what, name, (int)child, WEXITSTATUS(status));
-               else
+               else {
                        zlog_debug("%s %s process %d exited normally", what,
                                   name, (int)child);
+
+                       if (restart && restart != &gs.restart) {
+                               dmn = container_of(restart, struct daemon,
+                                                  restart);
+                               restart_done(dmn);
+                       } else if (restart)
+                               for (dmn = gs.daemons; dmn; dmn = dmn->next)
+                                       restart_done(dmn);
+               }
        } else
                flog_err_sys(
                        EC_LIB_SYSTEM_CALL,
@@ -494,15 +507,27 @@ static int wakeup_init(struct thread *t_wakeup)
 
        dmn->t_wakeup = NULL;
        if (try_connect(dmn) < 0) {
-               SET_WAKEUP_DOWN(dmn);
                flog_err(EC_WATCHFRR_CONNECTION,
                         "%s state -> down : initial connection attempt failed",
                         dmn->name);
                dmn->state = DAEMON_DOWN;
        }
+       phase_check();
        return 0;
 }
 
+static void restart_done(struct daemon *dmn)
+{
+       if (dmn->state != DAEMON_DOWN) {
+               zlog_warn("wtf?");
+               return;
+       }
+       if (dmn->t_wakeup)
+               THREAD_OFF(dmn->t_wakeup);
+       if (try_connect(dmn) < 0)
+               SET_WAKEUP_DOWN(dmn);
+}
+
 static void daemon_down(struct daemon *dmn, const char *why)
 {
        if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
@@ -773,9 +798,25 @@ static void set_phase(restart_phase_t new_phase)
 
 static void phase_check(void)
 {
+       struct daemon *dmn;
+
        switch (gs.phase) {
        case PHASE_NONE:
                break;
+
+       case PHASE_INIT:
+               for (dmn = gs.daemons; dmn; dmn = dmn->next)
+                       if (dmn->state == DAEMON_INIT)
+                               return;
+
+               /* startup complete, everything out of INIT */
+               gs.phase = PHASE_NONE;
+               for (dmn = gs.daemons; dmn; dmn = dmn->next)
+                       if (dmn->state == DAEMON_DOWN) {
+                               SET_WAKEUP_DOWN(dmn);
+                               try_restart(dmn);
+                       }
+               break;
        case PHASE_STOPS_PENDING:
                if (gs.numpids)
                        break;
@@ -929,6 +970,31 @@ bool check_all_up(void)
        return true;
 }
 
+void watchfrr_status(struct vty *vty)
+{
+       struct daemon *dmn;
+       struct timeval delay;
+
+       vty_out(vty, "watchfrr global phase: %s\n", phase_str[gs.phase]);
+       if (gs.restart.pid)
+               vty_out(vty, "    global restart running, pid %ld\n",
+                       (long)gs.restart.pid);
+
+       for (dmn = gs.daemons; dmn; dmn = dmn->next) {
+               vty_out(vty, "  %-20s %s\n", dmn->name, state_str[dmn->state]);
+               if (dmn->restart.pid)
+                       vty_out(vty, "      restart running, pid %ld\n",
+                               (long)dmn->restart.pid);
+               else if (dmn->state == DAEMON_DOWN &&
+                       time_elapsed(&delay, &dmn->restart.time)->tv_sec
+                               < dmn->restart.interval)
+                       vty_out(vty, "      restarting in %ld seconds"
+                               " (%lds backoff interval)\n",
+                               dmn->restart.interval - delay.tv_sec,
+                               dmn->restart.interval);
+       }
+}
+
 static void sigint(void)
 {
        zlog_notice("Terminating on signal");
@@ -980,8 +1046,7 @@ static void watchfrr_init(int argc, char **argv)
                gs.numdown++;
                dmn->fd = -1;
                dmn->t_wakeup = NULL;
-               thread_add_timer_msec(master, wakeup_init, dmn,
-                                     100 + (random() % 900),
+               thread_add_timer_msec(master, wakeup_init, dmn, 0,
                                      &dmn->t_wakeup);
                dmn->restart.interval = gs.min_restart_interval;
                *add = dmn;
index ee16846a1dc9029244e44b85a5d3bb6d3fce43c7..c5f54769bd3083087f809b3a9868b911b5c55e75 100644 (file)
@@ -29,6 +29,10 @@ extern void watchfrr_vty_init(void);
 
 extern pid_t integrated_write_pid;
 extern void integrated_write_sigchld(int status);
+
+struct vty;
+extern void watchfrr_status(struct vty *vty);
+
 /*
  * Check if all daemons we are monitoring are in the DAEMON_UP state.
  *
index 1bfc41f255b90f08f73241e280d2ce3b70a72ddf..9b844d67f25d0aa427d945c51d4d7a75d52710fb 100644 (file)
@@ -124,6 +124,16 @@ DEFUN_NOSH (show_debugging_watchfrr,
        return CMD_SUCCESS;
 }
 
+DEFUN (show_watchfrr,
+       show_watchfrr_cmd,
+       "show watchfrr",
+       SHOW_STR
+       WATCHFRR_STR)
+{
+       watchfrr_status(vty);
+       return CMD_SUCCESS;
+}
+
 void integrated_write_sigchld(int status)
 {
        uint8_t reply[4] = {0, 0, 0, CMD_WARNING};
@@ -159,4 +169,5 @@ void watchfrr_vty_init(void)
        install_element(ENABLE_NODE, &config_write_integrated_cmd);
        install_element(ENABLE_NODE, &show_debugging_watchfrr_cmd);
        install_element(CONFIG_NODE, &show_debugging_watchfrr_cmd);
+       install_element(VIEW_NODE, &show_watchfrr_cmd);
 }
diff --git a/yang/confd/confd.frr-ripngd.yang b/yang/confd/confd.frr-ripngd.yang
new file mode 100644 (file)
index 0000000..5d876ff
--- /dev/null
@@ -0,0 +1,22 @@
+module confd.frr-ripngd {
+  namespace "urn:dummy";
+  prefix "dummy";
+
+  import tailf-common {
+    prefix tailf;
+  }
+  import frr-ripngd {
+    prefix frr-ripngd;
+  }
+
+  tailf:annotate-module "frr-ripngd" {
+    tailf:annotate-statement "container[name='ripngd']" {
+      tailf:annotate-statement "container[name='state']" {
+        tailf:callpoint "state";
+      }
+    }
+    tailf:annotate-statement "rpc[name='clear-ripng-route']" {
+      tailf:actionpoint "actionpoint";
+    }
+  }
+}
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
new file mode 100644 (file)
index 0000000..32b4d3a
--- /dev/null
@@ -0,0 +1,1404 @@
+module frr-isisd {
+  yang-version 1.1;
+  namespace "http://frrouting.org/yang/isisd";
+  prefix frr-isisd;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  import frr-interface {
+    prefix frr-interface;
+  }
+
+  import frr-route-types {
+    prefix frr-route-types;
+  }
+
+  organization
+    "Free Range Routing";
+  contact
+    "FRR Users List: <mailto:frog@lists.frrouting.org> FRR Development
+     List: <mailto:dev@lists.frrouting.org>";
+  description
+    "This module defines a model for managing FRR isisd daemon.";
+
+  revision 2018-07-26 {
+    description
+      "Initial revision.";
+    reference
+      "ISO/IEC 10589:2002.";
+  }
+
+  typedef level {
+    type enumeration {
+      enum "level-1" {
+        value 1;
+        description
+          "This enum indicates L1-only capability.";
+      }
+      enum "level-2" {
+        value 2;
+        description
+          "This enum indicates L2-only capability.";
+      }
+      enum "level-1-2" {
+        value 3;
+        description
+          "This enum indicates capability for both levels.";
+      }
+    }
+    description
+      "This type defines IS-IS level of an object.";
+  }
+
+  typedef network-type {
+    type enumeration {
+      enum "unknown" {
+        value 0;
+        description
+          "Unknown network type. Only valid as a state.";
+      }
+      enum "broadcast" {
+        value 1;
+        description
+          "Broadcast circuit network-type.";
+      }
+      enum "point-to-point" {
+        value 2;
+        description
+          "Point-to-point circuit network-type.";
+      }
+      enum "loopback" {
+        value 3;
+        description
+          "Loopback circuit network-type. Only valid as a state.";
+      }
+    }
+  }
+
+  typedef lsp-id {
+    type string {
+      pattern "[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}\\.[0-9][0-9]-[0-9][0-9]";
+    }
+    description
+      "This type defines the IS-IS LSP ID format using a
+       pattern, An example LSP ID is 0143.0438.AeF0.02-01";
+  }
+
+  typedef system-id {
+    type string {
+      pattern "[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}";
+    }
+    description
+      "This type defines IS-IS system-id using a pattern,
+       An example system-id is 0143.0438.AeF0";
+  }
+
+  typedef net-address {
+    type string {
+      pattern "[a-fA-F0-9]{2}(\\.[a-fA-F0-9]{4}){3,9}\\.[a-fA-F0-9]{2}";
+    }
+    description
+      "This type defines an OSI NET address using a pattern,
+       An example net-address is 49.0123.6452.1972.00";
+  }
+
+  typedef if-state-type {
+    type enumeration {
+      enum "up" {
+        value 0;
+        description
+          "Up state.";
+      }
+      enum "down" {
+        value 1;
+        description
+          "Down state";
+      }
+    }
+    description
+      "This type defines the state of an interface";
+  }
+
+  typedef adj-state-type {
+    type enumeration {
+      enum "up" {
+        value 0;
+        description
+          "State indicates the adjacency is established.";
+      }
+      enum "down" {
+        value 1;
+        description
+          "State indicates the adjacency is NOT established.";
+      }
+      enum "init" {
+        value 2;
+        description
+          "State indicates the adjacency is establishing.";
+      }
+      enum "failed" {
+        value 3;
+        description
+          "State indicates the adjacency is failed.";
+      }
+    }
+    description
+      "This type defines states of an adjacency";
+  }
+
+  typedef metric-style-type {
+    type enumeration {
+      enum "narrow" {
+        value 0;
+        description
+          "This enum describes narrow metric style";
+        reference
+          "RFC1195";
+      }
+      enum "wide" {
+        value 1;
+        description
+          "This enum describes wide metric style";
+        reference
+          "RFC5305";
+      }
+      enum "transition" {
+        value 2;
+        description
+          "This enum describes transition metric style";
+      }
+    }
+  }
+
+  grouping redistribute-attributes {
+    description
+      "Common optional attributes of any redistribute entry.";
+    choice attribute {
+      leaf route-map {
+        type string {
+          length "1..max";
+        }
+        description
+          "Applies the conditions of the specified route-map to routes that
+           are redistributed into this routing instance.";
+      }
+
+      leaf metric {
+        type uint32 {
+          range "0..16777215";
+        }
+        default "0";
+        description
+          "Metric used for the redistributed route. If 0,
+           the default-metric attribute is used instead.";
+      }
+    }
+  }
+
+  grouping redistribute-default {
+    description
+      "Redistribution of default route within a level.";
+    leaf always {
+      type boolean;
+      default "false";
+      description
+        "Always advertise default route.";
+    }
+
+    uses redistribute-attributes;
+  }
+
+  grouping isis-password {
+    description
+      "Authentication attributes or an IS-IS area or domain.";
+    leaf password {
+      type string {
+        length "1..254";
+      }
+      mandatory true;
+      description
+        "Actual password.";
+    }
+
+    leaf password-type {
+      type enumeration {
+        enum "clear" {
+          value 1;
+          description
+            "Clear-text password type.";
+        }
+        enum "md5" {
+          value 54;
+          description
+            "MD5 password type.";
+        }
+      }
+      mandatory true;
+      description
+        "Type of password used.";
+    }
+  }
+
+  grouping isis-area-password {
+    uses isis-password;
+
+    leaf authenticate-snp {
+      type enumeration {
+        enum "none" {
+          value 0;
+          description
+            "No SNP authentication.";
+        }
+        enum "send-only" {
+          value 1;
+          description
+            "Send authenticated PDUs but do not check on receiving.";
+        }
+        enum "validate" {
+          value 3;
+          description
+            "Send authenticated PDUs and check on receiving.";
+        }
+      }
+      default "none";
+      description
+        "SNP PDUs authentication.";
+    }
+  }
+
+  grouping notification-instance-hdr {
+    description
+      "Instance specific IS-IS notification data grouping";
+    leaf routing-instance {
+      type string;
+      description
+        "Name of the routing-instance instance.";
+    }
+
+    leaf routing-protocol-name {
+      type string;
+      description
+        "Name of the IS-IS instance.";
+    }
+
+    leaf isis-level {
+      type level;
+      description
+        "IS-IS level of the instance.";
+    }
+  }
+
+  grouping notification-interface-hdr {
+    description
+      "Interface specific IS-IS notification data grouping";
+    leaf interface-name {
+      type string;
+      description
+        "IS-IS interface name";
+    }
+
+    leaf interface-level {
+      type level;
+      description
+        "IS-IS level of the interface.";
+    }
+
+    leaf extended-circuit-id {
+      type uint32;
+      description
+        "Eextended circuit-id of the interface.";
+    }
+  }
+
+  container isis {
+    description
+      "Configuration of the IS-IS routing daemon.";
+    list instance {
+      key "area-tag";
+      description
+        "IS-IS routing instance.";
+      leaf area-tag {
+        type string;
+        description
+          "Area-tag associated to this routing instance.";
+      }
+
+      leaf is-type {
+        type level;
+        default "level-1";
+        description
+          "Level of the IS-IS routing instance (OSI only).";
+      }
+
+      leaf-list area-address {
+        type net-address;
+        max-elements 3;
+        description
+          "List of OSI NET addresses for this protocol instance.";
+      }
+
+      leaf dynamic-hostname {
+        type boolean;
+        default "true";
+        description
+          "Dynamic hostname support for IS-IS.";
+      }
+
+      leaf attached {
+        type boolean;
+        default "false";
+        description
+          "If true, identify as L1/L2 router for inter-area traffic.";
+      }
+
+      leaf overload {
+        type boolean;
+        default "false";
+        description
+          "If true, avoid any transit traffic.";
+      }
+
+      leaf metric-style {
+        type metric-style-type;
+        must ". = 'wide' or count(../multi-topology/*) = 0";
+        default "wide";
+        description
+          "Define the style of TLVs metric supported.";
+      }
+
+      leaf purge-originator {
+        type boolean;
+        default "false";
+        description
+          "Use the RFC 6232 purge-originator.";
+        reference
+          "RFC6232";
+      }
+
+      container lsp {
+        description
+          "Configuration of Link-State Packets (LSP) parameters";
+        leaf mtu {
+          type uint16 {
+            range "128..4352";
+          }
+          default "1497";
+          description
+            "MTU of an LSP.";
+        }
+
+        container refresh-interval {
+          description
+            "";
+          leaf level-1 {
+            type uint16;
+            units "seconds";
+            default "900";
+            description
+              "LSP refresh interval for level-1.";
+          }
+
+          leaf level-2 {
+            type uint16;
+            units "seconds";
+            default "900";
+            description
+              "LSP refresh interval for level-2.";
+          }
+        }
+
+        container maximum-lifetime {
+          description
+            "Maximum LSP lifetime.";
+          leaf level-1 {
+            type uint16 {
+              range "350..65535";
+            }
+            units "seconds";
+            must ". >= ../../refresh-interval/level-1 + 300";
+            default "1200";
+            description
+              "Maximum LSP lifetime for level-1.";
+          }
+
+          leaf level-2 {
+            type uint16 {
+              range "350..65535";
+            }
+            units "seconds";
+            must ". >= ../../refresh-interval/level-2 + 300";
+            default "1200";
+            description
+              "Maximum LSP lifetime for level-2.";
+          }
+        }
+
+        container generation-interval {
+          description
+            "Minimum LSP regeneration interval.";
+          leaf level-1 {
+            type uint16 {
+              range "1..120";
+            }
+            units "seconds";
+            must ". < ../../refresh-interval/level-1";
+            default "30";
+            description
+              "Minimum time allowed before level-1 LSP retransmissions.";
+          }
+
+          leaf level-2 {
+            type uint16 {
+              range "1..120";
+            }
+            units "seconds";
+            must ". < ../../refresh-interval/level-2";
+            default "30";
+            description
+              "Minimum time allowed before level-2 LSP retransmissions.";
+          }
+        }
+      }
+
+      container spf {
+        description
+          "Parameters related to the Shortest Path First algorithm.";
+        container ietf-backoff-delay {
+          presence "Present if IETF SPF back-off delay is enabled.";
+          description
+            "SPF back-off delay algorithm parameters (see RFC 8405).";
+          leaf init-delay {
+            type uint16 {
+              range "0..60000";
+            }
+            units "msec";
+            mandatory true;
+            description
+              "Delay used while in QUIET state";
+          }
+
+          leaf short-delay {
+            type uint16 {
+              range "0..60000";
+            }
+            units "msec";
+            mandatory true;
+            description
+              "Delay used while in SHORT_WAIT state";
+          }
+
+          leaf long-delay {
+            type uint16 {
+              range "0..60000";
+            }
+            units "msec";
+            mandatory true;
+            description
+              "Delay used while in LONG_WAIT state";
+          }
+
+          leaf hold-down {
+            type uint16 {
+              range "0..60000";
+            }
+            units "msec";
+            mandatory true;
+            description
+              "Time with no received IGP events before considering IGP stable";
+          }
+
+          leaf time-to-learn {
+            type uint16 {
+              range "0..60000";
+            }
+            units "msec";
+            mandatory true;
+            description
+              "Maximum duration needed to learn all the events related to a
+               single failure";
+          }
+        }
+
+        container minimum-interval {
+          description
+            "Minimum interval between consecutive executions of the
+             SPF algorithm.";
+          leaf level-1 {
+            type uint16 {
+              range "1..120";
+            }
+            units "seconds";
+            default "1";
+            description
+              "Minimum time between consecutive level-1 SPFs.";
+          }
+
+          leaf level-2 {
+            type uint16 {
+              range "1..120";
+            }
+            units "seconds";
+            default "1";
+            description
+              "Minimum time between consecutive level-2 SPFs.";
+          }
+        }
+      }
+
+      container area-password {
+        presence "Present if authentication is required for IS level-1.";
+        description
+          "Authentication password for an IS-IS area.";
+        uses isis-area-password;
+      }
+
+      container domain-password {
+        presence "Present if authentication is required for IS level-2.";
+        description
+          "Authentication password for an IS-IS domain.";
+        uses isis-area-password;
+      }
+
+      container default-information-originate {
+        description
+          "Distribution of default information.";
+        list ipv4 {
+          key "level";
+          description
+            "Distribute default route for IPv4.";
+          leaf level {
+            type level;
+            must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))";
+          }
+
+          uses redistribute-default;
+        }
+
+        list ipv6 {
+          key "level";
+          description
+            "Distribute default route for IPv6.";
+          leaf level {
+            type level;
+            must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))";
+          }
+
+          uses redistribute-default;
+        }
+      }
+
+      container redistribute {
+        description
+          "Redistributes routes learned from other routing protocols.";
+        list ipv4 {
+          key "protocol level";
+          description
+            "IPv4 route redistribution.";
+          leaf protocol {
+            type frr-route-types:frr-route-types-v4;
+            must ". != \"isis\"";
+            description
+              "Originating routing protocol for the IPv4 routes.";
+          }
+
+          leaf level {
+            type level;
+            must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))";
+            description
+              "IS-IS level into which the routes should be redistributed.";
+          }
+
+          uses redistribute-attributes;
+        }
+
+        list ipv6 {
+          key "protocol level";
+          description
+            "IPv6 route redistribution.";
+          leaf protocol {
+            type frr-route-types:frr-route-types-v6;
+            must ". != \"isis\"";
+            description
+              "Originating routing protocol for the IPv6 routes.";
+          }
+
+          leaf level {
+            type level;
+            must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))";
+            description
+              "IS-IS level into which the routes should be redistributed.";
+          }
+
+          uses redistribute-attributes;
+        }
+      }
+
+      container multi-topology {
+        description
+          "IS-IS topologies configured for this area.";
+        container ipv4-multicast {
+          presence "Present if a separate IPv4-multicast topology is configured for this area.";
+          description
+            "IPv4 multicast topology.";
+          leaf overload {
+            type boolean;
+            default "false";
+          }
+        }
+
+        container ipv4-management {
+          presence "Present if a separate IPv4-management topology is configured for this area.";
+          description
+            "IPv4 management topology.";
+          leaf overload {
+            type boolean;
+            default "false";
+          }
+        }
+
+        container ipv6-unicast {
+          presence "Present if a separate IPv6-unicast topology is configured for this area.";
+          description
+            "IPv6 unicast topology.";
+          leaf overload {
+            type boolean;
+            default "false";
+          }
+        }
+
+        container ipv6-multicast {
+          presence "Present if a separate IPv6-multicast topology is configured for this area.";
+          description
+            "IPv6 multicast topology.";
+          leaf overload {
+            type boolean;
+            default "false";
+          }
+        }
+
+        container ipv6-management {
+          presence "Present if a separate IPv6-management topology is configured for this area.";
+          description
+            "IPv6 management topology.";
+          leaf overload {
+            type boolean;
+            default "false";
+          }
+        }
+
+        container ipv6-dstsrc {
+          presence "Present if a separate IPv6 destination-source topology is configured for this area.";
+          description
+            "IPv6 destination-source topology.";
+          leaf overload {
+            type boolean;
+            default "false";
+          }
+        }
+      }
+
+      leaf log-adjacency-changes {
+        type boolean;
+        default "false";
+        description
+          "Log changes to the IS-IS adjacencies in this area.";
+      }
+    }
+
+    container mpls-te {
+      presence "Present if MPLS-TE is enabled.";
+      description
+        "Enable MPLS-TE functionality.";
+      leaf router-address {
+        type inet:ipv4-address;
+        description
+          "Stable IP address of the advertising router.";
+      }
+    }
+  }
+
+  augment "/frr-interface:lib/frr-interface:interface" {
+    description
+      "Extends interface model with IS-IS related parameters.";
+    container isis {
+      presence "Present if an IS-IS circuit is defined for this interface.";
+      description
+        "IS-IS interface parameters.";
+      leaf area-tag {
+        type string;
+        mandatory true;
+        description
+          "Area-tag associated to this circuit.";
+      }
+
+      leaf circuit-type {
+        type level;
+        default "level-1-2";
+        description
+          "IS-type of this circuit.";
+      }
+
+      leaf ipv4-routing {
+        type boolean;
+        default "false";
+        description
+          "Routing IS-IS IPv4 traffic over this circuit.";
+      }
+
+      leaf ipv6-routing {
+        type boolean;
+        default "false";
+        description
+          "Routing IS-IS IPv6 traffic over this circuit.";
+      }
+
+      container csnp-interval {
+        description
+          "Complete Sequence Number PDU (CSNP) generation interval.";
+        leaf level-1 {
+          type uint16 {
+            range "1..600";
+          }
+          units "seconds";
+          default "10";
+          description
+            "CNSP interval for level-1";
+        }
+
+        leaf level-2 {
+          type uint16 {
+            range "1..600";
+          }
+          units "seconds";
+          default "10";
+          description
+            "CNSP interval for level-2";
+        }
+      }
+
+      container psnp-interval {
+        description
+          "Partial Sequence Number PDU (PSNP) generation interval.";
+        leaf level-1 {
+          type uint16 {
+            range "1..120";
+          }
+          units "seconds";
+          default "2";
+          description
+            "PNSP interval for level-1";
+        }
+
+        leaf level-2 {
+          type uint16 {
+            range "1..120";
+          }
+          units "seconds";
+          default "2";
+          description
+            "PCNSP interval for level-2";
+        }
+      }
+
+      container hello {
+        description
+          "Parameters related to IS-IS hello PDUs.";
+        leaf padding {
+          type boolean;
+          default "true";
+          description
+            "Add padding to IS-IS hello PDUs.";
+        }
+
+        container interval {
+          description
+            "Interval between consecutive hello messages.";
+          leaf level-1 {
+            type uint32 {
+              range "1..600";
+            }
+            units "seconds";
+            default "3";
+            description
+              "Holding time for level-1; interval will depend on multiplier.";
+          }
+
+          leaf level-2 {
+            type uint32 {
+              range "1..600";
+            }
+            units "seconds";
+            default "3";
+            description
+              "Holding time for level-2; interval will depend on multiplier.";
+          }
+        }
+
+        container multiplier {
+          description
+            "Multiplier for the hello messages holding time.";
+          leaf level-1 {
+            type uint16 {
+              range "2..100";
+            }
+            default "10";
+            description
+              "Multiplier for the hello holding time.";
+          }
+
+          leaf level-2 {
+            type uint16 {
+              range "2..100";
+            }
+            default "10";
+            description
+              "Multiplier for the hello holding time.";
+          }
+        }
+      }
+
+      container metric {
+        description
+          "Default metric for this IS-IS circuit.";
+        leaf level-1 {
+          type uint32 {
+            range "0..16777215";
+          }
+          must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'";
+          default "10";
+          description
+            "Default level-1 metric for this IS-IS circuit.";
+        }
+
+        leaf level-2 {
+          type uint32 {
+            range "0..16777215";
+          }
+          must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'";
+          default "10";
+          description
+            "Default level-2 metric for this IS-IS circuit.";
+        }
+      }
+
+      container priority {
+        description
+          "Priority for Designated Router election.";
+        leaf level-1 {
+          type uint8 {
+            range "0..127";
+          }
+          default "64";
+          description
+            "Level-1 priority for this IS-IS circuit.";
+        }
+
+        leaf level-2 {
+          type uint8 {
+            range "0..127";
+          }
+          default "64";
+          description
+            "Level-2 priority for this IS-IS circuit.";
+        }
+      }
+
+      leaf network-type {
+        type network-type;
+        default "broadcast";
+        must "(. = \"point-to-point\") or (. = \"broadcast\")";
+        description
+          "Explicitly configured type of IS-IS circuit (broadcast or point-to-point).";
+      }
+
+      leaf passive {
+        type boolean;
+        default "false";
+        description
+          "Interface is in passive mode.";
+      }
+
+      container password {
+        presence "Present if a password is set for this IS interface.";
+        uses isis-password;
+      }
+
+      leaf disable-three-way-handshake {
+        type boolean;
+        default "false";
+        description
+          "Disables three-way handshake when creating new adjacencies.";
+      }
+
+      container multi-topology {
+        description
+          "IS-IS topologies configured on this circuit.";
+        leaf ipv4-unicast {
+          type boolean;
+          default "true";
+          description
+            "IPv4 unicast topology.";
+        }
+
+        leaf ipv4-multicast {
+          type boolean;
+          default "true";
+          description
+            "IPv4 multicast topology.";
+        }
+
+        leaf ipv4-management {
+          type boolean;
+          default "true";
+          description
+            "IPv4 management topology.";
+        }
+
+        leaf ipv6-unicast {
+          type boolean;
+          default "true";
+          description
+            "IPv6 unicast topology.";
+        }
+
+        leaf ipv6-multicast {
+          type boolean;
+          default "true";
+          description
+            "IPv6 multicast topology.";
+        }
+
+        leaf ipv6-management {
+          type boolean;
+          default "true";
+          description
+            "IPv6 management topology.";
+        }
+
+        leaf ipv6-dstsrc {
+          type boolean;
+          default "true";
+          description
+            "IPv6 destination-source topology.";
+        }
+      }
+    }
+  }
+
+  notification database-overload {
+    description
+      "This notification is sent when an IS-IS instance
+       overload state changes.";
+    uses notification-instance-hdr;
+
+    leaf overload {
+      type enumeration {
+        enum "off" {
+          value 0;
+          description
+            "Indicates IS-IS instance has left overload state";
+        }
+        enum "on" {
+          value 1;
+          description
+            "Indicates IS-IS instance has entered overload state";
+        }
+      }
+      description
+        "New overload state of the IS-IS instance";
+    }
+  }
+
+  notification lsp-too-large {
+    description
+      "This notification is sent when we attempt to propagate
+       an LSP that is larger than the dataLinkBlockSize for the
+       circuit.  The notification generation must be throttled
+       with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf pdu-size {
+      type uint32;
+      description
+        "Size of the LSP PDU";
+    }
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID";
+    }
+  }
+
+  notification if-state-change {
+    description
+      "This notification is sent when an interface
+       state change is detected.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf state {
+      type if-state-type;
+      description
+        "Interface state.";
+    }
+  }
+
+  notification corrupted-lsp-detected {
+    description
+      "This notification is sent when we find that
+       an LSP that was stored in memory has become
+       corrupted.";
+    uses notification-instance-hdr;
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID";
+    }
+  }
+
+  notification attempt-to-exceed-max-sequence {
+    description
+      "This notification is sent when the system
+       wraps the 32-bit sequence counter of an LSP.";
+    uses notification-instance-hdr;
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID";
+    }
+  }
+
+  notification id-len-mismatch {
+    description
+      "This notification is sent when we receive a PDU
+       with a different value for the System ID length.
+       The notification generation must be throttled
+       with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf pdu-field-len {
+      type uint8;
+      description
+        "Size of the ID length in the received PDU";
+    }
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+  }
+
+  notification max-area-addresses-mismatch {
+    description
+      "This notification is sent when we receive a PDU
+       with a different value for the Maximum Area Addresses.
+       The notification generation must be throttled
+       with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf max-area-addresses {
+      type uint8;
+      description
+        "Received number of supported areas";
+    }
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+  }
+
+  notification own-lsp-purge {
+    description
+      "This notification is sent when the system receives
+       a PDU with its own system ID and zero age.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID";
+    }
+  }
+
+  notification sequence-number-skipped {
+    description
+      "This notification is sent when the system receives a
+       PDU with its own system ID and different contents. The
+       system has to reoriginate the LSP with a higher sequence
+       number.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID";
+    }
+  }
+
+  notification authentication-type-failure {
+    description
+      "This notification is sent when the system receives a
+       PDU with the wrong authentication type field.
+       The notification generation must be throttled
+       with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+  }
+
+  notification authentication-failure {
+    description
+      "This notification is sent when the system receives
+       a PDU with the wrong authentication information.
+       The notification generation must be throttled with
+       with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+  }
+
+  notification version-skew {
+    description
+      "This notification is sent when the system receives a
+       PDU with a different protocol version number.
+       The notification generation must be throttled
+       with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf protocol-version {
+      type uint8;
+      description
+        "Protocol version received in the PDU.";
+    }
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+  }
+
+  notification area-mismatch {
+    description
+      "This notification is sent when the system receives a
+       Hello PDU from an IS that does not share any area
+       address. The notification generation must be throttled
+       with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+  }
+
+  notification rejected-adjacency {
+    description
+      "This notification is sent when the system receives a
+       Hello PDU from an IS but does not establish an adjacency
+       for some reason. The notification generation must be
+       throttled with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+
+    leaf reason {
+      type string;
+      description
+        "The system may provide a reason to reject the
+         adjacency. If the reason is not available,
+         an empty string will be returned.";
+    }
+  }
+
+  notification lsp-error-detected {
+    description
+      "This notification is sent when the system  receives an
+       LSP with a parse error. The notification generation must
+       be throttled with at least 5 seconds betweeen successive
+       notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID.";
+    }
+
+    leaf raw-pdu {
+      type binary;
+      description
+        "Received raw PDU.";
+    }
+
+    leaf error-offset {
+      type uint32;
+      description
+        "If the problem is a malformed TLV, the error-offset
+         points to the start of the TLV. If the problem is with
+         the LSP header, the error-offset points to the errant
+         byte";
+    }
+
+    leaf tlv-type {
+      type uint8;
+      description
+        "If the problem is a malformed TLV, the tlv-type is set
+         to the type value of the suspicious TLV. Otherwise,
+         this leaf is not present.";
+    }
+  }
+
+  notification adjacency-state-change {
+    description
+      "This notification is sent when an IS-IS adjacency
+       moves to Up state or to Down state.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf neighbor {
+      type string;
+      description
+        "Name of the neighbor. If the name of the neighbor is
+         not available, it is not returned.";
+    }
+
+    leaf neighbor-system-id {
+      type system-id;
+      description
+        "Neighbor system-id";
+    }
+
+    leaf state {
+      type adj-state-type;
+      description
+        "New state of the IS-IS adjacency.";
+    }
+
+    leaf reason {
+      type string;
+      description
+        "If the adjacency is going to DOWN,  this leaf provides
+         a reason for the adjacency going down. The reason is
+         provided as a text. If the adjacency is going to UP, no
+         reason is provided.";
+    }
+  }
+
+  notification lsp-received {
+    description
+      "This notification is sent when an LSP is received.
+       The notification generation must be throttled with at
+       least 5 seconds betweeen successive notifications.";
+    uses notification-instance-hdr;
+
+    uses notification-interface-hdr;
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID";
+    }
+
+    leaf sequence {
+      type uint32;
+      description
+        "Sequence number of the received LSP.";
+    }
+
+    leaf received-timestamp {
+      type yang:timestamp;
+      description
+        "Timestamp when the LSP was received.";
+    }
+
+    leaf neighbor-system-id {
+      type system-id;
+      description
+        "Neighbor system-id of LSP sender";
+    }
+  }
+
+  notification lsp-generation {
+    description
+      "This notification is sent when an LSP is regenerated.
+       The notification generation must be throttled with at
+       least 5 seconds betweeen successive notifications.";
+    uses notification-instance-hdr;
+
+    leaf lsp-id {
+      type lsp-id;
+      description
+        "LSP ID";
+    }
+
+    leaf sequence {
+      type uint32;
+      description
+        "Sequence number of the received LSP.";
+    }
+
+    leaf send-timestamp {
+      type yang:timestamp;
+      description
+        "Timestamp when our LSP was regenerated.";
+    }
+  }
+}
diff --git a/yang/frr-ripngd.yang b/yang/frr-ripngd.yang
new file mode 100644 (file)
index 0000000..0cc5f18
--- /dev/null
@@ -0,0 +1,321 @@
+module frr-ripngd {
+  yang-version 1.1;
+  namespace "http://frrouting.org/yang/ripngd";
+  prefix frr-ripngd;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+  import ietf-yang-types {
+    prefix yang;
+  }
+  import frr-interface {
+    prefix frr-interface;
+  }
+  import frr-route-types {
+    prefix frr-route-types;
+  }
+
+  organization
+    "Free Range Routing";
+  contact
+    "FRR Users List:       <mailto:frog@lists.frrouting.org>
+     FRR Development List: <mailto:dev@lists.frrouting.org>";
+  description
+    "This module defines a model for managing FRR ripngd daemon.";
+
+  revision 2018-11-27 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 2080: RIPng for IPv6.";
+  }
+
+  container ripngd {
+    /*
+     * Global configuration data
+     */
+    container instance {
+      presence "Present if the RIPng protocol is enabled.";
+      description
+        "RIPng routing instance.";
+
+      leaf allow-ecmp {
+        type boolean;
+        default "false";
+        description
+          "Allow equal-cost multi-path.";
+      }
+      leaf default-information-originate {
+        type boolean;
+        default "false";
+        description
+          "Control distribution of default route.";
+      }
+      leaf default-metric {
+        type uint8 {
+          range "1..16";
+        }
+        default "1";
+        description
+          "Default metric of redistributed routes.";
+      }
+      leaf-list network {
+        type inet:ipv6-prefix;
+        description
+          "Enable RIPng on the specified IPv6 network.";
+      }
+      leaf-list interface {
+        type string {
+          length "1..16";
+        }
+        description
+          "Enable RIPng on the specified interface.";
+      }
+      list offset-list {
+        key "interface direction";
+        description
+          "Offset-list to modify route metric.";
+        leaf interface {
+          type string;
+          description
+            "Interface to match. Use '*' to match all interfaces.";
+        }
+        leaf direction {
+          type enumeration {
+            enum in {
+              value 0;
+              description
+                "Incoming updates.";
+            }
+            enum out {
+              value 1;
+              description
+                "Outgoing updates.";
+            }
+          }
+          description
+            "Incoming or outgoing updates.";
+        }
+        leaf access-list {
+          type string;
+          mandatory true;
+          description
+            "Access-list name.";
+        }
+        leaf metric {
+          type uint8 {
+            range "0..16";
+          }
+          mandatory true;
+          description
+            "Route metric.";
+        }
+      }
+      leaf-list passive-interface {
+        type string {
+          length "1..16";
+        }
+        description
+          "A list of interfaces where the sending of RIPng packets
+           is disabled.";
+      }
+      list redistribute {
+        key "protocol";
+        description
+          "Redistributes routes learned from other routing protocols.";
+        leaf protocol {
+          type frr-route-types:frr-route-types-v6;
+          description
+            "Routing protocol.";
+          must '. != "ripng"';
+        }
+        leaf route-map {
+          type string {
+            length "1..max";
+          }
+          description
+            "Applies the conditions of the specified route-map to
+             routes that are redistributed into the RIPng routing
+             instance.";
+        }
+        leaf metric {
+          type uint8 {
+            range "0..16";
+          }
+          description
+            "Metric used for the redistributed route. If a metric is
+             not specified, the metric configured with the
+             default-metric attribute in RIPng router configuration is
+             used. If the default-metric attribute has not been
+             configured, the default metric for redistributed routes
+             is 0.";
+        }
+      }
+      leaf-list static-route {
+        type inet:ipv6-prefix;
+        description
+          "RIPng static routes.";
+      }
+      leaf-list aggregate-address {
+        type inet:ipv6-prefix;
+        description
+          "RIPng aggregate route announcement.";
+      }
+      container timers {
+        description
+          "Settings of basic timers";
+        leaf flush-interval {
+          type uint16 {
+            range "1..65535";
+          }
+          units "seconds";
+          default "120";
+          description
+            "Interval before a route is flushed from the routing
+             table.";
+        }
+        leaf holddown-interval {
+          type uint16 {
+            range "1..65535";
+          }
+          units "seconds";
+          default "180";
+          description
+            "Interval before better routes are released.";
+        }
+        leaf update-interval {
+          type uint16 {
+            range "1..65535";
+          }
+          units "seconds";
+          default "30";
+          description
+            "Interval at which RIPng updates are sent.";
+        }
+      }
+    }
+
+    /*
+     * Operational data.
+     */
+    container state {
+      config false;
+      description
+        "Operational data.";
+
+      container neighbors {
+        description
+          "Neighbor information.";
+        list neighbor {
+          key "address";
+          description
+            "A RIPng neighbor.";
+          leaf address {
+            type inet:ipv6-address;
+            description
+              "IPv6 address that a RIPng neighbor is using as its
+               source address.";
+          }
+          leaf last-update {
+            type yang:date-and-time;
+            description
+              "The time when the most recent RIPng update was
+               received from this neighbor.";
+          }
+          leaf bad-packets-rcvd {
+            type yang:counter32;
+            description
+              "The number of RIPng invalid packets received from
+               this neighbor which were subsequently discarded
+               for any reason (e.g. a version 0 packet, or an
+               unknown command type).";
+          }
+          leaf bad-routes-rcvd {
+            type yang:counter32;
+            description
+              "The number of routes received from this neighbor,
+               in valid RIPng packets, which were ignored for any
+               reason (e.g. unknown address family, or invalid
+               metric).";
+          }
+        }
+      }
+      container routes {
+        description
+          "Route information.";
+        list route {
+          key "prefix";
+          description
+            "A RIPng IPv6 route.";
+          leaf prefix {
+            type inet:ipv6-prefix;
+            description
+              "IPv6 address and prefix length, in the format
+               specified in RFC6991.";
+          }
+          leaf next-hop {
+            type inet:ipv6-address;
+            description
+              "Next hop IPv6 address.";
+          }
+          leaf interface {
+            type string;
+            description
+              "The interface that the route uses.";
+          }
+          leaf metric {
+            type uint8 {
+              range "0..16";
+            }
+            description
+              "Route metric.";
+          }
+        }
+      }
+    }
+  }
+
+  /*
+   * Per-interface configuration data
+   */
+  augment "/frr-interface:lib/frr-interface:interface" {
+    container ripng {
+      description
+        "RIPng interface parameters.";
+      leaf split-horizon {
+        type enumeration {
+          enum "disabled" {
+            value 0;
+            description
+              "Disables split-horizon processing.";
+          }
+          enum "simple" {
+            value 1;
+            description
+              "Enables simple split-horizon processing.";
+          }
+          enum "poison-reverse" {
+            value 2;
+            description
+              "Enables split-horizon processing with poison
+               reverse.";
+          }
+        }
+        default "simple";
+        description
+          "Controls RIPng split-horizon processing on the specified
+           interface.";
+      }
+    }
+  }
+
+  /*
+   * RPCs
+   */
+  rpc clear-ripng-route {
+    description
+      "Clears RIPng routes from the IPv6 routing table and routes
+       redistributed into the RIPng protocol.";
+  }
+}
index c02c0a11d7b38e492f760b8cd31981c3bb0553d8..d85b12ea06ee36adfeae3c56ae6b571407107c4d 100644 (file)
@@ -34,8 +34,6 @@ module frr-test-module {
         }
         container routes {
           list route {
-            key "prefix";
-
             leaf prefix {
               type inet:ipv4-prefix;
             }
index 07bd225780526ed459211442d4203a73f3f0a287..c95ec4dbff44b532fcd2bb031e0e9ceb43ce5a1f 100644 (file)
@@ -27,3 +27,11 @@ dist_yangmodels_DATA += yang/frr-route-types.yang
 if RIPD
 dist_yangmodels_DATA += yang/frr-ripd.yang
 endif
+
+if RIPNGD
+dist_yangmodels_DATA += yang/frr-ripngd.yang
+endif
+
+if ISISD
+dist_yangmodels_DATA += yang/frr-isisd.yang
+endif
index 8a7cb0e5284cee64eeb96b65c16fd6934a0db32b..4f89d53e399cdbf19e3eb581af5ed288b1d831ec 100644 (file)
@@ -918,6 +918,9 @@ void rtm_read(struct rt_msghdr *rtm)
        char ifname[INTERFACE_NAMSIZ + 1];
        short ifnlen = 0;
        struct nexthop nh;
+       struct prefix p;
+       ifindex_t ifindex = 0;
+       afi_t afi;
 
        zebra_flags = 0;
 
@@ -951,10 +954,6 @@ void rtm_read(struct rt_msghdr *rtm)
        if (flags & RTF_PROTO1)
                SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE);
 
-       /* This is persistent route. */
-       if (flags & RTF_STATIC)
-               SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC);
-
        memset(&nh, 0, sizeof(nh));
 
        nh.vrf_id = VRF_DEFAULT;
@@ -967,9 +966,14 @@ void rtm_read(struct rt_msghdr *rtm)
                nh.bh_type = BLACKHOLE_NULL;
        }
 
-       if (dest.sa.sa_family == AF_INET) {
-               struct prefix p;
+       /*
+        * Ignore our own messages.
+        */
+       if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
+               return;
 
+       if (dest.sa.sa_family == AF_INET) {
+               afi = AFI_IP;
                p.family = AF_INET;
                p.u.prefix4 = dest.sin.sin_addr;
                if (flags & RTF_HOST)
@@ -977,146 +981,12 @@ void rtm_read(struct rt_msghdr *rtm)
                else
                        p.prefixlen = ip_masklen(mask.sin.sin_addr);
 
-               /* Catch self originated messages and match them against our
-                * current RIB.
-                * At the same time, ignore unconfirmed messages, they should be
-                * tracked
-                * by rtm_write() and kernel_rtm_ipv4().
-                */
-               if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) {
-                       char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN];
-                       int ret;
-                       if (!IS_ZEBRA_DEBUG_RIB)
-                               return;
-                       ret = rib_lookup_ipv4_route((struct prefix_ipv4 *)&p,
-                                                   &gate, VRF_DEFAULT);
-                       prefix2str(&p, buf, sizeof(buf));
-                       switch (rtm->rtm_type) {
-                       case RTM_ADD:
-                       case RTM_GET:
-                       case RTM_CHANGE:
-                               /* The kernel notifies us about a new route in
-                                  FIB created by us.
-                                  Do we have a correspondent entry in our RIB?
-                                  */
-                               switch (ret) {
-                               case ZEBRA_RIB_NOTFOUND:
-                                       zlog_debug(
-                                               "%s: %s %s: desync: RR isn't yet in RIB, while already in FIB",
-                                               __func__,
-                                               lookup_msg(rtm_type_str,
-                                                          rtm->rtm_type, NULL),
-                                               buf);
-                                       break;
-                               case ZEBRA_RIB_FOUND_CONNECTED:
-                               case ZEBRA_RIB_FOUND_NOGATE:
-                                       inet_ntop(AF_INET, &gate.sin.sin_addr,
-                                                 gate_buf, INET_ADDRSTRLEN);
-                                       zlog_debug(
-                                               "%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)",
-                                               __func__,
-                                               lookup_msg(rtm_type_str,
-                                                          rtm->rtm_type, NULL),
-                                               buf, gate_buf);
-                                       break;
-                               case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR
-                                                              */
-                                       zlog_debug(
-                                               "%s: %s %s: done Ok", __func__,
-                                               lookup_msg(rtm_type_str,
-                                                          rtm->rtm_type, NULL),
-                                               buf);
-                                       rib_lookup_and_dump(
-                                               (struct prefix_ipv4 *)&p,
-                                               VRF_DEFAULT);
-                                       return;
-                                       break;
-                               }
-                               break;
-                       case RTM_DELETE:
-                               /* The kernel notifies us about a route deleted
-                                  by us. Do we still
-                                  have it in the RIB? Do we have anything
-                                  instead? */
-                               switch (ret) {
-                               case ZEBRA_RIB_FOUND_EXACT:
-                                       zlog_debug(
-                                               "%s: %s %s: desync: RR is still in RIB, while already not in FIB",
-                                               __func__,
-                                               lookup_msg(rtm_type_str,
-                                                          rtm->rtm_type, NULL),
-                                               buf);
-                                       rib_lookup_and_dump(
-                                               (struct prefix_ipv4 *)&p,
-                                               VRF_DEFAULT);
-                                       break;
-                               case ZEBRA_RIB_FOUND_CONNECTED:
-                               case ZEBRA_RIB_FOUND_NOGATE:
-                                       zlog_debug(
-                                               "%s: %s %s: desync: RR is still in RIB, plus gate differs",
-                                               __func__,
-                                               lookup_msg(rtm_type_str,
-                                                          rtm->rtm_type, NULL),
-                                               buf);
-                                       rib_lookup_and_dump(
-                                               (struct prefix_ipv4 *)&p,
-                                               VRF_DEFAULT);
-                                       break;
-                               case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
-                                       zlog_debug(
-                                               "%s: %s %s: done Ok", __func__,
-                                               lookup_msg(rtm_type_str,
-                                                          rtm->rtm_type, NULL),
-                                               buf);
-                                       rib_lookup_and_dump(
-                                               (struct prefix_ipv4 *)&p,
-                                               VRF_DEFAULT);
-                                       return;
-                                       break;
-                               }
-                               break;
-                       default:
-                               zlog_debug(
-                                       "%s: %s: warning: loopback RTM of type %s received",
-                                       __func__, buf,
-                                       lookup_msg(rtm_type_str, rtm->rtm_type,
-                                                  NULL));
-                       }
-                       return;
-               }
-
-               /* Change, delete the old prefix, we have no further information
-                * to specify the route really
-                */
-               if (rtm->rtm_type == RTM_CHANGE)
-                       rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
-                                  ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, 0, true);
-
                if (!nh.type) {
                        nh.type = NEXTHOP_TYPE_IPV4;
                        nh.gate.ipv4 = gate.sin.sin_addr;
                }
-
-               if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
-                   || rtm->rtm_type == RTM_CHANGE)
-                       rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
-                               ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                               &nh, 0, 0, 0, 0, 0);
-               else
-                       rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
-                                  ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, 0, true);
-       }
-       if (dest.sa.sa_family == AF_INET6) {
-               /* One day we might have a debug section here like one in the
-                * IPv4 case above. Just ignore own messages at the moment.
-                */
-               if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
-                       return;
-               struct prefix p;
-               ifindex_t ifindex = 0;
-
+       } else if (dest.sa.sa_family == AF_INET6) {
+               afi = AFI_IP6;
                p.family = AF_INET6;
                p.u.prefix6 = dest.sin6.sin6_addr;
                if (flags & RTF_HOST)
@@ -1131,31 +1001,29 @@ void rtm_read(struct rt_msghdr *rtm)
                }
 #endif /* KAME */
 
-               /* CHANGE: delete the old prefix, we have no further information
-                * to specify the route really
-                */
-               if (rtm->rtm_type == RTM_CHANGE)
-                       rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
-                                  ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, 0, true);
-
                if (!nh.type) {
                        nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
                                          : NEXTHOP_TYPE_IPV6;
                        nh.gate.ipv6 = gate.sin6.sin6_addr;
                        nh.ifindex = ifindex;
                }
+       } else
+               return;
 
-               if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
-                   || rtm->rtm_type == RTM_CHANGE)
-                       rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
-                               ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                               &nh, 0, 0, 0, 0, 0);
-               else
-                       rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
-                                  ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, 0, true);
-       }
+       /*
+        * CHANGE: delete the old prefix, we have no further information
+        * to specify the route really
+        */
+       if (rtm->rtm_type == RTM_CHANGE)
+               rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
+                          0, zebra_flags, &p, NULL, NULL, 0, 0, 0, true);
+       if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
+           || rtm->rtm_type == RTM_CHANGE)
+               rib_add(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
+                       zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0);
+       else
+               rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
+                          0, zebra_flags, &p, NULL, &nh, 0, 0, 0, true);
 }
 
 /* Interface function for the kernel routing table updates.  Support
index 97eae79f03c276cf0289d344e3e4f8ae28749383..ae25a0e67980acd6593863782c42d039938197fa 100644 (file)
@@ -282,8 +282,6 @@ extern enum multicast_mode multicast_mode_ipv4_get(void);
 extern void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id);
 extern void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id);
 
-extern int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
-                                vrf_id_t vrf_id);
 #define ZEBRA_RIB_LOOKUP_ERROR -1
 #define ZEBRA_RIB_FOUND_EXACT 0
 #define ZEBRA_RIB_FOUND_NOGATE 1
index cb9ef8e36f8dc0ac0cb7c1782bc03bb233592a70..8ce963b37b52bce522547d38295d51fd148598cf 100644 (file)
@@ -1584,7 +1584,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
        }
 
        /* Singlepath case. */
-       if (nexthop_num == 1 || multipath_num == 1) {
+       if (nexthop_num == 1) {
                nexthop_num = 0;
                for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
                        /*
@@ -1676,9 +1676,6 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
 
                nexthop_num = 0;
                for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
-                       if (nexthop_num >= multipath_num)
-                               break;
-
                        if (CHECK_FLAG(nexthop->flags,
                                       NEXTHOP_FLAG_RECURSIVE)) {
                                /* This only works for IPv4 now */
@@ -1876,12 +1873,6 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
 
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
-
-                               /* If we're only allowed a single nh, don't
-                                * continue.
-                                */
-                               if (multipath_num == 1)
-                                       break;
                        }
                }
        }
@@ -2698,7 +2689,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
        /* Fill nexthops (paths) based on single-path or multipath. The paths
         * chosen depend on the operation.
         */
-       if (nexthop_num == 1 || multipath_num == 1) {
+       if (nexthop_num == 1) {
                routedesc = "single-path";
                _netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
 
@@ -2745,9 +2736,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
                        if (!nexthop)
                                continue;
 
-                       if (nexthop_num >= multipath_num)
-                               break;
-
                        if ((cmd == RTM_NEWROUTE
                             && (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
                                 && CHECK_FLAG(nexthop->flags,
index 3f69b98413b11739c093bbdbf957e560ef42baf5..a4e10221482012a9204287860f7c3a92a525c57d 100644 (file)
@@ -252,8 +252,6 @@ static int zebra_ns_notify_read(struct thread *t)
 
                if (!(event->mask & (IN_CREATE | IN_DELETE)))
                        continue;
-               if (event->mask & IN_DELETE)
-                       return zebra_ns_delete(event->name);
 
                if (offsetof(struct inotify_event, name) + event->len
                    >= sizeof(buf)) {
@@ -268,6 +266,9 @@ static int zebra_ns_notify_read(struct thread *t)
                        break;
                }
 
+               if (event->mask & IN_DELETE)
+                       return zebra_ns_delete(event->name);
+
                netnspath = ns_netns_pathname(NULL, event->name);
                if (!netnspath)
                        continue;
index 965c8c206c7ffeb62ad0abefc938dafb6f8683d4..9b86657f1b092d3a36ad97ec3b2d1c06c95f9325 100644 (file)
@@ -76,7 +76,6 @@ static int zebra_ns_new(struct ns *ns)
 
        /* Do any needed per-NS data structure allocation. */
        zns->if_table = route_table_init();
-       zebra_vxlan_ns_init(zns);
 
        return 0;
 }
@@ -142,7 +141,6 @@ int zebra_ns_enable(ns_id_t ns_id, void **info)
 static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete)
 {
        route_table_finish(zns->if_table);
-       zebra_vxlan_ns_disable(zns);
 #if defined(HAVE_RTADV)
        rtadv_terminate(zns);
 #endif
@@ -201,7 +199,6 @@ int zebra_ns_init(void)
 
        /* Do any needed per-NS data structure allocation. */
        dzns->if_table = route_table_init();
-       zebra_vxlan_ns_init(dzns);
 
        /* Register zebra VRF callbacks, create and activate default VRF. */
        zebra_vrf_init();
index f2d07310eed10914e6bd28d21cc3837f78e99b03..5d6eac75330d0590ddf93e294882800bb0527a9a 100644 (file)
@@ -412,7 +412,7 @@ static void nexthop_set_resolved(afi_t afi, const struct nexthop *newhop,
 /* If force flag is not set, do not modify falgs at all for uninstall
    the route from FIB. */
 static int nexthop_active(afi_t afi, struct route_entry *re,
-                         struct nexthop *nexthop, int set,
+                         struct nexthop *nexthop, bool set,
                          struct route_node *top)
 {
        struct prefix p;
@@ -808,84 +808,6 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        return NULL;
 }
 
-/*
- * This clone function, unlike its original rib_lookup_ipv4(), checks
- * if specified IPv4 route record (prefix/mask -> gate) exists in
- * the whole RIB and has ROUTE_ENTRY_SELECTED_FIB set.
- *
- * Return values:
- * -1: error
- * 0: exact match found
- * 1: a match was found with a different gate
- * 2: connected route found
- * 3: no matches found
- */
-int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
-                         vrf_id_t vrf_id)
-{
-       struct route_table *table;
-       struct route_node *rn;
-       struct route_entry *match = NULL;
-       struct nexthop *nexthop;
-       int nexthops_active;
-       rib_dest_t *dest;
-
-       /* Lookup table.  */
-       table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
-       if (!table)
-               return ZEBRA_RIB_LOOKUP_ERROR;
-
-       /* Scan the RIB table for exactly matching RIB entry. */
-       rn = route_node_lookup(table, (struct prefix *)p);
-
-       /* No route for this prefix. */
-       if (!rn)
-               return ZEBRA_RIB_NOTFOUND;
-
-       /* Unlock node. */
-       route_unlock_node(rn);
-       dest = rib_dest_from_rnode(rn);
-
-       /* Find out if a "selected" RR for the discovered RIB entry exists ever.
-        */
-       if (dest && dest->selected_fib
-           && !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
-               match = dest->selected_fib;
-
-       /* None such found :( */
-       if (!match)
-               return ZEBRA_RIB_NOTFOUND;
-
-       if (match->type == ZEBRA_ROUTE_CONNECT)
-               return ZEBRA_RIB_FOUND_CONNECTED;
-
-       /* Ok, we have a cood candidate, let's check it's nexthop list... */
-       nexthops_active = 0;
-       for (ALL_NEXTHOPS(match->ng, nexthop))
-               if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
-                       nexthops_active = 1;
-                       if (nexthop->gate.ipv4.s_addr == sockunion2ip(qgate))
-                               return ZEBRA_RIB_FOUND_EXACT;
-                       if (IS_ZEBRA_DEBUG_RIB) {
-                               char gate_buf[INET_ADDRSTRLEN],
-                                       qgate_buf[INET_ADDRSTRLEN];
-                               inet_ntop(AF_INET, &nexthop->gate.ipv4.s_addr,
-                                         gate_buf, INET_ADDRSTRLEN);
-                               inet_ntop(AF_INET, &sockunion2ip(qgate),
-                                         qgate_buf, INET_ADDRSTRLEN);
-                               zlog_debug("%s: qgate == %s, %s == %s",
-                                          __func__, qgate_buf,
-                                          nexthop->rparent ? "rgate" : "gate",
-                                          gate_buf);
-                       }
-               }
-
-       if (nexthops_active)
-               return ZEBRA_RIB_FOUND_NOGATE;
-
-       return ZEBRA_RIB_NOTFOUND;
-}
-
 #define RIB_SYSTEM_ROUTE(R)                                                    \
        ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
 
@@ -904,7 +826,7 @@ int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
 
 static unsigned nexthop_active_check(struct route_node *rn,
                                     struct route_entry *re,
-                                    struct nexthop *nexthop, int set)
+                                    struct nexthop *nexthop, bool set)
 {
        struct interface *ifp;
        route_map_result_t ret = RMAP_MATCH;
@@ -1031,7 +953,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
  */
 
 static int nexthop_active_update(struct route_node *rn, struct route_entry *re,
-                                int set)
+                                bool set)
 {
        struct nexthop *nexthop;
        union g_addr prev_src;
@@ -1049,7 +971,18 @@ static int nexthop_active_update(struct route_node *rn, struct route_entry *re,
                prev_src = nexthop->rmap_src;
                prev_active = CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                prev_index = nexthop->ifindex;
-               if ((new_active = nexthop_active_check(rn, re, nexthop, set)))
+               /*
+                * We need to respect the multipath_num here
+                * as that what we should be able to install from
+                * a multipath perpsective should not be a data plane
+                * decision point.
+                */
+               new_active = nexthop_active_check(rn, re, nexthop, set);
+               if (new_active && re->nexthop_active_num >= multipath_num) {
+                       UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+                       new_active = 0;
+               }
+               if (new_active)
                        re->nexthop_active_num++;
                /* Don't allow src setting on IPv6 addr for now */
                if (prev_active != new_active || prev_index != nexthop->ifindex
@@ -1322,7 +1255,7 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
 
        /* Update real nexthop. This may actually determine if nexthop is active
         * or not. */
-       if (!nexthop_active_update(rn, new, 1)) {
+       if (!nexthop_active_update(rn, new, true)) {
                UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
                return;
        }
@@ -1383,7 +1316,7 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
         * down, causing the kernel to delete routes without sending DELROUTE
         * notifications
         */
-       if (!nexthop_active_update(rn, old, 1) &&
+       if (!nexthop_active_update(rn, old, true) &&
            (RIB_KERNEL_ROUTE(old)))
                SET_FLAG(old->status, ROUTE_ENTRY_REMOVED);
        else
@@ -1408,7 +1341,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
 
                /* Update the nexthop; we could determine here that nexthop is
                 * inactive. */
-               if (nexthop_active_update(rn, new, 1))
+               if (nexthop_active_update(rn, new, true))
                        nh_active = 1;
 
                /* If nexthop is active, install the selected route, if
@@ -1533,7 +1466,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
        /* Update prior route. */
        if (new != old) {
                /* Set real nexthop. */
-               nexthop_active_update(rn, old, 1);
+               nexthop_active_update(rn, old, true);
                UNSET_FLAG(old->status, ROUTE_ENTRY_CHANGED);
        }
 
@@ -1682,7 +1615,7 @@ static void rib_process(struct route_node *rn)
                 * recursive NHs.
                 */
                if (!CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)
-                   && !nexthop_active_update(rn, re, 0)) {
+                   && !nexthop_active_update(rn, re, false)) {
                        if (re->type == ZEBRA_ROUTE_TABLE) {
                                /* XXX: HERE BE DRAGONS!!!!!
                                 * In all honesty, I have not yet figured out
@@ -1774,7 +1707,7 @@ static void rib_process(struct route_node *rn)
        if (old_selected != new_selected || selected_changed) {
 
                if (new_selected && new_selected != new_fib) {
-                       nexthop_active_update(rn, new_selected, 1);
+                       nexthop_active_update(rn, new_selected, true);
                        UNSET_FLAG(new_selected->status, ROUTE_ENTRY_CHANGED);
                }
 
@@ -1950,7 +1883,7 @@ static void rib_process_after(struct zebra_dplane_ctx *ctx)
                                zvrf->removals++;
                } else {
                        zsend_route_notify_owner_ctx(ctx,
-                                                    ZAPI_ROUTE_FAIL_INSTALL);
+                                                    ZAPI_ROUTE_REMOVE_FAIL);
 
                        zlog_warn("%u:%s: Route Deletion failure",
                                  dplane_ctx_get_vrf(ctx),
@@ -2362,6 +2295,7 @@ static void rib_queue_init(struct zebra_t *zebra)
        /* XXX: TODO: These should be runtime configurable via vty */
        zebra->ribq->spec.max_retries = 3;
        zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
+       zebra->ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME;
 
        if (!(zebra->mq = meta_queue_new())) {
                flog_err(EC_ZEBRA_WQ_NONEXISTENT,
index e92cd8bb8a2511fec930a73ef1b4c3e7598dc55a..b1fbe8a6536de6dbdf2bf91b6f520ec8664a7266 100644 (file)
@@ -528,8 +528,7 @@ static void zebra_rnh_process_pbr_tables(int family,
  */
 static bool rnh_nexthop_valid(const struct nexthop *nh)
 {
-       return ((CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
-                || CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
+       return (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
                && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE));
 }
 
@@ -581,8 +580,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, int family,
                        /* Just being SELECTED isn't quite enough - must
                         * have an installed nexthop to be useful.
                         */
-                       for (nexthop = re->ng.nexthop; nexthop;
-                            nexthop = nexthop->next) {
+                       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                                if (rnh_nexthop_valid(nexthop))
                                        break;
                        }
@@ -915,7 +913,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
                num = 0;
                nump = stream_get_endp(s);
                stream_putc(s, 0);
-               for (nh = re->ng.nexthop; nh; nh = nh->next)
+               for (ALL_NEXTHOPS(re->ng, nh))
                        if (rnh_nexthop_valid(nh)) {
                                stream_putl(s, nh->vrf_id);
                                stream_putc(s, nh->type);
index afe3c708a012fa3ce20399c9cf008465908e2886..2e1c69fb9269af3cc29252e2b9577bd6a0b1c2e7 100644 (file)
@@ -24,6 +24,7 @@
 #include "zebra_router.h"
 #include "zebra_memory.h"
 #include "zebra_pbr.h"
+#include "zebra_vxlan.h"
 
 struct zebra_router zrouter;
 
@@ -157,6 +158,7 @@ void zebra_router_terminate(void)
                zebra_router_free_table(zrt);
        }
 
+       zebra_vxlan_disable();
        hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
        hash_free(zrouter.rules_hash);
 
@@ -170,8 +172,7 @@ void zebra_router_terminate(void)
 
 void zebra_router_init(void)
 {
-       zrouter.l3vni_table = NULL;
-
+       zebra_vxlan_init();
        zrouter.rules_hash = hash_create_size(8, zebra_pbr_rules_hash_key,
                                              zebra_pbr_rules_hash_equal,
                                              "Rules Hash");
index e6cc802d08129be32996cf24b2cffa143be72d69..8b06d2ae115a9683f0714e91503efc3ffdc225f9 100644 (file)
@@ -948,6 +948,39 @@ DEFUN (show_ip_nht,
        return CMD_SUCCESS;
 }
 
+DEFPY (show_ip_import_check,
+       show_ip_import_check_cmd,
+       "show <ip$ipv4|ipv6$ipv6> import-check [vrf NAME$vrf_name|vrf all$vrf_all]",
+       SHOW_STR
+       IP_STR
+       IP6_STR
+       "IP import check tracking table\n"
+       VRF_CMD_HELP_STR
+       VRF_ALL_CMD_HELP_STR)
+{
+       afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
+       vrf_id_t vrf_id = VRF_DEFAULT;
+
+       if (vrf_all) {
+               struct vrf *vrf;
+               struct zebra_vrf *zvrf;
+
+               RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+                       if ((zvrf = vrf->info) != NULL) {
+                               vty_out(vty, "\nVRF %s:\n",
+                                       zvrf_name(zvrf));
+                               zebra_print_rnh_table(zvrf_id(zvrf),
+                                                     afi, vty,
+                                                     RNH_NEXTHOP_TYPE);
+                       }
+               return CMD_SUCCESS;
+       }
+       if (vrf_name)
+               VRF_GET_ID(vrf_id, vrf_name, false);
+
+       zebra_print_rnh_table(vrf_id, afi, vty, RNH_IMPORT_CHECK_TYPE);
+       return CMD_SUCCESS;
+}
 
 DEFUN (show_ip_nht_vrf_all,
        show_ip_nht_vrf_all_cmd,
@@ -2907,6 +2940,7 @@ void zebra_vty_init(void)
        install_element(VIEW_NODE, &show_route_detail_cmd);
        install_element(VIEW_NODE, &show_route_summary_cmd);
        install_element(VIEW_NODE, &show_ip_nht_cmd);
+       install_element(VIEW_NODE, &show_ip_import_check_cmd);
        install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd);
        install_element(VIEW_NODE, &show_ipv6_nht_cmd);
        install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
index ed1c185f1a8280041a5276342802773778e4c120..20dc64b0bc95f68ff9ec5b9f466fa9e16c356afb 100644 (file)
@@ -8395,7 +8395,7 @@ int zebra_vxlan_if_add(struct interface *ifp)
                                "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
                                vni,
                                vlan_if ? vrf_id_to_name(vlan_if->vrf_id)
-                                       : "Default",
+                                       : VRF_DEFAULT_NAME,
                                ifp->name, ifp->ifindex, vxl->access_vlan,
                                inet_ntoa(vxl->vtep_ip),
                                zif->brslave_info.bridge_ifindex);
@@ -8864,14 +8864,14 @@ void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
 }
 
 /* init the l3vni table */
-void zebra_vxlan_ns_init(struct zebra_ns *zns)
+void zebra_vxlan_init(void)
 {
        zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
                                          "Zebra VRF L3 VNI table");
 }
 
 /* free l3vni table */
-void zebra_vxlan_ns_disable(struct zebra_ns *zns)
+void zebra_vxlan_disable(void)
 {
        hash_free(zrouter.l3vni_table);
 }
index eafc4812000888d6703dfeed58e5613cb88dc746..c50664a28ba45c346d420cde7b6fddcd78a2a376 100644 (file)
@@ -183,8 +183,8 @@ extern int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
 extern void zebra_vxlan_init_tables(struct zebra_vrf *zvrf);
 extern void zebra_vxlan_close_tables(struct zebra_vrf *);
 extern void zebra_vxlan_cleanup_tables(struct zebra_vrf *);
-extern void zebra_vxlan_ns_init(struct zebra_ns *zns);
-extern void zebra_vxlan_ns_disable(struct zebra_ns *zns);
+extern void zebra_vxlan_init(void);
+extern void zebra_vxlan_disable(void);
 extern void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id,
                                           struct ethaddr *rmac,
                                           struct ipaddr *ip,
index b40e9e2af51fff8688d09ba9a7fd3bd2e5d68f0a..a48505a5141074094f6cad73aa3779dd58e49aaa 100644 (file)
@@ -492,8 +492,8 @@ static int zserv_process_messages(struct thread *thread)
        struct zserv *client = THREAD_ARG(thread);
        struct stream *msg;
        struct stream_fifo *cache = stream_fifo_new();
-
        uint32_t p2p = zebrad.packets_to_process;
+       bool need_resched = false;
 
        pthread_mutex_lock(&client->ibuf_mtx);
        {
@@ -505,6 +505,12 @@ static int zserv_process_messages(struct thread *thread)
                }
 
                msg = NULL;
+
+               /* Need to reschedule processing work if there are still
+                * packets in the fifo.
+                */
+               if (stream_fifo_head(client->ibuf_fifo))
+                       need_resched = true;
        }
        pthread_mutex_unlock(&client->ibuf_mtx);
 
@@ -516,6 +522,10 @@ static int zserv_process_messages(struct thread *thread)
 
        stream_fifo_free(cache);
 
+       /* Reschedule ourselves if necessary */
+       if (need_resched)
+               zserv_event(client, ZSERV_PROCESS_MESSAGES);
+
        return 0;
 }
 
@@ -628,6 +638,7 @@ void zserv_close_client(struct zserv *client)
 
        thread_cancel_event(zebrad.master, client);
        THREAD_OFF(client->t_cleanup);
+       THREAD_OFF(client->t_process);
 
        /* destroy pthread */
        frr_pthread_destroy(client->pthread);
@@ -828,7 +839,7 @@ void zserv_event(struct zserv *client, enum zserv_event event)
                break;
        case ZSERV_PROCESS_MESSAGES:
                thread_add_event(zebrad.master, zserv_process_messages, client,
-                                0, NULL);
+                                0, &client->t_process);
                break;
        case ZSERV_HANDLE_CLIENT_FAIL:
                thread_add_event(zebrad.master, zserv_handle_client_fail,
index f7967f54f00b18e6afa5da7b5e4db12950ad21bd..439082e78a316786e012b35a48c4f3a4057523e8 100644 (file)
@@ -73,6 +73,9 @@ struct zserv {
        struct thread *t_read;
        struct thread *t_write;
 
+       /* Event for message processing, for the main pthread */
+       struct thread *t_process;
+
        /* Threads for the main pthread */
        struct thread *t_cleanup;
 
@@ -184,6 +187,7 @@ struct zebra_t {
 
 /* rib work queue */
 #define ZEBRA_RIB_PROCESS_HOLD_TIME 10
+#define ZEBRA_RIB_PROCESS_RETRY_TIME 5
        struct work_queue *ribq;
        struct meta_queue *mq;