+# 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
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
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
}
+++ /dev/null
- 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
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(
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);
}
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,
}
/* 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] =
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++;
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)
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)
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)
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.
*/
*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)
/* 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)
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;
*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)
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)
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;
/* 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);
}
/* 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);
}
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;
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;
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;
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;
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;
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;
*/
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.
*/
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;
|| 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.
*/
/* 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;
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)
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)
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)
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,
* 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)) {
/* 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. */
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,
/* 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)
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,
/* 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
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;
/* 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;
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)
/* 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;
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)
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;
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)
if (!rd_rn)
return;
- table = (struct bgp_table *)rd_rn->info;
+ table = bgp_node_get_bgp_table_info(rd_rn);
if (table == NULL)
return;
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,
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)
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;
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,
* 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;
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);
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++;
}
}
/*
* 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;
}
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;
}
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;
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,
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",
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) {
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 */
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)
#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");
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;
}
bnc_free(bnc);
- bgp_nexthop_set_node_info(rn, NULL);
+ bgp_node_set_bgp_nexthop_info(rn, NULL);
bgp_unlock_node(rn);
}
}
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)) {
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);
}
}
}
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);
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);
}
}
}
}
-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;
}
static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
- int detail)
+ int detail, bool import_table)
{
struct bgp *bgp;
return CMD_WARNING;
}
- bgp_show_nexthops(vty, bgp, detail);
+ bgp_show_nexthops(vty, bgp, detail, import_table);
return CMD_SUCCESS;
}
(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);
}
}
|| 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,
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);
}
}
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);
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;
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);
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",
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);
}
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];
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;
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;
if (!rn)
return;
- bnc = bgp_nexthop_get_node_info(rn);
+ bnc = bgp_node_get_bgp_nexthop_info(rn);
if (!bnc)
return;
|| (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);
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);
{
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);
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);
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))
/* 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;
}
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(
{
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);
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);
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)
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);
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);
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);
}
/* 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)
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;
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);
bgp_soft_reconfig_table(peer, afi, safi, table,
&prd);
}
+ }
}
/* 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;
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;
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)
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,
} 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))
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
{
afi_t afi;
struct bgp_node *rn;
+ struct bgp_table *table;
for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
if (afi == AFI_L2VPN)
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);
}
}
}
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);
}
}
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;
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;
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;
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;
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)) {
/* 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 {
/* 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. */
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;
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);
}
}
}
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);
}
}
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);
}
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)
}
}
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 {
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);
}
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
{
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;
* 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);
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)
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;
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;
/* 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,
/* 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,
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);
/* 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);
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);
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;
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;
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;
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();
if (path->extra->bgp_orig->inst_type
== BGP_INSTANCE_TYPE_DEFAULT)
- vn = "Default";
+ vn = VRF_DEFAULT_NAME;
else
vn = path->extra->bgp_orig->name;
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\" : {");
/* 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;
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
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);
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);
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;
}
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;
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;
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,
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,
if (rn == top)
continue;
- if (!rn->info)
+ if (!bgp_node_has_bgp_path_info_data(rn))
continue;
ts->counts[BGP_STATS_PREFIXES]++;
#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) {
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]++;
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;
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",
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);
"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);
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,
"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",
"%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,
/* 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. */
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) {
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);
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) {
/* 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) {
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;
!= 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;
/* 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;
/* 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;
/* 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;
/* 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;
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];
/* 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. */
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);
}
}
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;
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;
}
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
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;
}
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);
}
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)
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 */
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);
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;
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
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)
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
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;
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);
}
}
}
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
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");
}
}
}
- 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");
}
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
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) {
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
|| 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);
}
}
/* 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 */
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",
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);
}
* 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
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);
}
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);
}
/* debug */
if (VNC_DEBUG(VERBOSE)) {
- vnc_zlog_debug_verbose("%s: printing BI", __func__);
+ vnc_zlog_debug_verbose("%s: printing BPI", __func__);
rfapiPrintBi(NULL, new);
}
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);
}
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 */
}
}
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,
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) {
*/
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))
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;
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;
/*
* skip prefix list check if no routes here
*/
- if (!rn->info)
+ if (!bgp_node_has_bgp_path_info_data(rn))
continue;
{
}
}
- 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);
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;
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 */
struct bgp_table *table;
- table = (struct bgp_table *)(bnp->info);
+ table = bgp_node_get_bgp_table_info(bnp);
if (!table)
continue;
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 */
struct bgp_table *table;
- table = (struct bgp_table *)(bnp->info);
+ table = bgp_node_get_bgp_table_info(bnp);
if (!table)
continue;
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;
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;
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;
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;
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;
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;
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;
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
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])
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"
=====================================================================
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.
+++ /dev/null
-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.
-
+++ /dev/null
-../../ubuntu14.04/debian/frr.install
\ No newline at end of file
+++ /dev/null
-../../ubuntu14.04/debian/frr.postinst
\ No newline at end of file
+++ /dev/null
-../../ubuntu14.04/debian/frr.postrm
\ No newline at end of file
+++ /dev/null
-#!/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
+++ /dev/null
-3.0 (quilt)
+++ /dev/null
--1~ubuntu12.04+1
usr/bin/mtracebis
usr/include/frr/
usr/lib/
-tools/frr etc/init.d/
usr/share/doc/frr/
usr/share/snmp/mibs/
usr/share/yang/
+++ /dev/null
-#!/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#
-
+++ /dev/null
-#!/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#
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
# 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')
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 \
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
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
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
::
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
::
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
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
------------------------
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.
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
--------------------------
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:
+++ /dev/null
-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
eigrpd_eigrpd_SOURCES = eigrpd/eigrp_main.c
eigrpd_eigrpd_LDADD = eigrpd/libeigrp.a lib/libfrr.la @LIBCAP@
-
-EXTRA_DIST += eigrpd/EIGRP-MIB.txt
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)
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 \
#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
*
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;
}
{
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;
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);
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);
}
}
"Fabricd Neighbors");
rv->tier = rv->tier_config = ISIS_TIER_UNDEFINED;
+
+ rv->csnp_delay = FABRICD_DEFAULT_CSNP_DELAY;
return rv;
};
return;
isis_run_hopcount_spf(area, isis->sysid, f->spftree);
- neighbor_lists_update(f);
+ neighbors_neighbors_update(f);
fabricd_bump_tier_calculation_timer(f);
}
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)
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 */
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
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;
}
}
- 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;
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]);
}
}
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);
+}
#ifndef FABRICD_H
#define FABRICD_H
+#define FABRICD_DEFAULT_CSNP_DELAY 500
+
struct fabricd;
struct isis_circuit;
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
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++) {
#include "prefix.h"
#include "stream.h"
#include "qobj.h"
+#include "lib/northbound_cli.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
/*
* 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;
circuit->level_arg[i].level = i + 1;
circuit->level_arg[i].circuit = circuit;
}
+#endif /* ifndef FABRICD */
circuit->mtc = mpls_te_circuit_new();
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);
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) {
(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);
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)
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,
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 */
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);
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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_ */
if (lsp->pdu)
stream_free(lsp->pdu);
+
+ fabricd_lsp_free(lsp);
XFREE(MTYPE_ISIS_LSP, lsp);
}
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);
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);
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];
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 */
/* 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];
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);
"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;
}
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
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;
}
}
-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);
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);
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 */
#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"
/*
* 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)
{
},
};
+
static const struct frr_yang_module_info *isisd_yang_modules[] = {
&frr_interface_info,
+#ifndef FABRICD
+ &frr_isisd_info,
+#endif /* ifndef FABRICD */
};
#ifdef FABRICD
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();
isis_zebra_init(master);
isis_bfd_init();
+ fabricd_init();
frr_config_fork();
frr_run(master);
--- /dev/null
+/*
+ * 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,
+ },
+ }
+};
#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)
/* 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,
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
? "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,
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;
}
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;
}
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;
}
}
"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;
}
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;
}
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;
}
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;
}
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;
}
"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;
}
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
{
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)
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),
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;
}
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;
}
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:
} 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);
}
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;
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,
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)
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;
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';
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 */
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 =
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) {
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);
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;
}
"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;
}
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;
}
"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;
}
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);
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,
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;
|| 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);
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,
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 */
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,
/*
* 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;
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));
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);
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,
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);
--- /dev/null
+/*
+ * 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]);
+ }
+}
--- /dev/null
+/*
+ * 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
}
}
-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 =
}
}
-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);
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"
{
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;
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);
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;
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;
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"
"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);
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);
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;
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)
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 */
}
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
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",
/* 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;
[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;
/* 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,
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,
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;
#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;
};
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);
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));
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;
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);
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);
#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"
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",
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 */
}
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);
#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,
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);
}
+++ /dev/null
-/*
- * 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);
-}
#include "table.h"
#include "qobj.h"
#include "spf_backoff.h"
+#include "lib/northbound_cli.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
* 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);
*/
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
/*
* 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 */
area->newmetric = 1;
area->lsp_frag_threshold = 90;
area->lsp_mtu = DEFAULT_LSP_MTU;
+#endif /* ifndef FABRICD */
area_mt_init(area);
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;
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;
}
return CMD_SUCCESS;
}
+#ifdef FABRICD
static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid,
bool enabled)
{
0);
}
}
+#endif /* ifdef FABRICD */
int area_net_title(struct vty *vty, const char *net_title)
{
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);
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);
}
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++;
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++;
}
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",
}
}
+ 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
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
(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);
}
}
+ /*
+ * 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");
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,
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")
}
/*
- *'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
*/
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]",
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)
{
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)
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)
lsp_regenerate_schedule(area, level, 1);
}
+#ifdef FABRICD
DEFUN (log_adj_changes,
log_adj_changes_cmd,
"log-adjacency-changes",
return CMD_SUCCESS;
}
-
+#endif /* ifdef FABRICD */
+#ifdef FABRICD
/* IS-IS configuration write function */
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()
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);
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);
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);
install_element(ROUTER_NODE, &log_adj_changes_cmd);
install_element(ROUTER_NODE, &no_log_adj_changes_cmd);
+#endif /* ifdef FABRICD */
spf_backoff_cmd_init();
}
#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"
#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;
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 */
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;
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)
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);
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;
#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 { \
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
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 \
isisd/isisd.h \
isisd/iso_checksum.h \
isisd/fabricd.h \
+ isisd/isis_cli.h \
# end
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 \
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)
/*
* 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
/*
* 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
.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,
.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,
}
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,
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;
}
/*
* 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"
/*
* 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
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
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)";
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;
}
{
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;
/* 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. */
/* 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. */
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;
}
}
-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;
running_config = nb_config_new(NULL);
/* Initialize the northbound CLI. */
- nb_cli_init();
+ nb_cli_init(tm);
}
void nb_terminate(void)
#ifndef _FRR_NORTHBOUND_H_
#define _FRR_NORTHBOUND_H_
+#include "thread.h"
#include "hook.h"
#include "linklist.h"
#include "openbsd-tree.h"
* 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.
* 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.
};
/* 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. */
* 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);
/*
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)
{
}
change = &vty->cfg_changes[vty->num_cfg_changes++];
- change->xpath = xpath;
+ strlcpy(change->xpath, xpath, sizeof(change->xpath));
change->operation = operation;
change->value = value;
}
}
}
-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");
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);
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")
{
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;
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\
void nb_cli_install_default(int node)
{
+ install_element(node, &show_config_candidate_section_cmd);
+
if (frr_get_cli_mode() != FRR_CLI_TRANSACTIONAL)
return;
.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);
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_ */
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);
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++;
}
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. */
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;
break;
}
+ /* Reject the configuration changes. */
if (cdb_sub_abort_trans(cdb_sub_sock, errcode, 0, 0, "%s",
errmsg)
!= CONFD_OK) {
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)
{
{
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];
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);
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));
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;
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);
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;
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) {
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;
}
}
+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)
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) {
};
struct vty_cfg_change {
- const char *xpath;
+ char xpath[XPATH_MAXLEN];
enum nb_operation operation;
const char *value;
};
/* 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;
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;
}
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);
{
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;
#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;
/* 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,
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 */
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. */
{
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);
}
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];
#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
+++ /dev/null
- 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
+++ /dev/null
-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
+++ /dev/null
-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
"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;
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) {
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;
}
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");
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;
}
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");
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
EXTRA_DIST += \
ospfd/ChangeLog.opaque.txt \
- ospfd/OSPF-MIB.txt \
- ospfd/OSPF-TRAP-MIB.txt \
# end
# 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
# 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`;
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
}
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?
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
%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
+++ /dev/null
- 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
{
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
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;
extern unsigned long rip_debug_zebra;
extern void rip_debug_init(void);
-extern void rip_debug_reset(void);
#endif /* _ZEBRA_RIP_DEBUG_H */
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;
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);
return NB_OK;
yang_dnode_get_ipv4p(&p, dnode, NULL);
+ apply_mask_ipv4((struct prefix_ipv4 *)&p);
return rip_enable_network_add(&p);
}
return NB_OK;
yang_dnode_get_ipv4p(&p, dnode, NULL);
+ apply_mask_ipv4((struct prefix_ipv4 *)&p);
return rip_enable_network_delete(&p);
}
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;
}
return NB_OK;
yang_dnode_get_ipv4p(&p, dnode, NULL);
+ apply_mask_ipv4(&p);
memset(&nh, 0, sizeof(nh));
nh.type = NEXTHOP_TYPE_IPV4;
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);
#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()
{
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,
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;
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);
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
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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_ */
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;
extern unsigned long ripng_debug_zebra;
extern void ripng_debug_init(void);
-extern void ripng_debug_reset(void);
#endif /* _ZEBRA_RIPNG_DEBUG_H */
#include "privs.h"
#include "vrf.h"
#include "lib_errors.h"
+#include "northbound_cli.h"
#include "ripngd/ripngd.h"
#include "ripngd/ripng_debug.h"
}
}
-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;
}
/* 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;
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;
/* Unlock lookup lock. */
agg_unlock_node(node);
- return 1;
+ return NB_OK;
}
- return -1;
+
+ return NB_ERR_INCONSISTENCY;
}
/* Lookup function. */
}
/* 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);
ripng_enable_apply_all();
- return 1;
+ return NB_OK;
}
/* Wake up interface. */
}
/* 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);
ripng_passive_interface_apply_all();
- return CMD_SUCCESS;
+ return NB_OK;
}
/* Free all configured RIP passive-interface settings. */
}
/* 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;
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);
}
/* 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;
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;
}
{
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;
}
/* 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);
}
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. */
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,
/* RIPngd inits. */
ripng_init();
+ ripng_cli_init();
zebra_init(master);
ripng_peer_init();
--- /dev/null
+/*
+ * 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,
+ },
+ }
+};
#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)
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));
}
/* 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));
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)
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)
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;
}
#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();
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)
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;
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));
}
}
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)
#include "if_rmap.h"
#include "privs.h"
#include "lib_errors.h"
+#include "northbound_cli.h"
#include "ripngd/ripngd.h"
#include "ripngd/ripng_route.h"
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);
}
/* Create ripng socket. */
-static int ripng_make_socket(void)
+int ripng_make_socket(void)
{
int ret;
int sock;
}
/* 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);
/* 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);
/* 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);
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. */
/* 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,",
}
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,
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,
}
#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,
}
#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;
}
}
-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;
}
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);
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;
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);
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();
#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
#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. */
/* 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;
/* 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;
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];
};
/* 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
} \
} 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);
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);
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 *);
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,
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 */
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 \
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 \
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
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);
vty_init(master);
memory_init();
yang_init();
- nb_init(NULL, 0);
+ nb_init(master, NULL, 0);
/* OSPF vty inits. */
test_vty_init();
/* 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);
frr defaults @DFLT_NAME@\r
!\r
hostname test\r
+domainname test.domain\r
!\r
!\r
!\r
frr defaults @DFLT_NAME@\r
!\r
hostname foohost\r
+domainname test.domain\r
!\r
!\r
!\r
cmd_init(1);
yang_init();
- nb_init(NULL, 0);
+ nb_init(master, NULL, 0);
install_node(&bgp_node, NULL);
install_node(&rip_node, NULL);
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
*/
{
.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",
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);
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
+!
--- /dev/null
+#!/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
+
+
--- /dev/null
+#!/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))
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
!
hostname ce4
!
-interface lo
+interface ce4-cust2
ip address 99.0.0.4/32
!
interface ce4-eth0
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:
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)
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',
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')
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')
{'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)
########################################################################
]
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)
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
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
```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
+```
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.
|| 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" \
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)
# 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`.
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
return text
-def module_present(module, load=True):
+def module_present_linux(module, load):
"""
Returns whether `module` is present.
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:
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
))
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')
/gen_yang_deviations
/permutations
/ssd
+/watchfrr.sh
+/frrinit.sh
+/frrcommon.sh
"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) {
"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",
+++ /dev/null
-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"
# 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
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.
-#
-# 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.
service integrated-vtysh-config
-username cumulus nopassword
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))
# 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
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)"
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?
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
[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
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
--- /dev/null
+#!/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
+}
--- /dev/null
+#!/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
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
--- /dev/null
+#!/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 "$@"
return 0;
}
-void vtysh_pager_init(void)
+static void vtysh_pager_envdef(void)
{
char *pager_defined;
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,
/* "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);
void vtysh_config_init(void);
-void vtysh_pager_init(void);
-
void suid_on(void);
void suid_off(void);
exit(0);
}
- vtysh_pager_init();
-
vtysh_readline_init();
vty_hello(vty);
typedef enum {
PHASE_NONE = 0,
+ PHASE_INIT,
PHASE_STOPS_PENDING,
PHASE_WAITING_DOWN,
PHASE_ZEBRA_RESTART_PENDING,
} 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",
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,
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)
const char *name;
const char *what;
struct restart_info *restart;
+ struct daemon *dmn;
switch (child = waitpid(-1, &status, WNOHANG)) {
case -1:
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,
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))
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;
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");
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;
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.
*
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};
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);
}
--- /dev/null
+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";
+ }
+ }
+}
--- /dev/null
+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.";
+ }
+ }
+}
--- /dev/null
+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.";
+ }
+}
}
container routes {
list route {
- key "prefix";
-
leaf prefix {
type inet:ipv4-prefix;
}
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
char ifname[INTERFACE_NAMSIZ + 1];
short ifnlen = 0;
struct nexthop nh;
+ struct prefix p;
+ ifindex_t ifindex = 0;
+ afi_t afi;
zebra_flags = 0;
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;
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)
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)
}
#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
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
}
/* 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)) {
/*
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 */
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;
}
}
}
/* 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);
if (!nexthop)
continue;
- if (nexthop_num >= multipath_num)
- break;
-
if ((cmd == RTM_NEWROUTE
&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
&& CHECK_FLAG(nexthop->flags,
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)) {
break;
}
+ if (event->mask & IN_DELETE)
+ return zebra_ns_delete(event->name);
+
netnspath = ns_netns_pathname(NULL, event->name);
if (!netnspath)
continue;
/* Do any needed per-NS data structure allocation. */
zns->if_table = route_table_init();
- zebra_vxlan_ns_init(zns);
return 0;
}
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
/* 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();
/* 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;
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)
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;
*/
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;
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
/* 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;
}
* 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
/* 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
/* 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);
}
* 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
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);
}
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),
/* 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,
*/
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));
}
/* 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;
}
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);
#include "zebra_router.h"
#include "zebra_memory.h"
#include "zebra_pbr.h"
+#include "zebra_vxlan.h"
struct zebra_router zrouter;
zebra_router_free_table(zrt);
}
+ zebra_vxlan_disable();
hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
hash_free(zrouter.rules_hash);
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");
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,
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);
"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);
}
/* 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);
}
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,
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);
{
}
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);
stream_fifo_free(cache);
+ /* Reschedule ourselves if necessary */
+ if (need_resched)
+ zserv_event(client, ZSERV_PROCESS_MESSAGES);
+
return 0;
}
thread_cancel_event(zebrad.master, client);
THREAD_OFF(client->t_cleanup);
+ THREAD_OFF(client->t_process);
/* destroy pthread */
frr_pthread_destroy(client->pthread);
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,
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;
/* 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;