diff options
202 files changed, 12575 insertions, 14654 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index cedca17729..62d3c2350c 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,12 @@ +# HOW TO GET YOUR ISSUE ADDRESSED FASTER + +* When reporting a crash provide a backtrace +* When pasting configs, logs, shell output, backtraces, and other large chunks + of text [use Markdown code blocks](https://github.github.com/gfm/#fenced-code-blocks) +* Include the FRR version; if you built from Git, please provide the commit + hash +* Write your issue in English + ### How to submit an issue Please use this text as a template and replace text in the sections or remove the entire section if it does not apply to your issue. For example in case of diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c index 31778901a6..28ba8e16a2 100644 --- a/babeld/babel_filter.c +++ b/babeld/babel_filter.c @@ -39,10 +39,11 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen, struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); babel_interface_nfo *babel_ifp = ifp ? babel_get_if_nfo(ifp) : NULL; struct prefix p; - struct distribute *dist; + struct distribute *dist = NULL; struct access_list *alist; struct prefix_list *plist; int distribute; + struct babel *babel; p.family = v4mapped(prefix) ? AF_INET : AF_INET6; p.prefixlen = v4mapped(prefix) ? plen - 96 : plen; @@ -81,7 +82,9 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen, } /* All interface filter check. */ - dist = distribute_lookup (NULL); + babel = babel_lookup(); + if (babel) + dist = distribute_lookup (babel->distribute_ctx, NULL); if (dist) { if (dist->list[distribute]) { alist = access_list_lookup (p.family, dist->list[distribute]); diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 7121ca28d4..a8698bfce3 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -1248,11 +1248,16 @@ DEFUN (show_babel_parameters, "Babel information\n" "Configuration information\n") { + struct babel *babel_ctx; + vty_out (vty, " -- Babel running configuration --\n"); show_babel_main_configuration(vty); - vty_out (vty, " -- distribution lists --\n"); - config_show_distribute(vty); + babel_ctx = babel_lookup(); + if (babel_ctx) { + vty_out (vty, " -- distribution lists --\n"); + config_show_distribute(vty, babel_ctx->distribute_ctx); + } return CMD_SUCCESS; } diff --git a/babeld/babeld.c b/babeld/babeld.c index 0517cbea6d..702c1fbabb 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -53,7 +53,8 @@ static int babel_read_protocol (struct thread *thread); static int babel_main_loop(struct thread *thread); static void babel_set_timer(struct timeval *timeout); static void babel_fill_with_next_timeout(struct timeval *tv); - +static void +babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist); /* Informations relative to the babel running daemon. */ static struct babel *babel_routing_process = NULL; @@ -123,7 +124,7 @@ babel_config_write (struct vty *vty) } } - lines += config_write_distribute (vty); + lines += config_write_distribute (vty, babel_routing_process->distribute_ctx); return lines; } @@ -154,8 +155,12 @@ babel_create_routing_process (void) thread_add_read(master, &babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read); /* wait a little: zebra will announce interfaces, addresses, routes... */ thread_add_timer_msec(master, babel_init_routing_process, NULL, 200L, &babel_routing_process->t_update); - return 0; + /* Distribute list install. */ + babel_routing_process->distribute_ctx = distribute_list_ctx_create (vrf_lookup_by_id(VRF_DEFAULT)); + distribute_list_add_hook (babel_routing_process->distribute_ctx, babel_distribute_update); + distribute_list_delete_hook (babel_routing_process->distribute_ctx, babel_distribute_update); + return 0; fail: XFREE(MTYPE_BABEL, babel_routing_process); babel_routing_process = NULL; @@ -315,6 +320,7 @@ babel_clean_routing_process() thread_cancel(babel_routing_process->t_update); } + distribute_list_delete(&babel_routing_process->distribute_ctx); XFREE(MTYPE_BABEL, babel_routing_process); babel_routing_process = NULL; } @@ -539,7 +545,7 @@ resize_receive_buffer(int size) } static void -babel_distribute_update (struct distribute *dist) +babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist) { struct interface *ifp; babel_interface_nfo *babel_ifp; @@ -574,11 +580,12 @@ babel_distribute_update (struct distribute *dist) static void babel_distribute_update_interface (struct interface *ifp) { - struct distribute *dist; + struct distribute *dist = NULL; - dist = distribute_lookup (ifp->name); + if (babel_routing_process) + dist = distribute_lookup(babel_routing_process->distribute_ctx, ifp->name); if (dist) - babel_distribute_update (dist); + babel_distribute_update (babel_routing_process->distribute_ctx, dist); } /* Update all interface's distribute list. */ @@ -736,9 +743,7 @@ babeld_quagga_init(void) prefix_list_delete_hook (babel_distribute_update_all); /* Distribute list install. */ - distribute_list_init (BABEL_NODE); - distribute_list_add_hook (babel_distribute_update); - distribute_list_delete_hook (babel_distribute_update); + distribute_list_init(BABEL_NODE); } /* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */ @@ -767,3 +772,7 @@ redistribute_filter(const unsigned char *prefix, unsigned short plen, return 0; } +struct babel *babel_lookup(void) +{ + return babel_routing_process; +} diff --git a/babeld/babeld.h b/babeld/babeld.h index bc284c1e96..752cc8620a 100644 --- a/babeld/babeld.h +++ b/babeld/babeld.h @@ -111,6 +111,8 @@ struct babel /* Babel threads. */ struct thread *t_read; /* on Babel protocol's socket */ struct thread *t_update; /* timers */ + /* distribute_ctx */ + struct distribute_ctx *distribute_ctx; }; extern struct zebra_privs_t babeld_privs; @@ -125,6 +127,6 @@ extern int redistribute_filter(const unsigned char *prefix, unsigned short plen, unsigned int ifindex, int proto); extern int resize_receive_buffer(int size); extern void schedule_neighbours_check(int msecs, int override); - +extern struct babel *babel_lookup(void); #endif /* BABEL_BABELD_H */ diff --git a/bgpd/BGP4-MIB.txt b/bgpd/BGP4-MIB.txt deleted file mode 100644 index c911316c27..0000000000 --- a/bgpd/BGP4-MIB.txt +++ /dev/null @@ -1,929 +0,0 @@ - BGP4-MIB DEFINITIONS ::= BEGIN - - IMPORTS - MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, - IpAddress, Integer32, Counter32, Gauge32, mib-2 - FROM SNMPv2-SMI - MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP - FROM SNMPv2-CONF; - - bgp MODULE-IDENTITY - LAST-UPDATED "9902100000Z" - ORGANIZATION "IETF IDR Working Group" - CONTACT-INFO "E-mail: idr@merit.net - - Susan Hares (Editor) - Merit Network - 4251 Plymouth Road - Suite C - Ann Arbor, MI 48105-2785 - Tel: +1 734 936 2095 - Fax: +1 734 647 3185 - E-mail: skh@merit.edu - - Jeff Johnson (Editor) - RedBack Networks, Inc. - 1389 Moffett Park Drive - Sunnyvale, CA 94089-1134 - Tel: +1 408 548 3516 - Fax: +1 408 548 3599 - E-mail: jeff@redback.com" - DESCRIPTION - "The MIB module for BGP-4." - REVISION "9902100000Z" - DESCRIPTION - "Corrected duplicate OBJECT IDENTIFIER - assignment in the conformance information." - REVISION "9601080000Z" - DESCRIPTION - "1) Fixed the definitions of the traps to - make them equivalent to their initial - definition in RFC 1269. - 2) Added compliance and conformance info." - ::= { mib-2 15 } - - bgpVersion OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (1..255)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Vector of supported BGP protocol version - numbers. Each peer negotiates the version - from this vector. Versions are identified - via the string of bits contained within this - object. The first octet contains bits 0 to - 7, the second octet contains bits 8 to 15, - and so on, with the most significant bit - referring to the lowest bit number in the - octet (e.g., the MSB of the first octet - refers to bit 0). If a bit, i, is present - and set, then the version (i+1) of the BGP - is supported." - ::= { bgp 1 } - - bgpLocalAs OBJECT-TYPE - SYNTAX INTEGER (0..65535) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The local autonomous system number." - ::= { bgp 2 } - - - - -- BGP Peer table. This table contains, one entry per BGP - -- peer, information about the BGP peer. - - bgpPeerTable OBJECT-TYPE - SYNTAX SEQUENCE OF BgpPeerEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "BGP peer table. This table contains, - one entry per BGP peer, information about the - connections with BGP peers." - ::= { bgp 3 } - - bgpPeerEntry OBJECT-TYPE - SYNTAX BgpPeerEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Entry containing information about the - connection with a BGP peer." - INDEX { bgpPeerRemoteAddr } - ::= { bgpPeerTable 1 } - - BgpPeerEntry ::= SEQUENCE { - bgpPeerIdentifier - IpAddress, - bgpPeerState - INTEGER, - bgpPeerAdminStatus - INTEGER, - bgpPeerNegotiatedVersion - Integer32, - bgpPeerLocalAddr - IpAddress, - bgpPeerLocalPort - INTEGER, - bgpPeerRemoteAddr - IpAddress, - bgpPeerRemotePort - INTEGER, - bgpPeerRemoteAs - INTEGER, - bgpPeerInUpdates - Counter32, - bgpPeerOutUpdates - Counter32, - bgpPeerInTotalMessages - Counter32, - bgpPeerOutTotalMessages - Counter32, - bgpPeerLastError - OCTET STRING, - bgpPeerFsmEstablishedTransitions - Counter32, - bgpPeerFsmEstablishedTime - Gauge32, - bgpPeerConnectRetryInterval - INTEGER, - bgpPeerHoldTime - INTEGER, - bgpPeerKeepAlive - INTEGER, - bgpPeerHoldTimeConfigured - INTEGER, - bgpPeerKeepAliveConfigured - INTEGER, - bgpPeerMinASOriginationInterval - INTEGER, - bgpPeerMinRouteAdvertisementInterval - INTEGER, - bgpPeerInUpdateElapsedTime - Gauge32 - } - - bgpPeerIdentifier OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The BGP Identifier of this entry's BGP peer." - ::= { bgpPeerEntry 1 } - - bgpPeerState OBJECT-TYPE - SYNTAX INTEGER { - idle(1), - connect(2), - active(3), - opensent(4), - openconfirm(5), - established(6) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The BGP peer connection state." - ::= { bgpPeerEntry 2 } - - bgpPeerAdminStatus OBJECT-TYPE - SYNTAX INTEGER { - stop(1), - start(2) - } - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The desired state of the BGP connection. A - transition from 'stop' to 'start' will cause - the BGP Start Event to be generated. A - transition from 'start' to 'stop' will cause - the BGP Stop Event to be generated. This - parameter can be used to restart BGP peer - connections. Care should be used in providing - write access to this object without adequate - authentication." - ::= { bgpPeerEntry 3 } - - bgpPeerNegotiatedVersion OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The negotiated version of BGP running between - the two peers." - ::= { bgpPeerEntry 4 } - - bgpPeerLocalAddr OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The local IP address of this entry's BGP - connection." - ::= { bgpPeerEntry 5 } - - bgpPeerLocalPort OBJECT-TYPE - SYNTAX INTEGER (0..65535) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The local port for the TCP connection between - the BGP peers." - ::= { bgpPeerEntry 6 } - - bgpPeerRemoteAddr OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The remote IP address of this entry's BGP - peer." - ::= { bgpPeerEntry 7 } - - bgpPeerRemotePort OBJECT-TYPE - SYNTAX INTEGER (0..65535) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The remote port for the TCP connection between - the BGP peers. Note that the objects - bgpPeerLocalAddr, bgpPeerLocalPort, - bgpPeerRemoteAddr and bgpPeerRemotePort - provide the appropriate reference to the - standard MIB TCP connection table." - ::= { bgpPeerEntry 8 } - - bgpPeerRemoteAs OBJECT-TYPE - SYNTAX INTEGER (0..65535) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The remote autonomous system number." - ::= { bgpPeerEntry 9 } - - bgpPeerInUpdates OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of BGP UPDATE messages received on - this connection. This object should be - initialized to zero (0) when the connection is - established." - ::= { bgpPeerEntry 10 } - - bgpPeerOutUpdates OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of BGP UPDATE messages transmitted - on this connection. This object should be - initialized to zero (0) when the connection is - established." - ::= { bgpPeerEntry 11 } - - bgpPeerInTotalMessages OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of messages received from the - remote peer on this connection. This object - should be initialized to zero when the - connection is established." - ::= { bgpPeerEntry 12 } - - bgpPeerOutTotalMessages OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of messages transmitted to - the remote peer on this connection. This object - should be initialized to zero when the - connection is established." - ::= { bgpPeerEntry 13 } - - bgpPeerLastError OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (2)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The last error code and subcode seen by this - peer on this connection. If no error has - occurred, this field is zero. Otherwise, the - first byte of this two byte OCTET STRING - contains the error code, and the second byte - contains the subcode." - ::= { bgpPeerEntry 14 } - - bgpPeerFsmEstablishedTransitions OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of times the BGP FSM - transitioned into the established state." - ::= { bgpPeerEntry 15 } - - bgpPeerFsmEstablishedTime OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This timer indicates how long (in seconds) this - peer has been in the Established state or how long - since this peer was last in the Established state. - It is set to zero when a new peer is configured or - the router is booted." - ::= { bgpPeerEntry 16 } - - bgpPeerConnectRetryInterval OBJECT-TYPE - SYNTAX INTEGER (1..65535) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Time interval in seconds for the ConnectRetry - timer. The suggested value for this timer is - 120 seconds." - ::= { bgpPeerEntry 17 } - - bgpPeerHoldTime OBJECT-TYPE - SYNTAX INTEGER ( 0 | 3..65535 ) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Time interval in seconds for the Hold Timer - established with the peer. The value of this - object is calculated by this BGP speaker by - using the smaller of the value in - bgpPeerHoldTimeConfigured and the Hold Time - received in the OPEN message. This value - must be at lease three seconds if it is not - zero (0) in which case the Hold Timer has - not been established with the peer, or, the - value of bgpPeerHoldTimeConfigured is zero (0)." - ::= { bgpPeerEntry 18 } - - bgpPeerKeepAlive OBJECT-TYPE - SYNTAX INTEGER ( 0 | 1..21845 ) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Time interval in seconds for the KeepAlive - timer established with the peer. The value of - this object is calculated by this BGP speaker - such that, when compared with bgpPeerHoldTime, - it has the same proportion as what - bgpPeerKeepAliveConfigured has when compared - with bgpPeerHoldTimeConfigured. If the value - of this object is zero (0), it indicates that - the KeepAlive timer has not been established - with the peer, or, the value of - bgpPeerKeepAliveConfigured is zero (0)." - ::= { bgpPeerEntry 19 } - - bgpPeerHoldTimeConfigured OBJECT-TYPE - SYNTAX INTEGER ( 0 | 3..65535 ) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Time interval in seconds for the Hold Time - configured for this BGP speaker with this peer. - This value is placed in an OPEN message sent to - this peer by this BGP speaker, and is compared - with the Hold Time field in an OPEN message - received from the peer when determining the Hold - Time (bgpPeerHoldTime) with the peer. This value - must not be less than three seconds if it is not - zero (0) in which case the Hold Time is NOT to be - established with the peer. The suggested value for - this timer is 90 seconds." - ::= { bgpPeerEntry 20 } - - bgpPeerKeepAliveConfigured OBJECT-TYPE - SYNTAX INTEGER ( 0 | 1..21845 ) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Time interval in seconds for the KeepAlive timer - configured for this BGP speaker with this peer. - The value of this object will only determine the - KEEPALIVE messages' frequency relative to the value - specified in bgpPeerHoldTimeConfigured; the actual - time interval for the KEEPALIVE messages is - indicated by bgpPeerKeepAlive. A reasonable - maximum value for this timer would be configured to - be one third of that of bgpPeerHoldTimeConfigured. - If the value of this object is zero (0), no - periodical KEEPALIVE messages are sent to the peer - after the BGP connection has been established. The - suggested value for this timer is 30 seconds." - ::= { bgpPeerEntry 21 } - - bgpPeerMinASOriginationInterval OBJECT-TYPE - SYNTAX INTEGER (1..65535) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Time interval in seconds for the - MinASOriginationInterval timer. - The suggested value for this timer is 15 seconds." - ::= { bgpPeerEntry 22 } - - bgpPeerMinRouteAdvertisementInterval OBJECT-TYPE - SYNTAX INTEGER (1..65535) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Time interval in seconds for the - MinRouteAdvertisementInterval timer. - The suggested value for this timer is 30 seconds." - ::= { bgpPeerEntry 23 } - - bgpPeerInUpdateElapsedTime OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Elapsed time in seconds since the last BGP - UPDATE message was received from the peer. - Each time bgpPeerInUpdates is incremented, - the value of this object is set to zero (0)." - ::= { bgpPeerEntry 24 } - - - - bgpIdentifier OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The BGP Identifier of local system." - ::= { bgp 4 } - - - - -- Received Path Attribute Table. This table contains, - -- one entry per path to a network, path attributes - -- received from all peers running BGP version 3 or less. - -- This table is obsolete, having been replaced in - -- functionality with the bgp4PathAttrTable. - - bgpRcvdPathAttrTable OBJECT-TYPE - SYNTAX SEQUENCE OF BgpPathAttrEntry - MAX-ACCESS not-accessible - STATUS obsolete - DESCRIPTION - "The BGP Received Path Attribute Table contains - information about paths to destination networks - received from all peers running BGP version 3 or - less." - ::= { bgp 5 } - - bgpPathAttrEntry OBJECT-TYPE - SYNTAX BgpPathAttrEntry - MAX-ACCESS not-accessible - STATUS obsolete - DESCRIPTION - "Information about a path to a network." - INDEX { bgpPathAttrDestNetwork, - bgpPathAttrPeer } - ::= { bgpRcvdPathAttrTable 1 } - - BgpPathAttrEntry ::= SEQUENCE { - bgpPathAttrPeer - IpAddress, - bgpPathAttrDestNetwork - IpAddress, - bgpPathAttrOrigin - INTEGER, - bgpPathAttrASPath - OCTET STRING, - bgpPathAttrNextHop - IpAddress, - bgpPathAttrInterASMetric - Integer32 - } - - bgpPathAttrPeer OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The IP address of the peer where the path - information was learned." - ::= { bgpPathAttrEntry 1 } - - bgpPathAttrDestNetwork OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The address of the destination network." - ::= { bgpPathAttrEntry 2 } - - bgpPathAttrOrigin OBJECT-TYPE - SYNTAX INTEGER { - igp(1),-- networks are interior - egp(2),-- networks learned via EGP - incomplete(3) -- undetermined - } - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The ultimate origin of the path information." - ::= { bgpPathAttrEntry 3 } - - bgpPathAttrASPath OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (2..255)) - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The set of ASs that must be traversed to reach - the network. This object is probably best - represented as SEQUENCE OF INTEGER. For SMI - compatibility, though, it is represented as - OCTET STRING. Each AS is represented as a pair - of octets according to the following algorithm: - - first-byte-of-pair = ASNumber / 256; - second-byte-of-pair = ASNumber & 255;" - ::= { bgpPathAttrEntry 4 } - - bgpPathAttrNextHop OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The address of the border router that should - be used for the destination network." - ::= { bgpPathAttrEntry 5 } - - bgpPathAttrInterASMetric OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The optional inter-AS metric. If this - attribute has not been provided for this route, - the value for this object is 0." - ::= { bgpPathAttrEntry 6 } - - - - -- BGP-4 Received Path Attribute Table. This table contains, - -- one entry per path to a network, path attributes - -- received from all peers running BGP-4. - - bgp4PathAttrTable OBJECT-TYPE - SYNTAX SEQUENCE OF Bgp4PathAttrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The BGP-4 Received Path Attribute Table contains - information about paths to destination networks - received from all BGP4 peers." - ::= { bgp 6 } - - bgp4PathAttrEntry OBJECT-TYPE - SYNTAX Bgp4PathAttrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information about a path to a network." - INDEX { bgp4PathAttrIpAddrPrefix, - bgp4PathAttrIpAddrPrefixLen, - bgp4PathAttrPeer } - ::= { bgp4PathAttrTable 1 } - - Bgp4PathAttrEntry ::= SEQUENCE { - bgp4PathAttrPeer - IpAddress, - bgp4PathAttrIpAddrPrefixLen - INTEGER, - bgp4PathAttrIpAddrPrefix - IpAddress, - bgp4PathAttrOrigin - INTEGER, - bgp4PathAttrASPathSegment - OCTET STRING, - bgp4PathAttrNextHop - IpAddress, - bgp4PathAttrMultiExitDisc - INTEGER, - bgp4PathAttrLocalPref - INTEGER, - bgp4PathAttrAtomicAggregate - INTEGER, - bgp4PathAttrAggregatorAS - INTEGER, - bgp4PathAttrAggregatorAddr - IpAddress, - bgp4PathAttrCalcLocalPref - INTEGER, - bgp4PathAttrBest - INTEGER, - bgp4PathAttrUnknown - OCTET STRING - } - - bgp4PathAttrPeer OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP address of the peer where the path - information was learned." - ::= { bgp4PathAttrEntry 1 } - bgp4PathAttrIpAddrPrefixLen OBJECT-TYPE - SYNTAX INTEGER (0..32) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Length in bits of the IP address prefix in the - Network Layer Reachability Information field." - ::= { bgp4PathAttrEntry 2 } - - bgp4PathAttrIpAddrPrefix OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "An IP address prefix in the Network Layer - Reachability Information field. This object - is an IP address containing the prefix with - length specified by bgp4PathAttrIpAddrPrefixLen. - Any bits beyond the length specified by - bgp4PathAttrIpAddrPrefixLen are zeroed." - ::= { bgp4PathAttrEntry 3 } - - bgp4PathAttrOrigin OBJECT-TYPE - SYNTAX INTEGER { - igp(1),-- networks are interior - egp(2),-- networks learned via EGP - incomplete(3) -- undetermined - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The ultimate origin of the path information." - ::= { bgp4PathAttrEntry 4 } - - bgp4PathAttrASPathSegment OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (2..255)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The sequence of AS path segments. Each AS - path segment is represented by a triple - <type, length, value>. - - The type is a 1-octet field which has two - possible values: - 1 AS_SET: unordered set of ASs a - route in the UPDATE message - has traversed - 2 AS_SEQUENCE: ordered set of ASs - a route in the UPDATE message - has traversed. - - The length is a 1-octet field containing the - number of ASs in the value field. - - The value field contains one or more AS - numbers, each AS is represented in the octet - string as a pair of octets according to the - following algorithm: - - first-byte-of-pair = ASNumber / 256; - second-byte-of-pair = ASNumber & 255;" - ::= { bgp4PathAttrEntry 5 } - - bgp4PathAttrNextHop OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The address of the border router that should - be used for the destination network." - ::= { bgp4PathAttrEntry 6 } - - bgp4PathAttrMultiExitDisc OBJECT-TYPE - SYNTAX INTEGER (-1..2147483647) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This metric is used to discriminate between - multiple exit points to an adjacent autonomous - system. A value of -1 indicates the absence of - this attribute." - ::= { bgp4PathAttrEntry 7 } - - bgp4PathAttrLocalPref OBJECT-TYPE - SYNTAX INTEGER (-1..2147483647) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The originating BGP4 speaker's degree of - preference for an advertised route. A value of - -1 indicates the absence of this attribute." - ::= { bgp4PathAttrEntry 8 } - - bgp4PathAttrAtomicAggregate OBJECT-TYPE - SYNTAX INTEGER { - lessSpecificRrouteNotSelected(1), - lessSpecificRouteSelected(2) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Whether or not a system has selected - a less specific route without selecting a - more specific route." - ::= { bgp4PathAttrEntry 9 } - - bgp4PathAttrAggregatorAS OBJECT-TYPE - SYNTAX INTEGER (0..65535) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The AS number of the last BGP4 speaker that - performed route aggregation. A value of zero (0) - indicates the absence of this attribute." - ::= { bgp4PathAttrEntry 10 } - - bgp4PathAttrAggregatorAddr OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP address of the last BGP4 speaker that - performed route aggregation. A value of - 0.0.0.0 indicates the absence of this attribute." - ::= { bgp4PathAttrEntry 11 } - - bgp4PathAttrCalcLocalPref OBJECT-TYPE - SYNTAX INTEGER (-1..2147483647) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The degree of preference calculated by the - receiving BGP4 speaker for an advertised route. - A value of -1 indicates the absence of this - attribute." - ::= { bgp4PathAttrEntry 12 } - - bgp4PathAttrBest OBJECT-TYPE - SYNTAX INTEGER { - false(1),-- not chosen as best route - true(2) -- chosen as best route - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "An indication of whether or not this route - was chosen as the best BGP4 route." - ::= { bgp4PathAttrEntry 13 } - - bgp4PathAttrUnknown OBJECT-TYPE - SYNTAX OCTET STRING (SIZE(0..255)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "One or more path attributes not understood - by this BGP4 speaker. Size zero (0) indicates - the absence of such attribute(s). Octets - beyond the maximum size, if any, are not - recorded by this object." - ::= { bgp4PathAttrEntry 14 } - - - -- Traps. - - -- note that in RFC 1657, bgpTraps was incorrectly - -- assigned a value of { bgp 7 }, and each of the - -- traps had the bgpPeerRemoteAddr object inappropriately - -- removed from their OBJECTS clause. The following - -- definitions restore the semantics of the traps as - -- they were initially defined in RFC 1269. - - -- { bgp 7 } is unused - - bgpTraps OBJECT IDENTIFIER ::= { bgp 0 } - - bgpEstablished NOTIFICATION-TYPE - OBJECTS { bgpPeerRemoteAddr, - bgpPeerLastError, - bgpPeerState } - STATUS current - DESCRIPTION - "The BGP Established event is generated when - the BGP FSM enters the ESTABLISHED state." - ::= { bgpTraps 1 } - - bgpBackwardTransition NOTIFICATION-TYPE - OBJECTS { bgpPeerRemoteAddr, - bgpPeerLastError, - bgpPeerState } - STATUS current - DESCRIPTION - "The BGPBackwardTransition Event is generated - when the BGP FSM moves from a higher numbered - state to a lower numbered state." - ::= { bgpTraps 2 } - - -- conformance information - - bgpMIBConformance OBJECT IDENTIFIER ::= { bgp 8 } - bgpMIBCompliances OBJECT IDENTIFIER ::= { bgpMIBConformance 1 } - bgpMIBGroups OBJECT IDENTIFIER ::= { bgpMIBConformance 2 } - - -- compliance statements - - bgpMIBCompliance MODULE-COMPLIANCE - STATUS current - DESCRIPTION - "The compliance statement for entities which - implement the BGP4 mib." - MODULE -- this module - MANDATORY-GROUPS { bgp4MIBGlobalsGroup, - bgp4MIBPeerGroup, - bgp4MIBPathAttrGroup, - bgp4MIBNotificationGroup } - ::= { bgpMIBCompliances 1 } - - -- units of conformance - - bgp4MIBGlobalsGroup OBJECT-GROUP - OBJECTS { bgpVersion, - bgpLocalAs, - bgpIdentifier } - STATUS current - DESCRIPTION - "A collection of objects providing information - on global BGP state." - ::= { bgpMIBGroups 1 } - - bgp4MIBPeerGroup OBJECT-GROUP - OBJECTS { bgpPeerIdentifier, - bgpPeerState, - bgpPeerAdminStatus, - bgpPeerNegotiatedVersion, - bgpPeerLocalAddr, - bgpPeerLocalPort, - bgpPeerRemoteAddr, - bgpPeerRemotePort, - bgpPeerRemoteAs, - bgpPeerInUpdates, - bgpPeerOutUpdates, - bgpPeerInTotalMessages, - bgpPeerOutTotalMessages, - bgpPeerLastError, - bgpPeerFsmEstablishedTransitions, - bgpPeerFsmEstablishedTime, - bgpPeerConnectRetryInterval, - bgpPeerHoldTime, - bgpPeerKeepAlive, - bgpPeerHoldTimeConfigured, - bgpPeerKeepAliveConfigured, - bgpPeerMinASOriginationInterval, - bgpPeerMinRouteAdvertisementInterval, - bgpPeerInUpdateElapsedTime } - STATUS current - DESCRIPTION - "A collection of objects for managing - BGP peers." - ::= { bgpMIBGroups 2 } - - bgp4MIBRcvdPathAttrGroup OBJECT-GROUP - OBJECTS { bgpPathAttrPeer, - bgpPathAttrDestNetwork, - bgpPathAttrOrigin, - bgpPathAttrASPath, - bgpPathAttrNextHop, - bgpPathAttrInterASMetric } - STATUS obsolete - DESCRIPTION - "A collection of objects for managing BGP - path entries. - - This conformance group is obsolete, - replaced by bgp4MIBPathAttrGroup." - ::= { bgpMIBGroups 3 } - - bgp4MIBPathAttrGroup OBJECT-GROUP - OBJECTS { bgp4PathAttrPeer, - bgp4PathAttrIpAddrPrefixLen, - bgp4PathAttrIpAddrPrefix, - bgp4PathAttrOrigin, - bgp4PathAttrASPathSegment, - bgp4PathAttrNextHop, - bgp4PathAttrMultiExitDisc, - bgp4PathAttrLocalPref, - bgp4PathAttrAtomicAggregate, - bgp4PathAttrAggregatorAS, - bgp4PathAttrAggregatorAddr, - bgp4PathAttrCalcLocalPref, - bgp4PathAttrBest, - bgp4PathAttrUnknown } - STATUS current - DESCRIPTION - "A collection of objects for managing - BGP path entries." - ::= { bgpMIBGroups 4 } - - bgp4MIBNotificationGroup NOTIFICATION-GROUP - NOTIFICATIONS { bgpEstablished, - bgpBackwardTransition } - STATUS current - DESCRIPTION - "A collection of notifications for signaling - changes in BGP peer relationships." - ::= { bgpMIBGroups 5 } - - END diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 033525c91c..03f31eddfc 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -78,7 +78,7 @@ static const struct message attr_str[] = { {BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT"}, {BGP_ATTR_PMSI_TUNNEL, "PMSI_TUNNEL_ATTRIBUTE"}, {BGP_ATTR_ENCAP, "ENCAP"}, -#if ENABLE_BGP_VNC +#if ENABLE_BGP_VNC_ATTR {BGP_ATTR_VNC, "VNC"}, #endif {BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY"}, @@ -2593,7 +2593,7 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, case BGP_ATTR_EXT_COMMUNITIES: ret = bgp_attr_ext_communities(&attr_args); break; -#if ENABLE_BGP_VNC +#if ENABLE_BGP_VNC_ATTR case BGP_ATTR_VNC: #endif case BGP_ATTR_ENCAP: @@ -2946,7 +2946,7 @@ static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer, attrhdrlen = 1 + 1; /* subTLV T + L */ break; -#if ENABLE_BGP_VNC +#if ENABLE_BGP_VNC_ATTR case BGP_ATTR_VNC: attrname = "VNC"; subtlvs = attr->vnc_subtlvs; @@ -3433,7 +3433,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, /* Tunnel Encap attribute */ bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP); -#if ENABLE_BGP_VNC +#if ENABLE_BGP_VNC_ATTR /* VNC attribute */ bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC); #endif diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index da91f4623c..7f6d34808f 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5459,11 +5459,16 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, if (filter) SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY); - /* auto derive RD/RT */ + /* Map auto derive or configured RTs */ if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) evpn_auto_rt_import_add_for_vrf(bgp_vrf); + else + bgp_evpn_map_vrf_to_its_rts(bgp_vrf); + if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) evpn_auto_rt_export_add_for_vrf(bgp_vrf); + + /* auto derive RD */ bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf); /* link all corresponding l2vnis */ @@ -5531,12 +5536,16 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) /* remove the Rmac from the BGP vrf */ memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr)); - /* delete RD/RT */ + /* remove default import RT or Unmap non-default import RT */ if (!list_isempty(bgp_vrf->vrf_import_rtl)) { bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf); - list_delete_all_node(bgp_vrf->vrf_import_rtl); + if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) + list_delete_all_node(bgp_vrf->vrf_import_rtl); } - if (!list_isempty(bgp_vrf->vrf_export_rtl)) { + + /* remove default export RT */ + if (!list_isempty(bgp_vrf->vrf_export_rtl) && + !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) { list_delete_all_node(bgp_vrf->vrf_export_rtl); } diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index c6db45d7d3..776f8f8ef7 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2883,6 +2883,12 @@ DEFUN (bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "This command is only supported under Default VRF\n"); + return CMD_WARNING; + } + evpn_set_advertise_default_gw(bgp, NULL); return CMD_SUCCESS; @@ -2899,6 +2905,12 @@ DEFUN (no_bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "This command is only supported under Default VRF\n"); + return CMD_WARNING; + } + evpn_unset_advertise_default_gw(bgp, NULL); return CMD_SUCCESS; @@ -3011,6 +3023,12 @@ DEFPY (dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; + if (bgp_vrf->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "This command is only supported under Default VRF\n"); + return CMD_WARNING; + } + bgp_vrf->evpn_info->dup_addr_detect = true; if (time_val) @@ -3037,6 +3055,12 @@ DEFPY (dup_addr_detection_auto_recovery, if (!bgp_vrf) return CMD_WARNING; + if (bgp_vrf->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "This command is only supported under Default VRF\n"); + return CMD_WARNING; + } + bgp_vrf->evpn_info->dup_addr_detect = true; bgp_vrf->evpn_info->dad_freeze = true; bgp_vrf->evpn_info->dad_freeze_time = freeze_time; @@ -3066,6 +3090,12 @@ DEFPY (no_dup_addr_detection, if (!bgp_vrf) return CMD_WARNING; + if (bgp_vrf->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "This command is only supported under Default VRF\n"); + return CMD_WARNING; + } + if (argc == 2) { if (!bgp_vrf->evpn_info->dup_addr_detect) return CMD_SUCCESS; @@ -5104,7 +5134,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi, ecom)) { ecom_str = ecommunity_ecom2str( ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out(vty, " route-target import %s\n", ecom_str); + vty_out(vty, " route-target import %s\n", ecom_str); XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); } } @@ -5119,7 +5149,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi, ecom)) { ecom_str = ecommunity_ecom2str( ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out(vty, " route-target export %s\n", ecom_str); + vty_out(vty, " route-target export %s\n", ecom_str); XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); } } diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c index c6386dcdb5..cd5bec6267 100644 --- a/bgpd/bgp_flowspec_util.c +++ b/bgpd/bgp_flowspec_util.c @@ -23,6 +23,7 @@ #include "prefix.h" #include "lib_errors.h" +#include "bgp_route.h" #include "bgp_table.h" #include "bgp_flowspec_util.h" #include "bgp_flowspec_private.h" @@ -581,3 +582,27 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len, } return error; } + +/* return 1 if FS entry invalid or no NH IP */ +int bgp_flowspec_get_first_nh(struct bgp *bgp, struct bgp_path_info *pi, + struct prefix *p) +{ + struct bgp_pbr_entry_main api; + int i; + struct bgp_node *rn = pi->net; + struct bgp_pbr_entry_action *api_action; + + memset(&api, 0, sizeof(struct bgp_pbr_entry_main)); + if (bgp_pbr_build_and_validate_entry(&rn->p, pi, &api) < 0) + return 1; + for (i = 0; i < api.action_num; i++) { + api_action = &api.actions[i]; + if (api_action->action != ACTION_REDIRECT_IP) + continue; + p->family = AF_INET; + p->prefixlen = IPV4_MAX_BITLEN; + p->u.prefix4 = api_action->u.zr.redirect_ip_v4; + return 0; + } + return 1; +} diff --git a/bgpd/bgp_flowspec_util.h b/bgpd/bgp_flowspec_util.h index 9bf05847d3..2ce911da4e 100644 --- a/bgpd/bgp_flowspec_util.h +++ b/bgpd/bgp_flowspec_util.h @@ -54,4 +54,8 @@ extern bool bgp_flowspec_contains_prefix(struct prefix *pfs, struct prefix *input, int prefix_check); +extern int bgp_flowspec_get_first_nh(struct bgp *bgp, + struct bgp_path_info *pi, + struct prefix *nh); + #endif /* _FRR_BGP_FLOWSPEC_UTIL_H */ diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index dcaaea6868..a219c407da 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -120,20 +120,141 @@ mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi, return rn->local_label; } +/** + * This is passed as the callback function to bgp_labelpool.c:bgp_lp_get() + * by bgp_reg_dereg_for_label() when a label needs to be obtained from + * label pool. + * Note that it will reject the allocated label if a label index is found, + * because the label index supposes predictable labels + */ +int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid, + bool allocated) +{ + struct bgp_path_info *pi = (struct bgp_path_info *)labelid; + struct bgp_node *rn = (struct bgp_node *)pi->net; + char addr[PREFIX_STRLEN]; + + prefix2str(&rn->p, addr, PREFIX_STRLEN); + + if (BGP_DEBUG(labelpool, LABELPOOL)) + zlog_debug("%s: FEC %s label=%u, allocated=%d", __func__, addr, + new_label, allocated); + + if (!allocated) { + /* + * previously-allocated label is now invalid + */ + if (pi->attr->label_index == MPLS_INVALID_LABEL_INDEX + && pi->attr->label != MPLS_LABEL_NONE + && CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) { + bgp_unregister_for_label(rn); + label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1, + &rn->local_label); + bgp_set_valid_label(&rn->local_label); + } + return 0; + } + + /* + * label index is assigned, this should be handled by SR-related code, + * so retry FEC registration and then reject label allocation for + * it to be released to label pool + */ + if (pi->attr->label_index != MPLS_INVALID_LABEL_INDEX) { + flog_err( + EC_BGP_LABEL, + "%s: FEC %s Rejecting allocated label %u as Label Index is %u", + __func__, addr, new_label, pi->attr->label_index); + + bgp_register_for_label(pi->net, pi); + + return -1; + } + + if (pi->attr->label != MPLS_INVALID_LABEL) { + if (new_label == pi->attr->label) { + /* already have same label, accept but do nothing */ + return 0; + } + /* Shouldn't happen: different label allocation */ + flog_err(EC_BGP_LABEL, + "%s: %s had label %u but got new assignment %u", + __func__, addr, pi->attr->label, new_label); + /* continue means use new one */ + } + + label_ntop(new_label, 1, &rn->local_label); + bgp_set_valid_label(&rn->local_label); + + /* + * Get back to registering the FEC + */ + bgp_register_for_label(pi->net, pi); + + return 0; +} + void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi, - int reg) + bool reg) { + bool with_label_index = false; struct stream *s; struct prefix *p; + mpls_label_t *local_label; int command; uint16_t flags = 0; size_t flags_pos = 0; + char addr[PREFIX_STRLEN]; + + p = &(rn->p); + local_label = &(rn->local_label); + /* this prevents the loop when we're called by + * bgp_reg_for_label_callback() + */ + bool have_label_to_reg = bgp_is_valid_label(local_label) + && label_pton(local_label) != MPLS_LABEL_IMPLICIT_NULL; + + if (reg) { + assert(pi); + /* + * Determine if we will let zebra should derive label from + * label index instead of bgpd requesting from label pool + */ + if (CHECK_FLAG(pi->attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) + && pi->attr->label_index != BGP_INVALID_LABEL_INDEX) { + with_label_index = true; + } else { + /* + * If no label index was provided -- assume any label + * from label pool will do. This means that label index + * always takes precedence over auto-assigned labels. + */ + if (!have_label_to_reg) { + if (BGP_DEBUG(labelpool, LABELPOOL)) { + prefix2str(p, addr, PREFIX_STRLEN); + zlog_debug("%s: Requesting label from LP for %s", + __func__, addr); + } + /* bgp_reg_for_label_callback() will call back + * __func__ when it gets a label from the pool. + * This means we'll never register FECs without + * valid labels. + */ + bgp_lp_get(LP_TYPE_BGP_LU, pi, + bgp_reg_for_label_callback); + return; + } + } + } /* Check socket. */ if (!zclient || zclient->sock < 0) return; - p = &(rn->p); + /* If the route node has a local_label assigned or the + * path node has an MPLS SR label index allowing zebra to + * derive the label, proceed with registration. */ s = zclient->obuf; stream_reset(s); command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER; @@ -143,12 +264,12 @@ void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi, stream_putw(s, PREFIX_FAMILY(p)); stream_put_prefix(s, p); if (reg) { - assert(pi); - if (pi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) { - if (pi->attr->label_index != BGP_INVALID_LABEL_INDEX) { - flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX; - stream_putl(s, pi->attr->label_index); - } + if (have_label_to_reg) { + flags |= ZEBRA_FEC_REGISTER_LABEL; + stream_putl(s, label_pton(local_label)); + } else if (with_label_index) { + flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX; + stream_putl(s, pi->attr->label_index); } SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL); } else diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h index b0fc07e547..89bc9aabb0 100644 --- a/bgpd/bgp_label.h +++ b/bgpd/bgp_label.h @@ -30,8 +30,10 @@ struct bgp_node; struct bgp_path_info; struct peer; +extern int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid, + bool allocated); extern void bgp_reg_dereg_for_label(struct bgp_node *rn, - struct bgp_path_info *pi, int reg); + struct bgp_path_info *pi, bool reg); extern int bgp_parse_fec_update(void); extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_path_info *pi, struct peer *to, afi_t afi, safi_t safi); @@ -87,12 +89,12 @@ static inline void bgp_unset_valid_label(mpls_label_t *label) static inline void bgp_register_for_label(struct bgp_node *rn, struct bgp_path_info *pi) { - bgp_reg_dereg_for_label(rn, pi, 1); + bgp_reg_dereg_for_label(rn, pi, true); } static inline void bgp_unregister_for_label(struct bgp_node *rn) { - bgp_reg_dereg_for_label(rn, NULL, 0); + bgp_reg_dereg_for_label(rn, NULL, false); } /* Label stream to value */ diff --git a/bgpd/bgp_labelpool.h b/bgpd/bgp_labelpool.h index fa35cde0e1..0507e65489 100644 --- a/bgpd/bgp_labelpool.h +++ b/bgpd/bgp_labelpool.h @@ -29,6 +29,7 @@ * Types used in bgp_lp_get for debug tracking; add more as needed */ #define LP_TYPE_VRF 0x00000001 +#define LP_TYPE_BGP_LU 0x00000002 struct labelpool { struct skiplist *ledger; /* all requests */ diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 30d786fcda..70d3d7b69c 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -586,20 +586,28 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp, } } -static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail) +static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail, + bool import_table) { struct bgp_node *rn; struct bgp_nexthop_cache *bnc; char buf[PREFIX2STR_BUFFER]; time_t tbuf; afi_t afi; + struct bgp_table **table; - vty_out(vty, "Current BGP nexthop cache:\n"); + if (import_table) + vty_out(vty, "Current BGP import check cache:\n"); + else + vty_out(vty, "Current BGP nexthop cache:\n"); + if (import_table) + table = bgp->import_check_table; + else + table = bgp->nexthop_cache_table; for (afi = AFI_IP; afi < AFI_MAX; afi++) { - if (!bgp->nexthop_cache_table[afi]) + if (!table || !table[afi]) continue; - - for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn; + for (rn = bgp_table_top(table[afi]); rn; rn = bgp_route_next(rn)) { bnc = bgp_node_get_bgp_nexthop_info(rn); if (!bnc) @@ -638,7 +646,7 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail) } static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name, - int detail) + int detail, bool import_table) { struct bgp *bgp; @@ -651,7 +659,7 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name, return CMD_WARNING; } - bgp_show_nexthops(vty, bgp, detail); + bgp_show_nexthops(vty, bgp, detail, import_table); return CMD_SUCCESS; } @@ -666,7 +674,7 @@ static void bgp_show_all_instances_nexthops_vty(struct vty *vty) (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT_NAME : bgp->name); - bgp_show_nexthops(vty, bgp, 0); + bgp_show_nexthops(vty, bgp, 0, false); } } @@ -687,7 +695,28 @@ DEFUN (show_ip_bgp_nexthop, || argv_find(argv, argc, "vrf", &idx)) vrf = argv[++idx]->arg; int detail = argv_find(argv, argc, "detail", &idx) ? 1 : 0; - return show_ip_bgp_nexthop_table(vty, vrf, detail); + + return show_ip_bgp_nexthop_table(vty, vrf, detail, false); +} + +DEFUN (show_ip_bgp_import_check, + show_ip_bgp_import_check_cmd, + "show [ip] bgp [<view|vrf> VIEWVRFNAME] import-check-table [detail]", + SHOW_STR + IP_STR + BGP_STR + BGP_INSTANCE_HELP_STR + "BGP import check table\n" + "Show detailed information\n") +{ + int idx = 0; + char *vrf = NULL; + + if (argv_find(argv, argc, "view", &idx) + || argv_find(argv, argc, "vrf", &idx)) + vrf = argv[++idx]->arg; + int detail = argv_find(argv, argc, "detail", &idx) ? 1 : 0; + return show_ip_bgp_nexthop_table(vty, vrf, detail, true); } DEFUN (show_ip_bgp_instance_all_nexthop, @@ -720,6 +749,7 @@ void bgp_scan_init(struct bgp *bgp) void bgp_scan_vty_init(void) { install_element(VIEW_NODE, &show_ip_bgp_nexthop_cmd); + install_element(VIEW_NODE, &show_ip_bgp_import_check_cmd); install_element(VIEW_NODE, &show_ip_bgp_instance_all_nexthop_cmd); } diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index b6ef5a55c5..2b4ad22b93 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -42,6 +42,7 @@ #include "bgpd/bgp_nht.h" #include "bgpd/bgp_fsm.h" #include "bgpd/bgp_zebra.h" +#include "bgpd/bgp_flowspec_util.h" extern struct zclient *zclient; @@ -533,7 +534,15 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) && (pi->sub_type == BGP_ROUTE_STATIC)) ? 1 : 0; - + struct bgp_node *net = pi->net; + struct prefix *p_orig = &net->p; + + if (p_orig->family == AF_FLOWSPEC) { + if (!pi->peer) + return -1; + return bgp_flowspec_get_first_nh(pi->peer->bgp, + pi, p); + } memset(p, 0, sizeof(struct prefix)); switch (afi) { case AFI_IP: diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 73a07c8232..7b76d7e83e 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1612,6 +1612,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) } if (afi && peer->afc[afi][safi]) { + struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id); + /* End-of-RIB received */ if (!CHECK_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EOR_RECEIVED)) { @@ -1624,11 +1626,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) if (peer->nsf[afi][safi]) bgp_clear_stale_route(peer, afi, safi); - if (bgp_debug_neighbor_events(peer)) { - zlog_debug("rcvd End-of-RIB for %s from %s", - afi_safi_print(afi, safi), - peer->host); - } + zlog_info("%%NOTIFICATION: rcvd End-of-RIB for %s from %s in vrf %s", + afi_safi_print(afi, safi), peer->host, + vrf ? vrf->name : VRF_DEFAULT_NAME); } } diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index f0a0e615e6..f002154701 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -626,7 +626,7 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api) } /* return -1 if build or validation failed */ -static int bgp_pbr_build_and_validate_entry(struct prefix *p, +int bgp_pbr_build_and_validate_entry(struct prefix *p, struct bgp_path_info *path, struct bgp_pbr_entry_main *api) { diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h index 84095f9ab9..45c3c9ea13 100644 --- a/bgpd/bgp_pbr.h +++ b/bgpd/bgp_pbr.h @@ -290,4 +290,7 @@ extern void bgp_pbr_reset(struct bgp *bgp, afi_t afi); extern struct bgp_pbr_interface *bgp_pbr_interface_lookup(const char *name, struct bgp_pbr_interface_head *head); +extern int bgp_pbr_build_and_validate_entry(struct prefix *p, + struct bgp_path_info *path, + struct bgp_pbr_entry_main *api); #endif /* __BGP_PBR_H__ */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8293ea5451..3561674700 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2266,20 +2266,26 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, /* Do we need to allocate or free labels? * Right now, since we only deal with per-prefix labels, it is not - * necessary to do this upon changes to best path except if the label - * index changes + * necessary to do this upon changes to best path. Exceptions: + * - label index has changed -> recalculate resulting label + * - path_info sub_type changed -> switch to/from implicit-null + * - no valid label (due to removed static label binding) -> get new one */ if (bgp->allocate_mpls_labels[afi][safi]) { if (new_select) { if (!old_select || bgp_label_index_differs(new_select, old_select) - || new_select->sub_type != old_select->sub_type) { + || new_select->sub_type != old_select->sub_type + || !bgp_is_valid_label(&rn->local_label)) { + /* Enforced penultimate hop popping: + * implicit-null for local routes, aggregate + * and redistributed routes + */ if (new_select->sub_type == BGP_ROUTE_STATIC - && new_select->attr->flag - & ATTR_FLAG_BIT( - BGP_ATTR_PREFIX_SID) - && new_select->attr->label_index - != BGP_INVALID_LABEL_INDEX) { + || new_select->sub_type + == BGP_ROUTE_AGGREGATE + || new_select->sub_type + == BGP_ROUTE_REDISTRIBUTE) { if (CHECK_FLAG( rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) @@ -6593,7 +6599,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false; bool nexthop_othervrf = false; vrf_id_t nexthop_vrfid = VRF_DEFAULT; - const char *nexthop_vrfname = "Default"; + const char *nexthop_vrfname = VRF_DEFAULT_NAME; if (json_paths) json_path = json_object_new_object(); @@ -7875,7 +7881,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, if (path->extra->bgp_orig->inst_type == BGP_INSTANCE_TYPE_DEFAULT) - vn = "Default"; + vn = VRF_DEFAULT_NAME; else vn = path->extra->bgp_orig->name; @@ -8456,12 +8462,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (use_json && !*json_header_depth) { vty_out(vty, "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64 - ",\n \"routerId\": \"%s\",\n \"routes\": { ", + ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n" + " \"localAS\": %u,\n \"routes\": { ", bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? VRF_DEFAULT_NAME : bgp->name, - table->version, inet_ntoa(bgp->router_id)); + table->version, inet_ntoa(bgp->router_id), + bgp->default_local_pref, bgp->as); *json_header_depth = 2; if (rd) { vty_out(vty, " \"routeDistinguishers\" : {"); @@ -8629,6 +8637,9 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, else vty_out(vty, "%u", bgp->vrf_id); vty_out(vty, "\n"); + vty_out(vty, "Default local pref %u, ", + bgp->default_local_pref); + vty_out(vty, "local AS %u\n", bgp->as); vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_NCODE_HEADER); vty_out(vty, BGP_SHOW_OCODE_HEADER); @@ -9530,9 +9541,16 @@ DEFUN (show_ip_bgp_json, } if (argv_find(argv, argc, "community", &idx)) { - char *maybecomm = idx + 1 < argc ? argv[idx + 1]->text : NULL; + char *maybecomm = NULL; char *community = NULL; + if (idx + 1 < argc) { + if (argv[idx + 1]->type == VARIABLE_TKN) + maybecomm = argv[idx + 1]->arg; + else + maybecomm = argv[idx + 1]->text; + } + if (maybecomm && !strmatch(maybecomm, "json") && !strmatch(maybecomm, "exact-match")) community = maybecomm; @@ -10489,6 +10507,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, table->version); json_object_string_add(json, "bgpLocalRouterId", inet_ntoa(bgp->router_id)); + json_object_int_add(json, "defaultLocPrf", + bgp->default_local_pref); + json_object_int_add(json, "localAS", bgp->as); json_object_object_add(json, "bgpStatusCodes", json_scode); json_object_object_add(json, "bgpOriginCodes", @@ -10505,6 +10526,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, else vty_out(vty, "%u", bgp->vrf_id); vty_out(vty, "\n"); + vty_out(vty, "Default local pref %u, ", + bgp->default_local_pref); + vty_out(vty, "local AS %u\n", bgp->as); vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_NCODE_HEADER); vty_out(vty, BGP_SHOW_OCODE_HEADER); @@ -10532,6 +10556,11 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, "bgpLocalRouterId", inet_ntoa( bgp->router_id)); + json_object_int_add(json, + "defaultLocPrf", + bgp->default_local_pref); + json_object_int_add(json, + "localAS", bgp->as); json_object_object_add( json, "bgpStatusCodes", json_scode); @@ -10551,6 +10580,11 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, 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); @@ -10611,6 +10645,13 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, "bgpLocalRouterId", inet_ntoa( bgp->router_id)); + json_object_int_add( + json, "defaultLocPrf", + bgp->default_local_pref + ); + json_object_int_add( + json, "localAS", + bgp->as); json_object_object_add( json, "bgpStatusCodes", @@ -10637,6 +10678,13 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, 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); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index a308e8fec6..30159f9023 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -4200,6 +4200,13 @@ DEFUN (no_set_community, "community", NULL); } +ALIAS (no_set_community, + no_set_community_short_cmd, + "no set community", + NO_STR + SET_STR + "BGP community attribute\n") + DEFUN (set_community_delete, set_community_delete_cmd, @@ -4294,6 +4301,13 @@ DEFUN (no_set_lcommunity1, "large-community", NULL); } +ALIAS (no_set_lcommunity1, + no_set_lcommunity1_short_cmd, + "no set large-community", + NO_STR + SET_STR + "BGP large community attribute\n") + DEFUN (set_lcommunity_delete, set_lcommunity_delete_cmd, "set large-comm-list <(1-99)|(100-500)|WORD> delete", @@ -4332,6 +4346,13 @@ DEFUN (no_set_lcommunity_delete, "large-comm-list", NULL); } +ALIAS (no_set_lcommunity_delete, + no_set_lcommunity_delete_short_cmd, + "no set large-comm-list", + NO_STR + SET_STR + "set BGP large community list (for deletion)\n") + DEFUN (set_ecommunity_rt, set_ecommunity_rt_cmd, "set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...", @@ -4365,6 +4386,13 @@ DEFUN (no_set_ecommunity_rt, "extcommunity rt", NULL); } +ALIAS (no_set_ecommunity_rt, + no_set_ecommunity_rt_short_cmd, + "no set extcommunity rt", + NO_STR + SET_STR + "BGP extended community attribute\n" + "Route Target extended community\n") DEFUN (set_ecommunity_soo, set_ecommunity_soo_cmd, @@ -4399,6 +4427,13 @@ DEFUN (no_set_ecommunity_soo, "extcommunity soo", NULL); } +ALIAS (no_set_ecommunity_soo, + no_set_ecommunity_soo_short_cmd, + "no set extcommunity soo", + NO_STR + SET_STR + "GP extended community attribute\n" + "Site-of-Origin extended community\n") DEFUN (set_origin, set_origin_cmd, @@ -4976,18 +5011,23 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &set_community_cmd); install_element(RMAP_NODE, &set_community_none_cmd); install_element(RMAP_NODE, &no_set_community_cmd); + install_element(RMAP_NODE, &no_set_community_short_cmd); install_element(RMAP_NODE, &set_community_delete_cmd); install_element(RMAP_NODE, &no_set_community_delete_cmd); install_element(RMAP_NODE, &set_lcommunity_cmd); install_element(RMAP_NODE, &set_lcommunity_none_cmd); install_element(RMAP_NODE, &no_set_lcommunity_cmd); install_element(RMAP_NODE, &no_set_lcommunity1_cmd); + install_element(RMAP_NODE, &no_set_lcommunity1_short_cmd); install_element(RMAP_NODE, &set_lcommunity_delete_cmd); install_element(RMAP_NODE, &no_set_lcommunity_delete_cmd); + install_element(RMAP_NODE, &no_set_lcommunity_delete_short_cmd); install_element(RMAP_NODE, &set_ecommunity_rt_cmd); install_element(RMAP_NODE, &no_set_ecommunity_rt_cmd); + install_element(RMAP_NODE, &no_set_ecommunity_rt_short_cmd); install_element(RMAP_NODE, &set_ecommunity_soo_cmd); install_element(RMAP_NODE, &no_set_ecommunity_soo_cmd); + install_element(RMAP_NODE, &no_set_ecommunity_soo_short_cmd); #ifdef KEEP_OLD_VPN_COMMANDS install_element(RMAP_NODE, &set_vpn_nexthop_cmd); install_element(RMAP_NODE, &no_set_vpn_nexthop_cmd); diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index c69997a41d..b614e87d23 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -418,7 +418,8 @@ static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi, for (ain = bgp_node->adj_in; ain; ain = ain->next) { int ret; - struct bgp_path_info *path = bgp_info_from_node(bgp_node); + struct bgp_path_info *path = + bgp_node_get_bgp_path_info(bgp_node); mpls_label_t *label = NULL; uint32_t num_labels = 0; diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c index e9ba93bbd4..c1321dd7dc 100644 --- a/bgpd/bgp_snmp.c +++ b/bgpd/bgp_snmp.c @@ -715,7 +715,7 @@ static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[], if (rn) { bgp_unlock_node(rn); - for (path = bgp_info_from_node(rn); path; + for (path = bgp_node_get_bgp_path_info(rn); path; path = path->next) if (sockunion_same(&path->peer->su, &su)) return path; @@ -763,7 +763,7 @@ static struct bgp_path_info *bgp4PathAttrLookup(struct variable *v, oid name[], do { min = NULL; - for (path = bgp_info_from_node(rn); path; + 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) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 64c700e1bd..cf1421f5a6 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10934,7 +10934,6 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, if (use_json) { vty_out(vty, "%s\n", json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); } else { vty_out(vty, "\n"); } @@ -11009,8 +11008,10 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, } } - if (use_json) + if (use_json) { vty_out(vty, "}\n"); + json_object_free(json); + } else if (!nbr_output) vty_out(vty, "%% BGP instance not found\n"); } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 773047184e..5b8ceb0541 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7558,7 +7558,7 @@ int bgp_config_write(struct vty *vty) /* Confederation identifier*/ if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) - vty_out(vty, " bgp confederation identifier %i\n", + vty_out(vty, " bgp confederation identifier %u\n", bgp->confed_id); /* Confederation peer */ diff --git a/bgpd/bgpd.conf.sample b/bgpd/bgpd.conf.sample index 60a74a71ef..cb12a92522 100644 --- a/bgpd/bgpd.conf.sample +++ b/bgpd/bgpd.conf.sample @@ -1,6 +1,6 @@ ! -*- bgp -*- ! -! BGPd sample configuratin file +! BGPd sample configuration file ! ! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $ ! @@ -8,7 +8,7 @@ hostname bgpd password zebra !enable password please-set-at-here ! -!bgp mulitple-instance +!bgp multiple-instance ! router bgp 7675 ! bgp router-id 10.0.0.1 diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index a6d0188496..484fc105e8 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1283,7 +1283,7 @@ struct bgp_nlri { #define BGP_ATTR_ENCAP 23 #define BGP_ATTR_LARGE_COMMUNITIES 32 #define BGP_ATTR_PREFIX_SID 40 -#if ENABLE_BGP_VNC +#if ENABLE_BGP_VNC_ATTR #define BGP_ATTR_VNC 255 #endif diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 22df5c4c79..7dd1d73f69 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -224,5 +224,3 @@ bgpd/bgp_debug.$(OBJEXT): bgpd/bgp_debug_clippy.c bgpd/bgp_rpki_clippy.c: $(CLIPPY_DEPS) $(AUTOMAKE_DUMMY)bgpd/bgpd_bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c $(AUTOMAKE_DUMMY)bgpd/bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c - -EXTRA_DIST += bgpd/BGP4-MIB.txt diff --git a/debianpkg/frr.postinst b/debianpkg/frr.postinst index 32af741c98..a8d6ab2805 100644 --- a/debianpkg/frr.postinst +++ b/debianpkg/frr.postinst @@ -1,16 +1,13 @@ #!/bin/bash -e ###################### -PASSWDFILE=/etc/passwd -GROUPFILE=/etc/group +frruid=`getent passwd frr | awk -F ":" '{ print $3 }'` +frrgid=`getent group frr | awk -F ":" '{ print $3 }'` +frrvtygid=`getent group frrvty | awk -F ":" '{ print $3 }'` -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) +[ -n ${frruid} ] || (echo "No uid for frr" && /bin/false) +[ -n ${frrgid} ] || (echo "No gid for frr" && /bin/false) +[ -n ${frrVTYgid} ] || (echo "No gid for frrvty" && /bin/false) chown ${frruid}:${frrgid} /etc/frr chown ${frruid}:${frrgid} /etc/frr/* diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index 543dfdd3b9..1bb0886fd5 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -216,6 +216,12 @@ License for Contributions FRR is under a “GPLv2 or later” license. Any code submitted must be released under the same license (preferred) or any license which allows redistribution under this GPLv2 license (eg MIT License). +It is forbidden to push any code that prevents from using GPLv3 license. This +becomes a community rule, as FRR produces binaries that links with Apache 2.0 +libraries. Apache 2.0 and GPLv2 license are incompatible, if put together. +Please see `<http://www.apache.org/licenses/GPL-compatibility.html>`_ for +more information. This rule guarantees the user to distribute FRR binary code +without any licensing issues. Pre-submission Checklist ------------------------ diff --git a/doc/user/conf.py b/doc/user/conf.py index 2231989fe5..57a7c08473 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -132,7 +132,7 @@ language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build', 'rpki.rst', 'routeserver.rst', - 'ospf_fundamentals.rst', 'flowspec.rst'] + 'ospf_fundamentals.rst', 'flowspec.rst', 'snmptrap.rst'] # The reST default role (used for this markup: `text`) to use for all # documents. diff --git a/doc/user/index.rst b/doc/user/index.rst index 8190415bf4..4c218c6580 100644 --- a/doc/user/index.rst +++ b/doc/user/index.rst @@ -68,3 +68,23 @@ Appendix bugs packet-dumps glossary + +################ +Copyright notice +################ + +Copyright (c) 1996-2018 Kunihiro Ishiguro, et al. + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by Kunihiro Ishiguro. diff --git a/doc/user/installation.rst b/doc/user/installation.rst index 9654cc2eb8..2decfcc4b2 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -324,7 +324,7 @@ GNU/Linux, make sure that the current kernel configuration is what you want. FRR will run with any kernel configuration but some recommendations do exist. :makevar:`CONFIG_NETLINK` - Kernel/User Netlink socket. This is a enables an advanced interface between + Kernel/User Netlink socket. This enables an advanced interface between the Linux kernel and *zebra* (:ref:`kernel-interface`). :makevar:`CONFIG_RTNETLINK` @@ -356,9 +356,9 @@ Additional kernel modules are also needed to support MPLS forwarding. net.ipv6.conf.all.forwarding=1 :makevar:`MPLS forwarding` - Basic MPLS kernel support was introduced 4.1, additional capability - was introduced in 4.3 and 4.5. For some general information on Linux - MPLS support see + Basic MPLS support was introduced in the kernel in version 4.1 and + additional capability was introduced in 4.3 and 4.5. + For some general information on Linux MPLS support, see https://www.netdevconf.org/1.1/proceedings/slides/prabhu-mpls-tutorial.pdf. The following modules should be loaded to support MPLS forwarding, and are generally added to a configuration file such as @@ -418,7 +418,7 @@ Additional kernel modules are also needed to support MPLS forwarding. running these kernel versions, if unable to establish any VRF BGP adjacencies, either downgrade to 4.13 or set 'net.ipv4.tcp_l3mdev_accept=1'. The fix for this issue is planned to be - included in future kernel versions so upgrading your kernel may also + included in future kernel versions. So upgrading your kernel may also address this issue. @@ -440,7 +440,7 @@ the options you chose: --enable-watchfrr \ ... -After configuring the software, you are ready to build and install it for your +After configuring the software, you are ready to build and install it in your system. .. code-block:: shell diff --git a/doc/user/sharp.rst b/doc/user/sharp.rst index 8831c0159b..c2d32a718e 100644 --- a/doc/user/sharp.rst +++ b/doc/user/sharp.rst @@ -33,16 +33,20 @@ All sharp commands are under the enable node and preceeded by the ``sharp`` keyword. At present, no sharp commands will be preserved in the config. .. index:: sharp install -.. clicmd:: sharp install routes A.B.C.D nexthop <E.F.G.H|X:X::X:X> (1-1000000) +.. clicmd:: sharp install routes A.B.C.D <nexthop <E.F.G.H|X:X::X:X>|nexthop-group NAME> (1-1000000) [instance (0-255)] [repeat (2-1000)] Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D`` with specified nexthop ``E.F.G.H`` or ``X:X::X:X``. The nexthop is a ``NEXTHOP_TYPE_IPV4`` or ``NEXTHOP_TYPE_IPV6`` and must be reachable - to be installed into the kernel. The routes are installed into zebra as - ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route + to be installed into the kernel. Alternatively a nexthop-group NAME + can be specified and used as the nexthops. The routes are installed into + zebra as ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route redistribution. Route installation time is noted in the debug log. When zebra successfully installs a route into the kernel and SHARP receives success notifications for all routes this is logged as well. + Instance (0-255) if specified causes the routes to be installed in a different + instance. If repeat is used then we will install/uninstall the routes the + number of times specified. .. index:: sharp remove .. clicmd:: sharp remove routes A.B.C.D (1-1000000) diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index c509eb8583..9dfe1ea39c 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -276,6 +276,12 @@ Link Parameters Commands After setting TABLENO with this command, static routes defined after this are added to the specified table. +.. index:: ip nht resolve-via-default +.. clicmd:: ip nht resolve-via-default + + Allows nexthop tracking to resolve via the default route. This is useful + when e.g. you want to allow BGP to peer across the default route. + .. _zebra-vrf: Virtual Routing and Forwarding diff --git a/eigrpd/EIGRP-MIB.txt b/eigrpd/EIGRP-MIB.txt deleted file mode 100644 index f6ea298cfd..0000000000 --- a/eigrpd/EIGRP-MIB.txt +++ /dev/null @@ -1,1321 +0,0 @@ -CISCO-EIGRP-MIB DEFINITIONS ::= BEGIN - - IMPORTS - MODULE-IDENTITY, - OBJECT-TYPE, - NOTIFICATION-TYPE, - Unsigned32, - Gauge32, - Counter32, - Counter64 - FROM SNMPv2-SMI - TruthValue, - TEXTUAL-CONVENTION - FROM SNMPv2-TC - SnmpAdminString - FROM SNMP-FRAMEWORK-MIB - MODULE-COMPLIANCE, - OBJECT-GROUP, - NOTIFICATION-GROUP - FROM SNMPv2-CONF - ciscoMgmt - FROM CISCO-SMI - InterfaceIndexOrZero, - ifIndex - FROM IF-MIB - InetAddressType, - InetAddress, - InetAddressPrefixLength - FROM INET-ADDRESS-MIB; - -ciscoEigrpMIB MODULE-IDENTITY - LAST-UPDATED "200411160000Z" - ORGANIZATION "Cisco Systems, Inc." - CONTACT-INFO "Cisco Systems - Customer Service - - Postal: 170 W Tasman Drive - San Jose, CA 95134 - USA - - Tel: +1 800 553-NETS - - E-mail: cs-eigrp@cisco.com" - DESCRIPTION - "Enhanced Interior Gateway Protocol (EIGRP) is a Cisco - proprietary distance vector routing protocol. It is based on - the Diffusing Update Algorithm (DUAL), which is a method of - finding loop-free paths through a network. Directly - connected routers running EIGRP form neighbor adjacencies in - order to propagate best-path and alternate-path routing - information for configured and learned routes. - - The tables defined within the MIB are closely aligned with how - the router command-line interface for EIGRP displays - information on EIGRP configurations, i.e., the topology table - contains objects associated with the EIGRP topology commands, - and the peer table contains objects associated withe EIGRP - neighbor commands, etc. - - There are five main tables within this mib: - - EIGRP VPN table - Contains information regarding which virtual private - networks (VPN) are configured with EIGRP. - - EIGRP traffic statistics table - Contains counter & statistcs regarding specific types of - EIGRP packets sent and related collective information - per VPN and per autonomous system (AS). - - EIGRP topology table - Contains information regarding EIGRP routes received in - updates and originated locally. EIGRP sends and - receives routing updates from adjacent routers running - EIGRP with which it formed a peer relationship. - - EIGRP peer (neighbor) table - Contains information about neighbor EIGRP routers with - which peer adjacencies have been established. EIGRP - uses a Hello protocol to form neighbor relationships - with directly connected routers also running EIGRP. - - EIGRP interfaces table - Contains information and statistics on each of the - interfaces on the router over which EIGRP has been - configured to run." - - - REVISION "200411160000Z" - DESCRIPTION - "Initial version of the MIB module." - ::= { ciscoMgmt 449 } - --- --- Textual Conventions --- - - EigrpUpTimeString ::= TEXTUAL-CONVENTION - DISPLAY-HINT "8a" - STATUS current - DESCRIPTION - "Specifies a timer value in days, hours, minutes, - and seconds in ASCII format. - - If the up time is less than 24 hours, the number - of days will not be reflected and the string will - be formatted like this: 'hh:mm:ss', reflecting - hours, minutes, and seconds. - - If the up time is greater than 24 hours, EIGRP is - less precise and the minutes and seconds are not - reflected. Instead only the days and hours are shown - and the string will be formatted like this: 'xxxdxxh'." - SYNTAX OCTET STRING (SIZE (0..8)) - - EigrpVersionString ::= TEXTUAL-CONVENTION - DISPLAY-HINT "1d.1d/1d.1d" - STATUS current - DESCRIPTION - "Specifies an ASCII string representing the IOS major - and minor version followed by the EIGRP major and minor - version." - SYNTAX OCTET STRING (SIZE (0..9)) - --- --- Objects --- - - cEigrpMIBNotifications OBJECT IDENTIFIER ::= { ciscoEigrpMIB 0 } - cEigrpMIBObjects OBJECT IDENTIFIER ::= { ciscoEigrpMIB 1 } - cEigrpMIBConformance OBJECT IDENTIFIER ::= { ciscoEigrpMIB 2 } - cEigrpVpnInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 1 } - cEigrpAsInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 2 } - cEigrpTopologyInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 3 } - cEigrpPeerInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 4 } - cEigrpInterfaceInfo OBJECT IDENTIFIER ::= { cEigrpMIBObjects 5 } - - -- EIGRP VPN Base Table definition - - cEigrpVpnTable OBJECT-TYPE - SYNTAX SEQUENCE OF CEigrpVpnEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "This table contains information on those VPN's configured - to run EIGRP. The VPN creation on a router is independent - of the routing protocol to be used over it. A VPN is - given a name and has a dedicated routing table associated - with it. This routing table is identified internally - by a unique integer value." - ::= { cEigrpVpnInfo 1 } - - cEigrpVpnEntry OBJECT-TYPE - SYNTAX CEigrpVpnEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information relating to a single VPN which is configured - to run EIGRP." - INDEX { cEigrpVpnId } - ::= { cEigrpVpnTable 1 } - - CEigrpVpnEntry ::= - SEQUENCE { - cEigrpVpnId Unsigned32, - cEigrpVpnName SnmpAdminString - } - - cEigrpVpnId OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The unique VPN identifier. This is a unique integer - relative to all other VPN's defined on the router. It - also identifies internally the routing table instance." - ::= { cEigrpVpnEntry 1 } - - cEigrpVpnName OBJECT-TYPE - SYNTAX SnmpAdminString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The name given to the VPN." - ::= { cEigrpVpnEntry 2 } - - -- EIGRP Traffic Stats table definition - - cEigrpTraffStatsTable OBJECT-TYPE - SYNTAX SEQUENCE OF CEigrpTraffStatsEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Table of EIGRP traffic statistics and information - associated with all EIGRP autonomous systems." - ::= { cEigrpAsInfo 1 } - - cEigrpTraffStatsEntry OBJECT-TYPE - SYNTAX CEigrpTraffStatsEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The set of statistics and information for a single EIGRP - Autonomous System." - INDEX { cEigrpVpnId, cEigrpAsNumber } - ::= { cEigrpTraffStatsTable 1 } - - CEigrpTraffStatsEntry ::= - SEQUENCE { - cEigrpAsNumber Unsigned32, - cEigrpNbrCount Unsigned32, - cEigrpHellosSent Counter32, - cEigrpHellosRcvd Counter32, - cEigrpUpdatesSent Counter32, - cEigrpUpdatesRcvd Counter32, - cEigrpQueriesSent Counter32, - cEigrpQueriesRcvd Counter32, - cEigrpRepliesSent Counter32, - cEigrpRepliesRcvd Counter32, - cEigrpAcksSent Counter32, - cEigrpAcksRcvd Counter32, - cEigrpInputQHighMark Unsigned32, - cEigrpInputQDrops Counter32, - cEigrpSiaQueriesSent Counter32, - cEigrpSiaQueriesRcvd Counter32, - cEigrpAsRouterIdType InetAddressType, - cEigrpAsRouterId InetAddress, - cEigrpTopoRoutes Counter32, - cEigrpHeadSerial Counter64, - cEigrpNextSerial Counter64, - cEigrpXmitPendReplies Unsigned32, - cEigrpXmitDummies Unsigned32 - } - - cEigrpAsNumber OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Autonomous System number which is unique integer - per VPN." - ::= { cEigrpTraffStatsEntry 1 } - - cEigrpNbrCount OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of live EIGRP neighbors formed on all - interfaces whose IP addresses fall under networks configured - in the EIGRP AS." - ::= { cEigrpTraffStatsEntry 2 } - - cEigrpHellosSent OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number Hello packets that have been sent to all - EIGRP neighbors formed on all interfaces whose IP addresses - fall under networks configured for the EIGRP AS." - ::= { cEigrpTraffStatsEntry 3 } - - cEigrpHellosRcvd OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number Hello packets that have been received - from all EIGRP neighbors formed on all interfaces whose IP - addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 4 } - - cEigrpUpdatesSent OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number routing update packets that have been - sent to all EIGRP neighbors formed on all interfaces whose - IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 5 } - - cEigrpUpdatesRcvd OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number routing update packets that have been - received from all EIGRP neighbors formed on all interfaces - whose IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 6 } - - cEigrpQueriesSent OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number alternate route query packets that have - been sent to all EIGRP neighbors formed on all interfaces - whose IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 7 } - - cEigrpQueriesRcvd OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number alternate route query packets that - have been received from all EIGRP neighbors formed on - all interfaces whose IP addresses fall under networks - configured for the EIGRP AS." - ::= { cEigrpTraffStatsEntry 8 } - - cEigrpRepliesSent OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number query reply packets that have been sent - to all EIGRP neighbors formed on all interfaces whose IP - addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 9 } - - cEigrpRepliesRcvd OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number query reply packets that have been - received from all EIGRP neighbors formed on all interfaces - whose IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 10 } - - cEigrpAcksSent OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number packet acknowledgements that have been - sent to all EIGRP neighbors formed on all interfaces whose - IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 11 } - - cEigrpAcksRcvd OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number packet acknowledgements that have been - received from all EIGRP neighbors formed on all interfaces - whose IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 12 } - - cEigrpInputQHighMark OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The highest number of EIGRP packets in the input queue - waiting to be processed internally addressed to this - AS." - ::= { cEigrpTraffStatsEntry 13 } - - cEigrpInputQDrops OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of EIGRP packets dropped from the input - queue due to it being full within the AS." - ::= { cEigrpTraffStatsEntry 14 } - - cEigrpSiaQueriesSent OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of Stuck-In-Active (SIA) query packets - sent to all EIGRP neighbors formed on all interfaces whose - IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 15 } - - cEigrpSiaQueriesRcvd OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of Stuck-In-Active (SIA) query packets - received from all EIGRP neighbors formed on all interfaces - whose IP addresses fall under networks configured for the - EIGRP AS." - ::= { cEigrpTraffStatsEntry 16 } - - cEigrpAsRouterIdType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The format of the router-id configured or automatically - selected for the EIGRP AS." - ::= { cEigrpTraffStatsEntry 17 } - - cEigrpAsRouterId OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The router-id configured or automatically selected for the - EIGRP AS. Each EIGRP routing process has a unique - router-id selected from each autonomous system configured. - The format is governed by object cEigrpAsRouterIdType." - ::= { cEigrpTraffStatsEntry 18 } - - cEigrpTopoRoutes OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of EIGRP derived routes currently existing - in the topology table for the AS." - ::= { cEigrpTraffStatsEntry 19 } - - cEigrpHeadSerial OBJECT-TYPE - SYNTAX Counter64 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Routes in a topology table for an AS are assigned serial - numbers and are sequenced internally as they are inserted - and deleted. The serial number of the first route in - that internal sequence is called the head serial number. - Each AS has its own topology table, and its own serial - number space, each of which begins with the value 1. - A serial number of zero implies that there are no routes - in the topology." - ::= { cEigrpTraffStatsEntry 20 } - - cEigrpNextSerial OBJECT-TYPE - SYNTAX Counter64 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The serial number that would be assigned to the next new - or changed route in the topology table for the AS." - ::= { cEigrpTraffStatsEntry 21 } - - cEigrpXmitPendReplies OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "When alternate route query packets are sent to adjacent - EIGRP peers in an AS, replies are expected. This object - is the total number of outstanding replies expected to - queries that have been sent to peers in the current AS. - It remains at zero most of the time until an EIGRP route - becomes active." - ::= { cEigrpTraffStatsEntry 22 } - - cEigrpXmitDummies OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A dummy is a temporary internal entity used as a place - holder in the topology table for an AS. They are not - transmitted in routing updates. This is the total - number currently in existence associated with the AS." - ::= { cEigrpTraffStatsEntry 23 } - - -- EIGRP topology table definition - - cEigrpTopoTable OBJECT-TYPE - SYNTAX SEQUENCE OF CEigrpTopoEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The table of EIGRP routes and their associated - attributes for an Autonomous System (AS) configured - in a VPN is called a topology table. All route entries in - the topology table will be indexed by IP network type, - IP network number and network mask (prefix) size." - ::= { cEigrpTopologyInfo 1 } - - cEigrpTopoEntry OBJECT-TYPE - SYNTAX CEigrpTopoEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The entry for a single EIGRP topology table in the given - AS." - INDEX { cEigrpVpnId, cEigrpAsNumber, cEigrpDestNetType, - cEigrpDestNet, cEigrpDestNetPrefixLen } - ::= { cEigrpTopoTable 1 } - - CEigrpTopoEntry ::= - SEQUENCE { - cEigrpDestNetType InetAddressType, - cEigrpDestNet InetAddress, - cEigrpDestNetPrefixLen InetAddressPrefixLength, - cEigrpActive TruthValue, - cEigrpStuckInActive TruthValue, - cEigrpDestSuccessors Unsigned32, - cEigrpFdistance Unsigned32, - cEigrpRouteOriginType SnmpAdminString, - cEigrpRouteOriginAddrType InetAddressType, - cEigrpRouteOriginAddr InetAddress, - cEigrpNextHopAddressType InetAddressType, - cEigrpNextHopAddress InetAddress, - cEigrpNextHopInterface SnmpAdminString, - cEigrpDistance Unsigned32, - cEigrpReportDistance Unsigned32 - } - - cEigrpDestNetType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The format of the destination IP network number for - a single route in the topology table in the AS specified - in cEigrpDestNet." - ::= { cEigrpTopoEntry 1 } - - cEigrpDestNet OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The destination IP network number for a single route in - the topology table in the AS. The format is governed - by object cEigrpDestNetType." - ::= { cEigrpTopoEntry 2 } - - cEigrpDestNetPrefixLen OBJECT-TYPE - SYNTAX InetAddressPrefixLength - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The prefix length associated with the destination IP - network address for a single route in the topology - table in the AS. The format is governed by the object - cEigrpDestNetType." - ::= { cEigrpTopoEntry 4 } - - cEigrpActive OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A value of true(1) indicates the route to the - destination network has failed and an active (query) - search for an alternative path is in progress. A value - of false(2) indicates the route is stable (passive)." - ::= { cEigrpTopoEntry 5 } - - cEigrpStuckInActive OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A value of true(1) indicates that that this route which is - in active state (cEigrpActive = true(1)) has not received - any replies to queries for alternate paths, and a second - EIGRP route query, called a stuck-in-active query, has - now been sent." - ::= { cEigrpTopoEntry 6 } - - cEigrpDestSuccessors OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A successor is the next routing hop for a path to the - destination IP network number for a single route in the - topology table in the AS. There can be several - potential successors if there are multiple paths to the - destination. This is the total number of successors for - a topology entry." - ::= { cEigrpTopoEntry 7 } - - cEigrpFdistance OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The feasibility (best) distance is the minimum distance - from this router to the destination IP network in - this topology entry. The feasibility distance is - used in determining the best successor for a path to the - destination network." - ::= { cEigrpTopoEntry 8 } - - cEigrpRouteOriginType OBJECT-TYPE - SYNTAX SnmpAdminString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This is a text string describing the internal origin - of the EIGRP route represented by the topology entry." - ::= { cEigrpTopoEntry 9 } - - cEigrpRouteOriginAddrType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The format of the IP address defined as the origin of - this topology route entry." - ::= { cEigrpTopoEntry 10 } - - cEigrpRouteOriginAddr OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "If the origin of the topology route entry is external - to this router, then this object is the IP address - of the router from which it originated. The format - is governed by object cEigrpRouteOriginAddrType." - ::= { cEigrpTopoEntry 11 } - - cEigrpNextHopAddressType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The format of the next hop IP address for the route - represented by the topology entry." - ::= { cEigrpTopoEntry 12 } - - cEigrpNextHopAddress OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This is the next hop IP address for the route represented - by the topology entry. The next hop is where - network traffic will be routed to in order to reach - the destination network for this topology entry. The - format is governed by cEigrpNextHopAddressType." - ::= { cEigrpTopoEntry 13 } - - cEigrpNextHopInterface OBJECT-TYPE - SYNTAX SnmpAdminString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The interface through which the next hop IP address - is reached to send network traffic to the destination - network represented by the topology entry." - ::= { cEigrpTopoEntry 14 } - - cEigrpDistance OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The computed distance to the destination network entry - from this router." - ::= { cEigrpTopoEntry 15 } - - cEigrpReportDistance OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The computed distance to the destination network in the - topology entry reported to this router by the originator - of this route." - ::= { cEigrpTopoEntry 16 } - - -- EIGRP Peer table per VPN and AS (expansion table) - - cEigrpPeerTable OBJECT-TYPE - SYNTAX SEQUENCE OF CEigrpPeerEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The table of established EIGRP peers (neighbors) in the - selected autonomous system. Peers are indexed by their - unique internal handle id, as well as the AS number and - VPN id. The peer entry is removed from the table if - the peer is declared down." - ::= { cEigrpPeerInfo 1 } - - cEigrpPeerEntry OBJECT-TYPE - SYNTAX CEigrpPeerEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Statistics and operational parameters for a single peer - in the AS." - INDEX { cEigrpVpnId, cEigrpAsNumber, cEigrpHandle } - ::= { cEigrpPeerTable 1 } - - CEigrpPeerEntry ::= - SEQUENCE { - cEigrpHandle Unsigned32, - cEigrpPeerAddrType InetAddressType, - cEigrpPeerAddr InetAddress, - cEigrpPeerIfIndex InterfaceIndexOrZero, - cEigrpHoldTime Unsigned32, - cEigrpUpTime EigrpUpTimeString, - cEigrpSrtt Unsigned32, - cEigrpRto Unsigned32, - cEigrpPktsEnqueued Unsigned32, - cEigrpLastSeq Unsigned32, - cEigrpVersion EigrpVersionString, - cEigrpRetrans Counter32, - cEigrpRetries Unsigned32 - } - - cEigrpHandle OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The unique internal identifier for the peer in the AS. - This is a unique value among peer entries in a selected - table." - ::= { cEigrpPeerEntry 1 } - - cEigrpPeerAddrType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The format of the remote source IP address used by the - peer to establish the EIGRP adjacency with this router." - ::= { cEigrpPeerEntry 2 } - - cEigrpPeerAddr OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The source IP address used by the peer to establish the - EIGRP adjacency with this router. The format is - governed by object cEigrpPeerAddrType." - ::= { cEigrpPeerEntry 3 } - - cEigrpPeerIfIndex OBJECT-TYPE - SYNTAX InterfaceIndexOrZero - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The ifIndex of the interface on this router through - which this peer can be reached." - ::= { cEigrpPeerEntry 4 } - - cEigrpHoldTime OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The count-down timer indicating how much time must - pass without receiving a hello packet from this - EIGRP peer before this router declares the peer down. - A peer declared as down is removed from the table and - is no longer visible." - ::= { cEigrpPeerEntry 5 } - - cEigrpUpTime OBJECT-TYPE - SYNTAX EigrpUpTimeString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The elapsed time since the EIGRP adjacency was first - established with the peer." - ::= { cEigrpPeerEntry 6 } - - cEigrpSrtt OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "milliseconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The computed smooth round trip time for packets to and - from the peer." - ::= { cEigrpPeerEntry 7 } - - cEigrpRto OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "milliseconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The computed retransmission timeout for the peer. - This value is computed over time as packets are sent to - the peer and acknowledgements are received from it, - and is the amount of time to wait before resending - a packet from the retransmission queue to the peer - when an expected acknowledgement has not been received." - ::= { cEigrpPeerEntry 8 } - - cEigrpPktsEnqueued OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of any EIGRP packets currently enqueued - waiting to be sent to this peer." - ::= { cEigrpPeerEntry 9 } - - cEigrpLastSeq OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "All transmitted EIGRP packets have a sequence number - assigned. This is the sequence number of the last EIGRP - packet sent to this peer." - ::= { cEigrpPeerEntry 10 } - - cEigrpVersion OBJECT-TYPE - SYNTAX EigrpVersionString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The EIGRP version information reported by the remote - peer." - ::= { cEigrpPeerEntry 11 } - - cEigrpRetrans OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The cumulative number of retransmissions to this peer - during the period that the peer adjacency has remained - up." - ::= { cEigrpPeerEntry 12 } - - cEigrpRetries OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times the current unacknowledged packet - has been retried, i.e. resent to this peer to be - acknowledged." - ::= { cEigrpPeerEntry 13 } - - -- EIGRP Interfaces table per VPN and AS - - cEigrpInterfaceTable OBJECT-TYPE - SYNTAX SEQUENCE OF CEigrpInterfaceEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The table of interfaces over which EIGRP is running, and - their associated statistics. This table is independent - of whether any peer adjacencies have been formed over - the interfaces or not. Interfaces running EIGRP are - determined by whether their assigned IP addresses fall - within configured EIGRP network statements." - ::= { cEigrpInterfaceInfo 1 } - - cEigrpInterfaceEntry OBJECT-TYPE - SYNTAX CEigrpInterfaceEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information for a single interface running EIGRP in the - AS and VPN." - INDEX { cEigrpVpnId, cEigrpAsNumber, ifIndex } - ::= { cEigrpInterfaceTable 1 } - - CEigrpInterfaceEntry ::= - SEQUENCE { - cEigrpPeerCount Gauge32, - cEigrpXmitReliableQ Gauge32, - cEigrpXmitUnreliableQ Gauge32, - cEigrpMeanSrtt Unsigned32, - cEigrpPacingReliable Unsigned32, - cEigrpPacingUnreliable Unsigned32, - cEigrpMFlowTimer Unsigned32, - cEigrpPendingRoutes Gauge32, - cEigrpHelloInterval Unsigned32, - cEigrpXmitNextSerial Counter64, - cEigrpUMcasts Counter32, - cEigrpRMcasts Counter32, - cEigrpUUcasts Counter32, - cEigrpRUcasts Counter32, - cEigrpMcastExcepts Counter32, - cEigrpCRpkts Counter32, - cEigrpAcksSuppressed Counter32, - cEigrpRetransSent Counter32, - cEigrpOOSrcvd Counter32, - cEigrpAuthMode INTEGER, - cEigrpAuthKeyChain SnmpAdminString - } - - cEigrpPeerCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of EIGRP adjacencies currently formed with - peers reached through this interface." - ::= { cEigrpInterfaceEntry 3 } - - cEigrpXmitReliableQ OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of EIGRP packets currently waiting in the - reliable transport (acknowledgement-required) - transmission queue to be sent to a peer." - ::= { cEigrpInterfaceEntry 4 } - - cEigrpXmitUnreliableQ OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number EIGRP of packets currently waiting in - the unreliable transport (no acknowledgement required) - transmission queue." - ::= { cEigrpInterfaceEntry 5 } - - cEigrpMeanSrtt OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "milliseconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The average of all the computed smooth round trip time - values for a packet to and from all peers established on - this interface." - ::= { cEigrpInterfaceEntry 6 } - - cEigrpPacingReliable OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "milliseconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The configured time interval between EIGRP packet - transmissions on the interface when the reliable transport - method is used." - ::= { cEigrpInterfaceEntry 7 } - - cEigrpPacingUnreliable OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "milliseconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The configured time interval between EIGRP packet - transmissions on the interface when the unreliable - transport method is used." - ::= { cEigrpInterfaceEntry 8 } - - cEigrpMFlowTimer OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "milliseconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The configured multicast flow control timer value for - this interface." - ::= { cEigrpInterfaceEntry 9 } - - cEigrpPendingRoutes OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of queued EIGRP routing updates awaiting - transmission on this interface." - ::= { cEigrpInterfaceEntry 10 } - - cEigrpHelloInterval OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The configured time interval between Hello packet - transmissions for this interface." - ::= { cEigrpInterfaceEntry 11 } - - cEigrpXmitNextSerial OBJECT-TYPE - SYNTAX Counter64 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The serial number of the next EIGRP packet that is to - be queued for transmission on this interface." - ::= { cEigrpInterfaceEntry 12 } - - cEigrpUMcasts OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of unreliable (no acknowledgement - required) EIGRP multicast packets sent on this - interface." - ::= { cEigrpInterfaceEntry 13 } - - cEigrpRMcasts OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of reliable (acknowledgement required) - EIGRP multicast packets sent on this interface." - ::= { cEigrpInterfaceEntry 14 } - - cEigrpUUcasts OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of unreliable (no acknowledgement - required) EIGRP unicast packets sent on this - interface." - ::= { cEigrpInterfaceEntry 15 } - - cEigrpRUcasts OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of reliable (acknowledgement required) - unicast packets sent on this interface." - ::= { cEigrpInterfaceEntry 16 } - - cEigrpMcastExcepts OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of EIGRP multicast exception - transmissions that have occurred on this interface." - ::= { cEigrpInterfaceEntry 17 } - - cEigrpCRpkts OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number EIGRP Conditional-Receive packets sent on - this interface." - ::= { cEigrpInterfaceEntry 18 } - - cEigrpAcksSuppressed OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of individual EIGRP acknowledgement - packets that have been suppressed and combined in - an already enqueued outbound reliable packet on this - interface." - ::= { cEigrpInterfaceEntry 19 } - - cEigrpRetransSent OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number EIGRP packet retransmissions sent on - the interface." - ::= { cEigrpInterfaceEntry 20 } - - cEigrpOOSrcvd OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of out-of-sequence EIGRP packets - received." - ::= { cEigrpInterfaceEntry 21 } - - cEigrpAuthMode OBJECT-TYPE - SYNTAX INTEGER { - none(1), - md5(2) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The EIGRP authentication mode of the interface. - none : no authentication enabled on the interface - md5 : MD5 authentication enabled on the interface" - ::= { cEigrpInterfaceEntry 22 } - - cEigrpAuthKeyChain OBJECT-TYPE - SYNTAX SnmpAdminString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The name of the authentication key-chain configured - on this interface. The key-chain is a reference to - which set of secret keys are to be accessed in order - to determine which secret key string to use. The key - chain name is not the secret key string password and - can also be used in other routing protocols, such - as RIP and ISIS." - ::= { cEigrpInterfaceEntry 23 } - - -- Notifications - - cEigrpAuthFailureEvent NOTIFICATION-TYPE - OBJECTS { cEigrpPeerAddrType, cEigrpPeerAddr } - STATUS current - DESCRIPTION - "This notification is sent when EIGRP MD5 authentication - is enabled on any interface and peer adjacencies are - formed, and any adjacencies go down as a result of an - authentication failure." - ::= { cEigrpMIBNotifications 1 } - - cEigrpRouteStuckInActive NOTIFICATION-TYPE - OBJECTS { cEigrpPeerAddrType, cEigrpPeerAddr, - cEigrpStuckInActive } - STATUS current - DESCRIPTION - "This notification is sent when a route in the topology - table is stuck in an active state. During the query - phase for a new route to a destination network, a route - is described as being in the active state if when an - alternate path is actively being sought, no replies are - received to normal queries or stuck-in-active queries." - ::= { cEigrpMIBNotifications 2 } - - -- Conformance - - cEigrpMIBCompliances - OBJECT IDENTIFIER ::= { cEigrpMIBConformance 1 } - - cEigrpMIBGroups - OBJECT IDENTIFIER ::= { cEigrpMIBConformance 2 } - - -- Compliance - - cEigrpMIBCompliance MODULE-COMPLIANCE - STATUS current - DESCRIPTION - "The compliance statement for entities which implement - the Cisco EIGRP Management MIB." - MODULE - MANDATORY-GROUPS { - cEigrpVpnDataGroup, - cEigrpTrafficStatsGroup, - cEigrpInterfaceDataGroup, - cEigrpPeerDataGroup, - cEigrpTopoDataGroup, - cEigrpNotificationsGroup - } - - OBJECT cEigrpAsRouterIdType - SYNTAX INTEGER { ipv4(1) } - DESCRIPTION - "An implementation is only required to support - IPv4 address type." - - OBJECT cEigrpRouteOriginAddrType - SYNTAX INTEGER { ipv4(1) } - DESCRIPTION - "An implementation is only required to support - IPv4 address type." - - OBJECT cEigrpNextHopAddressType - SYNTAX INTEGER { ipv4(1) } - DESCRIPTION - "An implementation is only required to support - IPv4 address type." - - OBJECT cEigrpPeerAddrType - SYNTAX INTEGER { ipv4(1) } - DESCRIPTION - "An implementation is only required to support - IPv4 address type." - ::= { cEigrpMIBCompliances 1 } - - -- Units of Conformance - - cEigrpVpnDataGroup OBJECT-GROUP - OBJECTS { - cEigrpVpnName - } - STATUS current - DESCRIPTION - "The collection of VPN names which have been configured - with one or more EIGRP autonmous systems." - ::= { cEigrpMIBGroups 1 } - - cEigrpTrafficStatsGroup OBJECT-GROUP - OBJECTS { - cEigrpHellosSent, - cEigrpHellosRcvd, - cEigrpUpdatesSent, - cEigrpUpdatesRcvd, - cEigrpQueriesSent, - cEigrpQueriesRcvd, - cEigrpRepliesSent, - cEigrpRepliesRcvd, - cEigrpAcksSent, - cEigrpAcksRcvd, - cEigrpInputQHighMark, - cEigrpInputQDrops, - cEigrpSiaQueriesSent, - cEigrpSiaQueriesRcvd - } - STATUS current - DESCRIPTION - "A collection of objects providing management information - regarding collective EIGRP packet statistics for all EIGRP - autonomous systems configured." - ::= { cEigrpMIBGroups 2 } - - cEigrpInterfaceDataGroup OBJECT-GROUP - OBJECTS { - cEigrpPeerCount, - cEigrpXmitReliableQ, - cEigrpXmitUnreliableQ, - cEigrpMeanSrtt, - cEigrpPacingReliable, - cEigrpPacingUnreliable, - cEigrpMFlowTimer, - cEigrpPendingRoutes, - cEigrpHelloInterval, - cEigrpXmitNextSerial, - cEigrpUMcasts, - cEigrpRMcasts, - cEigrpUUcasts, - cEigrpRUcasts, - cEigrpMcastExcepts, - cEigrpCRpkts, - cEigrpAcksSuppressed, - cEigrpRetransSent, - cEigrpOOSrcvd, - cEigrpAuthMode, - cEigrpAuthKeyChain - } - STATUS current - DESCRIPTION - "A collection of objects providing management information - for interfaces over which EIGRP is configured and - running." - ::= { cEigrpMIBGroups 3 } - - cEigrpPeerDataGroup OBJECT-GROUP - OBJECTS { - cEigrpNbrCount, - cEigrpPeerAddrType, - cEigrpPeerAddr, - cEigrpPeerIfIndex, - cEigrpHoldTime, - cEigrpUpTime, - cEigrpSrtt, - cEigrpRto, - cEigrpPktsEnqueued, - cEigrpLastSeq, - cEigrpVersion, - cEigrpRetrans, - cEigrpRetries - } - STATUS current - DESCRIPTION - "A collection of objects providing management information - for EIGRP peer adjacencies formed in the EIGRP - autonoumous systems." - ::= { cEigrpMIBGroups 4 } - - cEigrpTopoDataGroup OBJECT-GROUP - OBJECTS { - cEigrpAsRouterId, - cEigrpAsRouterIdType, - cEigrpTopoRoutes, - cEigrpHeadSerial, - cEigrpNextSerial, - cEigrpXmitPendReplies, - cEigrpXmitDummies, - cEigrpActive, - cEigrpStuckInActive, - cEigrpDestSuccessors, - cEigrpFdistance, - cEigrpRouteOriginType, - cEigrpRouteOriginAddrType, - cEigrpRouteOriginAddr, - cEigrpNextHopAddressType, - cEigrpNextHopAddress, - cEigrpNextHopInterface, - cEigrpDistance, - cEigrpReportDistance - } - STATUS current - DESCRIPTION - "A collection of objects providing management information - for EIGRP topology routes derived within autonomous - systems and received in updates from EIGRP neighbors." - ::= { cEigrpMIBGroups 5 } - - cEigrpNotificationsGroup NOTIFICATION-GROUP - NOTIFICATIONS { - cEigrpAuthFailureEvent, - cEigrpRouteStuckInActive - } - STATUS current - DESCRIPTION - "Group of notifications on EIGRP routers." - ::= { cEigrpMIBGroups 6 } -END
\ No newline at end of file diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 27e02630a6..c975c0abc7 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -276,11 +276,8 @@ void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr, */ void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp) { - struct in_addr router_id; - router_id.s_addr = eigrp->router_id; - vty_out(vty, "\nEIGRP Topology Table for AS(%d)/ID(%s)\n\n", eigrp->AS, - inet_ntoa(router_id)); + inet_ntoa(eigrp->router_id)); vty_out(vty, "Codes: P - Passive, A - Active, U - Update, Q - Query, " "R - Reply\n r - reply Status, s - sia Status\n\n"); diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c index c1bf1647d8..93eed9452c 100644 --- a/eigrpd/eigrp_filter.c +++ b/eigrpd/eigrp_filter.c @@ -62,7 +62,8 @@ /* * Distribute-list update functions. */ -void eigrp_distribute_update(struct distribute *dist) +void eigrp_distribute_update(struct distribute_ctx *ctx, + struct distribute *dist) { struct interface *ifp; struct eigrp_interface *ei = NULL; @@ -285,10 +286,15 @@ void eigrp_distribute_update(struct distribute *dist) void eigrp_distribute_update_interface(struct interface *ifp) { struct distribute *dist; + struct eigrp *eigrp; - dist = distribute_lookup(ifp->name); + eigrp = eigrp_lookup(); + if (!eigrp) + return; + dist = distribute_lookup(eigrp->distribute_ctx, ifp->name); if (dist) - eigrp_distribute_update(dist); + eigrp_distribute_update(eigrp->distribute_ctx, + dist); } /* Update all interface's distribute list. diff --git a/eigrpd/eigrp_filter.h b/eigrpd/eigrp_filter.h index caec19b0fb..34d00ecc13 100644 --- a/eigrpd/eigrp_filter.h +++ b/eigrpd/eigrp_filter.h @@ -33,7 +33,8 @@ #ifndef EIGRPD_EIGRP_FILTER_H_ #define EIGRPD_EIGRP_FILTER_H_ -extern void eigrp_distribute_update(struct distribute *); +extern void eigrp_distribute_update(struct distribute_ctx *ctx, + struct distribute *dist); extern void eigrp_distribute_update_interface(struct interface *); extern void eigrp_distribute_update_all(struct prefix_list *); extern void eigrp_distribute_update_all_wrapper(struct access_list *); diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index 063fc5fec1..b19b383e65 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -217,8 +217,6 @@ int main(int argc, char **argv, char **envp) /* Distribute list install. */ distribute_list_init(EIGRP_NODE); - distribute_list_add_hook(eigrp_distribute_update); - distribute_list_delete_hook(eigrp_distribute_update); frr_config_fork(); frr_run(master); diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 35b45288b8..6bb619f0e1 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -227,7 +227,7 @@ int eigrp_network_set(struct eigrp *eigrp, struct prefix *p) rn->info = (void *)pref; /* Schedule Router ID Update. */ - if (eigrp->router_id == 0) + if (eigrp->router_id.s_addr == 0) eigrp_router_id_update(eigrp); /* Run network config now. */ /* Get target interface. */ @@ -293,7 +293,7 @@ void eigrp_if_update(struct interface *ifp) */ for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) { /* EIGRP must be on and Router-ID must be configured. */ - if (!eigrp || eigrp->router_id == 0) + if (!eigrp || eigrp->router_id.s_addr == 0) continue; /* Run each network for this interface. */ diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index ce03a21fba..644ab0829f 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -79,8 +79,8 @@ struct eigrp { char *name; /* EIGRP Router ID. */ - uint32_t router_id; /* Configured automatically. */ - uint32_t router_id_static; /* Configured manually. */ + struct in_addr router_id; /* Configured automatically. */ + struct in_addr router_id_static; /* Configured manually. */ struct list *eiflist; /* eigrp interfaces */ uint8_t passive_interface_default; /* passive-interface default */ @@ -131,6 +131,9 @@ struct eigrp { uint32_t metric; } route_map[ZEBRA_ROUTE_MAX]; + /* distribute_ctx */ + struct distribute_ctx *distribute_ctx; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(eigrp) diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index a0c4fa887a..474f683989 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -174,7 +174,7 @@ static int config_write_eigrp_distribute(struct vty *vty, struct eigrp *eigrp) int write = 0; /* Distribute configuration. */ - write += config_write_distribute(vty); + write += config_write_distribute(vty, eigrp->distribute_ctx); return write; } @@ -191,15 +191,10 @@ static int config_write_eigrp_router(struct vty *vty, struct eigrp *eigrp) write++; - if (!eigrp->networks) - return write; - /* Router ID print. */ - if (eigrp->router_id_static != 0) { - struct in_addr router_id_static; - router_id_static.s_addr = htonl(eigrp->router_id_static); + if (eigrp->router_id_static.s_addr != 0) { vty_out(vty, " eigrp router-id %s\n", - inet_ntoa(router_id_static)); + inet_ntoa(eigrp->router_id_static)); } /* Network area print. */ @@ -255,29 +250,31 @@ DEFUN (no_router_eigrp, return CMD_SUCCESS; } -DEFUN (eigrp_router_id, +DEFPY (eigrp_router_id, eigrp_router_id_cmd, - "eigrp router-id A.B.C.D", + "eigrp router-id A.B.C.D$addr", "EIGRP specific commands\n" "Router ID for this EIGRP process\n" "EIGRP Router-ID in IP address format\n") { - // struct eigrp *eigrp = vty->index; - /*TODO: */ + VTY_DECLVAR_CONTEXT(eigrp, eigrp); + + eigrp->router_id_static = addr; return CMD_SUCCESS; } -DEFUN (no_eigrp_router_id, +DEFPY (no_eigrp_router_id, no_eigrp_router_id_cmd, - "no eigrp router-id A.B.C.D", + "no eigrp router-id [A.B.C.D$addr]", NO_STR "EIGRP specific commands\n" "Router ID for this EIGRP process\n" "EIGRP Router-ID in IP address format\n") { - // struct eigrp *eigrp = vty->index; - /*TODO: */ + VTY_DECLVAR_CONTEXT(eigrp, eigrp); + + eigrp->router_id_static.s_addr = 0; return CMD_SUCCESS; } diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 9bbecdf9e3..5541ec15f3 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -44,6 +44,7 @@ #include "keychain.h" #include "libfrr.h" #include "lib_errors.h" +#include "distribute.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" @@ -55,6 +56,7 @@ #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_filter.h" DEFINE_QOBJ_TYPE(eigrp) @@ -95,21 +97,21 @@ void eigrp_router_id_update(struct eigrp *eigrp) { struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - uint32_t router_id, router_id_old; + struct in_addr router_id, router_id_old; router_id_old = eigrp->router_id; - if (eigrp->router_id_static != 0) + if (eigrp->router_id_static.s_addr != 0) router_id = eigrp->router_id_static; - else if (eigrp->router_id != 0) + else if (eigrp->router_id.s_addr != 0) router_id = eigrp->router_id; else - router_id = router_id_zebra.s_addr; + router_id = router_id_zebra; eigrp->router_id = router_id; - if (router_id_old != router_id) { + if (router_id_old.s_addr != router_id.s_addr) { // if (IS_DEBUG_EIGRP_EVENT) // zlog_debug("Router-ID[NEW:%s]: Update", // inet_ntoa(eigrp->router_id)); @@ -142,8 +144,8 @@ static struct eigrp *eigrp_new(const char *AS) /* init information relevant to peers */ eigrp->vrid = 0; eigrp->AS = atoi(AS); - eigrp->router_id = 0L; - eigrp->router_id_static = 0L; + eigrp->router_id.s_addr = 0; + eigrp->router_id_static.s_addr = 0; eigrp->sequence_number = 1; /*Configure default K Values for EIGRP Process*/ @@ -197,6 +199,13 @@ static struct eigrp *eigrp_new(const char *AS) eigrp->routemap[EIGRP_FILTER_IN] = NULL; eigrp->routemap[EIGRP_FILTER_OUT] = NULL; + /* Distribute list install. */ + eigrp->distribute_ctx = distribute_list_ctx_create( + vrf_lookup_by_id(VRF_DEFAULT)); + distribute_list_add_hook(eigrp->distribute_ctx, + eigrp_distribute_update); + distribute_list_delete_hook(eigrp->distribute_ctx, + eigrp_distribute_update); QOBJ_REG(eigrp, eigrp); return eigrp; } @@ -279,6 +288,7 @@ void eigrp_finish_final(struct eigrp *eigrp) listnode_delete(eigrp_om->eigrp, eigrp); stream_free(eigrp->ibuf); + distribute_list_delete(&eigrp->distribute_ctx); XFREE(MTYPE_EIGRP_TOP, eigrp); } diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 86061b3ae3..d532afbbe6 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -66,5 +66,3 @@ noinst_HEADERS += \ eigrpd_eigrpd_SOURCES = eigrpd/eigrp_main.c eigrpd_eigrpd_LDADD = eigrpd/libeigrp.a lib/libfrr.la @LIBCAP@ - -EXTRA_DIST += eigrpd/EIGRP-MIB.txt diff --git a/fpm/subdir.am b/fpm/subdir.am index 05cec5a528..a0fa3d274f 100644 --- a/fpm/subdir.am +++ b/fpm/subdir.am @@ -1,6 +1,8 @@ if FPM +if HAVE_PROTOBUF lib_LTLIBRARIES += fpm/libfrrfpm_pb.la endif +endif fpm_libfrrfpm_pb_la_LDFLAGS = -version-info 0:0:0 fpm_libfrrfpm_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS) @@ -10,11 +12,9 @@ fpm_libfrrfpm_pb_la_SOURCES = \ fpm/fpm_pb.c \ # end -if HAVE_PROTOBUF nodist_fpm_libfrrfpm_pb_la_SOURCES = \ fpm/fpm.pb-c.c \ # end -endif CLEANFILES += \ fpm/fpm.pb-c.c \ diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index b0f2947ec6..e1cdfc30ea 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -258,6 +258,11 @@ void isis_adj_state_change(struct isis_adjacency *adj, reason ? reason : "unspecified"); } +#ifndef FABRICD + /* send northbound notification */ + isis_notif_adj_state_change(adj, new_state, reason); +#endif /* ifndef FABRICD */ + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { del = false; for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index e76e27a7dc..81b4b397ec 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -38,6 +38,7 @@ #include "prefix.h" #include "stream.h" #include "qobj.h" +#include "lib/northbound_cli.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -78,6 +79,47 @@ struct isis_circuit *isis_circuit_new() /* * Default values */ +#ifndef FABRICD + circuit->is_type = yang_get_default_enum( + "/frr-interface:lib/interface/frr-isisd:isis/circuit-type"); + circuit->flags = 0; + + circuit->pad_hellos = yang_get_default_bool( + "/frr-interface:lib/interface/frr-isisd:isis/hello/padding"); + circuit->hello_interval[0] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1"); + circuit->hello_interval[1] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2"); + circuit->hello_multiplier[0] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1"); + circuit->hello_multiplier[1] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2"); + circuit->csnp_interval[0] = yang_get_default_uint16( + "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1"); + circuit->csnp_interval[1] = yang_get_default_uint16( + "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2"); + circuit->psnp_interval[0] = yang_get_default_uint16( + "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1"); + circuit->psnp_interval[1] = yang_get_default_uint16( + "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2"); + circuit->priority[0] = yang_get_default_uint8( + "/frr-interface:lib/interface/frr-isisd:isis/priority/level-1"); + circuit->priority[1] = yang_get_default_uint8( + "/frr-interface:lib/interface/frr-isisd:isis/priority/level-2"); + circuit->metric[0] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1"); + circuit->metric[1] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2"); + circuit->te_metric[0] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/metric/level-1"); + circuit->te_metric[1] = yang_get_default_uint32( + "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2"); + + for (i = 0; i < 2; i++) { + circuit->level_arg[i].level = i + 1; + circuit->level_arg[i].circuit = circuit; + } +#else circuit->is_type = IS_LEVEL_1_AND_2; circuit->flags = 0; circuit->pad_hellos = 1; @@ -92,6 +134,7 @@ struct isis_circuit *isis_circuit_new() circuit->level_arg[i].level = i + 1; circuit->level_arg[i].circuit = circuit; } +#endif /* ifndef FABRICD */ circuit->mtc = mpls_te_circuit_new(); @@ -666,11 +709,21 @@ int isis_circuit_up(struct isis_circuit *circuit) circuit->tx_queue = isis_tx_queue_new(circuit, send_lsp); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_if_state_change(circuit, false); +#endif /* ifndef FABRICD */ + return ISIS_OK; } void isis_circuit_down(struct isis_circuit *circuit) { +#ifndef FABRICD + /* send northbound notification */ + isis_notif_if_state_change(circuit, true); +#endif /* ifndef FABRICD */ + /* Clear the flags for all the lsps of the circuit. */ isis_circuit_update_all_srmflags(circuit, 0); @@ -919,6 +972,7 @@ DEFINE_HOOK(isis_circuit_config_write, (struct isis_circuit *circuit, struct vty *vty), (circuit, vty)) +#ifdef FABRICD int isis_interface_config_write(struct vty *vty) { struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); @@ -1141,6 +1195,33 @@ int isis_interface_config_write(struct vty *vty) return write; } +#else +int isis_interface_config_write(struct vty *vty) +{ + struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + int write = 0; + struct interface *ifp; + struct isis_circuit *circuit; + struct lyd_node *dnode; + + FOR_ALL_INTERFACES (vrf, ifp) { + dnode = yang_dnode_get( + running_config->dnode, + "/frr-interface:lib/interface[name='%s'][vrf='%s']", + ifp->name, vrf->name); + if (dnode == NULL) + continue; + + write++; + nb_cli_show_dnode_cmds(vty, dnode, false); + circuit = circuit_scan_by_ifp(ifp); + if (circuit) + write += hook_call(isis_circuit_config_write, circuit, + vty); + } + return write; +} +#endif /* ifdef FABRICD */ struct isis_circuit *isis_circuit_create(struct isis_area *area, struct interface *ifp) @@ -1261,35 +1342,22 @@ struct cmd_node interface_node = { INTERFACE_NODE, "%s(config-if)# ", 1, }; -ferr_r isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type) +void isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type) { if (circuit->circ_type == circ_type) - return ferr_ok(); - - /* Changing the network type to/of loopback or unknown interfaces - * is not supported. */ - if (circ_type == CIRCUIT_T_UNKNOWN || circ_type == CIRCUIT_T_LOOPBACK - || circuit->circ_type == CIRCUIT_T_LOOPBACK) { - return ferr_cfg_invalid( - "cannot change network type on unknown interface"); - } + return; if (circuit->state != C_STATE_UP) { circuit->circ_type = circ_type; circuit->circ_type_config = circ_type; } else { struct isis_area *area = circuit->area; - if (circ_type == CIRCUIT_T_BROADCAST - && !if_is_broadcast(circuit->interface)) - return ferr_cfg_reality( - "cannot configure non-broadcast interface for broadcast operation"); isis_csm_state_change(ISIS_DISABLE, circuit, area); circuit->circ_type = circ_type; circuit->circ_type_config = circ_type; isis_csm_state_change(ISIS_ENABLE, circuit, area); } - return ferr_ok(); } int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index 5a0d4ffbab..73ead8f7da 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -184,7 +184,7 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router, bool ipv6_router); ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive); void isis_circuit_is_type_set(struct isis_circuit *circuit, int is_type); -ferr_r isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type); +void isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type); ferr_r isis_circuit_metric_set(struct isis_circuit *circuit, int level, int metric); diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c new file mode 100644 index 0000000000..c68f49f92d --- /dev/null +++ b/isisd/isis_cli.c @@ -0,0 +1,2024 @@ +/* + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2018 Volta Networks + * Emanuele Di Pascale + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "if.h" +#include "vrf.h" +#include "log.h" +#include "prefix.h" +#include "command.h" +#include "northbound_cli.h" +#include "libfrr.h" +#include "yang.h" +#include "lib/linklist.h" +#include "isisd/isisd.h" +#include "isisd/isis_cli.h" +#include "isisd/isis_misc.h" +#include "isisd/isis_circuit.h" +#include "isisd/isis_csm.h" + +#ifndef VTYSH_EXTRACT_PL +#include "isisd/isis_cli_clippy.c" +#endif + +#ifndef FABRICD + +/* + * XPath: /frr-isisd:isis/instance + */ +DEFPY_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag", + ROUTER_STR + "ISO IS-IS\n" + "ISO Routing area tag\n") +{ + int ret; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, XPATH_MAXLEN, + "/frr-isisd:isis/instance[area-tag='%s']", tag); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + /* default value in yang for is-type is level-1, but in FRR + * the first instance is assigned is-type level-1-2. We + * need to make sure to set it in the yang model so that it + * is consistent with what FRR sees. + */ + if (listcount(isis->area_list) == 0) + nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, + "level-1-2"); + ret = nb_cli_apply_changes(vty, base_xpath); + if (ret == CMD_SUCCESS) + VTY_PUSH_XPATH(ISIS_NODE, base_xpath); + + return ret; +} + +DEFPY(no_router_isis, no_router_isis_cmd, "no router isis WORD$tag", + NO_STR ROUTER_STR + "ISO IS-IS\n" + "ISO Routing area tag\n") +{ + char temp_xpath[XPATH_MAXLEN]; + struct listnode *node, *nnode; + struct isis_circuit *circuit = NULL; + struct isis_area *area = NULL; + + if (!yang_dnode_exists(vty->candidate_config->dnode, + "/frr-isisd:isis/instance[area-tag='%s']", + tag)) { + vty_out(vty, "ISIS area %s not found.\n", tag); + return CMD_ERR_NOTHING_TODO; + } + + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + area = isis_area_lookup(tag); + if (area && area->circuit_list && listcount(area->circuit_list)) { + for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode, + circuit)) { + /* add callbacks to delete each of the circuits listed + */ + const char *vrf_name = + vrf_lookup_by_id(circuit->interface->vrf_id) + ->name; + snprintf( + temp_xpath, XPATH_MAXLEN, + "/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis", + circuit->interface->name, vrf_name); + nb_cli_enqueue_change(vty, temp_xpath, NB_OP_DELETE, + NULL); + } + } + + return nb_cli_apply_changes( + vty, "/frr-isisd:isis/instance[area-tag='%s']", tag); +} + +void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, "!\n"); + vty_out(vty, "router isis %s\n", + yang_dnode_get_string(dnode, "./area-tag")); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/ + * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing + * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing + * XPath: /frr-isisd:isis/instance + */ +DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + "IS-IS routing protocol\n" + "Routing process tag\n") +{ + char temp_xpath[XPATH_MAXLEN]; + const char *circ_type; + struct isis_area *area; + struct interface *ifp; + const struct lyd_node *dnode = + yang_dnode_get(running_config->dnode, VTY_CURR_XPATH); + + /* area will be created if it is not present. make sure the yang model + * is synced with FRR and call the appropriate NB cb. + */ + area = isis_area_lookup(tag); + if (!area) { + snprintf(temp_xpath, XPATH_MAXLEN, + "/frr-isisd:isis/instance[area-tag='%s']", tag); + nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag); + snprintf(temp_xpath, XPATH_MAXLEN, + "/frr-isisd:isis/instance[area-tag='%s']/is-type", + tag); + nb_cli_enqueue_change( + vty, temp_xpath, NB_OP_MODIFY, + listcount(isis->area_list) == 0 ? "level-1-2" : NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", + NB_OP_MODIFY, tag); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY, + listcount(isis->area_list) == 0 ? "level-1-2" + : "level-1"); + } else { + /* area exists, circuit type defaults to its area's is_type */ + switch (area->is_type) { + case IS_LEVEL_1: + circ_type = "level-1"; + break; + case IS_LEVEL_2: + circ_type = "level-2"; + break; + case IS_LEVEL_1_AND_2: + circ_type = "level-1-2"; + break; + default: + /* just to silence compiler warnings */ + return CMD_WARNING_CONFIG_FAILED; + } + nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", + NB_OP_MODIFY, tag); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type", + NB_OP_MODIFY, circ_type); + } + + /* check if the interface is a loopback and if so set it as passive */ + ifp = yang_dnode_get_entry(dnode, false); + if (ifp && if_is_loopback(ifp)) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + "IS-IS routing protocol\n" + "Routing process tag\n") +{ + char temp_xpath[XPATH_MAXLEN]; + const char *circ_type; + struct isis_area *area; + struct interface *ifp; + const struct lyd_node *dnode = + yang_dnode_get(running_config->dnode, VTY_CURR_XPATH); + + /* area will be created if it is not present. make sure the yang model + * is synced with FRR and call the appropriate NB cb. + */ + area = isis_area_lookup(tag); + if (!area) { + snprintf(temp_xpath, XPATH_MAXLEN, + "/frr-isisd:isis/instance[area-tag='%s']", tag); + nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag); + snprintf(temp_xpath, XPATH_MAXLEN, + "/frr-isisd:isis/instance[area-tag='%s']/is-type", + tag); + nb_cli_enqueue_change( + vty, temp_xpath, NB_OP_MODIFY, + listcount(isis->area_list) == 0 ? "level-1-2" : NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", + NB_OP_MODIFY, tag); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY, + listcount(isis->area_list) == 0 ? "level-1-2" + : "level-1"); + } else { + /* area exists, circuit type defaults to its area's is_type */ + switch (area->is_type) { + case IS_LEVEL_1: + circ_type = "level-1"; + break; + case IS_LEVEL_2: + circ_type = "level-2"; + break; + case IS_LEVEL_1_AND_2: + circ_type = "level-1-2"; + break; + default: + /* just to silence compiler warnings */ + return CMD_WARNING_CONFIG_FAILED; + } + nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", + NB_OP_MODIFY, tag); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type", + NB_OP_MODIFY, circ_type); + } + + /* check if the interface is a loopback and if so set it as passive */ + ifp = yang_dnode_get_entry(dnode, false); + if (ifp && if_is_loopback(ifp)) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_ip_router_isis, no_ip_router_isis_cmd, + "no <ip|ipv6>$ip router isis [WORD]$tag", + NO_STR + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + "IP router interface commands\n" + "IS-IS routing protocol\n" + "Routing process tag\n") +{ + const struct lyd_node *dnode = + yang_dnode_get(running_config->dnode, VTY_CURR_XPATH); + + /* if both ipv4 and ipv6 are off delete the interface isis container too + */ + if (!strncmp(ip, "ipv6", strlen("ipv6"))) { + if (dnode + && !yang_dnode_get_bool(dnode, + "./frr-isisd:isis/ipv4-routing")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis", + NB_OP_DELETE, NULL); + else + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/ipv6-routing", + NB_OP_MODIFY, "false"); + } else { /* no ipv4 */ + if (dnode + && !yang_dnode_get_bool(dnode, + "./frr-isisd:isis/ipv6-routing")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis", + NB_OP_DELETE, NULL); + else + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/ipv4-routing", + NB_OP_MODIFY, "false"); + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " ip router isis %s\n", + yang_dnode_get_string(dnode, "../area-tag")); +} + +void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " ipv6 router isis %s\n", + yang_dnode_get_string(dnode, "../area-tag")); +} + +/* + * XPath: /frr-isisd:isis/instance/area-address + */ +DEFPY(net, net_cmd, "[no] net WORD", + "Remove an existing Network Entity Title for this process\n" + "A Network Entity Title for this process (OSI only)\n" + "XX.XXXX. ... .XXX.XX Network entity title (NET)\n") +{ + nb_cli_enqueue_change(vty, "./area-address", + no ? NB_OP_DELETE : NB_OP_CREATE, net); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " net %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/is-type + */ +DEFPY(is_type, is_type_cmd, "is-type <level-1|level-1-2|level-2-only>$level", + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, + strmatch(level, "level-2-only") ? "level-2" + : level); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_is_type, no_is_type_cmd, + "no is-type [<level-1|level-1-2|level-2-only>]", + NO_STR + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + const char *value = NULL; + const struct lyd_node *dnode = + yang_dnode_get(running_config->dnode, VTY_CURR_XPATH); + struct isis_area *area = yang_dnode_get_entry(dnode, false); + + /* + * Put the is-type back to defaults: + * - level-1-2 on first area + * - level-1 for the rest + */ + if (area && listgetdata(listhead(isis->area_list)) == area) + value = "level-1-2"; + else + value = NULL; + nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, value); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_is_type(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + int is_type = yang_dnode_get_enum(dnode, NULL); + + switch (is_type) { + case IS_LEVEL_1: + vty_out(vty, " is-type level-1\n"); + break; + case IS_LEVEL_2: + vty_out(vty, " is-type level-2-only\n"); + break; + case IS_LEVEL_1_AND_2: + vty_out(vty, " is-type level-1-2\n"); + break; + } +} + +/* + * XPath: /frr-isisd:isis/instance/dynamic-hostname + */ +DEFPY(dynamic_hostname, dynamic_hostname_cmd, "[no] hostname dynamic", + NO_STR + "Dynamic hostname for IS-IS\n" + "Dynamic hostname\n") +{ + nb_cli_enqueue_change(vty, "./dynamic-hostname", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " hostname dynamic\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/overload + */ +DEFPY(set_overload_bit, set_overload_bit_cmd, "[no] set-overload-bit", + "Reset overload bit to accept transit traffic\n" + "Set overload bit to avoid any transit traffic\n") +{ + nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " set-overload-bit\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/attached + */ +DEFPY(set_attached_bit, set_attached_bit_cmd, "[no] set-attached-bit", + "Reset attached bit\n" + "Set attached bit to identify as L1/L2 router for inter-area traffic\n") +{ + nb_cli_enqueue_change(vty, "./attached", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " set-attached-bit\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/metric-style + */ +DEFPY(metric_style, metric_style_cmd, + "metric-style <narrow|transition|wide>$style", + "Use old-style (ISO 10589) or new-style packet formats\n" + "Use old style of TLVs with narrow metric\n" + "Send and accept both styles of TLVs during transition\n" + "Use new style of TLVs to carry wider metric\n") +{ + nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, style); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_metric_style, no_metric_style_cmd, + "no metric-style [narrow|transition|wide]", + NO_STR + "Use old-style (ISO 10589) or new-style packet formats\n" + "Use old style of TLVs with narrow metric\n" + "Send and accept both styles of TLVs during transition\n" + "Use new style of TLVs to carry wider metric\n") +{ + nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, "narrow"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + int metric = yang_dnode_get_enum(dnode, NULL); + + switch (metric) { + case ISIS_NARROW_METRIC: + vty_out(vty, " metric-style narrow\n"); + break; + case ISIS_WIDE_METRIC: + vty_out(vty, " metric-style wide\n"); + break; + case ISIS_TRANSITION_METRIC: + vty_out(vty, " metric-style transition\n"); + break; + } +} + +/* + * XPath: /frr-isisd:isis/instance/area-password + */ +DEFPY(area_passwd, area_passwd_cmd, + "area-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]", + "Configure the authentication password for an area\n" + "Clear-text authentication type\n" + "MD5 authentication type\n" + "Level-wide password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + nb_cli_enqueue_change(vty, "./area-password", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./area-password/password", NB_OP_MODIFY, + pwd); + nb_cli_enqueue_change(vty, "./area-password/password-type", + NB_OP_MODIFY, pwd_type); + nb_cli_enqueue_change(vty, "./area-password/authenticate-snp", + NB_OP_MODIFY, snp ? snp : "none"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_area_pwd(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *snp; + + vty_out(vty, " area-password %s %s", + yang_dnode_get_string(dnode, "./password-type"), + yang_dnode_get_string(dnode, "./password")); + snp = yang_dnode_get_string(dnode, "./authenticate-snp"); + if (!strmatch("none", snp)) + vty_out(vty, " authenticate snp %s", snp); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/domain-password + */ +DEFPY(domain_passwd, domain_passwd_cmd, + "domain-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]", + "Set the authentication password for a routing domain\n" + "Clear-text authentication type\n" + "MD5 authentication type\n" + "Level-wide password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + nb_cli_enqueue_change(vty, "./domain-password", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./domain-password/password", NB_OP_MODIFY, + pwd); + nb_cli_enqueue_change(vty, "./domain-password/password-type", + NB_OP_MODIFY, pwd_type); + nb_cli_enqueue_change(vty, "./domain-password/authenticate-snp", + NB_OP_MODIFY, snp ? snp : "none"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_area_passwd, no_area_passwd_cmd, + "no <area-password|domain-password>$cmd", + NO_STR + "Configure the authentication password for an area\n" + "Set the authentication password for a routing domain\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + + return nb_cli_apply_changes(vty, "./%s", cmd); +} + +void cli_show_isis_domain_pwd(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *snp; + + vty_out(vty, " domain-password %s %s", + yang_dnode_get_string(dnode, "./password-type"), + yang_dnode_get_string(dnode, "./password")); + snp = yang_dnode_get_string(dnode, "./authenticate-snp"); + if (!strmatch("none", snp)) + vty_out(vty, " authenticate snp %s", snp); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/generation-interval + */ +DEFPY(lsp_gen_interval, lsp_gen_interval_cmd, + "lsp-gen-interval [level-1|level-2]$level (1-120)$val", + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-1", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-2", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_lsp_gen_interval, no_lsp_gen_interval_cmd, + "no lsp-gen-interval [level-1|level-2]$level [(1-120)]", + NO_STR + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./lsp/generation-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_lsp_gen_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " lsp-gen-interval %s\n", l1); + else { + vty_out(vty, " lsp-gen-interval level-1 %s\n", l1); + vty_out(vty, " lsp-gen-interval level-2 %s\n", l2); + } +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/refresh-interval + */ +DEFPY(lsp_refresh_interval, lsp_refresh_interval_cmd, + "lsp-refresh-interval [level-1|level-2]$level (1-65235)$val", + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-1", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-2", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_lsp_refresh_interval, no_lsp_refresh_interval_cmd, + "no lsp-refresh-interval [level-1|level-2]$level [(1-65235)]", + NO_STR + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./lsp/refresh-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_lsp_ref_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " lsp-refresh-interval %s\n", l1); + else { + vty_out(vty, " lsp-refresh-interval level-1 %s\n", l1); + vty_out(vty, " lsp-refresh-interval level-2 %s\n", l2); + } +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/maximum-lifetime + */ +DEFPY(max_lsp_lifetime, max_lsp_lifetime_cmd, + "max-lsp-lifetime [level-1|level-2]$level (350-65535)$val", + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-1", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-2", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_max_lsp_lifetime, no_max_lsp_lifetime_cmd, + "no max-lsp-lifetime [level-1|level-2]$level [(350-65535)]", + NO_STR + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./lsp/maximum-lifetime/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_lsp_max_lifetime(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " max-lsp-lifetime %s\n", l1); + else { + vty_out(vty, " max-lsp-lifetime level-1 %s\n", l1); + vty_out(vty, " max-lsp-lifetime level-2 %s\n", l2); + } +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/mtu + */ +DEFPY(area_lsp_mtu, area_lsp_mtu_cmd, "lsp-mtu (128-4352)$val", + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_area_lsp_mtu, no_area_lsp_mtu_cmd, "no lsp-mtu [(128-4352)]", + NO_STR + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_lsp_mtu(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " lsp-mtu %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/spf/minimum-interval + */ +DEFPY(spf_interval, spf_interval_cmd, + "spf-interval [level-1|level-2]$level (1-120)$val", + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_spf_interval, no_spf_interval_cmd, + "no spf-interval [level-1|level-2]$level [(1-120)]", + NO_STR + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_spf_min_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " spf-interval %s\n", l1); + else { + vty_out(vty, " spf-interval level-1 %s\n", l1); + vty_out(vty, " spf-interval level-2 %s\n", l2); + } +} + +/* + * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay + */ +DEFPY(spf_delay_ietf, spf_delay_ietf_cmd, + "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", + "IETF SPF delay algorithm\n" + "Delay used while in QUIET state\n" + "Delay used while in QUIET state in milliseconds\n" + "Delay used while in SHORT_WAIT state\n" + "Delay used while in SHORT_WAIT state in milliseconds\n" + "Delay used while in LONG_WAIT\n" + "Delay used while in LONG_WAIT state in milliseconds\n" + "Time with no received IGP events before considering IGP stable\n" + "Time with no received IGP events before considering IGP stable (in milliseconds)\n" + "Maximum duration needed to learn all the events related to a single failure\n" + "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") +{ + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/init-delay", + NB_OP_MODIFY, init_delay_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/short-delay", + NB_OP_MODIFY, short_delay_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/long-delay", + NB_OP_MODIFY, long_delay_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/hold-down", + NB_OP_MODIFY, holddown_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/time-to-learn", + NB_OP_MODIFY, time_to_learn_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_spf_delay_ietf, no_spf_delay_ietf_cmd, + "no spf-delay-ietf [init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)]", + NO_STR + "IETF SPF delay algorithm\n" + "Delay used while in QUIET state\n" + "Delay used while in QUIET state in milliseconds\n" + "Delay used while in SHORT_WAIT state\n" + "Delay used while in SHORT_WAIT state in milliseconds\n" + "Delay used while in LONG_WAIT\n" + "Delay used while in LONG_WAIT state in milliseconds\n" + "Time with no received IGP events before considering IGP stable\n" + "Time with no received IGP events before considering IGP stable (in milliseconds)\n" + "Maximum duration needed to learn all the events related to a single failure\n" + "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") +{ + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_DELETE, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_spf_ietf_backoff(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, + " spf-delay-ietf init-delay %s short-delay %s long-delay %s holddown %s time-to-learn %s\n", + yang_dnode_get_string(dnode, "./init-delay"), + yang_dnode_get_string(dnode, "./short-delay"), + yang_dnode_get_string(dnode, "./long-delay"), + yang_dnode_get_string(dnode, "./hold-down"), + yang_dnode_get_string(dnode, "./time-to-learn")); +} + +/* + * XPath: /frr-isisd:isis/instance/purge-originator + */ +DEFPY(area_purge_originator, area_purge_originator_cmd, "[no] purge-originator", + NO_STR "Use the RFC 6232 purge-originator\n") +{ + nb_cli_enqueue_change(vty, "./purge-originator", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_purge_origin(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " purge-originator\n"); +} + +/* + * XPath: /frr-isisd:isis/mpls-te + */ +DEFPY(isis_mpls_te_on, isis_mpls_te_on_cmd, "mpls-te on", + MPLS_TE_STR "Enable the MPLS-TE functionality\n") +{ + nb_cli_enqueue_change(vty, "/frr-isisd:isis/mpls-te", NB_OP_CREATE, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_mpls_te_on, no_isis_mpls_te_on_cmd, "no mpls-te [on]", + NO_STR + "Disable the MPLS-TE functionality\n" + "Enable the MPLS-TE functionality\n") +{ + nb_cli_enqueue_change(vty, "/frr-isisd:isis/mpls-te", NB_OP_DELETE, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls-te on\n"); +} + +/* + * XPath: /frr-isisd:isis/mpls-te/router-address + */ +DEFPY(isis_mpls_te_router_addr, isis_mpls_te_router_addr_cmd, + "mpls-te router-address A.B.C.D", + MPLS_TE_STR + "Stable IP address of the advertising router\n" + "MPLS-TE router address in IPv4 address format\n") +{ + nb_cli_enqueue_change(vty, "/frr-isisd:isis/mpls-te/router-address", + NB_OP_MODIFY, router_address_str); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls-te router-address %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd, + "[no] mpls-te inter-as [level-1|level-1-2|level-2-only]", + NO_STR MPLS_TE_STR + "Configure MPLS-TE Inter-AS support\n" + "AREA native mode self originate INTER-AS LSP with L1 only flooding scope\n" + "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope\n" + "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n") +{ + vty_out(vty, "MPLS-TE Inter-AS is not yet supported."); + return CMD_SUCCESS; +} + +/* + * XPath: /frr-isisd:isis/instance/default-information-originate + */ +DEFPY(isis_default_originate, isis_default_originate_cmd, + "[no] default-information originate <ipv4|ipv6>$ip" + " <level-1|level-2>$level [always]$always" + " [<metric (0-16777215)$metric|route-map WORD$rmap>]", + NO_STR + "Control distribution of default information\n" + "Distribute a default route\n" + "Distribute default route for IPv4\n" + "Distribute default route for IPv6\n" + "Distribute default route into level-1\n" + "Distribute default route into level-2\n" + "Always advertise default route\n" + "Metric for default route\n" + "ISIS default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./always", NB_OP_MODIFY, + always ? "true" : "false"); + nb_cli_enqueue_change(vty, "./route-map", + rmap ? NB_OP_MODIFY : NB_OP_DELETE, + rmap ? rmap : NULL); + nb_cli_enqueue_change(vty, "./metric", + metric ? NB_OP_MODIFY : NB_OP_DELETE, + metric ? metric_str : NULL); + if (strmatch(ip, "ipv6") && !always) { + vty_out(vty, + "Zebra doesn't implement default-originate for IPv6 yet\n"); + vty_out(vty, + "so use with care or use default-originate always.\n"); + } + } + + return nb_cli_apply_changes( + vty, "./default-information-originate/%s[level='%s']", ip, + level); +} + +static void vty_print_def_origin(struct vty *vty, struct lyd_node *dnode, + const char *family, const char *level, + bool show_defaults) +{ + const char *metric; + + vty_out(vty, " default-information originate %s %s", family, level); + if (yang_dnode_get_bool(dnode, "./always")) + vty_out(vty, " always"); + + if (yang_dnode_exists(dnode, "./route-map")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./route-map")); + else if (yang_dnode_exists(dnode, "./metric")) { + metric = yang_dnode_get_string(dnode, "./metric"); + if (show_defaults || !yang_dnode_is_default(dnode, "./metric")) + vty_out(vty, " metric %s", metric); + } + vty_out(vty, "\n"); +} + +void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *level = yang_dnode_get_string(dnode, "./level"); + + vty_print_def_origin(vty, dnode, "ipv4", level, show_defaults); +} + +void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *level = yang_dnode_get_string(dnode, "./level"); + + vty_print_def_origin(vty, dnode, "ipv6", level, show_defaults); +} + +/* + * XPath: /frr-isisd:isis/instance/redistribute + */ +DEFPY(isis_redistribute, isis_redistribute_cmd, + "[no] redistribute <ipv4|ipv6>$ip " PROTO_REDIST_STR + "$proto" + " <level-1|level-2>$level" + " [<metric (0-16777215)|route-map WORD>]", + NO_STR REDIST_STR + "Redistribute IPv4 routes\n" + "Redistribute IPv6 routes\n" PROTO_REDIST_HELP + "Redistribute into level-1\n" + "Redistribute into level-2\n" + "Metric for redistributed routes\n" + "ISIS default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./route-map", + route_map ? NB_OP_MODIFY : NB_OP_DELETE, + route_map ? route_map : NULL); + nb_cli_enqueue_change(vty, "./metric", + metric ? NB_OP_MODIFY : NB_OP_DELETE, + metric ? metric_str : NULL); + } + + return nb_cli_apply_changes( + vty, "./redistribute/%s[protocol='%s'][level='%s']", ip, proto, + level); +} + +static void vty_print_redistribute(struct vty *vty, struct lyd_node *dnode, + const char *family) +{ + const char *level = yang_dnode_get_string(dnode, "./level"); + const char *protocol = yang_dnode_get_string(dnode, "./protocol"); + + vty_out(vty, " redistribute %s %s %s", family, protocol, level); + if (yang_dnode_exists(dnode, "./metric")) + vty_out(vty, " metric %s", + yang_dnode_get_string(dnode, "./metric")); + else if (yang_dnode_exists(dnode, "./route-map")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./route-map")); + vty_out(vty, "\n"); +} + +void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_print_redistribute(vty, dnode, "ipv4"); +} +void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_print_redistribute(vty, dnode, "ipv6"); +} + +/* + * XPath: /frr-isisd:isis/instance/multi-topology + */ +DEFPY(isis_topology, isis_topology_cmd, + "[no] topology " + "<ipv4-unicast" + "|ipv4-mgmt" + "|ipv6-unicast" + "|ipv4-multicast" + "|ipv6-multicast" + "|ipv6-mgmt" + "|ipv6-dstsrc>$topology " + "[overload]$overload", + NO_STR + "Configure IS-IS topologies\n" + "IPv4 unicast topology\n" + "IPv4 management topology\n" + "IPv6 unicast topology\n" + "IPv4 multicast topology\n" + "IPv6 multicast topology\n" + "IPv6 management topology\n" + "IPv6 dst-src topology\n" + "Set overload bit for topology\n") +{ + char base_xpath[XPATH_MAXLEN]; + + /* Since IPv4-unicast is not configurable it is not present in the + * YANG model, so we need to validate it here + */ + if (strmatch(topology, "ipv4-unicast")) { + vty_out(vty, "Cannot configure IPv4 unicast topology\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(topology, "ipv4-mgmt")) + snprintf(base_xpath, XPATH_MAXLEN, + "./multi-topology/ipv4-management"); + else if (strmatch(topology, "ipv6-mgmt")) + snprintf(base_xpath, XPATH_MAXLEN, + "./multi-topology/ipv6-management"); + else + snprintf(base_xpath, XPATH_MAXLEN, "./multi-topology/%s", + topology); + + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY, + overload ? "true" : "false"); + } + + return nb_cli_apply_changes(vty, base_xpath); +} + +void cli_show_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv4-multicast"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv4-mgmt"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-unicast"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-multicast"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-mgmt"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-dstsrc"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive + */ +DEFPY(isis_passive, isis_passive_cmd, "[no] isis passive", + NO_STR + "IS-IS routing protocol\n" + "Configure the passive mode for interface\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_passive(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis passive\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/password + */ + +DEFPY(isis_passwd, isis_passwd_cmd, "isis password <md5|clear>$type WORD$pwd", + "IS-IS routing protocol\n" + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password", + NB_OP_MODIFY, pwd); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password-type", + NB_OP_MODIFY, type); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_passwd, no_isis_passwd_cmd, "no isis password [<md5|clear> WORD]", + NO_STR + "IS-IS routing protocol\n" + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_DELETE, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_password(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " isis password %s %s\n", + yang_dnode_get_string(dnode, "./password-type"), + yang_dnode_get_string(dnode, "./password")); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric + */ +DEFPY(isis_metric, isis_metric_cmd, + "isis metric [level-1|level-2]$level (0-16777215)$met", + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n" + "Default metric value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1", + NB_OP_MODIFY, met_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2", + NB_OP_MODIFY, met_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_metric, no_isis_metric_cmd, + "no isis metric [level-1|level-2]$level [(0-16777215)]", + NO_STR + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n" + "Default metric value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_metric(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis metric %s\n", l1); + else { + vty_out(vty, " isis metric %s level-1\n", l1); + vty_out(vty, " isis metric %s level-2\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval + */ +DEFPY(isis_hello_interval, isis_hello_interval_cmd, + "isis hello-interval [level-1|level-2]$level (1-600)$intv", + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n" + "Holdtime 1 seconds, interval depends on multiplier\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-1", + NB_OP_MODIFY, intv_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-2", + NB_OP_MODIFY, intv_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_hello_interval, no_isis_hello_interval_cmd, + "no isis hello-interval [level-1|level-2]$level [(1-600)]", + NO_STR + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n" + "Holdtime 1 second, interval depends on multiplier\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_hello_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis hello-interval %s\n", l1); + else { + vty_out(vty, " isis hello-interval %s level-1\n", l1); + vty_out(vty, " isis hello-interval %s level-2\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier + */ +DEFPY(isis_hello_multiplier, isis_hello_multiplier_cmd, + "isis hello-multiplier [level-1|level-2]$level (2-100)$mult", + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n" + "Hello multiplier value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-1", + NB_OP_MODIFY, mult_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-2", + NB_OP_MODIFY, mult_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_hello_multiplier, no_isis_hello_multiplier_cmd, + "no isis hello-multiplier [level-1|level-2]$level [(2-100)]", + NO_STR + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n" + "Hello multiplier value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_hello_multi(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis hello-multiplier %s\n", l1); + else { + vty_out(vty, " isis hello-multiplier %s level-1\n", l1); + vty_out(vty, " isis hello-multiplier %s level-2\n", l2); + } +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake + */ +DEFPY(isis_threeway_adj, isis_threeway_adj_cmd, "[no] isis three-way-handshake", + NO_STR + "IS-IS commands\n" + "Enable/Disable three-way handshake\n") +{ + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/disable-three-way-handshake", + NB_OP_MODIFY, no ? "true" : "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_threeway_shake(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis three-way-handshake\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding + */ +DEFPY(isis_hello_padding, isis_hello_padding_cmd, "[no] isis hello padding", + NO_STR + "IS-IS routing protocol\n" + "Add padding to IS-IS hello packets\n" + "Pad hello packets\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/hello/padding", + NB_OP_MODIFY, no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_hello_padding(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " isis hello padding\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval + */ +DEFPY(csnp_interval, csnp_interval_cmd, + "isis csnp-interval (1-600)$intv [level-1|level-2]$level", + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-1", + NB_OP_MODIFY, intv_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-2", + NB_OP_MODIFY, intv_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_csnp_interval, no_csnp_interval_cmd, + "no isis csnp-interval [(1-600)] [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_csnp_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis csnp-interval %s\n", l1); + else { + vty_out(vty, " isis csnp-interval %s level-1\n", l1); + vty_out(vty, " isis csnp-interval %s level-2\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval + */ +DEFPY(psnp_interval, psnp_interval_cmd, + "isis psnp-interval (1-120)$intv [level-1|level-2]$level", + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-1", + NB_OP_MODIFY, intv_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-2", + NB_OP_MODIFY, intv_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_psnp_interval, no_psnp_interval_cmd, + "no isis psnp-interval [(1-120)] [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_psnp_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis psnp-interval %s\n", l1); + else { + vty_out(vty, " isis psnp-interval %s level-1\n", l1); + vty_out(vty, " isis psnp-interval %s level-2\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology + */ +DEFPY(circuit_topology, circuit_topology_cmd, + "[no] isis topology" + "<ipv4-unicast" + "|ipv4-mgmt" + "|ipv6-unicast" + "|ipv4-multicast" + "|ipv6-multicast" + "|ipv6-mgmt" + "|ipv6-dstsrc" + ">$topology", + NO_STR + "IS-IS routing protocol\n" + "Configure interface IS-IS topologies\n" + "IPv4 unicast topology\n" + "IPv4 management topology\n" + "IPv6 unicast topology\n" + "IPv4 multicast topology\n" + "IPv6 multicast topology\n" + "IPv6 management topology\n" + "IPv6 dst-src topology\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_MODIFY, no ? "false" : "true"); + + if (strmatch(topology, "ipv4-mgmt")) + return nb_cli_apply_changes( + vty, "./frr-isisd:isis/multi-topology/ipv4-management"); + else if (strmatch(topology, "ipv6-mgmt")) + return nb_cli_apply_changes( + vty, "./frr-isisd:isis/multi-topology/ipv6-management"); + else + return nb_cli_apply_changes( + vty, "./frr-isisd:isis/multi-topology/%s", topology); +} + +void cli_show_ip_isis_mt_ipv4_unicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv4-unicast\n"); +} + +void cli_show_ip_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv4-multicast\n"); +} + +void cli_show_ip_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv4-mgmt\n"); +} + +void cli_show_ip_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-unicast\n"); +} + +void cli_show_ip_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-multicast\n"); +} + +void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-mgmt\n"); +} + +void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-dstsrc\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type + */ +DEFPY(isis_circuit_type, isis_circuit_type_cmd, + "isis circuit-type <level-1|level-1-2|level-2-only>$type", + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY, + strmatch(type, "level-2-only") ? "level-2" : type); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_circuit_type, no_isis_circuit_type_cmd, + "no isis circuit-type [level-1|level-1-2|level-2-only]", + NO_STR + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + const struct lyd_node *dnode; + struct interface *ifp; + struct isis_circuit *circuit; + int is_type; + const char *circ_type; + + /* + * Default value depends on whether the circuit is part of an area, + * and the is-type of the area if there is one. So we need to do this + * here. + */ + dnode = yang_dnode_get(running_config->dnode, VTY_CURR_XPATH); + ifp = yang_dnode_get_entry(dnode, false); + if (!ifp) + goto def_val; + + circuit = circuit_scan_by_ifp(ifp); + if (!circuit) + goto def_val; + + if (circuit->state == C_STATE_UP) + is_type = circuit->area->is_type; + else + goto def_val; + + switch (is_type) { + case IS_LEVEL_1: + circ_type = "level-1"; + break; + case IS_LEVEL_2: + circ_type = "level-2"; + break; + case IS_LEVEL_1_AND_2: + circ_type = "level-1-2"; + break; + default: + return CMD_ERR_NO_MATCH; + } + nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type", + NB_OP_MODIFY, circ_type); + + return nb_cli_apply_changes(vty, NULL); + +def_val: + nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + int level = yang_dnode_get_enum(dnode, NULL); + + switch (level) { + case IS_LEVEL_1: + vty_out(vty, " isis circuit-type level-1\n"); + break; + case IS_LEVEL_2: + vty_out(vty, " isis circuit-type level-2-only\n"); + break; + case IS_LEVEL_1_AND_2: + vty_out(vty, " isis circuit-type level-1-2\n"); + break; + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type + */ +DEFPY(isis_network, isis_network_cmd, "[no] isis network point-to-point", + NO_STR + "IS-IS routing protocol\n" + "Set network type\n" + "point-to-point network type\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/network-type", + NB_OP_MODIFY, + no ? "broadcast" : "point-to-point"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_enum(dnode, NULL) != CIRCUIT_T_P2P) + vty_out(vty, " no"); + + vty_out(vty, " isis network point-to-point\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority + */ +DEFPY(isis_priority, isis_priority_cmd, + "isis priority (0-127)$prio [level-1|level-2]$level", + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1", + NB_OP_MODIFY, prio_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2", + NB_OP_MODIFY, prio_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_priority, no_isis_priority_cmd, + "no isis priority [(0-127)] [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis priority %s\n", l1); + else { + vty_out(vty, " isis priority %s level-1\n", l1); + vty_out(vty, " isis priority %s level-2\n", l2); + } +} + +/* + * XPath: /frr-isisd:isis/instance/log-adjacency-changes + */ +DEFPY(log_adj_changes, log_adj_changes_cmd, "[no] log-adjacency-changes", + NO_STR "Log changes in adjacency state\n") +{ + nb_cli_enqueue_change(vty, "./log-adjacency-changes", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_log_adjacency(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " log-adjacency-changes\n"); +} + +void isis_cli_init(void) +{ + install_element(CONFIG_NODE, &router_isis_cmd); + install_element(CONFIG_NODE, &no_router_isis_cmd); + + install_element(INTERFACE_NODE, &ip_router_isis_cmd); + install_element(INTERFACE_NODE, &ip6_router_isis_cmd); + install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); + + install_element(ISIS_NODE, &net_cmd); + + install_element(ISIS_NODE, &is_type_cmd); + install_element(ISIS_NODE, &no_is_type_cmd); + + install_element(ISIS_NODE, &dynamic_hostname_cmd); + + install_element(ISIS_NODE, &set_overload_bit_cmd); + install_element(ISIS_NODE, &set_attached_bit_cmd); + + install_element(ISIS_NODE, &metric_style_cmd); + install_element(ISIS_NODE, &no_metric_style_cmd); + + install_element(ISIS_NODE, &area_passwd_cmd); + install_element(ISIS_NODE, &domain_passwd_cmd); + install_element(ISIS_NODE, &no_area_passwd_cmd); + + install_element(ISIS_NODE, &lsp_gen_interval_cmd); + install_element(ISIS_NODE, &no_lsp_gen_interval_cmd); + install_element(ISIS_NODE, &lsp_refresh_interval_cmd); + install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd); + install_element(ISIS_NODE, &max_lsp_lifetime_cmd); + install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd); + install_element(ISIS_NODE, &area_lsp_mtu_cmd); + install_element(ISIS_NODE, &no_area_lsp_mtu_cmd); + + install_element(ISIS_NODE, &spf_interval_cmd); + install_element(ISIS_NODE, &no_spf_interval_cmd); + install_element(ISIS_NODE, &spf_delay_ietf_cmd); + install_element(ISIS_NODE, &no_spf_delay_ietf_cmd); + + install_element(ISIS_NODE, &area_purge_originator_cmd); + + install_element(ISIS_NODE, &isis_mpls_te_on_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd); + install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd); + install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd); + + install_element(ISIS_NODE, &isis_default_originate_cmd); + install_element(ISIS_NODE, &isis_redistribute_cmd); + + install_element(ISIS_NODE, &isis_topology_cmd); + + install_element(INTERFACE_NODE, &isis_passive_cmd); + + install_element(INTERFACE_NODE, &isis_passwd_cmd); + install_element(INTERFACE_NODE, &no_isis_passwd_cmd); + + install_element(INTERFACE_NODE, &isis_metric_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_cmd); + + install_element(INTERFACE_NODE, &isis_hello_interval_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); + + install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); + + install_element(INTERFACE_NODE, &isis_threeway_adj_cmd); + + install_element(INTERFACE_NODE, &isis_hello_padding_cmd); + + install_element(INTERFACE_NODE, &csnp_interval_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_cmd); + + install_element(INTERFACE_NODE, &psnp_interval_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_cmd); + + install_element(INTERFACE_NODE, &circuit_topology_cmd); + + install_element(INTERFACE_NODE, &isis_circuit_type_cmd); + install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); + + install_element(INTERFACE_NODE, &isis_network_cmd); + + install_element(INTERFACE_NODE, &isis_priority_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_cmd); + + install_element(ISIS_NODE, &log_adj_changes_cmd); +} + +#endif /* ifndef FABRICD */ diff --git a/isisd/isis_cli.h b/isisd/isis_cli.h new file mode 100644 index 0000000000..8dadf60981 --- /dev/null +++ b/isisd/isis_cli.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2018 Volta Networks + * Emanuele Di Pascale + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISISD_ISIS_CLI_H_ +#define ISISD_ISIS_CLI_H_ + +/* add cli_show declarations here as externs */ +void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_is_type(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_area_pwd(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_domain_pwd(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_lsp_gen_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_lsp_ref_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_lsp_max_lifetime(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_lsp_mtu(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_spf_min_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_spf_ietf_backoff(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_purge_origin(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_passive(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_password(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_metric(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_hello_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_hello_multi(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_threeway_shake(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_hello_padding(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_csnp_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_psnp_interval(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_mt_ipv4_unicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_mt_ipv4_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_mt_ipv4_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_mt_ipv6_unicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_mt_ipv6_multicast(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_isis_log_adjacency(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); + +#endif /* ISISD_ISIS_CLI_H_ */ diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 8d393c7a08..658624370b 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -355,6 +355,15 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno) else newseq = seqno + 1; +#ifndef FABRICD + /* check for overflow */ + if (newseq < lsp->hdr.seqno) { + /* send northbound notification */ + isis_notif_lsp_exceed_max(lsp->area, + rawlspid_print(lsp->hdr.lsp_id)); + } +#endif /* ifndef FABRICD */ + lsp->hdr.seqno = newseq; lsp_pack_pdu(lsp); @@ -1265,6 +1274,12 @@ int lsp_generate(struct isis_area *area, int level) "ISIS (%s): Built L%d LSP. Set triggered regenerate to non-pending.", area->area_tag, level); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_lsp_gen(area, rawlspid_print(newlsp->hdr.lsp_id), + newlsp->hdr.seqno, newlsp->last_generated); +#endif /* ifndef FABRICD */ + return ISIS_OK; } diff --git a/isisd/isis_main.c b/isisd/isis_main.c index cda3b2b3c5..9126e40d42 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -107,12 +107,23 @@ static __attribute__((__noreturn__)) void terminate(int i) /* * Signal handlers */ - +#ifdef FABRICD void sighup(void) { - zlog_notice("SIGHUP/reload is not implemented for isisd"); + zlog_notice("SIGHUP/reload is not implemented for fabricd"); return; } +#else +static struct frr_daemon_info isisd_di; +void sighup(void) +{ + zlog_info("SIGHUP received"); + + /* Reload config file. */ + vty_read_config(NULL, isisd_di.config_file, config_default); +} + +#endif __attribute__((__noreturn__)) void sigint(void) { @@ -151,8 +162,12 @@ struct quagga_signal_t isisd_signals[] = { }, }; + static const struct frr_yang_module_info *isisd_yang_modules[] = { &frr_interface_info, +#ifndef FABRICD + &frr_isisd_info, +#endif /* ifndef FABRICD */ }; #ifdef FABRICD @@ -217,6 +232,9 @@ int main(int argc, char **argv, char **envp) isis_init(); isis_circuit_init(); isis_vty_init(); +#ifndef FABRICD + isis_cli_init(); +#endif /* ifdef FABRICD */ isis_spf_cmds_init(); isis_redist_init(); isis_route_map_init(); diff --git a/isisd/isis_northbound.c b/isisd/isis_northbound.c new file mode 100644 index 0000000000..9c2bb1728e --- /dev/null +++ b/isisd/isis_northbound.c @@ -0,0 +1,3232 @@ +/* + * 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) { + flog_warn( + EC_LIB_NB_CB_CONFIG_VALIDATE, + "Cannot change network type on 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, + }, + } +}; diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 6303536c11..330da9b216 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -553,6 +553,10 @@ static int pdu_len_validate(uint16_t pdu_len, struct isis_circuit *circuit) static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, uint8_t *ssnpa) { + /* keep a copy of the raw pdu for NB notifications */ + size_t pdu_start = stream_get_getp(circuit->rcv_stream); + size_t pdu_end = stream_get_endp(circuit->rcv_stream); + char raw_pdu[pdu_end - pdu_start]; bool p2p_hello = (pdu_type == P2P_HELLO); int level = p2p_hello ? 0 : (pdu_type == L1_LAN_HELLO) ? ISIS_LEVEL1 @@ -562,6 +566,9 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, ? "P2P IIH" : (level == ISIS_LEVEL1) ? "L1 LAN IIH" : "L2 LAN IIH"; + + stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start, + pdu_end - pdu_start); if (isis->debugs & DEBUG_ADJ_PACKETS) { zlog_debug("ISIS-Adj (%s): Rcvd %s on %s, cirType %s, cirID %u", circuit->area->area_tag, pdu_name, @@ -576,11 +583,21 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, if (p2p_hello) { if (circuit->circ_type != CIRCUIT_T_P2P) { zlog_warn("p2p hello on non p2p circuit"); +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, "p2p hello on non p2p circuit", + raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_WARNING; } } else { if (circuit->circ_type != CIRCUIT_T_BROADCAST) { zlog_warn("lan hello on non broadcast circuit"); +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, "lan hello on non broadcast circuit", + raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_WARNING; } @@ -588,6 +605,12 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, zlog_debug( "level %d LAN Hello received over circuit with externalDomain = true", level); +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, + "LAN Hello received over circuit with externalDomain = true", + raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_WARNING; } @@ -598,6 +621,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, circuit->area->area_tag, circuit->interface->name); } +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, "Interface level mismatch", raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_WARNING; } } @@ -623,6 +650,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, "ISIS-Adj (%s): Rcvd %s from (%s) with invalid pdu length %" PRIu16, circuit->area->area_tag, pdu_name, circuit->interface->name, iih.pdu_len); +#ifndef FABRICD + isis_notif_reject_adjacency(circuit, "Invalid PDU length", + raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_WARNING; } @@ -630,6 +661,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, flog_err(EC_ISIS_PACKET, "Level %d LAN Hello with Circuit Type %d", level, iih.circ_type); +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, "LAN Hello with wrong IS-level", raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_ERROR; } @@ -639,24 +674,47 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, if (isis_unpack_tlvs(STREAM_READABLE(circuit->rcv_stream), circuit->rcv_stream, &iih.tlvs, &error_log)) { zlog_warn("isis_unpack_tlvs() failed: %s", error_log); +#ifndef FABRICD + isis_notif_reject_adjacency(circuit, "Failed to unpack TLVs", + raw_pdu); +#endif /* ifndef FABRICD */ goto out; } if (!iih.tlvs->area_addresses.count) { zlog_warn("No Area addresses TLV in %s", pdu_name); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_area_mismatch(circuit, raw_pdu); +#endif /* ifndef FABRICD */ goto out; } if (!iih.tlvs->protocols_supported.count) { zlog_warn("No supported protocols TLV in %s", pdu_name); +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, "No supported protocols TLV", raw_pdu); +#endif /* ifndef FABRICD */ goto out; } - if (!isis_tlvs_auth_is_valid(iih.tlvs, &circuit->passwd, - circuit->rcv_stream, false)) { + int auth_code = isis_tlvs_auth_is_valid(iih.tlvs, &circuit->passwd, + circuit->rcv_stream, false); + if (auth_code != ISIS_AUTH_OK) { isis_event_auth_failure(circuit->area->area_tag, "IIH authentication failure", iih.sys_id); +#ifndef FABRICD + /* send northbound notification */ + stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start, + pdu_end - pdu_start); + if (auth_code == ISIS_AUTH_FAILURE) + isis_notif_authentication_failure(circuit, raw_pdu); + else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */ + isis_notif_authentication_type_failure(circuit, + raw_pdu); +#endif /* ifndef FABRICD */ goto out; } @@ -664,6 +722,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, zlog_warn( "ISIS-Adj (%s): Received IIH with own sysid - discard", circuit->area->area_tag); +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, "Received IIH with our own sysid", raw_pdu); +#endif /* ifndef FABRICD */ goto out; } @@ -678,6 +740,10 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, circuit->area->area_tag, level, circuit->interface->name); } +#ifndef FABRICD + /* send northbound notification */ + isis_notif_area_mismatch(circuit, raw_pdu); +#endif /* ifndef FABRICD */ goto out; } @@ -693,7 +759,11 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, "ISIS-Adj (%s): Neither IPv4 nor IPv6 considered usable. Ignoring IIH", circuit->area->area_tag); } - +#ifndef FABRICD + isis_notif_reject_adjacency( + circuit, "Neither IPv4 not IPv6 considered usable", + raw_pdu); +#endif /* ifndef FABRICD */ goto out; } @@ -724,6 +794,12 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit, { int level; bool circuit_scoped; + size_t pdu_start = stream_get_getp(circuit->rcv_stream); + size_t pdu_end = stream_get_endp(circuit->rcv_stream); + char raw_pdu[pdu_end - pdu_start]; + + stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start, + pdu_end - pdu_start); if (pdu_type == FS_LINK_STATE) { if (!fabricd) @@ -768,6 +844,12 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit, hdr.checksum = stream_getw(circuit->rcv_stream); hdr.lsp_bits = stream_getc(circuit->rcv_stream); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_lsp_received(circuit, rawlspid_print(hdr.lsp_id), hdr.seqno, + time(NULL), sysid_print(hdr.lsp_id)); +#endif /* ifndef FABRICD */ + if (pdu_len_validate(hdr.pdu_len, circuit)) { zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %" PRIu16, circuit->area->area_tag, rawlspid_print(hdr.lsp_id), @@ -834,6 +916,17 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit, circuit->rcv_stream, &tlvs, &error_log)) { zlog_warn("Something went wrong unpacking the LSP: %s", error_log); +#ifndef FABRICD + /* send northbound notification. Note that the tlv-type and + * offset cannot correctly be set here as they are not returned + * by isis_unpack_tlvs, but in there I cannot fire a + * notification because I have no circuit information. So until + * we change the code above to return those extra fields, we + * will send dummy values which are ignored in the callback + */ + isis_notif_lsp_error(circuit, rawlspid_print(hdr.lsp_id), + raw_pdu, 0, 0); +#endif /* ifndef FABRICD */ goto out; } @@ -846,10 +939,20 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit, struct isis_passwd *passwd = (level == ISIS_LEVEL1) ? &circuit->area->area_passwd : &circuit->area->domain_passwd; - if (!isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream, true)) { + int auth_code = isis_tlvs_auth_is_valid(tlvs, passwd, + circuit->rcv_stream, true); + if (auth_code != ISIS_AUTH_OK) { isis_event_auth_failure(circuit->area->area_tag, "LSP authentication failure", hdr.lsp_id); +#ifndef FABRICD + /* send northbound notification */ + if (auth_code == ISIS_AUTH_FAILURE) + isis_notif_authentication_failure(circuit, raw_pdu); + else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */ + isis_notif_authentication_type_failure(circuit, + raw_pdu); +#endif /* ifndef FABRICD */ goto out; } @@ -988,6 +1091,16 @@ dontcheckadj: } else if (lsp->hdr.rem_lifetime != 0) { /* our own LSP -> 7.3.16.4 c) */ if (comp == LSP_NEWER) { +#ifndef FABRICD + if (lsp->hdr.seqno < hdr.seqno) { + /* send northbound + * notification */ + isis_notif_seqno_skipped( + circuit, + rawlspid_print( + hdr.lsp_id)); + } +#endif /* ifndef FABRICD */ lsp_inc_seqno(lsp, hdr.seqno); lsp_flood_or_update(lsp, NULL, circuit_scoped); @@ -1004,6 +1117,13 @@ dontcheckadj: 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; @@ -1028,6 +1148,11 @@ dontcheckadj: if (comp == LSP_NEWER) { /* 7.3.16.1 */ lsp_inc_seqno(lsp, hdr.seqno); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_seqno_skipped(circuit, + rawlspid_print(hdr.lsp_id)); +#endif /* ifndef FABRICD */ if (isis->debugs & DEBUG_UPDATE_PACKETS) { zlog_debug( "ISIS-Upd (%s): (2) re-originating LSP %s new seq 0x%08" PRIx32, @@ -1124,6 +1249,12 @@ out: static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, const uint8_t *ssnpa) { +#ifndef FABRICD + size_t pdu_start = stream_get_getp(circuit->rcv_stream); + size_t pdu_end = stream_get_endp(circuit->rcv_stream); + char raw_pdu[pdu_end - pdu_start]; +#endif /* ifndef FABRICD */ + bool is_csnp = (pdu_type == L1_COMPLETE_SEQ_NUM || pdu_type == L2_COMPLETE_SEQ_NUM); char typechar = is_csnp ? 'C' : 'P'; @@ -1134,6 +1265,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, uint16_t pdu_len = stream_getw(circuit->rcv_stream); uint8_t rem_sys_id[ISIS_SYS_ID_LEN]; + stream_get(rem_sys_id, circuit->rcv_stream, ISIS_SYS_ID_LEN); stream_forward_getp(circuit->rcv_stream, 1); /* Circuit ID - unused */ @@ -1237,13 +1369,26 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, struct isis_passwd *passwd = (level == IS_LEVEL_1) ? &circuit->area->area_passwd : &circuit->area->domain_passwd; - if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV) - && !isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream, - false)) { - isis_event_auth_failure(circuit->area->area_tag, - "SNP authentication failure", - rem_sys_id); - goto out; + if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)) { + int auth_code = isis_tlvs_auth_is_valid( + tlvs, passwd, circuit->rcv_stream, false); + if (auth_code != ISIS_AUTH_OK) { + isis_event_auth_failure(circuit->area->area_tag, + "SNP authentication failure", + rem_sys_id); +#ifndef FABRICD + /* send northbound notification */ + stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start, + pdu_end - pdu_start); + if (auth_code == ISIS_AUTH_FAILURE) + isis_notif_authentication_failure(circuit, + raw_pdu); + else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */ + isis_notif_authentication_type_failure(circuit, + raw_pdu); +#endif /* ifndef FABRICD */ + goto out; + } } struct isis_lsp_entry *entry_head = @@ -1423,6 +1568,12 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size) int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) { int retval = ISIS_OK; + size_t pdu_start = stream_get_getp(circuit->rcv_stream); + size_t pdu_end = stream_get_endp(circuit->rcv_stream); + char raw_pdu[pdu_end - pdu_start]; + + stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start, + pdu_end - pdu_start); /* Verify that at least the 8 bytes fixed header have been received */ if (stream_get_endp(circuit->rcv_stream) < ISIS_FIXED_HDR_LEN) { @@ -1437,6 +1588,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) uint8_t pdu_type = stream_getc(circuit->rcv_stream) & 0x1f; /* bits 6-8 are reserved */ uint8_t version2 = stream_getc(circuit->rcv_stream); + stream_forward_getp(circuit->rcv_stream, 1); /* reserved */ uint8_t max_area_addrs = stream_getc(circuit->rcv_stream); @@ -1456,6 +1608,10 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) if (version1 != 1) { zlog_warn("Unsupported ISIS version %" PRIu8, version1); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_version_skew(circuit, version1, raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_WARNING; } @@ -1465,6 +1621,10 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) "IDFieldLengthMismatch: ID Length field in a received PDU %" PRIu8 ", while the parameter for this IS is %u", id_len, ISIS_SYS_ID_LEN); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_id_len_mismatch(circuit, id_len, raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_ERROR; } @@ -1491,6 +1651,10 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) if (version2 != 1) { zlog_warn("Unsupported ISIS PDU version %" PRIu8, version2); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_version_skew(circuit, version2, raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_WARNING; } @@ -1509,6 +1673,11 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8 " while the parameter for this IS is %u", max_area_addrs, isis->max_area_addrs); +#ifndef FABRICD + /* send northbound notification */ + isis_notif_max_area_addr_mismatch(circuit, max_area_addrs, + raw_pdu); +#endif /* ifndef FABRICD */ return ISIS_ERROR; } @@ -2238,6 +2407,11 @@ void send_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp, 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)); diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index 6564149a43..815de513fc 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -388,9 +388,8 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis) } } -static void isis_redist_set(struct isis_area *area, int level, int family, - int type, uint32_t metric, const char *routemap, - int originate_type) +void isis_redist_set(struct isis_area *area, int level, int family, int type, + uint32_t metric, const char *routemap, int originate_type) { int protocol = redist_protocol(family); struct isis_redist *redist = @@ -445,8 +444,7 @@ static void isis_redist_set(struct isis_area *area, int level, int family, } } -static void isis_redist_unset(struct isis_area *area, int level, int family, - int type) +void isis_redist_unset(struct isis_area *area, int level, int family, int type) { struct isis_redist *redist = get_redist_settings(area, family, type, level); @@ -513,21 +511,15 @@ void isis_redist_area_finish(struct isis_area *area) isis_redist_update_zebra_subscriptions(area->isis); } +#ifdef FABRICD DEFUN (isis_redistribute, isis_redistribute_cmd, "redistribute <ipv4|ipv6> " PROTO_REDIST_STR -#ifndef FABRICD - " <level-1|level-2>" -#endif " [<metric (0-16777215)|route-map WORD>]", REDIST_STR "Redistribute IPv4 routes\n" "Redistribute IPv6 routes\n" PROTO_REDIST_HELP -#ifndef FABRICD - "Redistribute into level-1\n" - "Redistribute into level-2\n" -#endif "Metric for redistributed routes\n" "ISIS default metric\n" "Route map reference\n" @@ -535,7 +527,6 @@ DEFUN (isis_redistribute, { int idx_afi = 1; int idx_protocol = 2; - int idx_level = 3; int idx_metric_rmap = fabricd ? 3 : 4; VTY_DECLVAR_CONTEXT(isis_area, area); int family; @@ -557,14 +548,7 @@ DEFUN (isis_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - if (fabricd) - level = 2; - else if (!strcmp("level-1", argv[idx_level]->arg)) - level = 1; - else if (!strcmp("level-2", argv[idx_level]->arg)) - level = 2; - else - return CMD_WARNING_CONFIG_FAILED; + level = 2; if ((area->is_type & level) != level) { vty_out(vty, "Node is not a level-%d IS\n", level); @@ -593,24 +577,15 @@ DEFUN (isis_redistribute, DEFUN (no_isis_redistribute, no_isis_redistribute_cmd, - "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR -#ifndef FABRICD - " <level-1|level-2>" -#endif - , NO_STR + "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR, + NO_STR REDIST_STR "Redistribute IPv4 routes\n" "Redistribute IPv6 routes\n" - PROTO_REDIST_HELP -#ifndef FABRICD - "Redistribute into level-1\n" - "Redistribute into level-2\n" -#endif - ) + PROTO_REDIST_HELP) { int idx_afi = 2; int idx_protocol = 3; - int idx_level = 4; VTY_DECLVAR_CONTEXT(isis_area, area); int type; int level; @@ -629,10 +604,7 @@ DEFUN (no_isis_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - if (fabricd) - level = 2; - else - level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + level = 2; isis_redist_unset(area, level, family, type); return 0; @@ -641,18 +613,11 @@ DEFUN (no_isis_redistribute, DEFUN (isis_default_originate, isis_default_originate_cmd, "default-information originate <ipv4|ipv6>" -#ifndef FABRICD - " <level-1|level-2>" -#endif " [always] [<metric (0-16777215)|route-map WORD>]", "Control distribution of default information\n" "Distribute a default route\n" "Distribute default route for IPv4\n" "Distribute default route for IPv6\n" -#ifndef FABRICD - "Distribute default route into level-1\n" - "Distribute default route into level-2\n" -#endif "Always advertise default route\n" "Metric for default route\n" "ISIS default metric\n" @@ -660,7 +625,6 @@ DEFUN (isis_default_originate, "Pointer to route-map entries\n") { int idx_afi = 2; - int idx_level = 3; int idx_always = fabricd ? 3 : 4; int idx_metric_rmap = fabricd ? 3 : 4; VTY_DECLVAR_CONTEXT(isis_area, area); @@ -674,10 +638,7 @@ DEFUN (isis_default_originate, if (family < 0) return CMD_WARNING_CONFIG_FAILED; - if (fabricd) - level = 2; - else - level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + level = 2; if ((area->is_type & level) != level) { vty_out(vty, "Node is not a level-%d IS\n", level); @@ -711,23 +672,14 @@ DEFUN (isis_default_originate, DEFUN (no_isis_default_originate, no_isis_default_originate_cmd, - "no default-information originate <ipv4|ipv6>" -#ifndef FABRICD - " <level-1|level-2>" -#endif - , NO_STR + "no default-information originate <ipv4|ipv6>", + NO_STR "Control distribution of default information\n" "Distribute a default route\n" "Distribute default route for IPv4\n" - "Distribute default route for IPv6\n" -#ifndef FABRICD - "Distribute default route into level-1\n" - "Distribute default route into level-2\n" -#endif - ) + "Distribute default route for IPv6\n") { int idx_afi = 3; - int idx_level = 4; VTY_DECLVAR_CONTEXT(isis_area, area); int family; int level; @@ -736,18 +688,12 @@ DEFUN (no_isis_default_originate, if (family < 0) return CMD_WARNING_CONFIG_FAILED; - if (fabricd) - level = 2; - else if (strmatch("level-1", argv[idx_level]->text)) - level = 1; - else if (strmatch("level-2", argv[idx_level]->text)) - level = 2; - else - return CMD_WARNING_CONFIG_FAILED; + level = 2; isis_redist_unset(area, level, family, DEFAULT_ROUTE); return 0; } +#endif /* ifdef FABRICD */ int isis_redist_config_write(struct vty *vty, struct isis_area *area, int family) @@ -810,8 +756,11 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, void isis_redist_init(void) { +#ifdef FABRICD install_element(ROUTER_NODE, &isis_redistribute_cmd); install_element(ROUTER_NODE, &no_isis_redistribute_cmd); + install_element(ROUTER_NODE, &isis_default_originate_cmd); install_element(ROUTER_NODE, &no_isis_default_originate_cmd); +#endif /* ifdef FABRICD */ } diff --git a/isisd/isis_redist.h b/isisd/isis_redist.h index 95f06f71ec..9c37c310ea 100644 --- a/isisd/isis_redist.h +++ b/isisd/isis_redist.h @@ -55,4 +55,8 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, void isis_redist_init(void); void isis_redist_area_finish(struct isis_area *area); +void isis_redist_set(struct isis_area *area, int level, int family, int type, + uint32_t metric, const char *routemap, int originate_type); +void isis_redist_unset(struct isis_area *area, int level, int family, int type); + #endif diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 08b905c650..a69c95cadf 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -1087,141 +1087,6 @@ static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp) return circuit->mtc; } -DEFUN (isis_mpls_te_on, - isis_mpls_te_on_cmd, - "mpls-te on", - MPLS_TE_STR - "Enable MPLS-TE functionality\n") -{ - struct listnode *node; - struct isis_circuit *circuit; - - if (IS_MPLS_TE(isisMplsTE)) - return CMD_SUCCESS; - - if (IS_DEBUG_ISIS(DEBUG_TE)) - zlog_debug("ISIS MPLS-TE: OFF -> ON"); - - isisMplsTE.status = enable; - - /* - * Following code is intended to handle two cases; - * - * 1) MPLS-TE was disabled at startup time, but now become enabled. - * In this case, we must enable MPLS-TE Circuit regarding interface - * MPLS_TE flag - * 2) MPLS-TE was once enabled then disabled, and now enabled again. - */ - for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) { - if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type)) - continue; - - if ((circuit->mtc->status == disable) - && HAS_LINK_PARAMS(circuit->interface)) - circuit->mtc->status = enable; - else - continue; - - /* Reoriginate STD_TE & GMPLS circuits */ - if (circuit->area) - lsp_regenerate_schedule(circuit->area, circuit->is_type, - 0); - } - - return CMD_SUCCESS; -} - -DEFUN (no_isis_mpls_te_on, - no_isis_mpls_te_on_cmd, - "no mpls-te", - NO_STR - "Disable the MPLS-TE functionality\n") -{ - struct listnode *node; - struct isis_circuit *circuit; - - if (isisMplsTE.status == disable) - return CMD_SUCCESS; - - if (IS_DEBUG_ISIS(DEBUG_TE)) - zlog_debug("ISIS MPLS-TE: ON -> OFF"); - - isisMplsTE.status = disable; - - /* Flush LSP if circuit engage */ - for (ALL_LIST_ELEMENTS_RO(isisMplsTE.cir_list, node, circuit)) { - if (circuit->mtc == NULL || (circuit->mtc->status == disable)) - continue; - - /* disable MPLS_TE Circuit */ - circuit->mtc->status = disable; - - /* Re-originate circuit without STD_TE & GMPLS parameters */ - if (circuit->area) - lsp_regenerate_schedule(circuit->area, circuit->is_type, - 0); - } - - return CMD_SUCCESS; -} - -DEFUN (isis_mpls_te_router_addr, - isis_mpls_te_router_addr_cmd, - "mpls-te router-address A.B.C.D", - MPLS_TE_STR - "Stable IP address of the advertising router\n" - "MPLS-TE router address in IPv4 address format\n") -{ - int idx_ipv4 = 2; - struct in_addr value; - struct listnode *node; - struct isis_area *area; - - if (!inet_aton(argv[idx_ipv4]->arg, &value)) { - vty_out(vty, "Please specify Router-Addr by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - isisMplsTE.router_id.s_addr = value.s_addr; - - if (isisMplsTE.status == disable) - return CMD_SUCCESS; - - /* Update main Router ID in isis global structure */ - isis->router_id = value.s_addr; - /* And re-schedule LSP update */ - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) - if (listcount(area->area_addrs) > 0) - lsp_regenerate_schedule(area, area->is_type, 0); - - return CMD_SUCCESS; -} - -DEFUN (isis_mpls_te_inter_as, - isis_mpls_te_inter_as_cmd, - "mpls-te inter-as <level-1|level-1-2|level-2-only>", - MPLS_TE_STR - "Configure MPLS-TE Inter-AS support\n" - "AREA native mode self originate INTER-AS LSP with L1 only flooding scope)\n" - "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope)\n" - "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n") -{ - vty_out(vty, "Not yet supported\n"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_mpls_te_inter_as, - no_isis_mpls_te_inter_as_cmd, - "no mpls-te inter-as", - NO_STR - "Disable the MPLS-TE functionality\n" - "Disable MPLS-TE Inter-AS support\n") -{ - - vty_out(vty, "Not yet supported\n"); - return CMD_SUCCESS; -} - DEFUN (show_isis_mpls_te_router, show_isis_mpls_te_router_cmd, "show " PROTO_NAME " mpls-te router", @@ -1363,12 +1228,6 @@ void isis_mpls_te_init(void) /* Register new VTY commands */ install_element(VIEW_NODE, &show_isis_mpls_te_router_cmd); install_element(VIEW_NODE, &show_isis_mpls_te_interface_cmd); - - install_element(ROUTER_NODE, &isis_mpls_te_on_cmd); - install_element(ROUTER_NODE, &no_isis_mpls_te_on_cmd); - install_element(ROUTER_NODE, &isis_mpls_te_router_addr_cmd); - install_element(ROUTER_NODE, &isis_mpls_te_inter_as_cmd); - install_element(ROUTER_NODE, &no_isis_mpls_te_inter_as_cmd); #endif return; diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 87d8273350..5a6c7bc300 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -3304,17 +3304,17 @@ static const auth_validator_func auth_validators[] = { [ISIS_PASSWD_TYPE_HMAC_MD5] = auth_validator_hmac_md5, }; -bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd, - struct stream *stream, bool is_lsp) +int isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd, + struct stream *stream, bool is_lsp) { /* If no auth is set, always pass authentication */ if (!passwd->type) - return true; + return ISIS_AUTH_OK; /* If we don't known how to validate the auth, return invalid */ if (passwd->type >= array_size(auth_validators) || !auth_validators[passwd->type]) - return false; + return ISIS_AUTH_NO_VALIDATOR; struct isis_auth *auth_head = (struct isis_auth *)tlvs->isis_auth.head; struct isis_auth *auth; @@ -3325,10 +3325,14 @@ bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd, /* If matching auth TLV could not be found, return invalid */ if (!auth) - return false; + return ISIS_AUTH_TYPE_FAILURE; + /* Perform validation and return result */ - return auth_validators[passwd->type](passwd, stream, auth, is_lsp); + if (auth_validators[passwd->type](passwd, stream, auth, is_lsp)) + return ISIS_AUTH_OK; + else + return ISIS_AUTH_FAILURE; } bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs, diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 4144809fa3..fce30d4ee7 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -196,6 +196,13 @@ struct isis_purge_originator { uint8_t sender[6]; }; +enum isis_auth_result { + ISIS_AUTH_OK = 0, + ISIS_AUTH_TYPE_FAILURE, + ISIS_AUTH_FAILURE, + ISIS_AUTH_NO_VALIDATOR, +}; + RB_HEAD(isis_mt_item_list, isis_item_list); struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m, @@ -337,8 +344,8 @@ void isis_tlvs_add_ipv4_addresses(struct isis_tlvs *tlvs, struct list *addresses); void isis_tlvs_add_ipv6_addresses(struct isis_tlvs *tlvs, struct list *addresses); -bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd, - struct stream *stream, bool is_lsp); +int isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd, + struct stream *stream, bool is_lsp); bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs, struct list *addresses); struct isis_adjacency; diff --git a/isisd/isis_vty_common.c b/isisd/isis_vty_common.c index c211763042..06432db0b2 100644 --- a/isisd/isis_vty_common.c +++ b/isisd/isis_vty_common.c @@ -27,13 +27,11 @@ #include <zebra.h> #include "command.h" -#include "spf_backoff.h" #include "bfd.h" #include "isis_circuit.h" #include "isis_csm.h" #include "isis_misc.h" -#include "isis_mt.h" #include "isisd.h" #include "isis_bfd.h" #include "isis_vty_common.h" @@ -57,449 +55,6 @@ struct isis_circuit *isis_circuit_lookup(struct vty *vty) return circuit; } -DEFUN (ip_router_isis, - ip_router_isis_cmd, - "ip router " PROTO_NAME " WORD", - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - PROTO_HELP - "Routing process tag\n") -{ - int idx_afi = 0; - int idx_word = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct isis_circuit *circuit; - struct isis_area *area; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - /* Prevent more than one area per circuit */ - circuit = circuit_scan_by_ifp(ifp); - if (circuit && circuit->area) { - if (strcmp(circuit->area->area_tag, area_tag)) { - vty_out(vty, "ISIS circuit is already defined on %s\n", - circuit->area->area_tag); - return CMD_ERR_NOTHING_TODO; - } - } - - area = isis_area_lookup(area_tag); - if (!area) - area = isis_area_create(area_tag); - - if (!circuit || !circuit->area) { - circuit = isis_circuit_create(area, ifp); - - if (circuit->state != C_STATE_CONF - && circuit->state != C_STATE_UP) { - vty_out(vty, - "Couldn't bring up interface, please check log.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = true; - else - ip = true; - - isis_circuit_af_set(circuit, ip, ipv6); - return CMD_SUCCESS; -} - -DEFUN (ip6_router_isis, - ip6_router_isis_cmd, - "ipv6 router " PROTO_NAME " WORD", - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - PROTO_HELP - "Routing process tag\n") -{ - return ip_router_isis(self, vty, argc, argv); -} - -DEFUN (no_ip_router_isis, - no_ip_router_isis_cmd, - "no <ip|ipv6> router " PROTO_NAME " WORD", - NO_STR - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - "IP router interface commands\n" - PROTO_HELP - "Routing process tag\n") -{ - int idx_afi = 1; - int idx_word = 4; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct isis_area *area; - struct isis_circuit *circuit; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - area = isis_area_lookup(area_tag); - if (!area) { - vty_out(vty, "Can't find ISIS instance %s\n", - area_tag); - return CMD_ERR_NO_MATCH; - } - - circuit = circuit_lookup_by_ifp(ifp, area->circuit_list); - if (!circuit) { - vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); - return CMD_ERR_NO_MATCH; - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = false; - else - ip = false; - - isis_circuit_af_set(circuit, ip, ipv6); - return CMD_SUCCESS; -} - -DEFUN (isis_passive, - isis_passive_cmd, - PROTO_NAME " passive", - PROTO_HELP - "Configure the passive mode for interface\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1), - "Cannot set passive: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_passive, - no_isis_passive_cmd, - "no " PROTO_NAME " passive", - NO_STR - PROTO_HELP - "Configure the passive mode for interface\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0), - "Cannot set no passive: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (isis_passwd, - isis_passwd_cmd, - PROTO_NAME " password <md5|clear> WORD", - PROTO_HELP - "Configure the authentication password for a circuit\n" - "HMAC-MD5 authentication\n" - "Cleartext password\n" - "Circuit password\n") -{ - int idx_encryption = 2; - int idx_word = 3; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - ferr_r rv; - - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (argv[idx_encryption]->arg[0] == 'm') - rv = isis_circuit_passwd_hmac_md5_set(circuit, - argv[idx_word]->arg); - else - rv = isis_circuit_passwd_cleartext_set(circuit, - argv[idx_word]->arg); - - CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_passwd, - no_isis_passwd_cmd, - "no " PROTO_NAME " password [<md5|clear> WORD]", - NO_STR - PROTO_HELP - "Configure the authentication password for a circuit\n" - "HMAC-MD5 authentication\n" - "Cleartext password\n" - "Circuit password\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit), - "Failed to unset circuit password: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (isis_metric, - isis_metric_cmd, - PROTO_NAME " metric (0-16777215)", - PROTO_HELP - "Set default metric for circuit\n" - "Default metric value\n") -{ - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - met = atoi(argv[idx_number]->arg); - - /* RFC3787 section 5.1 */ - if (circuit->area && circuit->area->oldmetric == 1 - && met > MAX_NARROW_LINK_METRIC) { - vty_out(vty, - "Invalid metric %d - should be <0-63> " - "when narrow metric type enabled\n", - met); - return CMD_WARNING_CONFIG_FAILED; - } - - /* RFC4444 */ - if (circuit->area && circuit->area->newmetric == 1 - && met > MAX_WIDE_LINK_METRIC) { - vty_out(vty, - "Invalid metric %d - should be <0-16777215> " - "when wide metric type enabled\n", - met); - return CMD_WARNING_CONFIG_FAILED; - } - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met), - "Failed to set L1 metric: $ERR"); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_metric, - no_isis_metric_cmd, - "no " PROTO_NAME " metric [(0-16777215)]", - NO_STR - PROTO_HELP - "Set default metric for circuit\n" - "Default metric value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L1 metric: $ERR"); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (isis_hello_interval, - isis_hello_interval_cmd, - PROTO_NAME " hello-interval (1-600)", - PROTO_HELP - "Set Hello interval\n" - "Holdtime 1 seconds, interval depends on multiplier\n") -{ - uint32_t interval = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[0] = interval; - circuit->hello_interval[1] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_hello_interval, - no_isis_hello_interval_cmd, - "no " PROTO_NAME " hello-interval [(1-600)]", - NO_STR - PROTO_HELP - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; - circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (isis_hello_multiplier, - isis_hello_multiplier_cmd, - PROTO_NAME " hello-multiplier (2-100)", - PROTO_HELP - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n") -{ - uint16_t mult = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[0] = mult; - circuit->hello_multiplier[1] = mult; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_hello_multiplier, - no_isis_hello_multiplier_cmd, - "no " PROTO_NAME " hello-multiplier [(2-100)]", - NO_STR - PROTO_HELP - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; - circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - -DEFUN (csnp_interval, - csnp_interval_cmd, - PROTO_NAME " csnp-interval (1-600)", - PROTO_HELP - "Set CSNP interval in seconds\n" - "CSNP interval value\n") -{ - uint16_t interval = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[0] = interval; - circuit->csnp_interval[1] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_csnp_interval, - no_csnp_interval_cmd, - "no " PROTO_NAME " csnp-interval [(1-600)]", - NO_STR - PROTO_HELP - "Set CSNP interval in seconds\n" - "CSNP interval value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; - circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (psnp_interval, - psnp_interval_cmd, - PROTO_NAME " psnp-interval (1-120)", - PROTO_HELP - "Set PSNP interval in seconds\n" - "PSNP interval value\n") -{ - uint16_t interval = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[0] = interval; - circuit->psnp_interval[1] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_psnp_interval, - no_psnp_interval_cmd, - "no " PROTO_NAME " psnp-interval [(1-120)]", - NO_STR - PROTO_HELP - "Set PSNP interval in seconds\n" - "PSNP interval value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; - circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (circuit_topology, - circuit_topology_cmd, - PROTO_NAME " topology " ISIS_MT_NAMES, - PROTO_HELP - "Configure interface IS-IS topologies\n" - ISIS_MT_DESCRIPTIONS) -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[2]->arg; - uint16_t mtid = isis_str2mtid(arg); - - if (circuit->area && circuit->area->oldmetric) { - vty_out(vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (mtid == (uint16_t)-1) { - vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return isis_circuit_mt_enabled_set(circuit, mtid, true); -} - -DEFUN (no_circuit_topology, - no_circuit_topology_cmd, - "no " PROTO_NAME " topology " ISIS_MT_NAMES, - NO_STR - PROTO_HELP - "Configure interface IS-IS topologies\n" - ISIS_MT_DESCRIPTIONS) -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[3]->arg; - uint16_t mtid = isis_str2mtid(arg); - - if (circuit->area && circuit->area->oldmetric) { - vty_out(vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (mtid == (uint16_t)-1) { - vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return isis_circuit_mt_enabled_set(circuit, mtid, false); -} - DEFUN (isis_bfd, isis_bfd_cmd, PROTO_NAME " bfd", @@ -543,466 +98,12 @@ DEFUN (no_isis_bfd, return CMD_SUCCESS; } -DEFUN (set_overload_bit, - set_overload_bit_cmd, - "set-overload-bit", - "Set overload bit to avoid any transit traffic\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_overload_bit_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_set_overload_bit, - no_set_overload_bit_cmd, - "no set-overload-bit", - "Reset overload bit to accept transit traffic\n" - "Reset overload bit\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_overload_bit_set(area, false); - return CMD_SUCCESS; -} - -static int isis_vty_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - struct listnode *node; - struct isis_circuit *circuit; - - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { - if (circuit->state != C_STATE_INIT - && circuit->state != C_STATE_UP) - continue; - if (lsp_mtu > isis_circuit_pdu_size(circuit)) { - vty_out(vty, - "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", - circuit->interface->name, - isis_circuit_pdu_size(circuit)); - return CMD_WARNING_CONFIG_FAILED; - } - } - - isis_area_lsp_mtu_set(area, lsp_mtu); - return CMD_SUCCESS; -} - -DEFUN (area_lsp_mtu, - area_lsp_mtu_cmd, - "lsp-mtu (128-4352)", - "Configure the maximum size of generated LSPs\n" - "Maximum size of generated LSPs\n") -{ - int idx_number = 1; - unsigned int lsp_mtu; - - lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10); - - return isis_vty_lsp_mtu_set(vty, lsp_mtu); -} - -DEFUN (no_area_lsp_mtu, - no_area_lsp_mtu_cmd, - "no lsp-mtu [(128-4352)]", - NO_STR - "Configure the maximum size of generated LSPs\n" - "Maximum size of generated LSPs\n") -{ - return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU); -} - -DEFUN (area_purge_originator, - area_purge_originator_cmd, - "[no] purge-originator", - NO_STR - "Use the RFC 6232 purge-originator\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->purge_originator = !!strcmp(argv[0]->text, "no"); - return CMD_SUCCESS; -} - -int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int lvl; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - - if (interval >= area->lsp_refresh[lvl - 1]) { - vty_out(vty, - "LSP gen interval %us must be less than " - "the LSP refresh interval %us\n", - interval, area->lsp_refresh[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - area->lsp_gen_interval[lvl - 1] = interval; - } - - return CMD_SUCCESS; -} - -DEFUN (lsp_gen_interval, - lsp_gen_interval_cmd, - "lsp-gen-interval (1-120)", - "Minimum interval between regenerating same LSP\n" - "Minimum interval in seconds\n") -{ - uint16_t interval = atoi(argv[1]->arg); - - return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval); -} - -DEFUN (no_lsp_gen_interval, - no_lsp_gen_interval_cmd, - "no lsp-gen-interval [(1-120)]", - NO_STR - "Minimum interval between regenerating same LSP\n" - "Minimum interval in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, - DEFAULT_MIN_LSP_GEN_INTERVAL); -} - -DEFUN (spf_interval, - spf_interval_cmd, - "spf-interval (1-120)", - "Minimum interval between SPF calculations\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval = atoi(argv[1]->arg); - - area->min_spf_interval[0] = interval; - area->min_spf_interval[1] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_interval, - no_spf_interval_cmd, - "no spf-interval [(1-120)]", - NO_STR - "Minimum interval between SPF calculations\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_delay_ietf, - no_spf_delay_ietf_cmd, - "no spf-delay-ietf", - NO_STR - "IETF SPF delay algorithm\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - spf_backoff_free(area->spf_delay_ietf[0]); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[0] = NULL; - area->spf_delay_ietf[1] = NULL; - - return CMD_SUCCESS; -} - -DEFUN (spf_delay_ietf, - spf_delay_ietf_cmd, - "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", - "IETF SPF delay algorithm\n" - "Delay used while in QUIET state\n" - "Delay used while in QUIET state in milliseconds\n" - "Delay used while in SHORT_WAIT state\n" - "Delay used while in SHORT_WAIT state in milliseconds\n" - "Delay used while in LONG_WAIT\n" - "Delay used while in LONG_WAIT state in milliseconds\n" - "Time with no received IGP events before considering IGP stable\n" - "Time with no received IGP events before considering IGP stable (in milliseconds)\n" - "Maximum duration needed to learn all the events related to a single failure\n" - "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - long init_delay = atol(argv[2]->arg); - long short_delay = atol(argv[4]->arg); - long long_delay = atol(argv[6]->arg); - long holddown = atol(argv[8]->arg); - long timetolearn = atol(argv[10]->arg); - - size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); - char *buf = XCALLOC(MTYPE_TMP, bufsiz); - - snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[0]); - area->spf_delay_ietf[0] = - spf_backoff_new(master, buf, init_delay, short_delay, - long_delay, holddown, timetolearn); - - snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[1] = - spf_backoff_new(master, buf, init_delay, short_delay, - long_delay, holddown, timetolearn); - - XFREE(MTYPE_TMP, buf); - return CMD_SUCCESS; -} - -int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int lvl; - uint16_t refresh_interval = interval - 300; - int set_refresh_interval[ISIS_LEVELS] = {0, 0}; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { - if (!(lvl & level)) - continue; - - if (refresh_interval < area->lsp_refresh[lvl - 1]) { - vty_out(vty, - "Level %d Max LSP lifetime %us must be 300s greater than " - "the configured LSP refresh interval %us\n", - lvl, interval, area->lsp_refresh[lvl - 1]); - vty_out(vty, - "Automatically reducing level %d LSP refresh interval " - "to %us\n", - lvl, refresh_interval); - set_refresh_interval[lvl - 1] = 1; - - if (refresh_interval - <= area->lsp_gen_interval[lvl - 1]) { - vty_out(vty, - "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - refresh_interval, - area->lsp_gen_interval[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { - if (!(lvl & level)) - continue; - isis_area_max_lsp_lifetime_set(area, lvl, interval); - if (set_refresh_interval[lvl - 1]) - isis_area_lsp_refresh_set(area, lvl, refresh_interval); - } - - return CMD_SUCCESS; -} - -DEFUN (max_lsp_lifetime, - max_lsp_lifetime_cmd, - "max-lsp-lifetime (350-65535)", - "Maximum LSP lifetime\n" - "LSP lifetime in seconds\n") -{ - int lifetime = atoi(argv[1]->arg); - - return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime); -} - - -DEFUN (no_max_lsp_lifetime, - no_max_lsp_lifetime_cmd, - "no max-lsp-lifetime [(350-65535)]", - NO_STR - "Maximum LSP lifetime\n" - "LSP lifetime in seconds\n") -{ - return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, - DEFAULT_LSP_LIFETIME); -} - -int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int lvl; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - if (interval <= area->lsp_gen_interval[lvl - 1]) { - vty_out(vty, - "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - interval, area->lsp_gen_interval[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) { - vty_out(vty, - "LSP refresh interval %us must be less than " - "the configured LSP lifetime %us less 300\n", - interval, area->max_lsp_lifetime[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - isis_area_lsp_refresh_set(area, lvl, interval); - } - - return CMD_SUCCESS; -} - -DEFUN (lsp_refresh_interval, - lsp_refresh_interval_cmd, - "lsp-refresh-interval (1-65235)", - "LSP refresh interval\n" - "LSP refresh interval in seconds\n") -{ - unsigned int interval = atoi(argv[1]->arg); - return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval); -} - -DEFUN (no_lsp_refresh_interval, - no_lsp_refresh_interval_cmd, - "no lsp-refresh-interval [(1-65235)]", - NO_STR - "LSP refresh interval\n" - "LSP refresh interval in seconds\n") -{ - return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, - DEFAULT_MAX_LSP_GEN_INTERVAL); -} - -int isis_vty_password_set(struct vty *vty, int argc, - struct cmd_token *argv[], int level) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - int idx_algo = 1; - int idx_password = 2; - int idx_snp_auth = 5; - uint8_t snp_auth = 0; - - const char *passwd = argv[idx_password]->arg; - if (strlen(passwd) > 254) { - vty_out(vty, "Too long area password (>254)\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argc > idx_snp_auth) { - snp_auth = SNP_AUTH_SEND; - if (strmatch(argv[idx_snp_auth]->text, "validate")) - snp_auth |= SNP_AUTH_RECV; - } - - if (strmatch(argv[idx_algo]->text, "clear")) { - return isis_area_passwd_cleartext_set(area, level, - passwd, snp_auth); - } else if (strmatch(argv[idx_algo]->text, "md5")) { - return isis_area_passwd_hmac_md5_set(area, level, - passwd, snp_auth); - } - - return CMD_WARNING_CONFIG_FAILED; -} - -DEFUN (domain_passwd, - domain_passwd_cmd, - "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]", - "Set the authentication password for a routing domain\n" - "Authentication type\n" - "Authentication type\n" - "Level-wide password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2); -} - -DEFUN (no_domain_passwd, - no_domain_passwd_cmd, - "no domain-password", - NO_STR - "Set the authentication password for a routing domain\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - return isis_area_passwd_unset(area, IS_LEVEL_2); -} - void isis_vty_init(void) { - install_element(INTERFACE_NODE, &ip_router_isis_cmd); - install_element(INTERFACE_NODE, &ip6_router_isis_cmd); - install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); - - install_element(INTERFACE_NODE, &isis_passive_cmd); - install_element(INTERFACE_NODE, &no_isis_passive_cmd); - - install_element(INTERFACE_NODE, &isis_passwd_cmd); - install_element(INTERFACE_NODE, &no_isis_passwd_cmd); - - install_element(INTERFACE_NODE, &isis_metric_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_cmd); - - install_element(INTERFACE_NODE, &isis_hello_interval_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); - - install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); - - install_element(INTERFACE_NODE, &csnp_interval_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_cmd); - - install_element(INTERFACE_NODE, &psnp_interval_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_cmd); - - install_element(INTERFACE_NODE, &circuit_topology_cmd); - install_element(INTERFACE_NODE, &no_circuit_topology_cmd); - install_element(INTERFACE_NODE, &isis_bfd_cmd); install_element(INTERFACE_NODE, &no_isis_bfd_cmd); - install_element(ROUTER_NODE, &set_overload_bit_cmd); - install_element(ROUTER_NODE, &no_set_overload_bit_cmd); - - install_element(ROUTER_NODE, &area_lsp_mtu_cmd); - install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd); - - install_element(ROUTER_NODE, &area_purge_originator_cmd); - - install_element(ROUTER_NODE, &lsp_gen_interval_cmd); - install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd); - - install_element(ROUTER_NODE, &spf_interval_cmd); - install_element(ROUTER_NODE, &no_spf_interval_cmd); - - install_element(ROUTER_NODE, &max_lsp_lifetime_cmd); - install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd); - - install_element(ROUTER_NODE, &lsp_refresh_interval_cmd); - install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd); - - install_element(ROUTER_NODE, &domain_passwd_cmd); - install_element(ROUTER_NODE, &no_domain_passwd_cmd); - - install_element(ROUTER_NODE, &spf_delay_ietf_cmd); - install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd); - +#ifdef FABRICD isis_vty_daemon_init(); +#endif /* ifdef FABRICD */ } diff --git a/isisd/isis_vty_common.h b/isisd/isis_vty_common.h index b726b4ee83..297da0e2c1 100644 --- a/isisd/isis_vty_common.h +++ b/isisd/isis_vty_common.h @@ -26,12 +26,6 @@ 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); diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c index aa48fe1d3a..b2c0440de6 100644 --- a/isisd/isis_vty_fabricd.c +++ b/isisd/isis_vty_fabricd.c @@ -29,6 +29,10 @@ #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, @@ -181,6 +185,854 @@ DEFUN (show_lsp_flooding, 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 + "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 (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") +{ + 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); @@ -189,4 +1041,58 @@ void isis_vty_daemon_init(void) install_element(ROUTER_NODE, &no_triggered_csnp_cmd); install_element(ENABLE_NODE, &show_lsp_flooding_cmd); + + install_element(INTERFACE_NODE, &ip_router_isis_cmd); + install_element(INTERFACE_NODE, &ip6_router_isis_cmd); + install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); + + install_element(ROUTER_NODE, &set_overload_bit_cmd); + install_element(ROUTER_NODE, &no_set_overload_bit_cmd); + + install_element(ROUTER_NODE, &domain_passwd_cmd); + install_element(ROUTER_NODE, &no_domain_passwd_cmd); + + install_element(ROUTER_NODE, &lsp_gen_interval_cmd); + install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd); + + install_element(ROUTER_NODE, &lsp_refresh_interval_cmd); + install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd); + + install_element(ROUTER_NODE, &max_lsp_lifetime_cmd); + install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd); + + install_element(ROUTER_NODE, &area_lsp_mtu_cmd); + install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd); + + install_element(ROUTER_NODE, &spf_interval_cmd); + install_element(ROUTER_NODE, &no_spf_interval_cmd); + + install_element(ROUTER_NODE, &spf_delay_ietf_cmd); + install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd); + + install_element(ROUTER_NODE, &area_purge_originator_cmd); + + install_element(INTERFACE_NODE, &isis_passive_cmd); + install_element(INTERFACE_NODE, &no_isis_passive_cmd); + + install_element(INTERFACE_NODE, &isis_passwd_cmd); + install_element(INTERFACE_NODE, &no_isis_passwd_cmd); + + install_element(INTERFACE_NODE, &isis_metric_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_cmd); + + install_element(INTERFACE_NODE, &isis_hello_interval_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); + + install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); + + install_element(INTERFACE_NODE, &csnp_interval_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_cmd); + + install_element(INTERFACE_NODE, &psnp_interval_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_cmd); + + install_element(INTERFACE_NODE, &circuit_topology_cmd); + install_element(INTERFACE_NODE, &no_circuit_topology_cmd); } diff --git a/isisd/isis_vty_isisd.c b/isisd/isis_vty_isisd.c deleted file mode 100644 index 95aaeae816..0000000000 --- a/isisd/isis_vty_isisd.c +++ /dev/null @@ -1,858 +0,0 @@ -/* - * IS-IS Rout(e)ing protocol - isis_vty_isisd.c - * - * This file contains the CLI that is specific to IS-IS - * - * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology - * Institute of Communications Engineering - * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. - * Copyright (C) 2018 Christian Franke, for NetDEF, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include "command.h" - -#include "isis_circuit.h" -#include "isis_csm.h" -#include "isis_misc.h" -#include "isis_mt.h" -#include "isisd.h" -#include "isis_vty_common.h" - -static int level_for_arg(const char *arg) -{ - if (!strcmp(arg, "level-1")) - return IS_LEVEL_1; - else - return IS_LEVEL_2; -} - -DEFUN (isis_circuit_type, - isis_circuit_type_cmd, - "isis circuit-type <level-1|level-1-2|level-2-only>", - "IS-IS routing protocol\n" - "Configure circuit type for interface\n" - "Level-1 only adjacencies are formed\n" - "Level-1-2 adjacencies are formed\n" - "Level-2 only adjacencies are formed\n") -{ - int idx_level = 2; - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - is_type = string2circuit_t(argv[idx_level]->arg); - if (!is_type) { - vty_out(vty, "Unknown circuit-type \n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (circuit->state == C_STATE_UP - && circuit->area->is_type != IS_LEVEL_1_AND_2 - && circuit->area->is_type != is_type) { - vty_out(vty, "Invalid circuit level for area %s.\n", - circuit->area->area_tag); - return CMD_WARNING_CONFIG_FAILED; - } - isis_circuit_is_type_set(circuit, is_type); - - return CMD_SUCCESS; -} - -DEFUN (no_isis_circuit_type, - no_isis_circuit_type_cmd, - "no isis circuit-type <level-1|level-1-2|level-2-only>", - NO_STR - "IS-IS routing protocol\n" - "Configure circuit type for interface\n" - "Level-1 only adjacencies are formed\n" - "Level-1-2 adjacencies are formed\n" - "Level-2 only adjacencies are formed\n") -{ - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - /* - * Set the circuits level to its default value - */ - if (circuit->state == C_STATE_UP) - is_type = circuit->area->is_type; - else - is_type = IS_LEVEL_1_AND_2; - isis_circuit_is_type_set(circuit, is_type); - - return CMD_SUCCESS; -} - -DEFUN (isis_network, - isis_network_cmd, - "isis network point-to-point", - "IS-IS routing protocol\n" - "Set network type\n" - "point-to-point network type\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) { - vty_out(vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (no_isis_network, - no_isis_network_cmd, - "no isis network point-to-point", - NO_STR - "IS-IS routing protocol\n" - "Set network type for circuit\n" - "point-to-point network type\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) { - vty_out(vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (isis_priority, - isis_priority_cmd, - "isis priority (0-127)", - "IS-IS routing protocol\n" - "Set priority for Designated Router election\n" - "Priority value\n") -{ - uint8_t prio = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[0] = prio; - circuit->priority[1] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority, - no_isis_priority_cmd, - "no isis priority [(0-127)]", - NO_STR - "IS-IS routing protocol\n" - "Set priority for Designated Router election\n" - "Priority value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[0] = DEFAULT_PRIORITY; - circuit->priority[1] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - -DEFUN (isis_priority_level, - isis_priority_level_cmd, - "isis priority (0-127) <level-1|level-2>", - "IS-IS routing protocol\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-1 routing\n" - "Specify priority for level-2 routing\n") -{ - uint8_t prio = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[level_for_arg(argv[3]->text)] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority_level, - no_isis_priority_level_cmd, - "no isis priority [(0-127)] <level-1|level-2>", - NO_STR - "IS-IS routing protocol\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-1 routing\n" - "Specify priority for level-2 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - int level = level_for_arg(argv[argc - 1]->text); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[level] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - -DEFUN (isis_metric_level, - isis_metric_level_cmd, - "isis metric (0-16777215) <level-1|level-2>", - "IS-IS routing protocol\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-1 routing\n" - "Specify metric for level-2 routing\n") -{ - uint32_t met = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, - level_for_arg(argv[3]->text), - met), - "Failed to set metric: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_metric_level, - no_isis_metric_level_cmd, - "no isis metric [(0-16777215)] <level-1|level-2>", - NO_STR - "IS-IS routing protocol\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-1 routing\n" - "Specify metric for level-2 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - int level = level_for_arg(argv[argc - 1]->text); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, level, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L1 metric: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (isis_hello_interval_level, - isis_hello_interval_level_cmd, - "isis hello-interval (1-600) <level-1|level-2>", - "IS-IS routing protocol\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-1 IIHs\n" - "Specify hello-interval for level-2 IIHs\n") -{ - uint32_t interval = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[level_for_arg(argv[3]->text)] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_hello_interval_level, - no_isis_hello_interval_level_cmd, - "no isis hello-interval [(1-600)] <level-1|level-2>", - NO_STR - "IS-IS routing protocol\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-1 IIHs\n" - "Specify hello-interval for level-2 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - int level = level_for_arg(argv[argc - 1]->text); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[level] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (isis_hello_multiplier_level, - isis_hello_multiplier_level_cmd, - "isis hello-multiplier (2-100) <level-1|level-2>", - "IS-IS routing protocol\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-1 IIHs\n" - "Specify hello multiplier for level-2 IIHs\n") -{ - uint16_t mult = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[level_for_arg(argv[3]->text)] = mult; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_hello_multiplier_level, - no_isis_hello_multiplier_level_cmd, - "no isis hello-multiplier [(2-100)] <level-1|level-2>", - NO_STR - "IS-IS routing protocol\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-1 IIHs\n" - "Specify hello multiplier for level-2 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - int level = level_for_arg(argv[argc - 1]->text); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[level] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - -DEFUN (isis_threeway_adj, - isis_threeway_adj_cmd, - "[no] isis three-way-handshake", - NO_STR - "IS-IS commands\n" - "Enable/Disable three-way handshake\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->disable_threeway_adj = !strcmp(argv[0]->text, "no"); - return CMD_SUCCESS; -} - -DEFUN (isis_hello_padding, - isis_hello_padding_cmd, - "isis hello padding", - "IS-IS routing protocol\n" - "Add padding to IS-IS hello packets\n" - "Pad hello packets\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->pad_hellos = 1; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_hello_padding, - no_isis_hello_padding_cmd, - "no isis hello padding", - NO_STR - "IS-IS routing protocol\n" - "Add padding to IS-IS hello packets\n" - "Pad hello packets\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->pad_hellos = 0; - - return CMD_SUCCESS; -} - -DEFUN (csnp_interval_level, - csnp_interval_level_cmd, - "isis csnp-interval (1-600) <level-1|level-2>", - "IS-IS routing protocol\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-1 CSNPs\n" - "Specify interval for level-2 CSNPs\n") -{ - uint16_t interval = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[level_for_arg(argv[3]->text)] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_csnp_interval_level, - no_csnp_interval_level_cmd, - "no isis csnp-interval [(1-600)] <level-1|level-2>", - NO_STR - "IS-IS routing protocol\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-1 CSNPs\n" - "Specify interval for level-2 CSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - int level = level_for_arg(argv[argc - 1]->text); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[level] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (psnp_interval_level, - psnp_interval_level_cmd, - "isis psnp-interval (1-120) <level-1|level-2>", - "IS-IS routing protocol\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-1 PSNPs\n" - "Specify interval for level-2 PSNPs\n") -{ - uint16_t interval = atoi(argv[2]->arg); - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[level_for_arg(argv[3]->text)] = (uint16_t)interval; - - return CMD_SUCCESS; -} - -DEFUN (no_psnp_interval_level, - no_psnp_interval_level_cmd, - "no isis psnp-interval [(1-120)] <level-1|level-2>", - NO_STR - "IS-IS routing protocol\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-1 PSNPs\n" - "Specify interval for level-2 PSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - int level = level_for_arg(argv[argc - 1]->text); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[level] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - -static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) -{ - struct isis_circuit *circuit; - struct listnode *node; - - if (!vty) - return CMD_WARNING_CONFIG_FAILED; - - if (!area) { - vty_out(vty, "ISIS area is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { - if ((area->is_type & IS_LEVEL_1) - && (circuit->is_type & IS_LEVEL_1) - && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) { - vty_out(vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_WARNING_CONFIG_FAILED; - } - if ((area->is_type & IS_LEVEL_2) - && (circuit->is_type & IS_LEVEL_2) - && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) { - vty_out(vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_WARNING_CONFIG_FAILED; - } - } - - return CMD_SUCCESS; -} - -DEFUN (metric_style, - metric_style_cmd, - "metric-style <narrow|transition|wide>", - "Use old-style (ISO 10589) or new-style packet formats\n" - "Use old style of TLVs with narrow metric\n" - "Send and accept both styles of TLVs during transition\n" - "Use new style of TLVs to carry wider metric\n") -{ - int idx_metric_style = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - int ret; - - if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) { - isis_area_metricstyle_set(area, false, true); - return CMD_SUCCESS; - } - - if (area_is_mt(area)) { - vty_out(vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = validate_metric_style_narrow(vty, area); - if (ret != CMD_SUCCESS) - return ret; - - if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0) - isis_area_metricstyle_set(area, true, true); - else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0) - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; - - return CMD_SUCCESS; -} - -DEFUN (no_metric_style, - no_metric_style_cmd, - "no metric-style", - NO_STR - "Use old-style (ISO 10589) or new-style packet formats\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int ret; - - if (area_is_mt(area)) { - vty_out(vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = validate_metric_style_narrow(vty, area); - if (ret != CMD_SUCCESS) - return ret; - - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; -} - -DEFUN (set_attached_bit, - set_attached_bit_cmd, - "set-attached-bit", - "Set attached bit to identify as L1/L2 router for inter-area traffic\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_attached_bit_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_set_attached_bit, - no_set_attached_bit_cmd, - "no set-attached-bit", - NO_STR - "Reset attached bit\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_attached_bit_set(area, false); - return CMD_SUCCESS; -} - -DEFUN (dynamic_hostname, - dynamic_hostname_cmd, - "hostname dynamic", - "Dynamic hostname for IS-IS\n" - "Dynamic hostname\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_dynhostname_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_dynamic_hostname, - no_dynamic_hostname_cmd, - "no hostname dynamic", - NO_STR - "Dynamic hostname for IS-IS\n" - "Dynamic hostname\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_dynhostname_set(area, false); - return CMD_SUCCESS; -} - -DEFUN (is_type, - is_type_cmd, - "is-type <level-1|level-1-2|level-2-only>", - "IS Level for this routing process (OSI only)\n" - "Act as a station router only\n" - "Act as both a station router and an area router\n" - "Act as an area router only\n") -{ - int idx_level = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - int type; - - type = string2circuit_t(argv[idx_level]->arg); - if (!type) { - vty_out(vty, "Unknown IS level \n"); - return CMD_SUCCESS; - } - - isis_area_is_type_set(area, type); - - return CMD_SUCCESS; -} - -DEFUN (no_is_type, - no_is_type_cmd, - "no is-type <level-1|level-1-2|level-2-only>", - NO_STR - "IS Level for this routing process (OSI only)\n" - "Act as a station router only\n" - "Act as both a station router and an area router\n" - "Act as an area router only\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int type; - - /* - * Put the is-type back to defaults: - * - level-1-2 on first area - * - level-1 for the rest - */ - if (listgetdata(listhead(isis->area_list)) == area) - type = IS_LEVEL_1_AND_2; - else - type = IS_LEVEL_1; - - isis_area_is_type_set(area, type); - - return CMD_SUCCESS; -} - -DEFUN (lsp_gen_interval_level, - lsp_gen_interval_level_cmd, - "lsp-gen-interval <level-1|level-2> (1-120)", - "Minimum interval between regenerating same LSP\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval in seconds\n") -{ - uint16_t interval = atoi(argv[2]->arg); - - return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[1]->text), - interval); -} - -DEFUN (no_lsp_gen_interval_level, - no_lsp_gen_interval_level_cmd, - "no lsp-gen-interval <level-1|level-2> [(1-120)]", - NO_STR - "Minimum interval between regenerating same LSP\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[2]->text), - DEFAULT_MIN_LSP_GEN_INTERVAL); -} - -DEFUN (max_lsp_lifetime_level, - max_lsp_lifetime_level_cmd, - "max-lsp-lifetime <level-1|level-2> (350-65535)", - "Maximum LSP lifetime\n" - "Maximum LSP lifetime for Level 1 only\n" - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime in seconds\n") -{ - uint16_t lifetime = atoi(argv[2]->arg); - - return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text), - lifetime); -} - -DEFUN (no_max_lsp_lifetime_level, - no_max_lsp_lifetime_level_cmd, - "no max-lsp-lifetime <level-1|level-2> [(350-65535)]", - NO_STR - "Maximum LSP lifetime\n" - "Maximum LSP lifetime for Level 1 only\n" - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime in seconds\n") -{ - return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text), - DEFAULT_LSP_LIFETIME); -} - -DEFUN (spf_interval_level, - spf_interval_level_cmd, - "spf-interval <level-1|level-2> (1-120)", - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval = atoi(argv[2]->arg); - - area->min_spf_interval[level_for_arg(argv[1]->text)] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_interval_level, - no_spf_interval_level_cmd, - "no spf-interval <level-1|level-2> [(1-120)]", - NO_STR - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int level = level_for_arg(argv[1]->text); - - area->min_spf_interval[level] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (lsp_refresh_interval_level, - lsp_refresh_interval_level_cmd, - "lsp-refresh-interval <level-1|level-2> (1-65235)", - "LSP refresh interval\n" - "LSP refresh interval for Level 1 only\n" - "LSP refresh interval for Level 2 only\n" - "LSP refresh interval in seconds\n") -{ - uint16_t interval = atoi(argv[2]->arg); - return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[1]->text), - interval); -} - -DEFUN (no_lsp_refresh_interval_level, - no_lsp_refresh_interval_level_cmd, - "no lsp-refresh-interval <level-1|level-2> [(1-65235)]", - NO_STR - "LSP refresh interval\n" - "LSP refresh interval for Level 1 only\n" - "LSP refresh interval for Level 2 only\n" - "LSP refresh interval in seconds\n") -{ - return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[2]->text), - DEFAULT_MAX_LSP_GEN_INTERVAL); -} - -DEFUN (area_passwd, - area_passwd_cmd, - "area-password <clear|md5> WORD [authenticate snp <send-only|validate>]", - "Configure the authentication password for an area\n" - "Authentication type\n" - "Authentication type\n" - "Area password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - return isis_vty_password_set(vty, argc, argv, IS_LEVEL_1); -} - -DEFUN (no_area_passwd, - no_area_passwd_cmd, - "no area-password", - NO_STR - "Configure the authentication password for an area\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - return isis_area_passwd_unset(area, IS_LEVEL_1); -} - -void isis_vty_daemon_init(void) -{ - install_element(INTERFACE_NODE, &isis_circuit_type_cmd); - install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); - - install_element(INTERFACE_NODE, &isis_network_cmd); - install_element(INTERFACE_NODE, &no_isis_network_cmd); - - install_element(INTERFACE_NODE, &isis_priority_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_cmd); - install_element(INTERFACE_NODE, &isis_priority_level_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_level_cmd); - - install_element(INTERFACE_NODE, &isis_metric_level_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_level_cmd); - - install_element(INTERFACE_NODE, &isis_hello_interval_level_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_level_cmd); - - install_element(INTERFACE_NODE, &isis_hello_multiplier_level_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_level_cmd); - - install_element(INTERFACE_NODE, &isis_threeway_adj_cmd); - - install_element(INTERFACE_NODE, &isis_hello_padding_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd); - - install_element(INTERFACE_NODE, &csnp_interval_level_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_level_cmd); - - install_element(INTERFACE_NODE, &psnp_interval_level_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_level_cmd); - - install_element(ROUTER_NODE, &metric_style_cmd); - install_element(ROUTER_NODE, &no_metric_style_cmd); - - install_element(ROUTER_NODE, &set_attached_bit_cmd); - install_element(ROUTER_NODE, &no_set_attached_bit_cmd); - - install_element(ROUTER_NODE, &dynamic_hostname_cmd); - install_element(ROUTER_NODE, &no_dynamic_hostname_cmd); - - install_element(ROUTER_NODE, &is_type_cmd); - install_element(ROUTER_NODE, &no_is_type_cmd); - - install_element(ROUTER_NODE, &lsp_gen_interval_level_cmd); - install_element(ROUTER_NODE, &no_lsp_gen_interval_level_cmd); - - install_element(ROUTER_NODE, &max_lsp_lifetime_level_cmd); - install_element(ROUTER_NODE, &no_max_lsp_lifetime_level_cmd); - - install_element(ROUTER_NODE, &spf_interval_level_cmd); - install_element(ROUTER_NODE, &no_spf_interval_level_cmd); - - install_element(ROUTER_NODE, &lsp_refresh_interval_level_cmd); - install_element(ROUTER_NODE, &no_lsp_refresh_interval_level_cmd); - - install_element(ROUTER_NODE, &area_passwd_cmd); - install_element(ROUTER_NODE, &no_area_passwd_cmd); -} diff --git a/isisd/isisd.c b/isisd/isisd.c index 0e496193a3..419127c34e 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -36,6 +36,7 @@ #include "table.h" #include "qobj.h" #include "spf_backoff.h" +#include "lib/northbound_cli.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -67,7 +68,6 @@ DEFINE_QOBJ_TYPE(isis_area) * Prototypes. */ int isis_area_get(struct vty *, const char *); -int isis_area_destroy(struct vty *, const char *); int area_net_title(struct vty *, const char *); int area_clear_net_title(struct vty *, const char *); int show_isis_interface_common(struct vty *, const char *ifname, char); @@ -113,10 +113,11 @@ struct isis_area *isis_area_create(const char *area_tag) */ if (fabricd) { area->is_type = IS_LEVEL_2; - } else if (listcount(isis->area_list) > 0) - area->is_type = IS_LEVEL_1; - else + } else if (listcount(isis->area_list) == 0) area->is_type = IS_LEVEL_1_AND_2; + else + area->is_type = yang_get_default_enum( + "/frr-isisd:isis/instance/is-type"); /* * intialize the databases @@ -138,6 +139,35 @@ struct isis_area *isis_area_create(const char *area_tag) /* * Default values */ +#ifndef FABRICD + enum isis_metric_style default_style; + + area->max_lsp_lifetime[0] = yang_get_default_uint16( + "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-1"); + area->max_lsp_lifetime[1] = yang_get_default_uint16( + "/frr-isisd:isis/instance/lsp/maximum-lifetime/level-2"); + area->lsp_refresh[0] = yang_get_default_uint16( + "/frr-isisd:isis/instance/lsp/refresh-interval/level-1"); + area->lsp_refresh[1] = yang_get_default_uint16( + "/frr-isisd:isis/instance/lsp/refresh-interval/level-2"); + area->lsp_gen_interval[0] = yang_get_default_uint16( + "/frr-isisd:isis/instance/lsp/generation-interval/level-1"); + area->lsp_gen_interval[1] = yang_get_default_uint16( + "/frr-isisd:isis/instance/lsp/generation-interval/level-2"); + area->min_spf_interval[0] = yang_get_default_uint16( + "/frr-isisd:isis/instance/spf/minimum-interval/level-1"); + area->min_spf_interval[1] = yang_get_default_uint16( + "/frr-isisd:isis/instance/spf/minimum-interval/level-1"); + area->dynhostname = yang_get_default_bool( + "/frr-isisd:isis/instance/dynamic-hostname"); + default_style = + yang_get_default_enum("/frr-isisd:isis/instance/metric-style"); + area->oldmetric = default_style == ISIS_WIDE_METRIC ? 0 : 1; + area->newmetric = default_style == ISIS_NARROW_METRIC ? 0 : 1; + area->lsp_frag_threshold = 90; /* not currently configurable */ + area->lsp_mtu = + yang_get_default_uint16("/frr-isisd:isis/instance/lsp/mtu"); +#else area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */ area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */ area->lsp_refresh[0] = DEFAULT_MAX_LSP_GEN_INTERVAL; /* 900 */ @@ -151,6 +181,7 @@ struct isis_area *isis_area_create(const char *area_tag) area->newmetric = 1; area->lsp_frag_threshold = 90; area->lsp_mtu = DEFAULT_LSP_MTU; +#endif /* ifndef FABRICD */ area_mt_init(area); @@ -207,7 +238,7 @@ int isis_area_get(struct vty *vty, const char *area_tag) return CMD_SUCCESS; } -int isis_area_destroy(struct vty *vty, const char *area_tag) +int isis_area_destroy(const char *area_tag) { struct isis_area *area; struct listnode *node, *nnode; @@ -217,7 +248,8 @@ int isis_area_destroy(struct vty *vty, const char *area_tag) area = isis_area_lookup(area_tag); if (area == NULL) { - vty_out(vty, "Can't find ISIS instance \n"); + zlog_warn("%s: could not find area with area-tag %s", + __func__, area_tag); return CMD_ERR_NO_MATCH; } @@ -287,6 +319,7 @@ int isis_area_destroy(struct vty *vty, const char *area_tag) return CMD_SUCCESS; } +#ifdef FABRICD static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid, bool enabled) { @@ -312,6 +345,7 @@ static void area_set_mt_overload(struct isis_area *area, uint16_t mtid, 0); } } +#endif /* ifdef FABRICD */ int area_net_title(struct vty *vty, const char *net_title) { @@ -1452,12 +1486,13 @@ DEFUN (show_database, return show_isis_database(vty, id, uilevel); } +#ifdef FABRICD /* - * 'router isis' command + * 'router openfabric' command */ -DEFUN_NOSH (router_isis, - router_isis_cmd, - "router " PROTO_NAME " WORD", +DEFUN_NOSH (router_openfabric, + router_openfabric_cmd, + "router openfabric WORD", ROUTER_STR PROTO_HELP "ISO Routing area tag\n") @@ -1467,20 +1502,21 @@ DEFUN_NOSH (router_isis, } /* - *'no router isis' command + *'no router openfabric' command */ -DEFUN (no_router_isis, - no_router_isis_cmd, - "no router " PROTO_NAME " WORD", +DEFUN (no_router_openfabric, + no_router_openfabric_cmd, + "no router openfabric WORD", NO_STR ROUTER_STR PROTO_HELP "ISO Routing area tag\n") { int idx_word = 3; - return isis_area_destroy(vty, argv[idx_word]->arg); + return isis_area_destroy(argv[idx_word]->arg); } - +#endif /* ifdef FABRICD */ +#ifdef FABRICD /* * 'net' command */ @@ -1507,7 +1543,8 @@ DEFUN (no_net, int idx_word = 2; return area_clear_net_title(vty, argv[idx_word]->arg); } - +#endif /* ifdef FABRICD */ +#ifdef FABRICD DEFUN (isis_topology, isis_topology_cmd, "topology " ISIS_MT_NAMES " [overload]", @@ -1572,6 +1609,7 @@ DEFUN (no_isis_topology, area_set_mt_overload(area, mtid, false); return CMD_SUCCESS; } +#endif /* ifdef FABRICD */ void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu) { @@ -1743,11 +1781,9 @@ void isis_area_is_type_set(struct isis_area *area, int is_type) void isis_area_metricstyle_set(struct isis_area *area, bool old_metric, bool new_metric) { - if (area->oldmetric != old_metric || area->newmetric != new_metric) { - area->oldmetric = old_metric; - area->newmetric = new_metric; - lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); - } + area->oldmetric = old_metric; + area->newmetric = new_metric; + lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); } void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit) @@ -1758,6 +1794,9 @@ void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit) area->overload_bit = new_overload_bit; lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1); } +#ifndef FABRICD + isis_notif_db_overload(area, overload_bit); +#endif /* ifndef FABRICD */ } void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit) @@ -1802,6 +1841,7 @@ void isis_area_lsp_refresh_set(struct isis_area *area, int level, lsp_regenerate_schedule(area, level, 1); } +#ifdef FABRICD DEFUN (log_adj_changes, log_adj_changes_cmd, "log-adjacency-changes", @@ -1826,7 +1866,8 @@ DEFUN (no_log_adj_changes, return CMD_SUCCESS; } - +#endif /* ifdef FABRICD */ +#ifdef FABRICD /* IS-IS configuration write function */ int isis_config_write(struct vty *vty) { @@ -2101,6 +2142,23 @@ int isis_config_write(struct vty *vty) return write; } +#else +/* IS-IS configuration write function */ +int isis_config_write(struct vty *vty) +{ + int write = 0; + struct lyd_node *dnode; + + dnode = yang_dnode_get(running_config->dnode, "/frr-isisd:isis"); + if (dnode) { + nb_cli_show_dnode_cmds(vty, dnode, false); + write++; + } + + return write; +} +#endif /* ifdef FABRICD */ + struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1}; void isis_init() @@ -2179,11 +2237,12 @@ void isis_init() install_element(CONFIG_NODE, &debug_isis_bfd_cmd); install_element(CONFIG_NODE, &no_debug_isis_bfd_cmd); - install_element(CONFIG_NODE, &router_isis_cmd); - install_element(CONFIG_NODE, &no_router_isis_cmd); - install_default(ROUTER_NODE); +#ifdef FABRICD + install_element(CONFIG_NODE, &router_openfabric_cmd); + install_element(CONFIG_NODE, &no_router_openfabric_cmd); + install_element(ROUTER_NODE, &net_cmd); install_element(ROUTER_NODE, &no_net_cmd); @@ -2192,6 +2251,7 @@ void isis_init() install_element(ROUTER_NODE, &log_adj_changes_cmd); install_element(ROUTER_NODE, &no_log_adj_changes_cmd); +#endif /* ifdef FABRICD */ spf_backoff_cmd_init(); } diff --git a/isisd/isisd.h b/isisd/isisd.h index 2c0ea203f3..fb879395c1 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -29,6 +29,7 @@ #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" @@ -50,6 +51,7 @@ static const bool fabricd = false; #define PROTO_REDIST_STR FRR_REDIST_STR_ISISD #define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_ISISD #define ROUTER_NODE ISIS_NODE +extern void isis_cli_init(void); #endif extern struct zebra_privs_t isisd_privs; @@ -96,6 +98,13 @@ struct lsp_refresh_arg { int level; }; +/* for yang configuration */ +enum isis_metric_style { + ISIS_NARROW_METRIC = 0, + ISIS_WIDE_METRIC, + ISIS_TRANSITION_METRIC, +}; + struct isis_area { struct isis *isis; /* back pointer */ dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */ @@ -184,6 +193,7 @@ void isis_new(unsigned long); struct isis_area *isis_area_create(const char *); struct isis_area *isis_area_lookup(const char *); int isis_area_get(struct vty *vty, const char *area_tag); +int isis_area_destroy(const char *area_tag); void print_debug(struct vty *, int, int); struct isis_lsp *lsp_for_arg(const char *argv, dict_t *lspdb); @@ -208,6 +218,52 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level, int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level, const char *passwd, uint8_t snp_auth); +extern const struct frr_yang_module_info frr_isisd_info; +extern void isis_northbound_init(void); + +/* YANG northbound notifications */ +extern void isis_notif_db_overload(const struct isis_area *area, bool overload); +extern void isis_notif_lsp_too_large(const struct isis_circuit *circuit, + uint32_t pdu_size, const char *lsp_id); +extern void isis_notif_if_state_change(const struct isis_circuit *circuit, + bool down); +extern void isis_notif_corrupted_lsp(const struct isis_area *area, + const char *lsp_id); /* currently unused */ +extern void isis_notif_lsp_exceed_max(const struct isis_area *area, + const char *lsp_id); +extern void +isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit, + uint8_t max_area_addrs, const char *raw_pdu); +extern void +isis_notif_authentication_type_failure(const struct isis_circuit *circuit, + const char *raw_pdu); +extern void +isis_notif_authentication_failure(const struct isis_circuit *circuit, + const char *raw_pdu); +extern void isis_notif_adj_state_change(const struct isis_adjacency *adj, + int new_state, const char *reason); +extern void isis_notif_reject_adjacency(const struct isis_circuit *circuit, + const char *reason, + const char *raw_pdu); +extern void isis_notif_area_mismatch(const struct isis_circuit *circuit, + const char *raw_pdu); +extern void isis_notif_lsp_received(const struct isis_circuit *circuit, + const char *lsp_id, uint32_t seqno, + uint32_t timestamp, const char *sys_id); +extern void isis_notif_lsp_gen(const struct isis_area *area, const char *lsp_id, + uint32_t seqno, uint32_t timestamp); +extern void isis_notif_id_len_mismatch(const struct isis_circuit *circuit, + uint8_t rcv_id_len, const char *raw_pdu); +extern void isis_notif_version_skew(const struct isis_circuit *circuit, + uint8_t version, const char *raw_pdu); +extern void isis_notif_lsp_error(const struct isis_circuit *circuit, + const char *lsp_id, const char *raw_pdu, + uint32_t offset, uint8_t tlv_type); +extern void isis_notif_seqno_skipped(const struct isis_circuit *circuit, + const char *lsp_id); +extern void isis_notif_own_lsp_purge(const struct isis_circuit *circuit, + const char *lsp_id); + /* Master of threads. */ extern struct thread_master *master; diff --git a/isisd/subdir.am b/isisd/subdir.am index 29ec1cdd17..c5b9b31a48 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -7,12 +7,12 @@ noinst_LIBRARIES += isisd/libisis.a sbin_PROGRAMS += isisd/isisd dist_examples_DATA += isisd/isisd.conf.sample vtysh_scan += \ + $(top_srcdir)/isisd/isis_cli.c \ $(top_srcdir)/isisd/isis_redist.c \ $(top_srcdir)/isisd/isis_spf.c \ $(top_srcdir)/isisd/isis_te.c \ $(top_srcdir)/isisd/isis_vty_common.c \ $(top_srcdir)/isisd/isis_vty_fabricd.c \ - $(top_srcdir)/isisd/isis_vty_isisd.c \ $(top_srcdir)/isisd/isisd.c \ # end man8 += $(MANBUILD)/isisd.8 @@ -57,6 +57,7 @@ noinst_HEADERS += \ isisd/isisd.h \ isisd/iso_checksum.h \ isisd/fabricd.h \ + isisd/isis_cli.h \ # end LIBISIS_SOURCES = \ @@ -103,11 +104,19 @@ ISIS_LDADD_COMMON = lib/libfrr.la @LIBCAP@ isisd_libisis_a_SOURCES = \ $(LIBISIS_SOURCES) \ - isisd/isis_vty_isisd.c \ + isisd/isis_northbound.c \ + isisd/isis_cli.c \ #end + +isisd/isis_cli_clippy.c: $(CLIPPY_DEPS) +isisd/isis_cli.$(OBJEXT): isisd/isis_cli_clippy.c + isisd_isisd_LDADD = isisd/libisis.a $(ISIS_LDADD_COMMON) isisd_isisd_SOURCES = $(ISIS_SOURCES) - +nodist_isisd_isisd_SOURCES = \ + yang/frr-isisd.yang.c \ + # end + # Building fabricd FABRICD_CPPFLAGS = -DFABRICD=1 $(AM_CPPFLAGS) diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index 56af76d94e..c16d92f28b 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -139,6 +139,16 @@ ldpe(void) void ldpe_init(struct ldpd_init *init) { +#ifdef __OpenBSD__ + /* This socket must be open before dropping privileges. */ + global.pfkeysock = pfkey_init(); + if (sysdep.no_pfkey == 0) { + pfkey_ev = NULL; + thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock, + &pfkey_ev); + } +#endif + /* drop privileges */ ldpe_privs.user = init->user; ldpe_privs.group = init->group; @@ -159,14 +169,6 @@ ldpe_init(struct ldpd_init *init) fatal("inet_pton"); if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1) fatal("inet_pton"); -#ifdef __OpenBSD__ - global.pfkeysock = pfkey_init(); - if (sysdep.no_pfkey == 0) { - pfkey_ev = NULL; - thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock, - &pfkey_ev); - } -#endif /* mark sockets as closed */ global.ipv4.ldp_disc_socket = -1; diff --git a/ldpd/socket.c b/ldpd/socket.c index bebd7a7d61..78a07b1ed4 100644 --- a/ldpd/socket.c +++ b/ldpd/socket.c @@ -268,9 +268,18 @@ sock_set_bindany(int fd, int enable) return (-1); } return (0); +#elif defined(IP_BINDANY) + frr_elevate_privs(&ldpd_privs) { + if (setsockopt(fd, IPPROTO_IP, IP_BINDANY, &enable, sizeof(int)) + < 0) { + log_warn("%s: error setting IP_BINDANY", __func__); + return (-1); + } + } #else - log_warnx("%s: missing SO_BINDANY and IP_FREEBIND, unable to bind " - "to a nonlocal IP address", __func__); + log_warnx( + "%s: missing SO_BINDANY, IP_FREEBIND and IP_BINDANY, unable to bind to a nonlocal IP address", + __func__); return (-1); #endif /* HAVE_SO_BINDANY */ } diff --git a/lib/distribute.c b/lib/distribute.c index 9697916332..3a6b775bc8 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -27,16 +27,12 @@ #include "distribute.h" #include "memory.h" +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_CTX, "Distribute ctx") DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list") DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname") DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name") -/* Hash of distribute list. */ -struct hash *disthash; - -/* Hook functions. */ -void (*distribute_add_hook)(struct distribute *); -void (*distribute_delete_hook)(struct distribute *); +struct list *dist_ctx_list; static struct distribute *distribute_new(void) { @@ -62,7 +58,8 @@ static void distribute_free(struct distribute *dist) XFREE(MTYPE_DISTRIBUTE, dist); } -static void distribute_free_if_empty(struct distribute *dist) +static void distribute_free_if_empty(struct distribute_ctx *ctx, + struct distribute *dist) { int i; @@ -70,12 +67,13 @@ static void distribute_free_if_empty(struct distribute *dist) if (dist->list[i] != NULL || dist->prefix[i] != NULL) return; - hash_release(disthash, dist); + hash_release(ctx->disthash, dist); distribute_free(dist); } /* Lookup interface's distribute list. */ -struct distribute *distribute_lookup(const char *ifname) +struct distribute *distribute_lookup(struct distribute_ctx *ctx, + const char *ifname) { struct distribute key; struct distribute *dist; @@ -83,7 +81,7 @@ struct distribute *distribute_lookup(const char *ifname) /* temporary reference */ key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL; - dist = hash_lookup(disthash, &key); + dist = hash_lookup(ctx->disthash, &key); if (key.ifname) XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname); @@ -91,14 +89,18 @@ struct distribute *distribute_lookup(const char *ifname) return dist; } -void distribute_list_add_hook(void (*func)(struct distribute *)) +void distribute_list_add_hook(struct distribute_ctx *ctx, + void (*func)(struct distribute_ctx *ctx, + struct distribute *)) { - distribute_add_hook = func; + ctx->distribute_add_hook = func; } -void distribute_list_delete_hook(void (*func)(struct distribute *)) +void distribute_list_delete_hook(struct distribute_ctx *ctx, + void (*func)(struct distribute_ctx *ctx, + struct distribute *)) { - distribute_delete_hook = func; + ctx->distribute_delete_hook = func; } static void *distribute_hash_alloc(struct distribute *arg) @@ -114,7 +116,8 @@ static void *distribute_hash_alloc(struct distribute *arg) } /* Make new distribute list and push into hash. */ -static struct distribute *distribute_get(const char *ifname) +static struct distribute *distribute_get(struct distribute_ctx *ctx, + const char *ifname) { struct distribute key; struct distribute *ret; @@ -122,7 +125,7 @@ static struct distribute *distribute_get(const char *ifname) /* temporary reference */ key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL; - ret = hash_get(disthash, &key, + ret = hash_get(ctx->disthash, &key, (void *(*)(void *))distribute_hash_alloc); if (key.ifname) @@ -152,29 +155,32 @@ static bool distribute_cmp(const struct distribute *dist1, } /* Set access-list name to the distribute list. */ -static void distribute_list_set(const char *ifname, enum distribute_type type, +static void distribute_list_set(struct distribute_ctx *ctx, + const char *ifname, enum distribute_type type, const char *alist_name) { struct distribute *dist; - dist = distribute_get(ifname); + dist = distribute_get(ctx, ifname); if (dist->list[type]) XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]); dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name); /* Apply this distribute-list to the interface. */ - (*distribute_add_hook)(dist); + (ctx->distribute_add_hook)(ctx, dist); } /* Unset distribute-list. If matched distribute-list exist then return 1. */ -static int distribute_list_unset(const char *ifname, enum distribute_type type, +static int distribute_list_unset(struct distribute_ctx *ctx, + const char *ifname, + enum distribute_type type, const char *alist_name) { struct distribute *dist; - dist = distribute_lookup(ifname); + dist = distribute_lookup(ctx, ifname); if (!dist) return 0; @@ -187,39 +193,41 @@ static int distribute_list_unset(const char *ifname, enum distribute_type type, dist->list[type] = NULL; /* Apply this distribute-list to the interface. */ - (*distribute_delete_hook)(dist); + (ctx->distribute_delete_hook)(ctx, dist); /* If all dist are NULL, then free distribute list. */ - distribute_free_if_empty(dist); + distribute_free_if_empty(ctx, dist); return 1; } /* Set access-list name to the distribute list. */ -static void distribute_list_prefix_set(const char *ifname, +static void distribute_list_prefix_set(struct distribute_ctx *ctx, + const char *ifname, enum distribute_type type, const char *plist_name) { struct distribute *dist; - dist = distribute_get(ifname); + dist = distribute_get(ctx, ifname); if (dist->prefix[type]) XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]); dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name); /* Apply this distribute-list to the interface. */ - (*distribute_add_hook)(dist); + (ctx->distribute_add_hook)(ctx, dist); } /* Unset distribute-list. If matched distribute-list exist then return 1. */ -static int distribute_list_prefix_unset(const char *ifname, +static int distribute_list_prefix_unset(struct distribute_ctx *ctx, + const char *ifname, enum distribute_type type, const char *plist_name) { struct distribute *dist; - dist = distribute_lookup(ifname); + dist = distribute_lookup(ctx, ifname); if (!dist) return 0; @@ -232,10 +240,10 @@ static int distribute_list_prefix_unset(const char *ifname, dist->prefix[type] = NULL; /* Apply this distribute-list to the interface. */ - (*distribute_delete_hook)(dist); + (ctx->distribute_delete_hook)(ctx, dist); /* If all dist are NULL, then free distribute list. */ - distribute_free_if_empty(dist); + distribute_free_if_empty(ctx, dist); return 1; } @@ -250,15 +258,17 @@ DEFUN (distribute_list, "Interface name\n") { int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0; - /* Check of distribute list type. */ enum distribute_type type = argv[2 + prefix]->arg[0] == 'i' ? DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT; /* Set appropriate function call */ - void (*distfn)(const char *, enum distribute_type, const char *) = + void (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_set : &distribute_list_set; + struct distribute_ctx *ctx = + (struct distribute_ctx *)listnode_head(dist_ctx_list); /* if interface is present, get name */ const char *ifname = NULL; @@ -266,7 +276,7 @@ DEFUN (distribute_list, ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - distfn(ifname, type, argv[1 + prefix]->arg); + distfn(ctx, ifname, type, argv[1 + prefix]->arg); return CMD_SUCCESS; } @@ -283,15 +293,16 @@ DEFUN (ipv6_distribute_list, "Interface name\n") { int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0; - /* Check of distribute list type. */ enum distribute_type type = argv[3 + prefix]->arg[0] == 'i' ? DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT; /* Set appropriate function call */ - void (*distfn)(const char *, enum distribute_type, const char *) = + void (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_set : &distribute_list_set; + struct distribute_ctx *ctx = listnode_head(dist_ctx_list); /* if interface is present, get name */ const char *ifname = NULL; @@ -299,7 +310,7 @@ DEFUN (ipv6_distribute_list, ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - distfn(ifname, type, argv[2 + prefix]->arg); + distfn(ctx, ifname, type, argv[2 + prefix]->arg); return CMD_SUCCESS; } @@ -316,7 +327,6 @@ DEFUN (no_distribute_list, "Interface name\n") { int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0; - int idx_alname = 2 + prefix; int idx_disttype = idx_alname + 1; enum distribute_type type = @@ -324,16 +334,17 @@ DEFUN (no_distribute_list, DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT; /* Set appropriate function call */ - int (*distfn)(const char *, enum distribute_type, - const char *) = + int (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_unset : &distribute_list_unset; + struct distribute_ctx *ctx = listnode_head(dist_ctx_list); /* if interface is present, get name */ const char *ifname = NULL; if (argv[argc - 1]->type == VARIABLE_TKN) ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - int ret = distfn(ifname, type, argv[2 + prefix]->arg); + int ret = distfn(ctx, ifname, type, argv[2 + prefix]->arg); if (!ret) { vty_out(vty, "distribute list doesn't exist\n"); @@ -355,16 +366,17 @@ DEFUN (no_ipv6_distribute_list, "Interface name\n") { int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0; - int idx_alname = 3 + prefix; int idx_disttype = idx_alname + 1; enum distribute_type type = argv[idx_disttype]->arg[0] == 'i' ? DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT; + struct distribute_ctx *ctx = listnode_head(dist_ctx_list); /* Set appropriate function call */ - int (*distfn)(const char *, enum distribute_type, const char *) = + int (*distfn)(struct distribute_ctx *, const char *, + enum distribute_type, const char *) = prefix ? &distribute_list_prefix_unset : &distribute_list_unset; /* if interface is present, get name */ @@ -373,7 +385,7 @@ DEFUN (no_ipv6_distribute_list, if (argv[argc - 1]->type == VARIABLE_TKN) ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - int ret = distfn(ifname, type, argv[3 + prefix]->arg); + int ret = distfn(ctx, ifname, type, argv[3 + prefix]->arg); if (!ret) { vty_out(vty, "distribute list doesn't exist\n"); @@ -393,7 +405,7 @@ static int distribute_print(struct vty *vty, char *tab[], int is_prefix, return has_print; } -int config_show_distribute(struct vty *vty) +int config_show_distribute(struct vty *vty, struct distribute_ctx *dist_ctxt) { unsigned int i; int has_print = 0; @@ -401,7 +413,7 @@ int config_show_distribute(struct vty *vty) struct distribute *dist; /* Output filter configuration. */ - dist = distribute_lookup(NULL); + dist = distribute_lookup(dist_ctxt, NULL); vty_out(vty, " Outgoing update filter list for all interface is"); has_print = 0; if (dist) { @@ -419,8 +431,8 @@ int config_show_distribute(struct vty *vty) else vty_out(vty, " not set\n"); - for (i = 0; i < disthash->size; i++) - for (mp = disthash->index[i]; mp; mp = mp->next) { + for (i = 0; i < dist_ctxt->disthash->size; i++) + for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) { dist = mp->data; if (dist->ifname) { vty_out(vty, " %s filtered by", @@ -447,7 +459,7 @@ int config_show_distribute(struct vty *vty) /* Input filter configuration. */ - dist = distribute_lookup(NULL); + dist = distribute_lookup(dist_ctxt, NULL); vty_out(vty, " Incoming update filter list for all interface is"); has_print = 0; if (dist) { @@ -465,8 +477,8 @@ int config_show_distribute(struct vty *vty) else vty_out(vty, " not set\n"); - for (i = 0; i < disthash->size; i++) - for (mp = disthash->index[i]; mp; mp = mp->next) { + for (i = 0; i < dist_ctxt->disthash->size; i++) + for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) { dist = mp->data; if (dist->ifname) { vty_out(vty, " %s filtered by", @@ -494,7 +506,8 @@ int config_show_distribute(struct vty *vty) } /* Configuration write function. */ -int config_write_distribute(struct vty *vty) +int config_write_distribute(struct vty *vty, + struct distribute_ctx *dist_ctxt) { unsigned int i; int j; @@ -502,8 +515,8 @@ int config_write_distribute(struct vty *vty) struct hash_backet *mp; int write = 0; - for (i = 0; i < disthash->size; i++) - for (mp = disthash->index[i]; mp; mp = mp->next) { + for (i = 0; i < dist_ctxt->disthash->size; i++) + for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) { struct distribute *dist; dist = mp->data; @@ -543,19 +556,38 @@ int config_write_distribute(struct vty *vty) return write; } -/* Clear all distribute list. */ -void distribute_list_reset() +void distribute_list_delete(struct distribute_ctx **ctx) { - hash_clean(disthash, (void (*)(void *))distribute_free); + if ((*ctx)->disthash) { + hash_clean((*ctx)->disthash, (void (*)(void *))distribute_free); + } + if (!dist_ctx_list) + dist_ctx_list = list_new(); + listnode_delete(dist_ctx_list, *ctx); + if (list_isempty(dist_ctx_list)) + list_delete(&dist_ctx_list); + XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx)); } -/* Initialize distribute list related hash. */ -void distribute_list_init(int node) +/* Initialize distribute list container */ +struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf) { - disthash = hash_create( + struct distribute_ctx *ctx; + + ctx = XCALLOC(MTYPE_DISTRIBUTE_CTX, sizeof(struct distribute_ctx)); + ctx->vrf = vrf; + ctx->disthash = hash_create( distribute_hash_make, (bool (*)(const void *, const void *))distribute_cmp, NULL); + if (!dist_ctx_list) + dist_ctx_list = list_new(); + listnode_add(dist_ctx_list, ctx); + return ctx; +} +/* Initialize distribute list vty commands */ +void distribute_list_init(int node) +{ /* vtysh command-extraction doesn't grok install_element(node, ) */ if (node == RIP_NODE) { install_element(RIP_NODE, &distribute_list_cmd); @@ -563,10 +595,7 @@ void distribute_list_init(int node) } else if (node == RIPNG_NODE) { install_element(RIPNG_NODE, &distribute_list_cmd); install_element(RIPNG_NODE, &no_distribute_list_cmd); - } - - /* install v6 */ - if (node == RIPNG_NODE) { + /* install v6 */ install_element(RIPNG_NODE, &ipv6_distribute_list_cmd); install_element(RIPNG_NODE, &no_ipv6_distribute_list_cmd); } diff --git a/lib/distribute.h b/lib/distribute.h index 35c5e0d6b6..44c699b38a 100644 --- a/lib/distribute.h +++ b/lib/distribute.h @@ -45,14 +45,36 @@ struct distribute { char *prefix[DISTRIBUTE_MAX]; }; +struct distribute_ctx { + /* Hash of distribute list. */ + struct hash *disthash; + + /* Hook functions. */ + void (*distribute_add_hook)(struct distribute_ctx *ctx, + struct distribute *dist); + void (*distribute_delete_hook)(struct distribute_ctx *ctx, + struct distribute *dist); + + /* vrf information */ + struct vrf *vrf; +}; + /* Prototypes for distribute-list. */ -extern void distribute_list_init(int); -extern void distribute_list_reset(void); -extern void distribute_list_add_hook(void (*)(struct distribute *)); -extern void distribute_list_delete_hook(void (*)(struct distribute *)); -extern struct distribute *distribute_lookup(const char *); -extern int config_write_distribute(struct vty *); -extern int config_show_distribute(struct vty *); +extern void distribute_list_init(int node); +extern struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf); +extern void distribute_list_delete(struct distribute_ctx **ctx); +extern void distribute_list_add_hook(struct distribute_ctx *ctx, + void (*)(struct distribute_ctx *ctx, + struct distribute *)); +extern void distribute_list_delete_hook(struct distribute_ctx *ctx, + void (*)(struct distribute_ctx *ctx, + struct distribute *)); +extern struct distribute *distribute_lookup(struct distribute_ctx *ctx, + const char *ifname); +extern int config_write_distribute(struct vty *vty, + struct distribute_ctx *ctx); +extern int config_show_distribute(struct vty *vty, + struct distribute_ctx *ctx); extern enum filter_type distribute_apply_in(struct interface *, struct prefix *); diff --git a/lib/hook.c b/lib/hook.c index 4fe305f282..870d158aac 100644 --- a/lib/hook.c +++ b/lib/hook.c @@ -1,23 +1,17 @@ /* * Copyright (c) 2016 David Lamparter, for NetDEF, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H diff --git a/lib/hook.h b/lib/hook.h index ee496ab365..96fec97d7e 100644 --- a/lib/hook.h +++ b/lib/hook.h @@ -1,23 +1,17 @@ /* * Copyright (c) 2016 David Lamparter, for NetDEF, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _FRR_HOOK_H diff --git a/lib/lib_errors.c b/lib/lib_errors.c index b1ed7d2f6b..7e428f135c 100644 --- a/lib/lib_errors.c +++ b/lib/lib_errors.c @@ -105,10 +105,16 @@ static struct log_ref ferr_lib_warn[] = { .suggestion = "Check if the installed FRR YANG modules are in sync with the FRR binaries", }, { - .code = EC_LIB_NB_CB_CONFIG, - .title = "A northbound configuration callback has failed", - .description = "The northbound subsystem has detected that a callback used to process a configuration change has returned an error", - .suggestion = "The log message should contain further details on the specific error that occurred; investigate the reported error.", + .code = EC_LIB_NB_CB_CONFIG_VALIDATE, + .title = "A northbound configuration callback has failed in the VALIDATE phase", + .description = "A callback used to process a configuration change has returned a validation error", + .suggestion = "The provided configuration is invalid. Fix any inconsistency and try again.", + }, + { + .code = EC_LIB_NB_CB_CONFIG_PREPARE, + .title = "A northbound configuration callback has failed in the PREPARE phase", + .description = "A callback used to process a configuration change has returned a resource allocation error", + .suggestion = "The system might be running out of resources. Check the log for more details.", }, { .code = EC_LIB_NB_CB_STATE, @@ -327,6 +333,18 @@ static struct log_ref ferr_lib_err[] = { .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, } }; diff --git a/lib/lib_errors.h b/lib/lib_errors.h index 5534edbd8d..86a83df46c 100644 --- a/lib/lib_errors.h +++ b/lib/lib_errors.h @@ -57,7 +57,10 @@ enum lib_log_refs { EC_LIB_NB_CB_MISSING, EC_LIB_NB_CB_INVALID_PRIO, EC_LIB_NB_CBS_VALIDATION, - EC_LIB_NB_CB_CONFIG, + EC_LIB_NB_CB_CONFIG_VALIDATE, + EC_LIB_NB_CB_CONFIG_PREPARE, + EC_LIB_NB_CB_CONFIG_ABORT, + EC_LIB_NB_CB_CONFIG_APPLY, EC_LIB_NB_CB_STATE, EC_LIB_NB_CB_RPC, EC_LIB_NB_CANDIDATE_INVALID, diff --git a/lib/mlag.c b/lib/mlag.c new file mode 100644 index 0000000000..acdc662924 --- /dev/null +++ b/lib/mlag.c @@ -0,0 +1,41 @@ +/* mlag generic code. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR 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, or (at your option) any + * later version. + * + * FRR 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 FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include <zebra.h> + +#include <mlag.h> + +char *mlag_role2str(enum mlag_role role, char *buf, size_t size) +{ + switch (role) { + case MLAG_ROLE_NONE: + snprintf(buf, size, "NONE"); + break; + case MLAG_ROLE_PRIMARY: + snprintf(buf, size, "PRIMARY"); + break; + case MLAG_ROLE_SECONDARY: + snprintf(buf, size, "SECONDARY"); + break; + } + + return buf; +} diff --git a/lib/mlag.h b/lib/mlag.h new file mode 100644 index 0000000000..73725ca3fd --- /dev/null +++ b/lib/mlag.h @@ -0,0 +1,32 @@ +/* mlag header. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR 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, or (at your option) any + * later version. + * + * FRR 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 FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#ifndef __MLAG_H__ +#define __MLAG_H__ + +enum mlag_role { + MLAG_ROLE_NONE, + MLAG_ROLE_PRIMARY, + MLAG_ROLE_SECONDARY +}; + +extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size); +#endif diff --git a/lib/module.c b/lib/module.c index 7d5671290b..6754b94579 100644 --- a/lib/module.c +++ b/lib/module.c @@ -1,23 +1,17 @@ /* * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "config.h" diff --git a/lib/module.h b/lib/module.h index e66e5cd650..68ed959270 100644 --- a/lib/module.h +++ b/lib/module.h @@ -1,23 +1,17 @@ /* * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _FRR_MODULE_H diff --git a/lib/northbound.c b/lib/northbound.c index 8b96dc4a6c..a7f9c8620e 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -719,6 +719,7 @@ static int nb_configuration_callback(const enum nb_event event, const struct lyd_node *dnode = change->cb.dnode; union nb_resource *resource; int ret = NB_ERR; + enum lib_log_refs ref; if (debug_northbound) { const char *value = "(none)"; @@ -751,12 +752,36 @@ static int nb_configuration_callback(const enum nb_event event, break; } - if (ret != NB_OK) - flog_warn( - EC_LIB_NB_CB_CONFIG, - "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]", - __func__, nb_err_name(ret), nb_event_name(event), - nb_operation_name(operation), xpath); + if (ret != NB_OK) { + switch (event) { + case NB_EV_VALIDATE: + ref = EC_LIB_NB_CB_CONFIG_VALIDATE; + break; + case NB_EV_PREPARE: + ref = EC_LIB_NB_CB_CONFIG_PREPARE; + break; + case NB_EV_ABORT: + ref = EC_LIB_NB_CB_CONFIG_ABORT; + break; + case NB_EV_APPLY: + ref = EC_LIB_NB_CB_CONFIG_APPLY; + break; + } + if (event == NB_EV_VALIDATE || event == NB_EV_PREPARE) + flog_warn( + ref, + "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]", + __func__, nb_err_name(ret), + nb_event_name(event), + nb_operation_name(operation), xpath); + else + flog_err( + ref, + "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]", + __func__, nb_err_name(ret), + nb_event_name(event), + nb_operation_name(operation), xpath); + } return ret; } @@ -1071,7 +1096,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node, /* Iterate over all list entries. */ do { struct yang_list_keys list_keys; - char xpath[XPATH_MAXLEN]; + char xpath[XPATH_MAXLEN * 2]; int ret; /* Obtain list entry. */ diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index d685a4e7c2..2b024ace93 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -71,7 +71,7 @@ void nb_cli_enqueue_change(struct vty *vty, const char *xpath, } change = &vty->cfg_changes[vty->num_cfg_changes++]; - change->xpath = xpath; + strlcpy(change->xpath, xpath, sizeof(change->xpath)); change->operation = operation; change->value = value; } @@ -79,8 +79,7 @@ void nb_cli_enqueue_change(struct vty *vty, const char *xpath, int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) { struct nb_config *candidate_transitory; - char xpath_base[XPATH_MAXLEN]; - va_list ap; + char xpath_base[XPATH_MAXLEN] = {}; bool error = false; int ret; @@ -94,9 +93,13 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) candidate_transitory = nb_config_dup(vty->candidate_config); /* Parse the base XPath format string. */ - va_start(ap, xpath_base_fmt); - vsnprintf(xpath_base, sizeof(xpath_base), xpath_base_fmt, ap); - va_end(ap); + if (xpath_base_fmt) { + va_list ap; + + va_start(ap, xpath_base_fmt); + vsnprintf(xpath_base, sizeof(xpath_base), xpath_base_fmt, ap); + va_end(ap); + } /* Edit candidate configuration. */ for (size_t i = 0; i < vty->num_cfg_changes; i++) { diff --git a/lib/northbound_cli.h b/lib/northbound_cli.h index 362a4bc325..884f250941 100644 --- a/lib/northbound_cli.h +++ b/lib/northbound_cli.h @@ -60,7 +60,7 @@ extern void nb_cli_enqueue_change(struct vty *vty, const char *xpath, * * xpath_base_fmt * Prepend the given XPath (absolute or relative) to all enqueued - * configuration changes. + * configuration changes. This is an optional parameter. * * Returns: * CMD_SUCCESS on success, CMD_WARNING_CONFIG_FAILED otherwise. diff --git a/lib/subdir.am b/lib/subdir.am index 43b39100cb..ccbe13bca6 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -44,6 +44,7 @@ lib_libfrr_la_SOURCES = \ lib/md5.c \ lib/memory.c \ lib/memory_vty.c \ + lib/mlag.c \ lib/module.c \ lib/mpls.c \ lib/network.c \ @@ -134,6 +135,7 @@ pkginclude_HEADERS += \ lib/bitfield.h \ lib/buffer.h \ lib/checksum.h \ + lib/mlag.h \ lib/command.h \ lib/command_graph.h \ lib/command_match.h \ @@ -330,6 +330,8 @@ vrf_id_t vrf_name_to_id(const char *name) vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid // id/ routine not used. + if (!name) + return vrf_id; vrf = vrf_lookup_by_name(name); if (vrf) vrf_id = vrf->vrf_id; @@ -43,7 +43,7 @@ struct vty_error { }; struct vty_cfg_change { - const char *xpath; + char xpath[XPATH_MAXLEN]; enum nb_operation operation; const char *value; }; diff --git a/lib/workqueue.c b/lib/workqueue.c index c927d5d714..24ef24c774 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -91,9 +91,10 @@ struct work_queue *work_queue_new(struct thread_master *m, new->cycles.granularity = WORK_QUEUE_MIN_GRANULARITY; - /* Default values, can be overriden by caller */ + /* Default values, can be overridden by caller */ new->spec.hold = WORK_QUEUE_DEFAULT_HOLD; new->spec.yield = THREAD_YIELD_TIME_SLOT; + new->spec.retry = WORK_QUEUE_DEFAULT_RETRY; return new; } @@ -133,8 +134,17 @@ static int work_queue_schedule(struct work_queue *wq, unsigned int delay) if (CHECK_FLAG(wq->flags, WQ_UNPLUGGED) && (wq->thread == NULL) && !work_queue_empty(wq)) { wq->thread = NULL; - thread_add_timer_msec(wq->master, work_queue_run, wq, delay, - &wq->thread); + + /* Schedule timer if there's a delay, otherwise just schedule + * as an 'event' + */ + if (delay > 0) + thread_add_timer_msec(wq->master, work_queue_run, wq, + delay, &wq->thread); + else + thread_add_event(wq->master, work_queue_run, wq, 0, + &wq->thread); + /* set thread yield time, if needed */ if (wq->thread && wq->spec.yield != THREAD_YIELD_TIME_SLOT) thread_set_yield_time(wq->thread, wq->spec.yield); @@ -234,7 +244,7 @@ int work_queue_run(struct thread *thread) { struct work_queue *wq; struct work_queue_item *item, *titem; - wq_item_status ret; + wq_item_status ret = WQ_SUCCESS; unsigned int cycles = 0; char yielded = 0; @@ -376,9 +386,14 @@ stats: #endif /* Is the queue done yet? If it is, call the completion callback. */ - if (!work_queue_empty(wq)) - work_queue_schedule(wq, 0); - else if (wq->spec.completion_func) + if (!work_queue_empty(wq)) { + if (ret == WQ_RETRY_LATER || + ret == WQ_QUEUE_BLOCKED) + work_queue_schedule(wq, wq->spec.retry); + else + work_queue_schedule(wq, 0); + + } else if (wq->spec.completion_func) wq->spec.completion_func(wq); return 0; diff --git a/lib/workqueue.h b/lib/workqueue.h index fe1700f8de..7c84655063 100644 --- a/lib/workqueue.h +++ b/lib/workqueue.h @@ -30,6 +30,9 @@ DECLARE_MTYPE(WORK_QUEUE) /* Hold time for the initial schedule of a queue run, in millisec */ #define WORK_QUEUE_DEFAULT_HOLD 50 +/* Retry for queue that is 'blocked' or 'retry later' */ +#define WORK_QUEUE_DEFAULT_RETRY 0 + /* action value, for use by item processor and item error handlers */ typedef enum { WQ_SUCCESS = 0, @@ -90,6 +93,8 @@ struct work_queue { unsigned long yield; /* yield time in us for associated thread */ + + uint32_t retry; /* Optional retry timeout if queue is blocked */ } spec; /* remaining fields should be opaque to users */ diff --git a/lib/yang.c b/lib/yang.c index 462e693549..71b41c35d8 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -71,9 +71,11 @@ static const char *yang_module_imp_clb(const char *mod_name, return NULL; } -static const char * const frr_native_modules[] = { +static const char *const frr_native_modules[] = { "frr-interface", "frr-ripd", + "frr-ripngd", + "frr-isisd", }; /* Generate the yang_modules tree. */ diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c index 96076d6468..6273dff3ce 100644 --- a/lib/yang_wrappers.c +++ b/lib/yang_wrappers.c @@ -171,6 +171,7 @@ int yang_str2enum(const char *xpath, const char *value) { const struct lys_node *snode; const struct lys_node_leaf *sleaf; + const struct lys_type *type; const struct lys_type_info_enums *enums; snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0); @@ -182,7 +183,12 @@ int yang_str2enum(const char *xpath, const char *value) } sleaf = (const struct lys_node_leaf *)snode; - enums = &sleaf->type.info.enums; + type = &sleaf->type; + enums = &type->info.enums; + while (enums->count == 0 && type->der) { + type = &type->der->type; + enums = &type->info.enums; + } for (unsigned int i = 0; i < enums->count; i++) { const struct lys_type_enum *enm = &enums->enm[i]; diff --git a/lib/zclient.c b/lib/zclient.c index beb3ca4f34..1c40750db0 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1770,19 +1770,19 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s, vrf_id_t vrf_id, vrf_id_t *new_vrf_id) { - unsigned int ifindex; + char ifname[INTERFACE_NAMSIZ]; struct interface *ifp; vrf_id_t new_id; - /* Get interface index. */ - ifindex = stream_getl(s); + /* Read interface name. */ + stream_get(ifname, s, INTERFACE_NAMSIZ); /* Lookup interface. */ - ifp = if_lookup_by_index(ifindex, vrf_id); + ifp = if_lookup_by_name(ifname, vrf_id); if (ifp == NULL) { flog_err(EC_LIB_ZAPI_ENCODE, - "INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d", - ifindex, vrf_id); + "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d", + ifname, vrf_id); return NULL; } @@ -2355,6 +2355,7 @@ static void zclient_capability_decode(int command, struct zclient *zclient, STREAM_GETC(s, mpls_enabled); cap.mpls_enabled = !!mpls_enabled; STREAM_GETL(s, cap.ecmp); + STREAM_GETC(s, cap.role); if (zclient->zebra_capabilities) (*zclient->zebra_capabilities)(&cap); diff --git a/lib/zclient.h b/lib/zclient.h index adb48b252a..831cccfb7e 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -36,6 +36,8 @@ /* For union pw_protocol_fields */ #include "pw.h" +#include "mlag.h" + /* For input/output buffer to zebra. */ #define ZEBRA_MAX_PACKET_SIZ 16384 @@ -58,6 +60,10 @@ #define ZEBRA_IPTABLES_FORWARD 0 #define ZEBRA_IPTABLES_DROP 1 +/* Zebra FEC register command flags. */ +#define ZEBRA_FEC_REGISTER_LABEL 0x1 +#define ZEBRA_FEC_REGISTER_LABEL_INDEX 0x2 + extern struct sockaddr_storage zclient_addr; extern socklen_t zclient_addr_len; @@ -167,6 +173,7 @@ struct redist_proto { struct zclient_capabilities { uint32_t ecmp; bool mpls_enabled; + enum mlag_role role; }; /* Structure for the zebra client. */ diff --git a/lib/zebra.h b/lib/zebra.h index 46721cc1ab..09115951e9 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -410,21 +410,47 @@ extern const char *zserv_command_string(unsigned int command); #define strmatch(a,b) (!strcmp((a), (b))) /* Zebra message flags */ + +/* + * Cause Zebra to consider this routes nexthops recursively + */ #define ZEBRA_FLAG_ALLOW_RECURSION 0x01 +/* + * This is a route that is read in on startup that was left around + * from a previous run of FRR + */ #define ZEBRA_FLAG_SELFROUTE 0x02 -#define ZEBRA_FLAG_IBGP 0x08 -#define ZEBRA_FLAG_SELECTED 0x10 -#define ZEBRA_FLAG_STATIC 0x40 -#define ZEBRA_FLAG_SCOPE_LINK 0x100 -#define ZEBRA_FLAG_FIB_OVERRIDE 0x200 -#define ZEBRA_FLAG_EVPN_ROUTE 0x400 -#define ZEBRA_FLAG_RR_USE_DISTANCE 0x800 -#define ZEBRA_FLAG_ONLINK 0x1000 -/* ZEBRA_FLAG_BLACKHOLE was 0x04 */ -/* ZEBRA_FLAG_REJECT was 0x80 */ - -/* Zebra FEC flags. */ -#define ZEBRA_FEC_REGISTER_LABEL_INDEX 0x1 +/* + * 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 #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */ diff --git a/ospf6d/OSPFv3-MIB.txt b/ospf6d/OSPFv3-MIB.txt deleted file mode 100644 index 258f533ef4..0000000000 --- a/ospf6d/OSPFv3-MIB.txt +++ /dev/null @@ -1,3951 +0,0 @@ - OSPFV3-MIB DEFINITIONS ::= BEGIN - - IMPORTS - MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, mib-2, - Counter32, Gauge32, Integer32, Unsigned32 - FROM SNMPv2-SMI - TEXTUAL-CONVENTION, TruthValue, RowStatus, TimeStamp - FROM SNMPv2-TC - MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP - FROM SNMPv2-CONF - InterfaceIndex - FROM IF-MIB - InetAddressType, InetAddress, InetAddressPrefixLength, - InetAddressIPv6 - FROM INET-ADDRESS-MIB - Metric, BigMetric, Status, - HelloRange, DesignatedRouterPriority - FROM OSPF-MIB; - - ospfv3MIB MODULE-IDENTITY - LAST-UPDATED "200908130000Z" - ORGANIZATION "IETF OSPF Working Group" - CONTACT-INFO - "WG E-Mail: ospf@ietf.org - WG Chairs: Acee Lindem - acee@redback.com - - Abhay Roy - akr@cisco.com - - Editors: Dan Joyal - Nortel - 600 Technology Park Drive - Billerica, MA 01821, USA - djoyal@nortel.com - - Vishwas Manral - IP Infusion - Almora, Uttarakhand - India - vishwas@ipinfusion.com" - DESCRIPTION - "The MIB module for OSPF version 3. - - Copyright (c) 2009 IETF Trust and the persons - identified as authors of the code. All rights - reserved. - - Redistribution and use in source and binary forms, with - or without modification, are permitted provided that - the following conditions are met: - - - Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - - - Redistributions in binary form must reproduce the - above copyright notice, this list of conditions and - the following disclaimer in the documentation and/or - other materials provided with the distribution. - - - Neither the name of Internet Society, IETF or IETF - Trust, nor the names of specific contributors, may be - used to endorse or promote products derived from this - software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - This version of this MIB module is part of RFC 5643; - see the RFC itself for full legal notices." - - REVISION "200908130000Z" - DESCRIPTION - "Initial version, published as RFC 5643" - ::= { mib-2 191 } - - -- Textual conventions - - Ospfv3UpToRefreshIntervalTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "The values one might be able to configure for - variables bounded by the Refresh Interval." - REFERENCE - "OSPF Version 2, Appendix B, Architectural Constants" - SYNTAX Unsigned32 (1..1800) - - Ospfv3DeadIntervalRangeTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "The range, in seconds, of dead interval value." - REFERENCE - "OSPF for IPv6, Appendix C.3, Router Interface - Parameters" - SYNTAX Unsigned32 (1..'FFFF'h) - - Ospfv3RouterIdTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "A 32-bit, unsigned integer uniquely identifying the - router in the Autonomous System. To ensure - uniqueness, this may default to the value of one of - the router's IPv4 host addresses if IPv4 is - configured on the router." - REFERENCE - "OSPF for IPv6, Appendix C.1, Global Parameters" - SYNTAX Unsigned32 (1..'FFFFFFFF'h) - - Ospfv3LsIdTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "A unique 32-bit identifier of the piece of the - routing domain that is being described by a link - state advertisement. In contrast to OSPFv2, the - Link State ID (LSID) has no addressing semantics." - REFERENCE - "OSPF Version 2, Section 12.1.4, Link State ID" - SYNTAX Unsigned32 (1..'FFFFFFFF'h) - - Ospfv3AreaIdTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "An OSPFv3 Area Identifier. A value of zero - identifies the backbone area." - REFERENCE - "OSPF for IPv6, Appendix C.3 Router Interface - Parameters" - SYNTAX Unsigned32 (0..'FFFFFFFF'h) - - Ospfv3IfInstIdTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "An OSPFv3 Interface Instance ID." - REFERENCE - "OSPF for IPv6, Appendix C.3, Router Interface - Parameters" - SYNTAX Unsigned32 (0..255) - - Ospfv3LsaSequenceTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "The sequence number field is a signed 32-bit - integer. It is used to detect old and duplicate - link state advertisements. The space of - sequence numbers is linearly ordered. The - larger the sequence number, the more recent the - advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.6, LS sequence - number" - SYNTAX Integer32 - - Ospfv3LsaAgeTC ::= TEXTUAL-CONVENTION - DISPLAY-HINT "d" - STATUS current - DESCRIPTION - "The age of the link state advertisement in - seconds. The high-order bit of the LS age - field is considered the DoNotAge bit for - support of on-demand circuits." - REFERENCE - "OSPF Version 2, Section 12.1.1, LS age; - Extending OSPF to Support Demand Circuits, - Section 2.2, The LS age field" - SYNTAX Unsigned32 (0..3600 | 32768..36368) - - -- Top-level structure of MIB - ospfv3Notifications OBJECT IDENTIFIER ::= { ospfv3MIB 0 } - ospfv3Objects OBJECT IDENTIFIER ::= { ospfv3MIB 1 } - ospfv3Conformance OBJECT IDENTIFIER ::= { ospfv3MIB 2 } - - -- OSPFv3 General Variables - - -- These parameters apply globally to the Router's - -- OSPFv3 Process. - - ospfv3GeneralGroup OBJECT IDENTIFIER ::= { ospfv3Objects 1 } - - ospfv3RouterId OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "A 32-bit unsigned integer uniquely identifying - the router in the Autonomous System. To ensure - uniqueness, this may default to the 32-bit - unsigned integer representation of one of - the router's IPv4 interface addresses (if IPv4 - is configured on the router). - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - REFERENCE - "OSPF for IPv6, Appendix C.1, Global Parameters" - ::= { ospfv3GeneralGroup 1 } - - ospfv3AdminStatus OBJECT-TYPE - SYNTAX Status - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The administrative status of OSPFv3 in the - router. The value 'enabled' denotes that the - OSPFv3 Process is active on at least one - interface; 'disabled' disables it on all - interfaces. - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - ::= { ospfv3GeneralGroup 2 } - - ospfv3VersionNumber OBJECT-TYPE - SYNTAX INTEGER { version3 (3) } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The version number of OSPF for IPv6 is 3." - ::= { ospfv3GeneralGroup 3 } - - ospfv3AreaBdrRtrStatus OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A flag to denote whether this router is an area - border router. The value of this object is true (1) - when the router is an area border router." - REFERENCE - "OSPF Version 2, Section 3, Splitting the AS into - Areas" - ::= { ospfv3GeneralGroup 4 } - - ospfv3ASBdrRtrStatus OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "A flag to note whether this router is - configured as an Autonomous System border router. - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - REFERENCE - "OSPF Version 2, Section 3.3, Classification of - routers" - ::= { ospfv3GeneralGroup 5 } - - ospfv3AsScopeLsaCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of AS-scope (e.g., AS-External) link state - advertisements in the link state database." - ::= { ospfv3GeneralGroup 6 } - - ospfv3AsScopeLsaCksumSum OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32-bit unsigned sum of the LS checksums of - the AS-scoped link state advertisements - contained in the link state database. This sum - can be used to determine if there has been a - change in a router's link state database or - to compare the link state database of two - routers." - ::= { ospfv3GeneralGroup 7 } - - ospfv3OriginateNewLsas OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of new link state advertisements - that have been originated. This number is - incremented each time the router originates a new - LSA. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3GeneralGroup 8 } - - ospfv3RxNewLsas OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of link state advertisements - received that are determined to be new - instantiations. This number does not include - newer instantiations of self-originated link state - advertisements. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3GeneralGroup 9 } - - ospfv3ExtLsaCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of External (LS type 0x4005) in the - link state database." - ::= { ospfv3GeneralGroup 10 } - - ospfv3ExtAreaLsdbLimit OBJECT-TYPE - SYNTAX Integer32 (-1..'7FFFFFFF'h) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The maximum number of non-default - AS-external-LSA entries that can be stored in the - link state database. If the value is -1, then - there is no limit. - - When the number of non-default AS-external-LSAs - in a router's link state database reaches - ospfv3ExtAreaLsdbLimit, the router enters Overflow - state. The router never holds more than - ospfv3ExtAreaLsdbLimit non-default AS-external-LSAs - in its database. ospfv3ExtAreaLsdbLimit MUST be set - identically in all routers attached to the OSPFv3 - backbone and/or any regular OSPFv3 area (i.e., - OSPFv3 stub areas and not-so-stubby-areas (NSSAs) - are excluded). - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - ::= { ospfv3GeneralGroup 11 } - - ospfv3ExitOverflowInterval OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "seconds" - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The number of seconds that, after entering - Overflow state, a router will attempt to leave - Overflow state. This allows the router to again - originate non-default, AS-External-LSAs. When - set to 0, the router will not leave Overflow - state until restarted. - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - ::= { ospfv3GeneralGroup 12 } - - ospfv3DemandExtensions OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The router's support for demand circuits. - The value of this object is true (1) when - demand circuits are supported. - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - REFERENCE - "OSPF Version 2; Extending OSPF to Support Demand - Circuits" - ::= { ospfv3GeneralGroup 13 } - - ospfv3ReferenceBandwidth OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "kilobits per second" - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Reference bandwidth in kilobits per second for - calculating default interface metrics. The - default value is 100,000 KBPS (100 MBPS). - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - REFERENCE - "OSPF Version 2, Appendix C.3, Router interface - parameters" - DEFVAL { 100000 } - ::= { ospfv3GeneralGroup 14 } - - ospfv3RestartSupport OBJECT-TYPE - SYNTAX INTEGER { none(1), - plannedOnly(2), - plannedAndUnplanned(3) - } - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The router's support for OSPF graceful restart. - Options include no restart support, only planned - - restarts, or both planned and unplanned restarts. - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - REFERENCE "Graceful OSPF Restart, Appendix B.1, Global - Parameters (Minimum subset)" - ::= { ospfv3GeneralGroup 15 } - - ospfv3RestartInterval OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Configured OSPF graceful restart timeout interval. - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - REFERENCE "Graceful OSPF Restart, Appendix B.1, Global - Parameters (Minimum subset)" - DEFVAL { 120 } - ::= { ospfv3GeneralGroup 16 } - - ospfv3RestartStrictLsaChecking OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "Indicates if strict LSA checking is enabled for - graceful restart. A value of true (1) indicates that - strict LSA checking is enabled. - - This object is persistent, and when written, - the entity SHOULD save the change to non-volatile - storage." - REFERENCE "Graceful OSPF Restart, Appendix B.2, Global - Parameters (Optional)" - DEFVAL { true } - ::= { ospfv3GeneralGroup 17 } - - ospfv3RestartStatus OBJECT-TYPE - SYNTAX INTEGER { notRestarting(1), - plannedRestart(2), - unplannedRestart(3) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The current status of OSPF graceful restart capability." - ::= { ospfv3GeneralGroup 18 } - - ospfv3RestartAge OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Remaining time in the current OSPF graceful restart - interval." - ::= { ospfv3GeneralGroup 19 } - - ospfv3RestartExitReason OBJECT-TYPE - SYNTAX INTEGER { none(1), - inProgress(2), - completed(3), - timedOut(4), - topologyChanged(5) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Describes the outcome of the last attempt at a - graceful restart. - - none: no restart has yet been attempted. - inProgress: a restart attempt is currently underway. - completed: the last restart completed successfully. - timedOut: the last restart timed out. - topologyChanged: the last restart was aborted due to - a topology change." - ::= { ospfv3GeneralGroup 20 } - - ospfv3NotificationEnable OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "This object provides a coarse level of control - over the generation of OSPFv3 notifications. - - If this object is set to true (1), then it enables - the generation of OSPFv3 notifications. If it is - set to false (2), these notifications are not - generated. - - This object is persistent, and when written, the - entity SHOULD save the change to non-volatile - storage." - ::= { ospfv3GeneralGroup 21 } - -ospfv3StubRouterSupport OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The router's support for stub router functionality. An - object value of true (1) indicates that stub router - functionality is supported." - REFERENCE - "OSPF Stub Router Advertisement" - ::= { ospfv3GeneralGroup 22 } - - ospfv3StubRouterAdvertisement OBJECT-TYPE - SYNTAX INTEGER { - doNotAdvertise(1), - advertise(2) - } - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "This object controls the advertisement of - stub LSAs by the router. The value - doNotAdvertise (1) will result in the advertisement - of standard LSAs and is the default value. - - This object is persistent, and when written, - the entity SHOULD save the change to non-volatile - storage." - REFERENCE - "OSPF Stub Router Advertisement, Section 2, Proposed - Solution" - DEFVAL { doNotAdvertise } - ::= { ospfv3GeneralGroup 23 } - -ospfv3DiscontinuityTime OBJECT-TYPE - SYNTAX TimeStamp - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value of sysUpTime on the most recent occasion - at which any one of this MIB's counters suffered - a discontinuity. - - If no such discontinuities have occurred since the last - re-initialization of the local management subsystem, - then this object contains a zero value." - ::= { ospfv3GeneralGroup 24 } - - ospfv3RestartTime OBJECT-TYPE - SYNTAX TimeStamp - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value of sysUpTime on the most recent occasion - at which the ospfv3RestartExitReason was updated." - ::= { ospfv3GeneralGroup 25 } - - -- The OSPFv3 Area Data Structure contains information - -- regarding the various areas. The interfaces and - -- virtual links are configured as part of these areas. - -- Area 0, by definition, is the backbone area. - - ospfv3AreaTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3AreaEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information describing the configured - parameters and cumulative statistics of the router's - attached areas. The interfaces and - virtual links are configured as part of these areas. - Area 0, by definition, is the backbone area." - REFERENCE - "OSPF Version 2, Section 6, The Area Data - Structure" - ::= { ospfv3Objects 2 } - - ospfv3AreaEntry OBJECT-TYPE - SYNTAX Ospfv3AreaEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information describing the configured - parameters and cumulative statistics of one of the - router's attached areas. - - The information in this table is persistent, - and when written, the entity SHOULD save the a - change to non-volatile storage." - INDEX { ospfv3AreaId } - ::= { ospfv3AreaTable 1 } - - Ospfv3AreaEntry ::= SEQUENCE { - ospfv3AreaId - Ospfv3AreaIdTC, - ospfv3AreaImportAsExtern - INTEGER, - ospfv3AreaSpfRuns - Counter32, - ospfv3AreaBdrRtrCount - Gauge32, - ospfv3AreaAsBdrRtrCount - Gauge32, - ospfv3AreaScopeLsaCount - Gauge32, - ospfv3AreaScopeLsaCksumSum - Unsigned32, - ospfv3AreaSummary - INTEGER, - ospfv3AreaRowStatus - RowStatus, - ospfv3AreaStubMetric - BigMetric, - ospfv3AreaNssaTranslatorRole - INTEGER, - ospfv3AreaNssaTranslatorState - INTEGER, - ospfv3AreaNssaTranslatorStabInterval - Unsigned32, - ospfv3AreaNssaTranslatorEvents - Counter32, - ospfv3AreaStubMetricType - INTEGER, - ospfv3AreaTEEnabled - TruthValue - } - - ospfv3AreaId OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A 32-bit unsigned integer uniquely identifying an area. - Area ID 0 is used for the OSPFv3 backbone." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - ::= { ospfv3AreaEntry 1 } - - ospfv3AreaImportAsExtern OBJECT-TYPE - SYNTAX INTEGER { - importExternal(1), -- normal area - importNoExternal(2), -- stub area - importNssa(3) -- not-so-stubby-area - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Indicates whether an area is a stub area, NSSA, or - standard area. AS-scope LSAs are not imported into stub - areas or NSSAs. NSSAs import AS-External data as NSSA - LSAs that have Area-scope." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - DEFVAL { importExternal } - ::= { ospfv3AreaEntry 2 } - - ospfv3AreaSpfRuns OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times that the intra-area route - table has been calculated using this area's - link state database. This is typically done - using Dijkstra's algorithm. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3AreaEntry 3 } - - ospfv3AreaBdrRtrCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of area border routers - reachable within this area. This is initially zero, - and is calculated in each Shortest Path First (SPF) - pass." - DEFVAL { 0 } - ::= { ospfv3AreaEntry 4 } - - ospfv3AreaAsBdrRtrCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of Autonomous System border - routers reachable within this area. This is - initially zero, and is calculated in each SPF - pass." - DEFVAL { 0 } - ::= { ospfv3AreaEntry 5 } - - ospfv3AreaScopeLsaCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of Area-scope link state - advertisements in this area's link state - database." - DEFVAL { 0 } - ::= { ospfv3AreaEntry 6 } - - ospfv3AreaScopeLsaCksumSum OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32-bit unsigned sum of the Area-scope link state - advertisements' LS checksums contained in this - area's link state database. The sum can be used - to determine if there has been a change in a - router's link state database or to compare the - link state database of two routers." - ::= { ospfv3AreaEntry 7 } - - ospfv3AreaSummary OBJECT-TYPE - SYNTAX INTEGER { - noAreaSummary(1), - sendAreaSummary(2) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The variable ospfv3AreaSummary controls the - import of Inter-Area LSAs into stub and - NSSA areas. It has no effect on other areas. - - If it is noAreaSummary, the router will neither - originate nor propagate Inter-Area LSAs into the - stub or NSSA area. It will only advertise a - default route. - - If it is sendAreaSummary, the router will both - summarize and propagate Inter-Area LSAs." - DEFVAL { sendAreaSummary } - ::= { ospfv3AreaEntry 8 } - - ospfv3AreaRowStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This object permits management of the table by - facilitating actions such as row creation, - construction, and destruction. - - The value of this object has no effect on - whether other objects in this conceptual row can be - modified." - ::= { ospfv3AreaEntry 9 } - - ospfv3AreaStubMetric OBJECT-TYPE - SYNTAX BigMetric - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The metric value advertised for the default route - into stub and NSSA areas. By default, this equals the - least metric among the interfaces to other areas." - ::= { ospfv3AreaEntry 10 } - - ospfv3AreaNssaTranslatorRole OBJECT-TYPE - SYNTAX INTEGER { always(1), candidate(2) } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Indicates an NSSA border router's policy to - perform NSSA translation of NSSA-LSAs into - AS-External-LSAs." - DEFVAL { candidate } - ::= { ospfv3AreaEntry 11 } - - ospfv3AreaNssaTranslatorState OBJECT-TYPE - SYNTAX INTEGER { - enabled(1), - elected(2), - disabled(3) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates if and how an NSSA border router is - performing NSSA translation of NSSA-LSAs into - AS-External-LSAs. When this object is set to - 'enabled', the NSSA border router's - ospfv3AreaNssaTranslatorRole has been set to 'always'. - When this object is set to 'elected', a candidate - NSSA border router is translating NSSA-LSAs into - AS-External-LSAs. When this object is set to - 'disabled', a candidate NSSA Border router is NOT - translating NSSA-LSAs into AS-External-LSAs." - ::= { ospfv3AreaEntry 12 } - - ospfv3AreaNssaTranslatorStabInterval OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The stability interval defined as the number of - seconds after an elected translator determines its - services are no longer required that it should - continue to perform its translation duties." - DEFVAL { 40 } - ::= { ospfv3AreaEntry 13 } - - ospfv3AreaNssaTranslatorEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates the number of Translator state changes - that have occurred since the last start-up of the - OSPFv3 routing process. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3AreaEntry 14 } - - ospfv3AreaStubMetricType OBJECT-TYPE - SYNTAX INTEGER { - ospfv3Metric(1), -- OSPF Metric - comparableCost(2), -- external type 1 - nonComparable(3) -- external type 2 - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable assigns the type of metric - advertised as a default route." - DEFVAL { ospfv3Metric } - ::= { ospfv3AreaEntry 15 } - - ospfv3AreaTEEnabled OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Indicates whether or not traffic engineering - is enabled in the area. The object is set - to the value true (1) to enable traffic engineering. - Traffic engineering is disabled by default." - DEFVAL { false } - ::= { ospfv3AreaEntry 16 } - - -- OSPFv3 AS-Scope Link State Database - - ospfv3AsLsdbTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3AsLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPFv3 Process's AS-scope link state database - (LSDB). The LSDB contains the AS-scope link state - advertisements from throughout the areas that the - device is attached to." - ::= { ospfv3Objects 3 } - - ospfv3AsLsdbEntry OBJECT-TYPE - SYNTAX Ospfv3AsLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A single AS-scope link state advertisement." - INDEX { ospfv3AsLsdbType, - ospfv3AsLsdbRouterId, - ospfv3AsLsdbLsid } - ::= { ospfv3AsLsdbTable 1 } - - Ospfv3AsLsdbEntry ::= SEQUENCE { - ospfv3AsLsdbType - Unsigned32, - ospfv3AsLsdbRouterId - Ospfv3RouterIdTC, - ospfv3AsLsdbLsid - Ospfv3LsIdTC, - ospfv3AsLsdbSequence - Ospfv3LsaSequenceTC, - ospfv3AsLsdbAge - Ospfv3LsaAgeTC, - ospfv3AsLsdbChecksum - Integer32, - ospfv3AsLsdbAdvertisement - OCTET STRING, - ospfv3AsLsdbTypeKnown - TruthValue - } - - ospfv3AsLsdbType OBJECT-TYPE - SYNTAX Unsigned32(0..'FFFFFFFF'h) - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The type of the link state advertisement. - Each link state type has a separate - advertisement format. AS-scope LSAs not recognized - by the router may be stored in the database." - ::= { ospfv3AsLsdbEntry 1 } - - ospfv3AsLsdbRouterId OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The 32-bit number that uniquely identifies the - originating router in the Autonomous System." - REFERENCE - "OSPF Version 2, Appendix C.1, Global parameters" - ::= { ospfv3AsLsdbEntry 2 } - - ospfv3AsLsdbLsid OBJECT-TYPE - SYNTAX Ospfv3LsIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Link State ID is an LS type-specific field - containing a unique identifier; - it identifies the piece of the routing domain - that is being described by the advertisement. - In contrast to OSPFv2, the LSID has no - addressing semantics." - ::= { ospfv3AsLsdbEntry 3 } - - -- Note that the OSPF sequence number is a 32-bit signed - -- integer. It starts with the value '80000001'h - -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h. - -- Thus, a typical sequence number will be very negative. - - ospfv3AsLsdbSequence OBJECT-TYPE - SYNTAX Ospfv3LsaSequenceTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The sequence number field is a signed 32-bit - integer. It is used to detect old and duplicate - link state advertisements. The space of - sequence numbers is linearly ordered. The - larger the sequence number, the more recent the - advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.6, LS sequence - number" - ::= { ospfv3AsLsdbEntry 4 } - - ospfv3AsLsdbAge OBJECT-TYPE - SYNTAX Ospfv3LsaAgeTC - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the age of the link state - advertisement in seconds. The high-order bit - of the LS age field is considered the DoNotAge - bit for support of on-demand circuits." - REFERENCE - "OSPF Version 2, Section 12.1.1, LS age; - Extending OSPF to Support Demand Circuits, - Section 2.2, The LS age field." - ::= { ospfv3AsLsdbEntry 5 } - - ospfv3AsLsdbChecksum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the checksum of the complete - contents of the advertisement, excepting the - age field. The age field is excepted so that - an advertisement's age can be incremented - without updating the checksum. The checksum - used is the same that is used for ISO - connectionless datagrams; it is commonly - referred to as the Fletcher checksum." - REFERENCE - "OSPF Version 2, Section 12.1.7, LS checksum" - ::= { ospfv3AsLsdbEntry 6 } - - ospfv3AsLsdbAdvertisement OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (1..65535)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The entire link state advertisement, including - its header." - ::= { ospfv3AsLsdbEntry 7 } - - ospfv3AsLsdbTypeKnown OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value true (1) indicates that the LSA type - is recognized by this router." - ::= { ospfv3AsLsdbEntry 8 } - - -- OSPFv3 Area-Scope Link State Database - - ospfv3AreaLsdbTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3AreaLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPFv3 Process's Area-scope LSDB. - The LSDB contains the Area-scope link state - advertisements from throughout the area that the - device is attached to." - ::= { ospfv3Objects 4 } - - ospfv3AreaLsdbEntry OBJECT-TYPE - SYNTAX Ospfv3AreaLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A single Area-scope link state advertisement." - INDEX { ospfv3AreaLsdbAreaId, - ospfv3AreaLsdbType, - ospfv3AreaLsdbRouterId, - ospfv3AreaLsdbLsid } - ::= { ospfv3AreaLsdbTable 1 } - - Ospfv3AreaLsdbEntry ::= SEQUENCE { - ospfv3AreaLsdbAreaId - Ospfv3AreaIdTC, - ospfv3AreaLsdbType - Unsigned32, - ospfv3AreaLsdbRouterId - Ospfv3RouterIdTC, - ospfv3AreaLsdbLsid - Ospfv3LsIdTC, - ospfv3AreaLsdbSequence - Ospfv3LsaSequenceTC, - ospfv3AreaLsdbAge - Ospfv3LsaAgeTC, - ospfv3AreaLsdbChecksum - Integer32, - ospfv3AreaLsdbAdvertisement - OCTET STRING, - ospfv3AreaLsdbTypeKnown - TruthValue - } - - ospfv3AreaLsdbAreaId OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The 32-bit identifier of the Area from which the - LSA was received." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - ::= { ospfv3AreaLsdbEntry 1 } - - ospfv3AreaLsdbType OBJECT-TYPE - SYNTAX Unsigned32(0..'FFFFFFFF'h) - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The type of the link state advertisement. - Each link state type has a separate - advertisement format. Area-scope LSAs unrecognized - by the router are also stored in this database." - ::= { ospfv3AreaLsdbEntry 2 } - - ospfv3AreaLsdbRouterId OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The 32-bit number that uniquely identifies the - originating router in the Autonomous System." - REFERENCE - "OSPF Version 2, Appendix C.1, Global parameters" - ::= { ospfv3AreaLsdbEntry 3 } - - ospfv3AreaLsdbLsid OBJECT-TYPE - SYNTAX Ospfv3LsIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Link State ID is an LS type-specific field - containing a unique identifier; - it identifies the piece of the routing domain - that is being described by the advertisement. - In contrast to OSPFv2, the LSID has no - addressing semantics." - ::= { ospfv3AreaLsdbEntry 4 } - - -- Note that the OSPF sequence number is a 32-bit signed - -- integer. It starts with the value '80000001'h - -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h. - -- Thus, a typical sequence number will be very negative. - - ospfv3AreaLsdbSequence OBJECT-TYPE - SYNTAX Ospfv3LsaSequenceTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The sequence number field is a signed 32-bit - integer. It is used to detect old and - duplicate link state advertisements. The space - of sequence numbers is linearly ordered. The - larger the sequence number, the more recent the - advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.6, LS sequence - number" - ::= { ospfv3AreaLsdbEntry 5 } - - ospfv3AreaLsdbAge OBJECT-TYPE - SYNTAX Ospfv3LsaAgeTC - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the age of the link state - advertisement in seconds. The high-order bit - of the LS age field is considered the DoNotAge - bit for support of on-demand circuits." - REFERENCE - "OSPF Version 2, Section 12.1.1, LS age; - Extending OSPF to Support Demand Circuits, - Section 2.2, The LS age field." - ::= { ospfv3AreaLsdbEntry 6 } - - ospfv3AreaLsdbChecksum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the checksum of the complete - contents of the advertisement, excepting the - age field. The age field is excepted so that - an advertisement's age can be incremented - without updating the checksum. The checksum - used is the same that is used for ISO - connectionless datagrams; it is commonly - referred to as the Fletcher checksum." - REFERENCE - "OSPF Version 2, Section 12.1.7, LS checksum" - ::= { ospfv3AreaLsdbEntry 7 } - - ospfv3AreaLsdbAdvertisement OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (1..65535)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The entire link state advertisement, including - its header." - ::= { ospfv3AreaLsdbEntry 8 } - - ospfv3AreaLsdbTypeKnown OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value true (1) indicates that the LSA type is - recognized by this router." - ::= { ospfv3AreaLsdbEntry 9 } - - -- OSPFv3 Link-Scope Link State Database, for non-virtual interfaces - - ospfv3LinkLsdbTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3LinkLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPFv3 Process's Link-scope LSDB for non-virtual - interfaces. The LSDB contains the Link-scope link - state advertisements from the interfaces that the - device is attached to." - ::= { ospfv3Objects 5 } - - ospfv3LinkLsdbEntry OBJECT-TYPE - SYNTAX Ospfv3LinkLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A single Link-scope link state advertisement." - INDEX { ospfv3LinkLsdbIfIndex, - ospfv3LinkLsdbIfInstId, - ospfv3LinkLsdbType, - ospfv3LinkLsdbRouterId, - ospfv3LinkLsdbLsid } - ::= { ospfv3LinkLsdbTable 1 } - - Ospfv3LinkLsdbEntry ::= SEQUENCE { - ospfv3LinkLsdbIfIndex - InterfaceIndex, - ospfv3LinkLsdbIfInstId - Ospfv3IfInstIdTC, - ospfv3LinkLsdbType - Unsigned32, - ospfv3LinkLsdbRouterId - Ospfv3RouterIdTC, - ospfv3LinkLsdbLsid - Ospfv3LsIdTC, - ospfv3LinkLsdbSequence - Ospfv3LsaSequenceTC, - ospfv3LinkLsdbAge - Ospfv3LsaAgeTC, - ospfv3LinkLsdbChecksum - Integer32, - ospfv3LinkLsdbAdvertisement - OCTET STRING, - ospfv3LinkLsdbTypeKnown - TruthValue - } - - ospfv3LinkLsdbIfIndex OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The identifier of the link from which the LSA - was received." - ::= { ospfv3LinkLsdbEntry 1 } - - ospfv3LinkLsdbIfInstId OBJECT-TYPE - SYNTAX Ospfv3IfInstIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The identifier of the interface instance from - which the LSA was received." - ::= { ospfv3LinkLsdbEntry 2 } - - ospfv3LinkLsdbType OBJECT-TYPE - SYNTAX Unsigned32(0..'FFFFFFFF'h) - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The type of the link state advertisement. - Each link state type has a separate - advertisement format. Link-scope LSAs unrecognized - by the router are also stored in this database." - ::= { ospfv3LinkLsdbEntry 3 } - - ospfv3LinkLsdbRouterId OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The 32-bit number that uniquely identifies the - originating router in the Autonomous System." - REFERENCE - "OSPF Version 2, Appendix C.1, Global parameters" - ::= { ospfv3LinkLsdbEntry 4 } - - ospfv3LinkLsdbLsid OBJECT-TYPE - SYNTAX Ospfv3LsIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Link State ID is an LS type-specific field - containing a unique identifier; - it identifies the piece of the routing domain - that is being described by the advertisement. - In contrast to OSPFv2, the LSID has no - addressing semantics. However, in OSPFv3 - the Link State ID always contains the flooding - scope of the LSA." - ::= { ospfv3LinkLsdbEntry 5 } - - -- Note that the OSPF sequence number is a 32-bit signed - -- integer. It starts with the value '80000001'h - -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h. - -- Thus, a typical sequence number will be very negative. - - ospfv3LinkLsdbSequence OBJECT-TYPE - SYNTAX Ospfv3LsaSequenceTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The sequence number field is a signed 32-bit - integer. It is used to detect old and duplicate - link state advertisements. The space of - sequence numbers is linearly ordered. The - larger the sequence number, the more recent the - advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.6, LS sequence - number" - ::= { ospfv3LinkLsdbEntry 6 } - - ospfv3LinkLsdbAge OBJECT-TYPE - SYNTAX Ospfv3LsaAgeTC - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the age of the link state - advertisement in seconds. The high-order bit - of the LS age field is considered the DoNotAge - bit for support of on-demand circuits." - REFERENCE - "OSPF Version 2, Section 12.1.1, LS age; - Extending OSPF to Support Demand Circuits, - Section 2.2, The LS age field." - ::= { ospfv3LinkLsdbEntry 7 } - - ospfv3LinkLsdbChecksum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the checksum of the complete - contents of the advertisement, excepting the - age field. The age field is excepted so that - an advertisement's age can be incremented - without updating the checksum. The checksum - used is the same that is used for ISO - connectionless datagrams; it is commonly - referred to as the Fletcher checksum." - REFERENCE - "OSPF Version 2, Section 12.1.7, LS checksum" - ::= { ospfv3LinkLsdbEntry 8 } - - ospfv3LinkLsdbAdvertisement OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (1..65535)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The entire link state advertisement, including - its header." - ::= { ospfv3LinkLsdbEntry 9 } - - ospfv3LinkLsdbTypeKnown OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value true (1) indicates that the LSA type is - recognized by this router." - ::= { ospfv3LinkLsdbEntry 10 } - - -- OSPF Host Table - - ospfv3HostTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3HostEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Host/Metric Table indicates what hosts are - directly attached to the router and their - corresponding metrics." - REFERENCE - "OSPF Version 2, Appendix C.7, Host route - parameters" - ::= { ospfv3Objects 6 } - - ospfv3HostEntry OBJECT-TYPE - SYNTAX Ospfv3HostEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A metric to be advertised when a given host is - reachable. - - The information in this table is persistent, and - when written, the entity SHOULD save the change - to non-volatile storage." - INDEX { ospfv3HostAddressType, - ospfv3HostAddress } - ::= { ospfv3HostTable 1 } - - Ospfv3HostEntry ::= SEQUENCE { - ospfv3HostAddressType - InetAddressType, - ospfv3HostAddress - InetAddress, - ospfv3HostMetric - Metric, - ospfv3HostRowStatus - RowStatus, - ospfv3HostAreaID - Ospfv3AreaIdTC - } - - ospfv3HostAddressType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The address type of ospfv3HostAddress. Only IPv6 - global address type is expected." - REFERENCE - "OSPF Version 2, Appendix C.7, Host route - parameters" - ::= { ospfv3HostEntry 1 } - - ospfv3HostAddress OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The IPv6 address of the host. Must be an - IPv6 global address." - REFERENCE - "OSPF Version 2, Appendix C.7, Host route - parameters" - ::= { ospfv3HostEntry 2 } - - ospfv3HostMetric OBJECT-TYPE - SYNTAX Metric - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The metric to be advertised." - REFERENCE - "OSPF Version 2, Appendix C.7, Host route - parameters" - ::= { ospfv3HostEntry 3 } - - ospfv3HostRowStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This object permits management of the table by - facilitating actions such as row creation, - construction, and destruction. - - The value of this object has no effect on - whether other objects in this conceptual row can be - modified." - ::= { ospfv3HostEntry 4 } - - ospfv3HostAreaID OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The Area the host entry is to be found within. - By default, the area for the subsuming OSPFv3 - interface, or Area 0 if there is no subsuming - interface." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - ::= { ospfv3HostEntry 5 } - - -- OSPFv3 Interface Table - - ospfv3IfTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3IfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPFv3 Interface Table describes the - interfaces from the viewpoint of OSPFv3." - REFERENCE - "OSPF for IPv6, Appendix C.3, Router Interface - Parameters" - ::= { ospfv3Objects 7 } - - ospfv3IfEntry OBJECT-TYPE - SYNTAX Ospfv3IfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPFv3 Interface Entry describes one - interface from the viewpoint of OSPFv3. - - The information in this table is persistent, - and when written, the entity SHOULD save the - change to non-volatile storage." - INDEX { ospfv3IfIndex, - ospfv3IfInstId } - ::= { ospfv3IfTable 1 } - - Ospfv3IfEntry ::= SEQUENCE { - ospfv3IfIndex - InterfaceIndex, - ospfv3IfInstId - Ospfv3IfInstIdTC, - ospfv3IfAreaId - Ospfv3AreaIdTC, - ospfv3IfType - INTEGER, - ospfv3IfAdminStatus - Status, - ospfv3IfRtrPriority - DesignatedRouterPriority, - ospfv3IfTransitDelay - Ospfv3UpToRefreshIntervalTC, - ospfv3IfRetransInterval - Ospfv3UpToRefreshIntervalTC, - ospfv3IfHelloInterval - HelloRange, - ospfv3IfRtrDeadInterval - Ospfv3DeadIntervalRangeTC, - ospfv3IfPollInterval - Unsigned32, - ospfv3IfState - INTEGER, - ospfv3IfDesignatedRouter - Ospfv3RouterIdTC, - ospfv3IfBackupDesignatedRouter - Ospfv3RouterIdTC, - ospfv3IfEvents - Counter32, - ospfv3IfRowStatus - RowStatus, - ospfv3IfDemand - TruthValue, - ospfv3IfMetricValue - Metric, - ospfv3IfLinkScopeLsaCount - Gauge32, - ospfv3IfLinkLsaCksumSum - Unsigned32, - ospfv3IfDemandNbrProbe - TruthValue, - ospfv3IfDemandNbrProbeRetransLimit - Unsigned32, - ospfv3IfDemandNbrProbeInterval - Unsigned32, - ospfv3IfTEDisabled - TruthValue, - ospfv3IfLinkLSASuppression - TruthValue - } - - ospfv3IfIndex OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The interface index of this OSPFv3 interface. - It corresponds to the interface index of the - IPv6 interface on which OSPFv3 is configured." - ::= { ospfv3IfEntry 1 } - - ospfv3IfInstId OBJECT-TYPE - SYNTAX Ospfv3IfInstIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Enables multiple interface instances of OSPFv3 - to be run over a single link. Each interface - instance would be assigned a separate ID. This ID - has local link significance only." - ::= { ospfv3IfEntry 2 } - - ospfv3IfAreaId OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "A 32-bit integer uniquely identifying the area - to which the interface connects. Area ID - 0 is used for the OSPFv3 backbone." - DEFVAL { 0 } - ::= { ospfv3IfEntry 3 } - - ospfv3IfType OBJECT-TYPE - SYNTAX INTEGER { - broadcast(1), - nbma(2), - pointToPoint(3), - pointToMultipoint(5) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The OSPFv3 interface type." - ::= { ospfv3IfEntry 4 } - - ospfv3IfAdminStatus OBJECT-TYPE - SYNTAX Status - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The OSPFv3 interface's administrative status. - The value formed on the interface; the interface - will be advertised as an internal route to some - area. The value 'disabled' denotes that the - interface is external to OSPFv3. - - Note that a value of 'disabled' for the object - ospfv3AdminStatus will override a value of - 'enabled' for the interface." - DEFVAL { enabled } - ::= { ospfv3IfEntry 5 } - - ospfv3IfRtrPriority OBJECT-TYPE - SYNTAX DesignatedRouterPriority - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The priority of this interface. Used in - multi-access networks, this field is used in - the designated-router election algorithm. The - value 0 signifies that the router is not - eligible to become the Designated Router on this - particular network. In the event of a tie in - this value, routers will use their Router ID as - a tie breaker." - DEFVAL { 1 } - ::= { ospfv3IfEntry 6 } - - ospfv3IfTransitDelay OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The estimated number of seconds it takes to transmit - a Link State Update packet over this interface. LSAs - contained in the update packet must have their age - incremented by this amount before transmission. This - value should take into account the transmission and - propagation delays of the interface." - REFERENCE - "OSPF for IPv6, Appendix C.3, Router Interface - Parameters." - DEFVAL { 1 } - ::= { ospfv3IfEntry 7 } - - ospfv3IfRetransInterval OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds between link state - advertisement retransmissions for adjacencies - - belonging to this interface. This value is - also used when retransmitting database - description and Link State Request packets." - DEFVAL { 5 } - ::= { ospfv3IfEntry 8 } - - ospfv3IfHelloInterval OBJECT-TYPE - SYNTAX HelloRange - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The length of time, in seconds, between the - Hello packets that the router sends on the - interface. This value must be the same for all - routers attached to a common network." - DEFVAL { 10 } - ::= { ospfv3IfEntry 9 } - - ospfv3IfRtrDeadInterval OBJECT-TYPE - SYNTAX Ospfv3DeadIntervalRangeTC - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds that a router's Hello - packets have not been seen before its - neighbors declare the router down on the interface. - This should be some multiple of the Hello interval. - This value must be the same for all routers attached - to a common network." - DEFVAL { 40 } - ::= { ospfv3IfEntry 10 } - - ospfv3IfPollInterval OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The larger time interval, in seconds, between - the Hello packets sent to an inactive, - non-broadcast multi-access neighbor." - DEFVAL { 120 } - ::= { ospfv3IfEntry 11 } - - ospfv3IfState OBJECT-TYPE - SYNTAX INTEGER { - down(1), - loopback(2), - waiting(3), - pointToPoint(4), - designatedRouter(5), - backupDesignatedRouter(6), - otherDesignatedRouter(7), - standby(8) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The OSPFv3 interface state. An interface may be - in standby state if there are multiple interfaces - on the link and another interface is active. The - interface may be in Down state if the underlying - IPv6 interface is down or if the admin status is - 'disabled' either globally or for the interface." - ::= { ospfv3IfEntry 12 } - - ospfv3IfDesignatedRouter OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Router ID of the Designated Router." - ::= { ospfv3IfEntry 13 } - - ospfv3IfBackupDesignatedRouter OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Router ID of the Backup Designated - Router." - ::= { ospfv3IfEntry 14 } - - ospfv3IfEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times this OSPFv3 interface has - changed its state or an error has occurred. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3IfEntry 15 } - - ospfv3IfRowStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This object permits management of the table by - facilitating actions such as row creation, - construction, and destruction. - - The value of this object has no effect on - whether other objects in this conceptual row can be - modified." - ::= { ospfv3IfEntry 16 } - - ospfv3IfDemand OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Indicates whether Demand OSPFv3 procedures - (Hello suppression to FULL neighbors and - setting the DoNotAge flag on propagated LSAs) - should be performed on this interface." - DEFVAL { false } - ::= { ospfv3IfEntry 17 } - - ospfv3IfMetricValue OBJECT-TYPE - SYNTAX Metric - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The metric assigned to this interface. - The default value of the metric is - 'Reference Bandwidth / ifSpeed'. The value - of the reference bandwidth can be set - in the ospfv3ReferenceBandwidth object." - ::= { ospfv3IfEntry 18 } - - ospfv3IfLinkScopeLsaCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of Link-scope link state - advertisements in this link's link state - database." - ::= { ospfv3IfEntry 19 } - - ospfv3IfLinkLsaCksumSum OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32-bit unsigned sum of the Link-scope link state - advertisements' LS checksums contained in this - link's link state database. The sum can be used - to determine if there has been a change in a - router's link state database or to compare the - link state database of two routers." - ::= { ospfv3IfEntry 20 } - - ospfv3IfDemandNbrProbe OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Indicates whether or not neighbor probing is - enabled to determine whether or not the neighbor - is inactive. Neighbor probing is disabled by - default." - DEFVAL { false } - ::= { ospfv3IfEntry 21 } - -ospfv3IfDemandNbrProbeRetransLimit OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of consecutive LSA retransmissions before - the neighbor is deemed inactive and the neighbor - adjacency is brought down." - DEFVAL { 10 } - ::= { ospfv3IfEntry 22} - -ospfv3IfDemandNbrProbeInterval OBJECT-TYPE - SYNTAX Unsigned32 - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Defines how often the neighbor will be probed." - DEFVAL { 120 } - ::= { ospfv3IfEntry 23 } - - ospfv3IfTEDisabled OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Indicates whether or not traffic engineering - is disabled on the interface when traffic - engineering is enabled in the area where the - interface is attached. The object is set - to the value true (1) to disable traffic engineering - on the interface. Traffic engineering is enabled - by default on the interface when traffic engineering - is enabled in the area where the interface is - attached." - DEFVAL { false } - ::= { ospfv3IfEntry 24 } - - ospfv3IfLinkLSASuppression OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Specifies whether or not link LSA origination is - suppressed for broadcast or NBMA interface types. - The object is set to value true (1) to suppress - the origination." - REFERENCE - "OSPF for IPv6, Appendix C.3, Router Interface - Parameters" - DEFVAL { false } - ::= { ospfv3IfEntry 25 } - - -- OSPFv3 Virtual Interface Table - - ospfv3VirtIfTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3VirtIfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information about this router's virtual - interfaces that the OSPFv3 Process is configured - to carry on." - REFERENCE - "OSPF for IPv6, Appendix C.4, Virtual Link - Parameters" - ::= { ospfv3Objects 8 } - - ospfv3VirtIfEntry OBJECT-TYPE - SYNTAX Ospfv3VirtIfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information about a single virtual interface. - - The information in this table is persistent, - and when written, the entity SHOULD save the - change to non-volatile storage." - INDEX { ospfv3VirtIfAreaId, - ospfv3VirtIfNeighbor } - ::= { ospfv3VirtIfTable 1 } - - Ospfv3VirtIfEntry ::= SEQUENCE { - ospfv3VirtIfAreaId - Ospfv3AreaIdTC, - ospfv3VirtIfNeighbor - Ospfv3RouterIdTC, - ospfv3VirtIfIndex - InterfaceIndex, - ospfv3VirtIfInstId - Ospfv3IfInstIdTC, - ospfv3VirtIfTransitDelay - Ospfv3UpToRefreshIntervalTC, - ospfv3VirtIfRetransInterval - Ospfv3UpToRefreshIntervalTC, - ospfv3VirtIfHelloInterval - HelloRange, - ospfv3VirtIfRtrDeadInterval - Ospfv3DeadIntervalRangeTC, - ospfv3VirtIfState - INTEGER, - ospfv3VirtIfEvents - Counter32, - ospfv3VirtIfRowStatus - RowStatus, - ospfv3VirtIfLinkScopeLsaCount - Gauge32, - ospfv3VirtIfLinkLsaCksumSum - Unsigned32 - } - - ospfv3VirtIfAreaId OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The transit area that the virtual link - traverses. By definition, this is not - Area 0." - ::= { ospfv3VirtIfEntry 1 } - - ospfv3VirtIfNeighbor OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Router ID of the virtual neighbor." - ::= { ospfv3VirtIfEntry 2 } - - ospfv3VirtIfIndex OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The local interface index assigned by the - OSPFv3 Process to this OSPFv3 virtual interface. - It is advertised in Hellos sent over the virtual - link and in the router's router-LSAs." - ::= { ospfv3VirtIfEntry 3 } - - ospfv3VirtIfInstId OBJECT-TYPE - SYNTAX Ospfv3IfInstIdTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The local Interface Instance ID assigned by the - OSPFv3 Process to this OSPFv3 virtual interface." - ::= { ospfv3VirtIfEntry 4 } - - ospfv3VirtIfTransitDelay OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The estimated number of seconds it takes to - transmit a Link State Update packet over this - interface." - DEFVAL { 1 } - ::= { ospfv3VirtIfEntry 5 } - - ospfv3VirtIfRetransInterval OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds between link state - advertisement retransmissions for adjacencies - belonging to this interface. This value is - also used when retransmitting database - description and Link State Request packets. This - value should be well over the expected - round-trip time." - DEFVAL { 5 } - ::= { ospfv3VirtIfEntry 6 } - - ospfv3VirtIfHelloInterval OBJECT-TYPE - SYNTAX HelloRange - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The length of time, in seconds, between the - Hello packets that the router sends on the - interface. This value must be the same for the - virtual neighbor." - DEFVAL { 10 } - ::= { ospfv3VirtIfEntry 7 } - - ospfv3VirtIfRtrDeadInterval OBJECT-TYPE - SYNTAX Ospfv3DeadIntervalRangeTC - UNITS "seconds" - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds that a router's Hello - packets have not been seen before its - neighbors declare the router down. This should - be some multiple of the Hello interval. This - value must be the same for the virtual - neighbor." - DEFVAL { 60 } - ::= { ospfv3VirtIfEntry 8 } - - ospfv3VirtIfState OBJECT-TYPE - SYNTAX INTEGER { - down(1), - pointToPoint(4) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "OSPF virtual interface states. The same encoding - as the ospfV3IfTable is used." - ::= { ospfv3VirtIfEntry 9 } - - ospfv3VirtIfEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of state changes or error events on - this virtual link. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3VirtIfEntry 10 } - - ospfv3VirtIfRowStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This object permits management of the table by - facilitating actions such as row creation, - construction, and destruction. - - The value of this object has no effect on - whether other objects in this conceptual row can be - modified." - ::= { ospfv3VirtIfEntry 11 } - - ospfv3VirtIfLinkScopeLsaCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of Link-scope link state - advertisements in this virtual link's link state - database." - ::= { ospfv3VirtIfEntry 12 } - - ospfv3VirtIfLinkLsaCksumSum OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32-bit unsigned sum of the Link-scope link state - advertisements' LS checksums contained in this - virtual link's link state database. The sum can be used - to determine if there has been a change in a - router's link state database or to compare the - link state database of two routers." - ::= { ospfv3VirtIfEntry 13 } - - -- OSPFv3 Neighbor Table - - ospfv3NbrTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3NbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A table describing all neighbors in the - locality of the OSPFv3 router." - REFERENCE - "OSPF Version 2, Section 10, The Neighbor Data - Structure" - ::= { ospfv3Objects 9 } - - ospfv3NbrEntry OBJECT-TYPE - SYNTAX Ospfv3NbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The information regarding a single neighbor." - REFERENCE - "OSPF Version 2, Section 10, The Neighbor Data - Structure" - INDEX { ospfv3NbrIfIndex, - ospfv3NbrIfInstId, - ospfv3NbrRtrId } - ::= { ospfv3NbrTable 1 } - - Ospfv3NbrEntry ::= SEQUENCE { - ospfv3NbrIfIndex - InterfaceIndex, - ospfv3NbrIfInstId - Ospfv3IfInstIdTC, - ospfv3NbrRtrId - Ospfv3RouterIdTC, - ospfv3NbrAddressType - InetAddressType, - ospfv3NbrAddress - InetAddress, - ospfv3NbrOptions - Integer32, - ospfv3NbrPriority - DesignatedRouterPriority, - ospfv3NbrState - INTEGER, - ospfv3NbrEvents - Counter32, - ospfv3NbrLsRetransQLen - Gauge32, - ospfv3NbrHelloSuppressed - TruthValue, - ospfv3NbrIfId - InterfaceIndex, - ospfv3NbrRestartHelperStatus - INTEGER, - ospfv3NbrRestartHelperAge - Ospfv3UpToRefreshIntervalTC, - ospfv3NbrRestartHelperExitReason - INTEGER - } - - ospfv3NbrIfIndex OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Local Link ID of the link over which the - neighbor can be reached." - ::= { ospfv3NbrEntry 1 } - - ospfv3NbrIfInstId OBJECT-TYPE - SYNTAX Ospfv3IfInstIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Interface instance over which the neighbor - can be reached. This ID has local link - significance only." - ::= { ospfv3NbrEntry 2 } - - ospfv3NbrRtrId OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A 32-bit unsigned integer uniquely identifying the - neighboring router in the Autonomous System." - ::= { ospfv3NbrEntry 3 } - - ospfv3NbrAddressType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The address type of ospfv3NbrAddress. Only IPv6 - addresses without zone index are expected." - ::= { ospfv3NbrEntry 4 } - - ospfv3NbrAddress OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IPv6 address of the neighbor associated with - the local link." - ::= { ospfv3NbrEntry 5 } - - ospfv3NbrOptions OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A bit mask corresponding to the neighbor's - options field." - REFERENCE - "OSPF for IPv6, Appendix A.2, The Options Field" - ::= { ospfv3NbrEntry 6 } - - ospfv3NbrPriority OBJECT-TYPE - SYNTAX DesignatedRouterPriority - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The priority of this neighbor in the designated- - router election algorithm. The value 0 signifies - that the neighbor is not eligible to become the - Designated Router on this particular network." - ::= { ospfv3NbrEntry 7 } - - ospfv3NbrState OBJECT-TYPE - SYNTAX INTEGER { - down(1), - attempt(2), - init(3), - twoWay(4), - exchangeStart(5), - exchange(6), - loading(7), - full(8) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The state of the relationship with this - neighbor." - REFERENCE - "OSPF Version 2, Section 10.1, Neighbor states" - ::= { ospfv3NbrEntry 8 } - - ospfv3NbrEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times this neighbor relationship - has changed state or an error has occurred. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3NbrEntry 9 } - - ospfv3NbrLsRetransQLen OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The current length of the retransmission - queue." - ::= { ospfv3NbrEntry 10 } - - ospfv3NbrHelloSuppressed OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates whether Hellos are being suppressed - to the neighbor." - ::= { ospfv3NbrEntry 11 } - - ospfv3NbrIfId OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Interface ID that the neighbor advertises - in its Hello packets on this link, that is, the - neighbor's local interface index." - ::= { ospfv3NbrEntry 12 } - - ospfv3NbrRestartHelperStatus OBJECT-TYPE - SYNTAX INTEGER { notHelping(1), - helping(2) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates whether the router is acting - as a graceful restart helper for the neighbor." - ::= { ospfv3NbrEntry 13 } - - ospfv3NbrRestartHelperAge OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Remaining time in current OSPF graceful restart - interval, if the router is acting as a restart - helper for the neighbor." - ::= { ospfv3NbrEntry 14 } - - ospfv3NbrRestartHelperExitReason OBJECT-TYPE - SYNTAX INTEGER { none(1), - inProgress(2), - completed(3), - timedOut(4), - topologyChanged(5) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Describes the outcome of the last attempt at acting - as a graceful restart helper for the neighbor. - - none: no restart has yet been attempted. - inProgress: a restart attempt is currently underway. - completed: the last restart completed successfully. - timedOut: the last restart timed out. - topologyChanged: the last restart was aborted due to - a topology change." - ::= { ospfv3NbrEntry 15 } - - -- OSPFv3 Configured Neighbor Table - - ospfv3CfgNbrTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3CfgNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A table describing all configured neighbors. - - The Configured Neighbors table just gives - OSPFv3 information for sending OSPFv3 packets - to potential neighbors and is typically used - on NBMA and Point-to-Multipoint networks. - Once a Hello is received from a neighbor in - the Configured Neighbor table, an entry for - that neighbor is created in the Neighbor table - and adjacency state is maintained there. - Neighbors on multi-access or Point-to-Point - networks can use multicast addressing, so only - Neighbor table entries are created for them." - REFERENCE - "OSPF Version 2, Section 10, The Neighbor Data - Structure" - ::= { ospfv3Objects 10 } - - ospfv3CfgNbrEntry OBJECT-TYPE - SYNTAX Ospfv3CfgNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The information regarding a single configured - neighbor. - - The information in this table is persistent, - and when written, the entity SHOULD save the - change to non-volatile storage." - REFERENCE - "OSPF Version 2, Section 10, The Neighbor Data - Structure" - INDEX { ospfv3CfgNbrIfIndex, - ospfv3CfgNbrIfInstId, - ospfv3CfgNbrAddressType, - ospfv3CfgNbrAddress } - ::= { ospfv3CfgNbrTable 1 } - - Ospfv3CfgNbrEntry ::= SEQUENCE { - ospfv3CfgNbrIfIndex - InterfaceIndex, - ospfv3CfgNbrIfInstId - Ospfv3IfInstIdTC, - ospfv3CfgNbrAddressType - InetAddressType, - ospfv3CfgNbrAddress - InetAddress, - ospfv3CfgNbrPriority - DesignatedRouterPriority, - ospfv3CfgNbrRowStatus - RowStatus - } - - ospfv3CfgNbrIfIndex OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Local Link ID of the link over which the - neighbor can be reached." - ::= { ospfv3CfgNbrEntry 1 } - - ospfv3CfgNbrIfInstId OBJECT-TYPE - SYNTAX Ospfv3IfInstIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Interface instance over which the neighbor - can be reached. This ID has local link - significance only." - ::= { ospfv3CfgNbrEntry 2 } - - ospfv3CfgNbrAddressType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The address type of ospfv3NbrAddress. Only IPv6 - addresses without zone index are expected." - ::= { ospfv3CfgNbrEntry 3 } - - ospfv3CfgNbrAddress OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The IPv6 address of the neighbor associated with - the local link." - ::= { ospfv3CfgNbrEntry 4 } - - ospfv3CfgNbrPriority OBJECT-TYPE - SYNTAX DesignatedRouterPriority - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The priority of this neighbor in the designated- - router election algorithm. The value 0 signifies - that the neighbor is not eligible to become the - Designated Router on this particular network." - DEFVAL { 1 } - ::= { ospfv3CfgNbrEntry 5 } - - ospfv3CfgNbrRowStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This object permits management of the table by - facilitating actions such as row creation, - construction, and destruction. - - The value of this object has no effect on - whether other objects in this conceptual row can be - modified." - ::= { ospfv3CfgNbrEntry 6 } - - -- OSPFv3 Virtual Neighbor Table - - ospfv3VirtNbrTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3VirtNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A table describing all virtual neighbors." - REFERENCE - "OSPF Version 2, Section 15, Virtual Links" - ::= { ospfv3Objects 11 } - - ospfv3VirtNbrEntry OBJECT-TYPE - SYNTAX Ospfv3VirtNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Virtual neighbor information." - INDEX { ospfv3VirtNbrArea, - ospfv3VirtNbrRtrId } - ::= { ospfv3VirtNbrTable 1 } - - Ospfv3VirtNbrEntry ::= SEQUENCE { - ospfv3VirtNbrArea - Ospfv3AreaIdTC, - ospfv3VirtNbrRtrId - Ospfv3RouterIdTC, - ospfv3VirtNbrIfIndex - InterfaceIndex, - ospfv3VirtNbrIfInstId - Ospfv3IfInstIdTC, - ospfv3VirtNbrAddressType - InetAddressType, - ospfv3VirtNbrAddress - InetAddress, - ospfv3VirtNbrOptions - Integer32, - ospfv3VirtNbrState - INTEGER, - ospfv3VirtNbrEvents - Counter32, - ospfv3VirtNbrLsRetransQLen - Gauge32, - ospfv3VirtNbrHelloSuppressed - TruthValue, - ospfv3VirtNbrIfId - InterfaceIndex, - ospfv3VirtNbrRestartHelperStatus - INTEGER, - ospfv3VirtNbrRestartHelperAge - Ospfv3UpToRefreshIntervalTC, - ospfv3VirtNbrRestartHelperExitReason - INTEGER - } - - ospfv3VirtNbrArea OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The transit area Identifier." - ::= { ospfv3VirtNbrEntry 1 } - - ospfv3VirtNbrRtrId OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A 32-bit integer uniquely identifying the - neighboring router in the Autonomous System." - ::= { ospfv3VirtNbrEntry 2 } - - ospfv3VirtNbrIfIndex OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The local Interface ID for the virtual link over - which the neighbor can be reached." - ::= { ospfv3VirtNbrEntry 3 } - - ospfv3VirtNbrIfInstId OBJECT-TYPE - SYNTAX Ospfv3IfInstIdTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The interface instance for the virtual link over - which the neighbor can be reached." - ::= { ospfv3VirtNbrEntry 4 } - - ospfv3VirtNbrAddressType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The address type of ospfv3VirtNbrAddress. Only IPv6 - addresses without zone index are expected." - ::= { ospfv3VirtNbrEntry 5 } - - ospfv3VirtNbrAddress OBJECT-TYPE - SYNTAX InetAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IPv6 address advertised by this virtual neighbor. - It must be a global scope address." - ::= { ospfv3VirtNbrEntry 6 } - - ospfv3VirtNbrOptions OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A bit mask corresponding to the neighbor's options - field." - REFERENCE - "OSPF for IPv6, Appendix A.2, The Options Field" - ::= { ospfv3VirtNbrEntry 7 } - - ospfv3VirtNbrState OBJECT-TYPE - SYNTAX INTEGER { - down(1), - attempt(2), - init(3), - twoWay(4), - exchangeStart(5), - exchange(6), - loading(7), - full(8) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The state of the virtual neighbor relationship." - ::= { ospfv3VirtNbrEntry 8 } - - ospfv3VirtNbrEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times this virtual link has - changed its state or an error has occurred. - - Discontinuities in the value of this counter - can occur at re-initialization of the management - system and at other times as indicated by the - value of ospfv3DiscontinuityTime." - ::= { ospfv3VirtNbrEntry 9 } - - ospfv3VirtNbrLsRetransQLen OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The current length of the retransmission - queue." - ::= { ospfv3VirtNbrEntry 10 } - - ospfv3VirtNbrHelloSuppressed OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates whether Hellos are being suppressed - to the neighbor." - ::= { ospfv3VirtNbrEntry 11 } - - ospfv3VirtNbrIfId OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Interface ID that the neighbor advertises - in its Hello packets on this virtual link, that is, - the neighbor's local Interface ID." - ::= { ospfv3VirtNbrEntry 12 } - -ospfv3VirtNbrRestartHelperStatus OBJECT-TYPE - SYNTAX INTEGER { notHelping(1), - helping(2) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates whether the router is acting - as a graceful restart helper for the neighbor." - ::= { ospfv3VirtNbrEntry 13 } - - ospfv3VirtNbrRestartHelperAge OBJECT-TYPE - SYNTAX Ospfv3UpToRefreshIntervalTC - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Remaining time in the current OSPF graceful restart - interval, if the router is acting as a restart - helper for the neighbor." - ::= { ospfv3VirtNbrEntry 14 } - - ospfv3VirtNbrRestartHelperExitReason OBJECT-TYPE - SYNTAX INTEGER { none(1), - inProgress(2), - completed(3), - timedOut(4), - topologyChanged(5) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Describes the outcome of the last attempt at acting - as a graceful restart helper for the neighbor. - - none: no restart has yet been attempted. - inProgress: a restart attempt is currently underway. - completed: the last restart completed successfully. - timedOut: the last restart timed out. - topologyChanged: the last restart was aborted due to - a topology change." - ::= { ospfv3VirtNbrEntry 15 } - - -- - -- The OSPFv3 Area Aggregate Table - -- - - ospfv3AreaAggregateTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3AreaAggregateEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Area Aggregate Table acts as an adjunct - to the Area Table. It describes those address - aggregates that are configured to be propagated - from an area. Its purpose is to reduce the amount - of information that is known beyond an area's - borders. - - A range of IPv6 prefixes specified by a - prefix / prefix length pair. Note that if - ranges are configured such that one range - subsumes another range, the most specific - match is the preferred one." - ::= { ospfv3Objects 12 } - - ospfv3AreaAggregateEntry OBJECT-TYPE - SYNTAX Ospfv3AreaAggregateEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A single area aggregate entry. - - Information in this table is persistent, and - when this object is written, the entity SHOULD - save the change to non-volatile storage." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - INDEX { ospfv3AreaAggregateAreaID, - ospfv3AreaAggregateAreaLsdbType, - ospfv3AreaAggregatePrefixType, - ospfv3AreaAggregatePrefix, - ospfv3AreaAggregatePrefixLength } - ::= { ospfv3AreaAggregateTable 1 } - - Ospfv3AreaAggregateEntry ::= SEQUENCE { - ospfv3AreaAggregateAreaID - Ospfv3AreaIdTC, - ospfv3AreaAggregateAreaLsdbType - INTEGER, - ospfv3AreaAggregatePrefixType - InetAddressType, - ospfv3AreaAggregatePrefix - InetAddress, - ospfv3AreaAggregatePrefixLength - InetAddressPrefixLength, - ospfv3AreaAggregateRowStatus - RowStatus, - ospfv3AreaAggregateEffect - INTEGER, - ospfv3AreaAggregateRouteTag - Unsigned32 - } - - ospfv3AreaAggregateAreaID OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The area the Address Aggregate is to be found - within." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - ::= { ospfv3AreaAggregateEntry 1 } - - ospfv3AreaAggregateAreaLsdbType OBJECT-TYPE - SYNTAX INTEGER { - interAreaPrefixLsa(8195), -- 0x2003 - nssaExternalLsa(8199) -- 0x2007 - } - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The type of the Address Aggregate. This field - specifies the Area LSDB type that this Address - Aggregate applies to." - REFERENCE - "OSPF Version 2, Appendix A.4.1, The LSA header" - ::= { ospfv3AreaAggregateEntry 2 } - - ospfv3AreaAggregatePrefixType OBJECT-TYPE - SYNTAX InetAddressType - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The prefix type of ospfv3AreaAggregatePrefix. Only - IPv6 addresses are expected." - ::= { ospfv3AreaAggregateEntry 3 } - - ospfv3AreaAggregatePrefix OBJECT-TYPE - SYNTAX InetAddress (SIZE (0..16)) - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The IPv6 prefix." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - ::= { ospfv3AreaAggregateEntry 4 } - - ospfv3AreaAggregatePrefixLength OBJECT-TYPE - SYNTAX InetAddressPrefixLength (3..128) - UNITS "bits" - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The length of the prefix (in bits). A prefix can - not be shorter than 3 bits." - REFERENCE - "OSPF Version 2, Appendix C.2, Area parameters" - ::= { ospfv3AreaAggregateEntry 5 } - - ospfv3AreaAggregateRowStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This object permits management of the table by - facilitating actions such as row creation, - construction, and destruction. - - The value of this object has no effect on - whether other objects in this conceptual row can be - modified." - ::= { ospfv3AreaAggregateEntry 6 } - - ospfv3AreaAggregateEffect OBJECT-TYPE - SYNTAX INTEGER { - advertiseMatching(1), - doNotAdvertiseMatching(2) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Prefixes subsumed by ranges will either trigger the - advertisement of the indicated aggregate - (advertiseMatching) or result in the prefix not - being advertised at all outside the area." - DEFVAL { advertiseMatching } - ::= { ospfv3AreaAggregateEntry 7 } - - ospfv3AreaAggregateRouteTag OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This tag is advertised only in the summarized - As-External LSA when summarizing from NSSA-LSAs to - AS-External-LSAs." - DEFVAL { 0 } - ::= { ospfv3AreaAggregateEntry 8 } - - -- OSPFv3 Link-Scope Link State Database, for virtual interfaces - - ospfv3VirtLinkLsdbTable OBJECT-TYPE - SYNTAX SEQUENCE OF Ospfv3VirtLinkLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPFv3 Process's Link-scope LSDB for virtual - interfaces. The LSDB contains the Link-scope link - state advertisements from virtual interfaces." - ::= { ospfv3Objects 13 } - - ospfv3VirtLinkLsdbEntry OBJECT-TYPE - SYNTAX Ospfv3VirtLinkLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A single Link-scope link state advertisement - for a virtual interface." - INDEX { ospfv3VirtLinkLsdbIfAreaId, - ospfv3VirtLinkLsdbIfNeighbor, - ospfv3VirtLinkLsdbType, - ospfv3VirtLinkLsdbRouterId, - ospfv3VirtLinkLsdbLsid } - ::= { ospfv3VirtLinkLsdbTable 1 } - - Ospfv3VirtLinkLsdbEntry ::= SEQUENCE { - ospfv3VirtLinkLsdbIfAreaId - Ospfv3AreaIdTC, - ospfv3VirtLinkLsdbIfNeighbor - Ospfv3RouterIdTC, - ospfv3VirtLinkLsdbType - Unsigned32, - ospfv3VirtLinkLsdbRouterId - Ospfv3RouterIdTC, - ospfv3VirtLinkLsdbLsid - Ospfv3LsIdTC, - ospfv3VirtLinkLsdbSequence - Ospfv3LsaSequenceTC, - ospfv3VirtLinkLsdbAge - Ospfv3LsaAgeTC, - ospfv3VirtLinkLsdbChecksum - Integer32, - ospfv3VirtLinkLsdbAdvertisement - OCTET STRING, - ospfv3VirtLinkLsdbTypeKnown - TruthValue - } - - ospfv3VirtLinkLsdbIfAreaId OBJECT-TYPE - SYNTAX Ospfv3AreaIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The transit area that the virtual link - traverses. By definition, this is not - Area 0." - ::= { ospfv3VirtLinkLsdbEntry 1 } - - ospfv3VirtLinkLsdbIfNeighbor OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Router ID of the virtual neighbor." - ::= { ospfv3VirtLinkLsdbEntry 2 } - - ospfv3VirtLinkLsdbType OBJECT-TYPE - SYNTAX Unsigned32(0..'FFFFFFFF'h) - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The type of the link state advertisement. - Each link state type has a separate - advertisement format. Link-scope LSAs unrecognized - by the router are also stored in this database." - ::= { ospfv3VirtLinkLsdbEntry 3 } - - ospfv3VirtLinkLsdbRouterId OBJECT-TYPE - SYNTAX Ospfv3RouterIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The 32-bit number that uniquely identifies the - originating router in the Autonomous System." - REFERENCE - "OSPF Version 2, Appendix C.1, Global parameters" - ::= { ospfv3VirtLinkLsdbEntry 4 } - - ospfv3VirtLinkLsdbLsid OBJECT-TYPE - SYNTAX Ospfv3LsIdTC - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The Link State ID is an LS type-specific field - containing a unique identifier; - it identifies the piece of the routing domain - that is being described by the advertisement. - In contrast to OSPFv2, the LSID has no - addressing semantics." - ::= { ospfv3VirtLinkLsdbEntry 5 } - - -- Note that the OSPF sequence number is a 32-bit signed - -- integer. It starts with the value '80000001'h - -- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h. - -- Thus, a typical sequence number will be very negative. - - ospfv3VirtLinkLsdbSequence OBJECT-TYPE - SYNTAX Ospfv3LsaSequenceTC - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The sequence number field is a signed 32-bit - integer. It is used to detect old and duplicate - link state advertisements. The space of - sequence numbers is linearly ordered. The - larger the sequence number, the more recent the - advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.6, LS sequence - number" - ::= { ospfv3VirtLinkLsdbEntry 6 } - - ospfv3VirtLinkLsdbAge OBJECT-TYPE - SYNTAX Ospfv3LsaAgeTC - UNITS "seconds" - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the age of the link state - advertisement in seconds. The high-order bit - of the LS age field is considered the DoNotAge - bit for support of on-demand circuits." - REFERENCE - "OSPF Version 2, Section 12.1.1, LS age; - Extending OSPF to Support Demand Circuits, - Section 2.2, The LS age field." - ::= { ospfv3VirtLinkLsdbEntry 7 } - - ospfv3VirtLinkLsdbChecksum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the checksum of the complete - contents of the advertisement, excepting the - age field. The age field is excepted so that - an advertisement's age can be incremented - without updating the checksum. The checksum - used is the same that is used for ISO - connectionless datagrams; it is commonly - referred to as the Fletcher checksum." - REFERENCE - "OSPF Version 2, Section 12.1.7, LS checksum" - ::= { ospfv3VirtLinkLsdbEntry 8 } - - ospfv3VirtLinkLsdbAdvertisement OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (1..65535)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The entire link state advertisement, including - its header." - ::= { ospfv3VirtLinkLsdbEntry 9 } - - ospfv3VirtLinkLsdbTypeKnown OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value true (1) indicates that the LSA type is - recognized by this router." - ::= { ospfv3VirtLinkLsdbEntry 10 } - - -- The Ospfv3 Notification Table - - -- The Ospfv3 Notification Table records fields that are - -- required for notifications. - - ospfv3NotificationEntry OBJECT IDENTIFIER - ::= { ospfv3Objects 14 } - - ospfv3ConfigErrorType OBJECT-TYPE - SYNTAX INTEGER { - badVersion(1), - areaMismatch(2), - unknownNbmaNbr(3), -- Router is DR eligible - unknownVirtualNbr(4), - helloIntervalMismatch(5), - deadIntervalMismatch(6), - optionMismatch(7), - mtuMismatch(8), - duplicateRouterId(9), - noError(10) } - MAX-ACCESS accessible-for-notify - STATUS current - DESCRIPTION - "Potential types of configuration conflicts. - Used by the ospfv3ConfigError and - ospfv3ConfigVirtError notifications." - ::= { ospfv3NotificationEntry 1 } - - ospfv3PacketType OBJECT-TYPE - SYNTAX INTEGER { - hello(1), - dbDescript(2), - lsReq(3), - lsUpdate(4), - lsAck(5), - nullPacket(6) } - MAX-ACCESS accessible-for-notify - STATUS current - DESCRIPTION - "OSPFv3 packet types." - ::= { ospfv3NotificationEntry 2 } - - ospfv3PacketSrc OBJECT-TYPE - SYNTAX InetAddressIPv6 - MAX-ACCESS accessible-for-notify - STATUS current - DESCRIPTION - "The IPv6 address of an inbound packet that cannot - be identified by a neighbor instance. - - Only IPv6 addresses without zone index are expected." - ::= { ospfv3NotificationEntry 3 } - - -- Notification Definitions - - -- The notifications need to be throttled so as to not overwhelm the - -- management agent in case of rapid changes to the OSPFv3 module. - -ospfv3VirtIfStateChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3VirtIfState -- The new state - } - STATUS current - DESCRIPTION - "An ospfv3VirtIfStateChange notification signifies that - there has been a change in the state of an OSPFv3 virtual - interface. - - This notification should be generated when the interface - state regresses (e.g., goes from Point-to-Point to Down) - or progresses to a terminal state (i.e., Point-to-Point)." - ::= { ospfv3Notifications 1 } - -ospfv3NbrStateChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3NbrState -- The new state - - } - STATUS current - DESCRIPTION - "An ospfv3NbrStateChange notification signifies that - there has been a change in the state of a - non-virtual OSPFv3 neighbor. This notification should be - generated when the neighbor state regresses - (e.g., goes from Attempt or Full to 1-Way or - Down) or progresses to a terminal state (e.g., - 2-Way or Full). When a neighbor transitions - from or to Full on non-broadcast multi-access - and broadcast networks, the notification should be - generated by the Designated Router. A Designated - Router transitioning to Down will be noted by - ospfIfStateChange." - ::= { ospfv3Notifications 2 } - -ospfv3VirtNbrStateChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3VirtNbrState -- The new state - } - STATUS current - DESCRIPTION - "An ospfv3VirtNbrStateChange notification signifies - that there has been a change in the state of an OSPFv3 - virtual neighbor. This notification should be generated - when the neighbor state regresses (e.g., goes - from Attempt or Full to 1-Way or Down) or - progresses to a terminal state (e.g., Full)." - ::= { ospfv3Notifications 3 } - -ospfv3IfConfigError NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3IfState, -- State of the interface - ospfv3PacketSrc, -- IPv6 address of source - ospfv3ConfigErrorType, -- Type of error - ospfv3PacketType -- Type of packet - } - STATUS current - DESCRIPTION - "An ospfv3IfConfigError notification signifies that a - packet has been received on a non-virtual - interface from a router whose configuration - parameters conflict with this router's - configuration parameters. Note that the event - optionMismatch should cause a notification only if it - prevents an adjacency from forming." - ::= { ospfv3Notifications 4 } - -ospfv3VirtIfConfigError NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3VirtIfState, -- State of the interface - ospfv3ConfigErrorType, -- Type of error - ospfv3PacketType - } - STATUS current - DESCRIPTION - "An ospfv3VirtIfConfigError notification signifies that a - packet has been received on a virtual interface - from a router whose configuration parameters - conflict with this router's configuration - parameters. Note that the event optionMismatch - should cause a notification only if it prevents an - adjacency from forming." - ::= { ospfv3Notifications 5 } - -ospfv3IfRxBadPacket NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3IfState, -- State of the interface - ospfv3PacketSrc, -- The source IPv6 address - ospfv3PacketType -- Type of packet - } - STATUS current - DESCRIPTION - "An ospfv3IfRxBadPacket notification signifies that an - OSPFv3 packet that cannot be parsed has been received on a - non-virtual interface." - ::= { ospfv3Notifications 6 } - -ospfv3VirtIfRxBadPacket NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3VirtIfState, -- State of the interface - ospfv3PacketType -- Type of packet - } - STATUS current - DESCRIPTION - "An ospfv3VirtIfRxBadPacket notification signifies - that an OSPFv3 packet that cannot be parsed has been - received on a virtual interface." - ::= { ospfv3Notifications 7 } - -ospfv3LsdbOverflow NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3ExtAreaLsdbLimit -- Limit on External LSAs - } - STATUS current - DESCRIPTION - "An ospfv3LsdbOverflow notification signifies that the - number of LSAs in the router's link state - database has exceeded ospfv3ExtAreaLsdbLimit." - ::= { ospfv3Notifications 8 } - -ospfv3LsdbApproachingOverflow NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3ExtAreaLsdbLimit - } - STATUS current - DESCRIPTION - "An ospfv3LsdbApproachingOverflow notification signifies - that the number of LSAs in the router's - link state database has exceeded ninety percent of - ospfv3ExtAreaLsdbLimit." - ::= { ospfv3Notifications 9 } - -ospfv3IfStateChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3IfState -- The new state - } - STATUS current - DESCRIPTION - "An ospfv3IfStateChange notification signifies that there - has been a change in the state of a non-virtual - OSPFv3 interface. This notification should be generated - when the interface state regresses (e.g., goes - from DR to Down) or progresses to a terminal - state (i.e., Point-to-Point, DR Other, DR, or - Backup)." - ::= { ospfv3Notifications 10 } - -ospfv3NssaTranslatorStatusChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3AreaNssaTranslatorState -- new state - } - STATUS current - DESCRIPTION - "An ospfv3NssaTranslatorStatusChange notification - indicates that there has been a change in the router's - ability to translate OSPFv3 NSSA LSAs into OSPFv3 External - LSAs. This notification should be generated when the - Translator Status transitions from or to any defined - status on a per-area basis." - ::= { ospfv3Notifications 11 } - -ospfv3RestartStatusChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3RestartStatus, -- new status - ospfv3RestartInterval, - ospfv3RestartExitReason - } - STATUS current - DESCRIPTION - "An ospfv3RestartStatusChange notification signifies that - there has been a change in the graceful restart - state for the router. This notification should be - generated when the router restart status - changes." - ::= { ospfv3Notifications 12 } - -ospfv3NbrRestartHelperStatusChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3NbrRestartHelperStatus, -- new status - ospfv3NbrRestartHelperAge, - ospfv3NbrRestartHelperExitReason - } - STATUS current - DESCRIPTION - "An ospfv3NbrRestartHelperStatusChange notification - signifies that there has been a change in the - graceful restart helper state for the neighbor. - This notification should be generated when the - neighbor restart helper status transitions for a neighbor." - ::= { ospfv3Notifications 13 } - -ospfv3VirtNbrRestartHelperStatusChange NOTIFICATION-TYPE - OBJECTS { ospfv3RouterId, -- The originator of the notification - ospfv3VirtNbrRestartHelperStatus, -- new status - ospfv3VirtNbrRestartHelperAge, - ospfv3VirtNbrRestartHelperExitReason - } - STATUS current - DESCRIPTION - "An ospfv3VirtNbrRestartHelperStatusChange - notification signifies that there has been a - change in the graceful restart helper state for - the virtual neighbor. This notification should be - generated when the virtual neighbor restart helper status - transitions for a virtual neighbor." - ::= { ospfv3Notifications 14 } - - -- Conformance Information - - ospfv3Groups OBJECT IDENTIFIER ::= { ospfv3Conformance 1 } - ospfv3Compliances OBJECT IDENTIFIER ::= { ospfv3Conformance 2 } - - -- Compliance Statements - - ospfv3FullCompliance MODULE-COMPLIANCE - STATUS current - DESCRIPTION "The compliance statement" - MODULE -- this module - MANDATORY-GROUPS { - ospfv3BasicGroup, - ospfv3AreaGroup, - ospfv3IfGroup, - ospfv3VirtIfGroup, - ospfv3NbrGroup, - ospfv3CfgNbrGroup, - ospfv3VirtNbrGroup, - ospfv3AreaAggregateGroup - } - - GROUP ospfv3AsLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their AS-scope link state database." - - GROUP ospfv3AreaLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their Area-scope link state database." - - GROUP ospfv3LinkLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their Link-scope link state database - for non-virtual interfaces." - - GROUP ospfv3VirtLinkLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their Link-scope link state database - for virtual interfaces." - - GROUP ospfv3HostGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - support attached hosts." - - GROUP ospfv3NotificationObjectGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - support OSPFv3 notifications." - - GROUP ospfv3NotificationGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - support OSPFv3 notifications." - - OBJECT ospfv3NbrAddressType - SYNTAX InetAddressType { ipv6(2) } - DESCRIPTION - "An implementation is only required to support IPv6 - address without zone index." - - OBJECT ospfv3NbrAddress - SYNTAX InetAddress (SIZE (16)) - DESCRIPTION - "An implementation is only required to support IPv6 - address without zone index." - - OBJECT ospfv3VirtNbrAddressType - SYNTAX InetAddressType { ipv6(2) } - DESCRIPTION - "An implementation is only required to support IPv6 - address without zone index." - - OBJECT ospfv3VirtNbrAddress - SYNTAX InetAddress (SIZE (16)) - DESCRIPTION - "An implementation is only required to support IPv6 - address without zone index." - ::= { ospfv3Compliances 1 } - - ospfv3ReadOnlyCompliance MODULE-COMPLIANCE - STATUS current - DESCRIPTION - "When this MIB module is implemented without - support for read-create (i.e., in read-only - mode), the implementation can claim read-only - compliance. Such a device can then be monitored, - but cannot be configured with this MIB." - - MODULE -- this module - MANDATORY-GROUPS { - ospfv3BasicGroup, - ospfv3AreaGroup, - ospfv3IfGroup, - ospfv3VirtIfGroup, - ospfv3NbrGroup, - ospfv3CfgNbrGroup, - ospfv3VirtNbrGroup, - ospfv3AreaAggregateGroup - } - - GROUP ospfv3AsLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their AS-scope link state database." - - GROUP ospfv3AreaLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their Area-scope link state database." - - GROUP ospfv3LinkLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their Link-scope link state database - for non-virtual interfaces." - - GROUP ospfv3VirtLinkLsdbGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - display their Link-scope link state database - for virtual interfaces." - - GROUP ospfv3HostGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - support attached hosts." - - GROUP ospfv3NotificationObjectGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - support OSPFv3 notifications." - - GROUP ospfv3NotificationGroup - DESCRIPTION - "This group is required for OSPFv3 systems that - support OSPFv3 notifications." - - OBJECT ospfv3RouterId - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AdminStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3ExtAreaLsdbLimit - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3ExitOverflowInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3DemandExtensions - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3ReferenceBandwidth - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3RestartSupport - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3RestartInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3RestartStrictLsaChecking - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3NotificationEnable - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3StubRouterAdvertisement - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaImportAsExtern - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaSummary - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaRowStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaStubMetric - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaNssaTranslatorRole - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaNssaTranslatorStabInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaStubMetricType - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaTEEnabled - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3HostMetric - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3HostRowStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3HostAreaID - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfAreaId - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfType - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfAdminStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfRtrPriority - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfTransitDelay - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfRetransInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfHelloInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfRtrDeadInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfPollInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfRowStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfDemand - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfMetricValue - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfDemandNbrProbe - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfDemandNbrProbeRetransLimit - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfDemandNbrProbeInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfTEDisabled - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3IfLinkLSASuppression - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3VirtIfTransitDelay - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3VirtIfRetransInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3VirtIfHelloInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3VirtIfRtrDeadInterval - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3VirtIfRowStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3CfgNbrPriority - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3CfgNbrRowStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaAggregateRowStatus - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaAggregateEffect - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - - OBJECT ospfv3AreaAggregateRouteTag - MIN-ACCESS read-only - DESCRIPTION - "Write access is not required." - ::= { ospfv3Compliances 2 } - - -- units of conformance - - ospfv3BasicGroup OBJECT-GROUP - OBJECTS { - ospfv3RouterId, - ospfv3AdminStatus, - ospfv3VersionNumber, - ospfv3AreaBdrRtrStatus, - ospfv3ASBdrRtrStatus, - ospfv3AsScopeLsaCount, - ospfv3AsScopeLsaCksumSum, - ospfv3OriginateNewLsas, - ospfv3RxNewLsas, - ospfv3ExtLsaCount, - ospfv3ExtAreaLsdbLimit, - ospfv3ExitOverflowInterval, - ospfv3DemandExtensions, - ospfv3ReferenceBandwidth, - ospfv3RestartSupport, - ospfv3RestartInterval, - ospfv3RestartStrictLsaChecking, - ospfv3RestartStatus, - ospfv3RestartAge, - ospfv3RestartExitReason, - ospfv3NotificationEnable, - ospfv3StubRouterSupport, - ospfv3StubRouterAdvertisement, - ospfv3DiscontinuityTime, - ospfv3RestartTime - } - STATUS current - DESCRIPTION - "These objects are used for managing/monitoring - OSPFv3 global parameters." - ::= { ospfv3Groups 1 } - - ospfv3AreaGroup OBJECT-GROUP - OBJECTS { - ospfv3AreaImportAsExtern, - ospfv3AreaSpfRuns, - ospfv3AreaBdrRtrCount, - ospfv3AreaAsBdrRtrCount, - ospfv3AreaScopeLsaCount, - ospfv3AreaScopeLsaCksumSum, - ospfv3AreaSummary, - ospfv3AreaRowStatus, - ospfv3AreaStubMetric, - ospfv3AreaNssaTranslatorRole, - ospfv3AreaNssaTranslatorState, - ospfv3AreaNssaTranslatorStabInterval, - ospfv3AreaNssaTranslatorEvents, - ospfv3AreaStubMetricType, - ospfv3AreaTEEnabled - } - STATUS current - DESCRIPTION - "These objects are used for OSPFv3 systems - supporting areas." - ::= { ospfv3Groups 2 } - - ospfv3AsLsdbGroup OBJECT-GROUP - OBJECTS { - ospfv3AsLsdbSequence, - ospfv3AsLsdbAge, - ospfv3AsLsdbChecksum, - ospfv3AsLsdbAdvertisement, - ospfv3AsLsdbTypeKnown - } - STATUS current - DESCRIPTION - "These objects are used for OSPFv3 systems - that display their AS-scope link state database." - ::= { ospfv3Groups 3 } - - ospfv3AreaLsdbGroup OBJECT-GROUP - OBJECTS { - ospfv3AreaLsdbSequence, - ospfv3AreaLsdbAge, - ospfv3AreaLsdbChecksum, - ospfv3AreaLsdbAdvertisement, - ospfv3AreaLsdbTypeKnown - } - STATUS current - DESCRIPTION - "These objects are used for OSPFv3 systems - that display their Area-scope link state database." - ::= { ospfv3Groups 4 } - - ospfv3LinkLsdbGroup OBJECT-GROUP - OBJECTS { - ospfv3LinkLsdbSequence, - ospfv3LinkLsdbAge, - ospfv3LinkLsdbChecksum, - ospfv3LinkLsdbAdvertisement, - ospfv3LinkLsdbTypeKnown - } - STATUS current - DESCRIPTION - "These objects are used for OSPFv3 systems - that display their Link-scope link state database - for non-virtual interfaces." - ::= { ospfv3Groups 5 } - - ospfv3HostGroup OBJECT-GROUP - OBJECTS { - ospfv3HostMetric, - ospfv3HostRowStatus, - ospfv3HostAreaID - } - STATUS current - DESCRIPTION - "These objects are used for OSPFv3 systems - that support attached hosts." - ::= { ospfv3Groups 6 } - - ospfv3IfGroup OBJECT-GROUP - OBJECTS { - ospfv3IfAreaId, - ospfv3IfType, - ospfv3IfAdminStatus, - ospfv3IfRtrPriority, - ospfv3IfTransitDelay, - ospfv3IfRetransInterval, - ospfv3IfHelloInterval, - ospfv3IfRtrDeadInterval, - ospfv3IfPollInterval, - ospfv3IfState, - ospfv3IfDesignatedRouter, - ospfv3IfBackupDesignatedRouter, - ospfv3IfEvents, - ospfv3IfRowStatus, - ospfv3IfDemand, - ospfv3IfMetricValue, - ospfv3IfLinkScopeLsaCount, - ospfv3IfLinkLsaCksumSum, - ospfv3IfDemandNbrProbe, - ospfv3IfDemandNbrProbeRetransLimit, - ospfv3IfDemandNbrProbeInterval, - ospfv3IfTEDisabled, - ospfv3IfLinkLSASuppression - } - STATUS current - DESCRIPTION - "These interface objects are used for - managing/monitoring OSPFv3 interfaces." - ::= { ospfv3Groups 7 } - - ospfv3VirtIfGroup OBJECT-GROUP - OBJECTS { - ospfv3VirtIfIndex, - ospfv3VirtIfInstId, - ospfv3VirtIfTransitDelay, - ospfv3VirtIfRetransInterval, - ospfv3VirtIfHelloInterval, - ospfv3VirtIfRtrDeadInterval, - ospfv3VirtIfState, - ospfv3VirtIfEvents, - ospfv3VirtIfRowStatus, - ospfv3VirtIfLinkScopeLsaCount, - ospfv3VirtIfLinkLsaCksumSum - } - STATUS current - DESCRIPTION - "These virtual interface objects are used for - managing/monitoring OSPFv3 virtual interfaces." - ::= { ospfv3Groups 8 } - - ospfv3NbrGroup OBJECT-GROUP - OBJECTS { - ospfv3NbrAddressType, - ospfv3NbrAddress, - ospfv3NbrOptions, - ospfv3NbrPriority, - ospfv3NbrState, - ospfv3NbrEvents, - ospfv3NbrLsRetransQLen, - ospfv3NbrHelloSuppressed, - ospfv3NbrIfId, - ospfv3NbrRestartHelperStatus, - ospfv3NbrRestartHelperAge, - ospfv3NbrRestartHelperExitReason - } - STATUS current - DESCRIPTION - "These neighbor objects are used for - managing/monitoring OSPFv3 neighbors." - ::= { ospfv3Groups 9 } - - ospfv3CfgNbrGroup OBJECT-GROUP - OBJECTS { - ospfv3CfgNbrPriority, - ospfv3CfgNbrRowStatus - } - STATUS current - DESCRIPTION - "These configured neighbor objects are used for - managing/monitoring OSPFv3-configured neighbors." - ::= { ospfv3Groups 10 } - - ospfv3VirtNbrGroup OBJECT-GROUP - OBJECTS { - ospfv3VirtNbrIfIndex, - ospfv3VirtNbrIfInstId, - ospfv3VirtNbrAddressType, - ospfv3VirtNbrAddress, - ospfv3VirtNbrOptions, - ospfv3VirtNbrState, - ospfv3VirtNbrEvents, - ospfv3VirtNbrLsRetransQLen, - ospfv3VirtNbrHelloSuppressed, - ospfv3VirtNbrIfId, - ospfv3VirtNbrRestartHelperStatus, - ospfv3VirtNbrRestartHelperAge, - ospfv3VirtNbrRestartHelperExitReason - } - STATUS current - DESCRIPTION - "These virtual neighbor objects are used for - managing/monitoring OSPFv3 virtual neighbors." - ::= { ospfv3Groups 11 } - - ospfv3AreaAggregateGroup OBJECT-GROUP - OBJECTS { - ospfv3AreaAggregateRowStatus, - ospfv3AreaAggregateEffect, - ospfv3AreaAggregateRouteTag - } - STATUS current - DESCRIPTION - "These area aggregate objects are required for - aggregating OSPFv3 prefixes for summarization - across areas." - ::= { ospfv3Groups 12 } - - ospfv3VirtLinkLsdbGroup OBJECT-GROUP - OBJECTS { - ospfv3VirtLinkLsdbSequence, - ospfv3VirtLinkLsdbAge, - ospfv3VirtLinkLsdbChecksum, - ospfv3VirtLinkLsdbAdvertisement, - ospfv3VirtLinkLsdbTypeKnown - } - STATUS current - DESCRIPTION - "These objects are used for OSPFv3 systems - that display their Link-scope link state database - for virtual interfaces." - ::= { ospfv3Groups 13 } - - ospfv3NotificationObjectGroup OBJECT-GROUP - OBJECTS { - ospfv3ConfigErrorType, - ospfv3PacketType, - ospfv3PacketSrc - } - STATUS current - DESCRIPTION - "These objects are used to record notification - parameters." - ::= { ospfv3Groups 14 } - - ospfv3NotificationGroup NOTIFICATION-GROUP - NOTIFICATIONS { - ospfv3VirtIfStateChange, - ospfv3NbrStateChange, - ospfv3VirtNbrStateChange, - ospfv3IfConfigError, - ospfv3VirtIfConfigError, - ospfv3IfRxBadPacket, - ospfv3VirtIfRxBadPacket, - ospfv3LsdbOverflow, - ospfv3LsdbApproachingOverflow, - ospfv3IfStateChange, - ospfv3NssaTranslatorStatusChange, - ospfv3RestartStatusChange, - ospfv3NbrRestartHelperStatusChange, - ospfv3VirtNbrRestartHelperStatusChange - } - STATUS current - DESCRIPTION - "This group is used for OSPFv3 notifications." - ::= { ospfv3Groups 15 } - - END diff --git a/ospfd/OSPF-MIB.txt b/ospfd/OSPF-MIB.txt deleted file mode 100644 index 217c1e5160..0000000000 --- a/ospfd/OSPF-MIB.txt +++ /dev/null @@ -1,2723 +0,0 @@ -OSPF-MIB DEFINITIONS ::= BEGIN - - IMPORTS - MODULE-IDENTITY, OBJECT-TYPE, Counter32, Gauge32, - Integer32, IpAddress - FROM SNMPv2-SMI - TEXTUAL-CONVENTION, TruthValue, RowStatus - FROM SNMPv2-TC - MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF - mib-2 FROM RFC1213-MIB; - --- This MIB module uses the extended OBJECT-TYPE macro as --- defined in [9]. - -ospf MODULE-IDENTITY - LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995 - ORGANIZATION "IETF OSPF Working Group" - CONTACT-INFO - " Fred Baker - Postal: Cisco Systems - 519 Lado Drive - Santa Barbara, California 93111 - Tel: +1 805 681 0115 - E-Mail: fred@cisco.com - - Rob Coltun - Postal: RainbowBridge Communications - Tel: (301) 340-9416 - E-Mail: rcoltun@rainbow-bridge.com" - DESCRIPTION - "The MIB module to describe the OSPF Version 2 - Protocol" - ::= { mib-2 14 } - --- The Area ID, in OSPF, has the same format as an IP Address, --- but has the function of defining a summarization point for --- Link State Advertisements - -AreaID ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "An OSPF Area Identifier." - SYNTAX IpAddress - - --- The Router ID, in OSPF, has the same format as an IP Address, --- but identifies the router independent of its IP Address. - -RouterID ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "A OSPF Router Identifier." - SYNTAX IpAddress - - --- The OSPF Metric is defined as an unsigned value in the range - -Metric ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "The OSPF Internal Metric." - SYNTAX Integer32 (0..'FFFF'h) - -BigMetric ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "The OSPF External Metric." - SYNTAX Integer32 (0..'FFFFFF'h) - --- Status Values - -Status ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "The status of an interface: 'enabled' indicates that - it is willing to communicate with other OSPF Routers, - while 'disabled' indicates that it is not." - SYNTAX INTEGER { enabled (1), disabled (2) } - --- Time Durations measured in seconds - -PositiveInteger ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "A positive integer. Values in excess are precluded as - unnecessary and prone to interoperability issues." - SYNTAX Integer32 (0..'7FFFFFFF'h) - -HelloRange ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "The range of intervals on which hello messages are - exchanged." - SYNTAX Integer32 (1..'FFFF'h) - -UpToMaxAge ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "The values that one might find or configure for - variables bounded by the maximum age of an LSA." - SYNTAX Integer32 (0..3600) - - --- The range of ifIndex - -InterfaceIndex ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "The range of ifIndex." - SYNTAX Integer32 - - --- Potential Priorities for the Designated Router Election - -DesignatedRouterPriority ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "The values defined for the priority of a system for - becoming the designated router." - SYNTAX Integer32 (0..'FF'h) - -TOSType ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "Type of Service is defined as a mapping to the IP Type of - Service Flags as defined in the IP Forwarding Table MIB - - +-----+-----+-----+-----+-----+-----+-----+-----+ - | | | | - | PRECEDENCE | TYPE OF SERVICE | 0 | - | | | | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - IP TOS IP TOS - Field Policy Field Policy - - Contents Code Contents Code - 0 0 0 0 ==> 0 0 0 0 1 ==> 2 - 0 0 1 0 ==> 4 0 0 1 1 ==> 6 - 0 1 0 0 ==> 8 0 1 0 1 ==> 10 - 0 1 1 0 ==> 12 0 1 1 1 ==> 14 - 1 0 0 0 ==> 16 1 0 0 1 ==> 18 - 1 0 1 0 ==> 20 1 0 1 1 ==> 22 - 1 1 0 0 ==> 24 1 1 0 1 ==> 26 - 1 1 1 0 ==> 28 1 1 1 1 ==> 30 - - The remaining values are left for future definition." - SYNTAX Integer32 (0..30) - - --- OSPF General Variables - --- These parameters apply globally to the Router's --- OSPF Process. - -ospfGeneralGroup OBJECT IDENTIFIER ::= { ospf 1 } - - - ospfRouterId OBJECT-TYPE - SYNTAX RouterID - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "A 32-bit integer uniquely identifying the - router in the Autonomous System. - - By convention, to ensure uniqueness, this - should default to the value of one of the - router's IP interface addresses." - REFERENCE - "OSPF Version 2, C.1 Global parameters" - ::= { ospfGeneralGroup 1 } - - - ospfAdminStat OBJECT-TYPE - SYNTAX Status - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The administrative status of OSPF in the - router. The value 'enabled' denotes that the - OSPF Process is active on at least one inter- - face; 'disabled' disables it on all inter- - faces." - ::= { ospfGeneralGroup 2 } - - ospfVersionNumber OBJECT-TYPE - SYNTAX INTEGER { version2 (2) } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The current version number of the OSPF proto- - col is 2." - REFERENCE - "OSPF Version 2, Title" - ::= { ospfGeneralGroup 3 } - - - ospfAreaBdrRtrStatus OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A flag to note whether this router is an area - border router." - REFERENCE - "OSPF Version 2, Section 3 Splitting the AS into - Areas" - ::= { ospfGeneralGroup 4 } - - - ospfASBdrRtrStatus OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "A flag to note whether this router is config- - ured as an Autonomous System border router." - REFERENCE - "OSPF Version 2, Section 3.3 Classification of - routers" - ::= { ospfGeneralGroup 5 } - - ospfExternLsaCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of external (LS type 5) link-state - advertisements in the link-state database." - REFERENCE - "OSPF Version 2, Appendix A.4.5 AS external link - advertisements" - ::= { ospfGeneralGroup 6 } - - - ospfExternLsaCksumSum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32-bit unsigned sum of the LS checksums of - the external link-state advertisements con- - tained in the link-state database. This sum - can be used to determine if there has been a - change in a router's link state database, and - to compare the link-state database of two - routers." - ::= { ospfGeneralGroup 7 } - - - ospfTOSSupport OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The router's support for type-of-service rout- - ing." - REFERENCE - "OSPF Version 2, Appendix F.1.2 Optional TOS - support" - ::= { ospfGeneralGroup 8 } - - ospfOriginateNewLsas OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of new link-state advertisements - that have been originated. This number is in- - cremented each time the router originates a new - LSA." - ::= { ospfGeneralGroup 9 } - - - ospfRxNewLsas OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of link-state advertisements re- - ceived determined to be new instantiations. - This number does not include newer instantia- - tions of self-originated link-state advertise- - ments." - ::= { ospfGeneralGroup 10 } - - ospfExtLsdbLimit OBJECT-TYPE - SYNTAX Integer32 (-1..'7FFFFFFF'h) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The maximum number of non-default AS- - external-LSAs entries that can be stored in the - link-state database. If the value is -1, then - there is no limit. - - When the number of non-default AS-external-LSAs - in a router's link-state database reaches - ospfExtLsdbLimit, the router enters Overflow- - State. The router never holds more than - ospfExtLsdbLimit non-default AS-external-LSAs - in its database. OspfExtLsdbLimit MUST be set - identically in all routers attached to the OSPF - backbone and/or any regular OSPF area. (i.e., - OSPF stub areas and NSSAs are excluded)." - DEFVAL { -1 } - ::= { ospfGeneralGroup 11 } - - ospfMulticastExtensions OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "A Bit Mask indicating whether the router is - forwarding IP multicast (Class D) datagrams - based on the algorithms defined in the Multi- - cast Extensions to OSPF. - - Bit 0, if set, indicates that the router can - forward IP multicast datagrams in the router's - directly attached areas (called intra-area mul- - ticast routing). - - Bit 1, if set, indicates that the router can - forward IP multicast datagrams between OSPF - areas (called inter-area multicast routing). - - Bit 2, if set, indicates that the router can - forward IP multicast datagrams between Auto- - nomous Systems (called inter-AS multicast rout- - ing). - - Only certain combinations of bit settings are - allowed, namely: 0 (no multicast forwarding is - enabled), 1 (intra-area multicasting only), 3 - (intra-area and inter-area multicasting), 5 - (intra-area and inter-AS multicasting) and 7 - (multicasting everywhere). By default, no mul- - ticast forwarding is enabled." - DEFVAL { 0 } - ::= { ospfGeneralGroup 12 } - - ospfExitOverflowInterval OBJECT-TYPE - SYNTAX PositiveInteger - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The number of seconds that, after entering - OverflowState, a router will attempt to leave - OverflowState. This allows the router to again - originate non-default AS-external-LSAs. When - set to 0, the router will not leave Overflow- - State until restarted." - DEFVAL { 0 } - ::= { ospfGeneralGroup 13 } - - - ospfDemandExtensions OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "The router's support for demand routing." - REFERENCE - "OSPF Version 2, Appendix on Demand Routing" - ::= { ospfGeneralGroup 14 } - - --- The OSPF Area Data Structure contains information --- regarding the various areas. The interfaces and --- virtual links are configured as part of these areas. --- Area 0.0.0.0, by definition, is the Backbone Area - - - ospfAreaTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfAreaEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information describing the configured parame- - ters and cumulative statistics of the router's - attached areas." - REFERENCE - "OSPF Version 2, Section 6 The Area Data Struc- - ture" - ::= { ospf 2 } - - - ospfAreaEntry OBJECT-TYPE - SYNTAX OspfAreaEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information describing the configured parame- - ters and cumulative statistics of one of the - router's attached areas." - INDEX { ospfAreaId } - ::= { ospfAreaTable 1 } - -OspfAreaEntry ::= - SEQUENCE { - ospfAreaId - AreaID, - ospfAuthType - Integer32, - ospfImportAsExtern - INTEGER, - ospfSpfRuns - Counter32, - ospfAreaBdrRtrCount - Gauge32, - ospfAsBdrRtrCount - Gauge32, - ospfAreaLsaCount - Gauge32, - ospfAreaLsaCksumSum - Integer32, - ospfAreaSummary - INTEGER, - ospfAreaStatus - RowStatus - } - - ospfAreaId OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A 32-bit integer uniquely identifying an area. - Area ID 0.0.0.0 is used for the OSPF backbone." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfAreaEntry 1 } - - - ospfAuthType OBJECT-TYPE - SYNTAX Integer32 - -- none (0), - -- simplePassword (1) - -- md5 (2) - -- reserved for specification by IANA (> 2) - MAX-ACCESS read-create - STATUS obsolete - DESCRIPTION - "The authentication type specified for an area. - Additional authentication types may be assigned - locally on a per Area basis." - REFERENCE - "OSPF Version 2, Appendix E Authentication" - DEFVAL { 0 } -- no authentication, by default - ::= { ospfAreaEntry 2 } - - ospfImportAsExtern OBJECT-TYPE - SYNTAX INTEGER { - importExternal (1), - importNoExternal (2), - importNssa (3) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The area's support for importing AS external - link- state advertisements." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - DEFVAL { importExternal } - ::= { ospfAreaEntry 3 } - - - ospfSpfRuns OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times that the intra-area route - table has been calculated using this area's - link-state database. This is typically done - using Dijkstra's algorithm." - ::= { ospfAreaEntry 4 } - - - ospfAreaBdrRtrCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of area border routers reach- - able within this area. This is initially zero, - and is calculated in each SPF Pass." - ::= { ospfAreaEntry 5 } - - ospfAsBdrRtrCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of Autonomous System border - routers reachable within this area. This is - initially zero, and is calculated in each SPF - Pass." - ::= { ospfAreaEntry 6 } - - - ospfAreaLsaCount OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of link-state advertisements - in this area's link-state database, excluding - AS External LSA's." - ::= { ospfAreaEntry 7 } - - - ospfAreaLsaCksumSum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32-bit unsigned sum of the link-state ad- - vertisements' LS checksums contained in this - area's link-state database. This sum excludes - external (LS type 5) link-state advertisements. - The sum can be used to determine if there has - been a change in a router's link state data- - base, and to compare the link-state database of - two routers." - DEFVAL { 0 } - ::= { ospfAreaEntry 8 } - - ospfAreaSummary OBJECT-TYPE - SYNTAX INTEGER { - noAreaSummary (1), - sendAreaSummary (2) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The variable ospfAreaSummary controls the im- - port of summary LSAs into stub areas. It has - no effect on other areas. - - If it is noAreaSummary, the router will neither - originate nor propagate summary LSAs into the - stub area. It will rely entirely on its de- - fault route. - - If it is sendAreaSummary, the router will both - summarize and propagate summary LSAs." - DEFVAL { noAreaSummary } - ::= { ospfAreaEntry 9 } - - - ospfAreaStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfAreaEntry 10 } - - --- OSPF Area Default Metric Table - --- The OSPF Area Default Metric Table describes the metrics --- that a default Area Border Router will advertise into a --- Stub area. - - - ospfStubAreaTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfStubAreaEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The set of metrics that will be advertised by - a default Area Border Router into a stub area." - REFERENCE - "OSPF Version 2, Appendix C.2, Area Parameters" - ::= { ospf 3 } - - - ospfStubAreaEntry OBJECT-TYPE - SYNTAX OspfStubAreaEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The metric for a given Type of Service that - will be advertised by a default Area Border - Router into a stub area." - REFERENCE - "OSPF Version 2, Appendix C.2, Area Parameters" - INDEX { ospfStubAreaId, ospfStubTOS } - ::= { ospfStubAreaTable 1 } - -OspfStubAreaEntry ::= - SEQUENCE { - ospfStubAreaId - AreaID, - ospfStubTOS - TOSType, - ospfStubMetric - BigMetric, - ospfStubStatus - RowStatus, - ospfStubMetricType - INTEGER - } - - ospfStubAreaId OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32 bit identifier for the Stub Area. On - creation, this can be derived from the in- - stance." - ::= { ospfStubAreaEntry 1 } - - - ospfStubTOS OBJECT-TYPE - SYNTAX TOSType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Type of Service associated with the - metric. On creation, this can be derived from - the instance." - ::= { ospfStubAreaEntry 2 } - - - ospfStubMetric OBJECT-TYPE - SYNTAX BigMetric - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The metric value applied at the indicated type - of service. By default, this equals the least - metric at the type of service among the inter- - faces to other areas." - ::= { ospfStubAreaEntry 3 } - - - ospfStubStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfStubAreaEntry 4 } - - ospfStubMetricType OBJECT-TYPE - SYNTAX INTEGER { - ospfMetric (1), -- OSPF Metric - comparableCost (2), -- external type 1 - nonComparable (3) -- external type 2 - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the type of metric ad- - vertised as a default route." - DEFVAL { ospfMetric } - ::= { ospfStubAreaEntry 5 } - --- OSPF Link State Database - --- The Link State Database contains the Link State --- Advertisements from throughout the areas that the --- device is attached to. - - - ospfLsdbTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPF Process's Link State Database." - REFERENCE - "OSPF Version 2, Section 12 Link State Adver- - tisements" - ::= { ospf 4 } - - - ospfLsdbEntry OBJECT-TYPE - SYNTAX OspfLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A single Link State Advertisement." - INDEX { ospfLsdbAreaId, ospfLsdbType, - ospfLsdbLsid, ospfLsdbRouterId } - ::= { ospfLsdbTable 1 } - -OspfLsdbEntry ::= - SEQUENCE { - ospfLsdbAreaId - AreaID, - ospfLsdbType - INTEGER, - ospfLsdbLsid - IpAddress, - ospfLsdbRouterId - RouterID, - ospfLsdbSequence - Integer32, - ospfLsdbAge - Integer32, - ospfLsdbChecksum - Integer32, - ospfLsdbAdvertisement - OCTET STRING - } - ospfLsdbAreaId OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32 bit identifier of the Area from which - the LSA was received." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfLsdbEntry 1 } - --- External Link State Advertisements are permitted --- for backward compatibility, but should be displayed in --- the ospfExtLsdbTable rather than here. - - ospfLsdbType OBJECT-TYPE - SYNTAX INTEGER { - routerLink (1), - networkLink (2), - summaryLink (3), - asSummaryLink (4), - asExternalLink (5), -- but see ospfExtLsdbTable - multicastLink (6), - nssaExternalLink (7) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The type of the link state advertisement. - Each link state type has a separate advertise- - ment format." - REFERENCE - "OSPF Version 2, Appendix A.4.1 The Link State - Advertisement header" - ::= { ospfLsdbEntry 2 } - - ospfLsdbLsid OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Link State ID is an LS Type Specific field - containing either a Router ID or an IP Address; - it identifies the piece of the routing domain - that is being described by the advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.4 Link State ID" - ::= { ospfLsdbEntry 3 } - ospfLsdbRouterId OBJECT-TYPE - SYNTAX RouterID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32 bit number that uniquely identifies the - originating router in the Autonomous System." - REFERENCE - "OSPF Version 2, Appendix C.1 Global parameters" - ::= { ospfLsdbEntry 4 } - --- Note that the OSPF Sequence Number is a 32 bit signed --- integer. It starts with the value '80000001'h, --- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h --- Thus, a typical sequence number will be very negative. - - ospfLsdbSequence OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The sequence number field is a signed 32-bit - integer. It is used to detect old and dupli- - cate link state advertisements. The space of - sequence numbers is linearly ordered. The - larger the sequence number the more recent the - advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.6 LS sequence - number" - ::= { ospfLsdbEntry 5 } - - - ospfLsdbAge OBJECT-TYPE - SYNTAX Integer32 -- Should be 0..MaxAge - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the age of the link state adver- - tisement in seconds." - REFERENCE - "OSPF Version 2, Section 12.1.1 LS age" - ::= { ospfLsdbEntry 6 } - - ospfLsdbChecksum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the checksum of the complete - contents of the advertisement, excepting the - age field. The age field is excepted so that - an advertisement's age can be incremented - without updating the checksum. The checksum - used is the same that is used for ISO connec- - tionless datagrams; it is commonly referred to - as the Fletcher checksum." - REFERENCE - "OSPF Version 2, Section 12.1.7 LS checksum" - ::= { ospfLsdbEntry 7 } - - - ospfLsdbAdvertisement OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (1..65535)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The entire Link State Advertisement, including - its header." - REFERENCE - "OSPF Version 2, Section 12 Link State Adver- - tisements" - ::= { ospfLsdbEntry 8 } - - --- Address Range Table - --- The Address Range Table acts as an adjunct to the Area --- Table; It describes those Address Range Summaries that --- are configured to be propagated from an Area to reduce --- the amount of information about it which is known beyond --- its borders. - - ospfAreaRangeTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfAreaRangeEntry - MAX-ACCESS not-accessible - STATUS obsolete - DESCRIPTION - "A range if IP addresses specified by an IP - address/IP network mask pair. For example, - class B address range of X.X.X.X with a network - mask of 255.255.0.0 includes all IP addresses - from X.X.0.0 to X.X.255.255" - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospf 5 } - ospfAreaRangeEntry OBJECT-TYPE - SYNTAX OspfAreaRangeEntry - MAX-ACCESS not-accessible - STATUS obsolete - DESCRIPTION - "A range if IP addresses specified by an IP - address/IP network mask pair. For example, - class B address range of X.X.X.X with a network - mask of 255.255.0.0 includes all IP addresses - from X.X.0.0 to X.X.255.255" - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - INDEX { ospfAreaRangeAreaId, ospfAreaRangeNet } - ::= { ospfAreaRangeTable 1 } - -OspfAreaRangeEntry ::= - SEQUENCE { - ospfAreaRangeAreaId - AreaID, - ospfAreaRangeNet - IpAddress, - ospfAreaRangeMask - IpAddress, - ospfAreaRangeStatus - RowStatus, - ospfAreaRangeEffect - INTEGER - } - - ospfAreaRangeAreaId OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The Area the Address Range is to be found - within." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfAreaRangeEntry 1 } - - - ospfAreaRangeNet OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS obsolete - DESCRIPTION - "The IP Address of the Net or Subnet indicated - by the range." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfAreaRangeEntry 2 } - - - ospfAreaRangeMask OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-create - STATUS obsolete - DESCRIPTION - "The Subnet Mask that pertains to the Net or - Subnet." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfAreaRangeEntry 3 } - - ospfAreaRangeStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS obsolete - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfAreaRangeEntry 4 } - - - ospfAreaRangeEffect OBJECT-TYPE - SYNTAX INTEGER { - advertiseMatching (1), - doNotAdvertiseMatching (2) - } - MAX-ACCESS read-create - STATUS obsolete - DESCRIPTION - "Subnets subsumed by ranges either trigger the - advertisement of the indicated summary (adver- - tiseMatching), or result in the subnet's not - being advertised at all outside the area." - DEFVAL { advertiseMatching } - ::= { ospfAreaRangeEntry 5 } - - - --- OSPF Host Table - --- The Host/Metric Table indicates what hosts are directly --- attached to the Router, and what metrics and types of --- service should be advertised for them. - - ospfHostTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfHostEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The list of Hosts, and their metrics, that the - router will advertise as host routes." - REFERENCE - "OSPF Version 2, Appendix C.6 Host route param- - eters" - ::= { ospf 6 } - - - ospfHostEntry OBJECT-TYPE - SYNTAX OspfHostEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A metric to be advertised, for a given type of - service, when a given host is reachable." - INDEX { ospfHostIpAddress, ospfHostTOS } - ::= { ospfHostTable 1 } - -OspfHostEntry ::= - SEQUENCE { - ospfHostIpAddress - IpAddress, - ospfHostTOS - TOSType, - ospfHostMetric - Metric, - ospfHostStatus - RowStatus, - ospfHostAreaID - AreaID - } - - ospfHostIpAddress OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP Address of the Host." - REFERENCE - "OSPF Version 2, Appendix C.6 Host route parame- - ters" - ::= { ospfHostEntry 1 } - - - ospfHostTOS OBJECT-TYPE - SYNTAX TOSType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Type of Service of the route being config- - ured." - REFERENCE - "OSPF Version 2, Appendix C.6 Host route parame- - ters" - ::= { ospfHostEntry 2 } - - - ospfHostMetric OBJECT-TYPE - SYNTAX Metric - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The Metric to be advertised." - REFERENCE - "OSPF Version 2, Appendix C.6 Host route parame- - ters" - ::= { ospfHostEntry 3 } - - ospfHostStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfHostEntry 4 } - - - ospfHostAreaID OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Area the Host Entry is to be found within. - By default, the area that a subsuming OSPF in- - terface is in, or 0.0.0.0" - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfHostEntry 5 } - - --- OSPF Interface Table - --- The OSPF Interface Table augments the ipAddrTable --- with OSPF specific information. - - ospfIfTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfIfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPF Interface Table describes the inter- - faces from the viewpoint of OSPF." - REFERENCE - "OSPF Version 2, Appendix C.3 Router interface - parameters" - ::= { ospf 7 } - - - ospfIfEntry OBJECT-TYPE - SYNTAX OspfIfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPF Interface Entry describes one inter- - face from the viewpoint of OSPF." - INDEX { ospfIfIpAddress, ospfAddressLessIf } - ::= { ospfIfTable 1 } - -OspfIfEntry ::= - SEQUENCE { - ospfIfIpAddress - IpAddress, - ospfAddressLessIf - Integer32, - ospfIfAreaId - AreaID, - ospfIfType - INTEGER, - ospfIfAdminStat - Status, - ospfIfRtrPriority - DesignatedRouterPriority, - ospfIfTransitDelay - UpToMaxAge, - ospfIfRetransInterval - UpToMaxAge, - ospfIfHelloInterval - HelloRange, - ospfIfRtrDeadInterval - PositiveInteger, - ospfIfPollInterval - PositiveInteger, - ospfIfState - INTEGER, - ospfIfDesignatedRouter - IpAddress, - ospfIfBackupDesignatedRouter - IpAddress, - ospfIfEvents - Counter32, - ospfIfAuthType - INTEGER, - ospfIfAuthKey - OCTET STRING, - ospfIfStatus - RowStatus, - ospfIfMulticastForwarding - INTEGER, - ospfIfDemand - TruthValue - } - - ospfIfIpAddress OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP address of this OSPF interface." - ::= { ospfIfEntry 1 } - - ospfAddressLessIf OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "For the purpose of easing the instancing of - addressed and addressless interfaces; This - variable takes the value 0 on interfaces with - IP Addresses, and the corresponding value of - ifIndex for interfaces having no IP Address." - ::= { ospfIfEntry 2 } - ospfIfAreaId OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "A 32-bit integer uniquely identifying the area - to which the interface connects. Area ID - 0.0.0.0 is used for the OSPF backbone." - DEFVAL { '00000000'H } -- 0.0.0.0 - ::= { ospfIfEntry 3 } - - ospfIfType OBJECT-TYPE - SYNTAX INTEGER { - broadcast (1), - nbma (2), - pointToPoint (3), - pointToMultipoint (5) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The OSPF interface type. - - By way of a default, this field may be intuited - from the corresponding value of ifType. Broad- - cast LANs, such as Ethernet and IEEE 802.5, - take the value 'broadcast', X.25 and similar - technologies take the value 'nbma', and links - that are definitively point to point take the - value 'pointToPoint'." - ::= { ospfIfEntry 4 } - - - ospfIfAdminStat OBJECT-TYPE - SYNTAX Status - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The OSPF interface's administrative status. - The value formed on the interface, and the in- - terface will be advertised as an internal route - to some area. The value 'disabled' denotes - that the interface is external to OSPF." - DEFVAL { enabled } - ::= { ospfIfEntry 5 } - - ospfIfRtrPriority OBJECT-TYPE - SYNTAX DesignatedRouterPriority - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The priority of this interface. Used in - multi-access networks, this field is used in - the designated router election algorithm. The - value 0 signifies that the router is not eligi- - ble to become the designated router on this - particular network. In the event of a tie in - this value, routers will use their Router ID as - a tie breaker." - DEFVAL { 1 } - ::= { ospfIfEntry 6 } - - - ospfIfTransitDelay OBJECT-TYPE - SYNTAX UpToMaxAge - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The estimated number of seconds it takes to - transmit a link state update packet over this - interface." - DEFVAL { 1 } - ::= { ospfIfEntry 7 } - - - ospfIfRetransInterval OBJECT-TYPE - SYNTAX UpToMaxAge - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds between link-state ad- - vertisement retransmissions, for adjacencies - belonging to this interface. This value is - also used when retransmitting database descrip- - tion and link-state request packets." - DEFVAL { 5 } - ::= { ospfIfEntry 8 } - - - ospfIfHelloInterval OBJECT-TYPE - SYNTAX HelloRange - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The length of time, in seconds, between the - Hello packets that the router sends on the in- - terface. This value must be the same for all - routers attached to a common network." - DEFVAL { 10 } - ::= { ospfIfEntry 9 } - - - ospfIfRtrDeadInterval OBJECT-TYPE - SYNTAX PositiveInteger - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds that a router's Hello - packets have not been seen before it's neigh- - bors declare the router down. This should be - some multiple of the Hello interval. This - value must be the same for all routers attached - to a common network." - DEFVAL { 40 } - ::= { ospfIfEntry 10 } - - - ospfIfPollInterval OBJECT-TYPE - SYNTAX PositiveInteger - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The larger time interval, in seconds, between - the Hello packets sent to an inactive non- - broadcast multi- access neighbor." - DEFVAL { 120 } - ::= { ospfIfEntry 11 } - - - ospfIfState OBJECT-TYPE - SYNTAX INTEGER { - down (1), - loopback (2), - waiting (3), - pointToPoint (4), - designatedRouter (5), - backupDesignatedRouter (6), - otherDesignatedRouter (7) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The OSPF Interface State." - DEFVAL { down } - ::= { ospfIfEntry 12 } - - - ospfIfDesignatedRouter OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP Address of the Designated Router." - DEFVAL { '00000000'H } -- 0.0.0.0 - ::= { ospfIfEntry 13 } - - - ospfIfBackupDesignatedRouter OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP Address of the Backup Designated - Router." - DEFVAL { '00000000'H } -- 0.0.0.0 - ::= { ospfIfEntry 14 } - - ospfIfEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times this OSPF interface has - changed its state, or an error has occurred." - ::= { ospfIfEntry 15 } - - - ospfIfAuthKey OBJECT-TYPE - SYNTAX OCTET STRING (SIZE (0..256)) - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The Authentication Key. If the Area's Author- - ization Type is simplePassword, and the key - length is shorter than 8 octets, the agent will - left adjust and zero fill to 8 octets. - - Note that unauthenticated interfaces need no - authentication key, and simple password authen- - tication cannot use a key of more than 8 oc- - tets. Larger keys are useful only with authen- - tication mechanisms not specified in this docu- - ment. - - When read, ospfIfAuthKey always returns an Oc- - tet String of length zero." - REFERENCE - "OSPF Version 2, Section 9 The Interface Data - Structure" - DEFVAL { '0000000000000000'H } -- 0.0.0.0.0.0.0.0 - ::= { ospfIfEntry 16 } - - ospfIfStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfIfEntry 17 } - - - ospfIfMulticastForwarding OBJECT-TYPE - SYNTAX INTEGER { - blocked (1), -- no multicast forwarding - multicast (2), -- using multicast address - unicast (3) -- to each OSPF neighbor - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The way multicasts should forwarded on this - interface; not forwarded, forwarded as data - link multicasts, or forwarded as data link uni- - casts. Data link multicasting is not meaning- - ful on point to point and NBMA interfaces, and - setting ospfMulticastForwarding to 0 effective- - ly disables all multicast forwarding." - DEFVAL { blocked } - ::= { ospfIfEntry 18 } - - - ospfIfDemand OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Indicates whether Demand OSPF procedures (hel- - lo suppression to FULL neighbors and setting the - DoNotAge flag on proogated LSAs) should be per- - formed on this interface." - DEFVAL { false } - ::= { ospfIfEntry 19 } - - - ospfIfAuthType OBJECT-TYPE - SYNTAX INTEGER (0..255) - -- none (0), - -- simplePassword (1) - -- md5 (2) - -- reserved for specification by IANA (> 2) - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The authentication type specified for an in- - terface. Additional authentication types may - be assigned locally." - REFERENCE - "OSPF Version 2, Appendix E Authentication" - DEFVAL { 0 } -- no authentication, by default - ::= { ospfIfEntry 20 } - - --- OSPF Interface Metric Table - --- The Metric Table describes the metrics to be advertised --- for a specified interface at the various types of service. --- As such, this table is an adjunct of the OSPF Interface --- Table. - --- Types of service, as defined by RFC 791, have the ability --- to request low delay, high bandwidth, or reliable linkage. - --- For the purposes of this specification, the measure of --- bandwidth - --- Metric = 10^8 / ifSpeed - --- is the default value. For multiple link interfaces, note --- that ifSpeed is the sum of the individual link speeds. --- This yields a number having the following typical values: - --- Network Type/bit rate Metric - --- >= 100 MBPS 1 --- Ethernet/802.3 10 --- E1 48 --- T1 (ESF) 65 --- 64 KBPS 1562 --- 56 KBPS 1785 --- 19.2 KBPS 5208 --- 9.6 KBPS 10416 - --- Routes that are not specified use the default (TOS 0) metric - - ospfIfMetricTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfIfMetricEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The TOS metrics for a non-virtual interface - identified by the interface index." - REFERENCE - "OSPF Version 2, Appendix C.3 Router interface - parameters" - ::= { ospf 8 } - - ospfIfMetricEntry OBJECT-TYPE - SYNTAX OspfIfMetricEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A particular TOS metric for a non-virtual in- - terface identified by the interface index." - REFERENCE - "OSPF Version 2, Appendix C.3 Router interface - parameters" - INDEX { ospfIfMetricIpAddress, - ospfIfMetricAddressLessIf, - ospfIfMetricTOS } - ::= { ospfIfMetricTable 1 } - -OspfIfMetricEntry ::= - SEQUENCE { - ospfIfMetricIpAddress - IpAddress, - ospfIfMetricAddressLessIf - Integer32, - ospfIfMetricTOS - TOSType, - ospfIfMetricValue - Metric, - ospfIfMetricStatus - RowStatus - } - - ospfIfMetricIpAddress OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP address of this OSPF interface. On row - creation, this can be derived from the in- - stance." - ::= { ospfIfMetricEntry 1 } - - ospfIfMetricAddressLessIf OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "For the purpose of easing the instancing of - addressed and addressless interfaces; This - variable takes the value 0 on interfaces with - IP Addresses, and the value of ifIndex for in- - terfaces having no IP Address. On row crea- - tion, this can be derived from the instance." - ::= { ospfIfMetricEntry 2 } - - - ospfIfMetricTOS OBJECT-TYPE - SYNTAX TOSType - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The type of service metric being referenced. - On row creation, this can be derived from the - instance." - ::= { ospfIfMetricEntry 3 } - - - ospfIfMetricValue OBJECT-TYPE - SYNTAX Metric - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The metric of using this type of service on - this interface. The default value of the TOS 0 - Metric is 10^8 / ifSpeed." - ::= { ospfIfMetricEntry 4 } - - ospfIfMetricStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfIfMetricEntry 5 } - - --- OSPF Virtual Interface Table - --- The Virtual Interface Table describes the virtual --- links that the OSPF Process is configured to --- carry on. - - ospfVirtIfTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfVirtIfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information about this router's virtual inter- - faces." - REFERENCE - "OSPF Version 2, Appendix C.4 Virtual link - parameters" - ::= { ospf 9 } - - - ospfVirtIfEntry OBJECT-TYPE - SYNTAX OspfVirtIfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information about a single Virtual Interface." - INDEX { ospfVirtIfAreaId, ospfVirtIfNeighbor } - ::= { ospfVirtIfTable 1 } - -OspfVirtIfEntry ::= - SEQUENCE { - ospfVirtIfAreaId - AreaID, - ospfVirtIfNeighbor - RouterID, - ospfVirtIfTransitDelay - UpToMaxAge, - ospfVirtIfRetransInterval - UpToMaxAge, - ospfVirtIfHelloInterval - HelloRange, - ospfVirtIfRtrDeadInterval - PositiveInteger, - ospfVirtIfState - INTEGER, - ospfVirtIfEvents - Counter32, - ospfVirtIfAuthType - INTEGER, - ospfVirtIfAuthKey - OCTET STRING, - ospfVirtIfStatus - RowStatus - } - - ospfVirtIfAreaId OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Transit Area that the Virtual Link - traverses. By definition, this is not 0.0.0.0" - ::= { ospfVirtIfEntry 1 } - - - ospfVirtIfNeighbor OBJECT-TYPE - SYNTAX RouterID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Router ID of the Virtual Neighbor." - ::= { ospfVirtIfEntry 2 } - - - ospfVirtIfTransitDelay OBJECT-TYPE - SYNTAX UpToMaxAge - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The estimated number of seconds it takes to - transmit a link- state update packet over this - interface." - DEFVAL { 1 } - ::= { ospfVirtIfEntry 3 } - - - ospfVirtIfRetransInterval OBJECT-TYPE - SYNTAX UpToMaxAge - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds between link-state ad- - vertisement retransmissions, for adjacencies - belonging to this interface. This value is - also used when retransmitting database descrip- - tion and link-state request packets. This - value should be well over the expected round- - trip time." - DEFVAL { 5 } - ::= { ospfVirtIfEntry 4 } - - - ospfVirtIfHelloInterval OBJECT-TYPE - SYNTAX HelloRange - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The length of time, in seconds, between the - Hello packets that the router sends on the in- - terface. This value must be the same for the - virtual neighbor." - DEFVAL { 10 } - ::= { ospfVirtIfEntry 5 } - - - ospfVirtIfRtrDeadInterval OBJECT-TYPE - SYNTAX PositiveInteger - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The number of seconds that a router's Hello - packets have not been seen before it's neigh- - bors declare the router down. This should be - some multiple of the Hello interval. This - value must be the same for the virtual neigh- - bor." - DEFVAL { 60 } - ::= { ospfVirtIfEntry 6 } - - - ospfVirtIfState OBJECT-TYPE - SYNTAX INTEGER { - down (1), -- these use the same encoding - pointToPoint (4) -- as the ospfIfTable - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "OSPF virtual interface states." - DEFVAL { down } - ::= { ospfVirtIfEntry 7 } - - - ospfVirtIfEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of state changes or error events on - this Virtual Link" - ::= { ospfVirtIfEntry 8 } - - - ospfVirtIfAuthKey OBJECT-TYPE - SYNTAX OCTET STRING (SIZE(0..256)) - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "If Authentication Type is simplePassword, the - device will left adjust and zero fill to 8 oc- - tets. - - Note that unauthenticated interfaces need no - authentication key, and simple password authen- - tication cannot use a key of more than 8 oc- - tets. Larger keys are useful only with authen- - tication mechanisms not specified in this docu- - ment. - - When read, ospfVifAuthKey always returns a - string of length zero." - REFERENCE - "OSPF Version 2, Section 9 The Interface Data - Structure" - DEFVAL { '0000000000000000'H } -- 0.0.0.0.0.0.0.0 - ::= { ospfVirtIfEntry 9 } - - - ospfVirtIfStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfVirtIfEntry 10 } - - - ospfVirtIfAuthType OBJECT-TYPE - SYNTAX INTEGER (0..255) - -- none (0), - -- simplePassword (1) - -- md5 (2) - -- reserved for specification by IANA (> 2) - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The authentication type specified for a virtu- - al interface. Additional authentication types - may be assigned locally." - REFERENCE - "OSPF Version 2, Appendix E Authentication" - DEFVAL { 0 } -- no authentication, by default - ::= { ospfVirtIfEntry 11 } - - --- OSPF Neighbor Table - --- The OSPF Neighbor Table describes all neighbors in --- the locality of the subject router. - - ospfNbrTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A table of non-virtual neighbor information." - REFERENCE - "OSPF Version 2, Section 10 The Neighbor Data - Structure" - ::= { ospf 10 } - - - ospfNbrEntry OBJECT-TYPE - SYNTAX OspfNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The information regarding a single neighbor." - REFERENCE - "OSPF Version 2, Section 10 The Neighbor Data - Structure" - INDEX { ospfNbrIpAddr, ospfNbrAddressLessIndex } - ::= { ospfNbrTable 1 } - -OspfNbrEntry ::= - SEQUENCE { - ospfNbrIpAddr - IpAddress, - ospfNbrAddressLessIndex - InterfaceIndex, - ospfNbrRtrId - RouterID, - ospfNbrOptions - Integer32, - ospfNbrPriority - DesignatedRouterPriority, - ospfNbrState - INTEGER, - ospfNbrEvents - Counter32, - ospfNbrLsRetransQLen - Gauge32, - ospfNbmaNbrStatus - RowStatus, - ospfNbmaNbrPermanence - INTEGER, - ospfNbrHelloSuppressed - TruthValue - } - - ospfNbrIpAddr OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP address this neighbor is using in its - IP Source Address. Note that, on addressless - links, this will not be 0.0.0.0, but the ad- - dress of another of the neighbor's interfaces." - ::= { ospfNbrEntry 1 } - - - ospfNbrAddressLessIndex OBJECT-TYPE - SYNTAX InterfaceIndex - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "On an interface having an IP Address, zero. - On addressless interfaces, the corresponding - value of ifIndex in the Internet Standard MIB. - On row creation, this can be derived from the - instance." - ::= { ospfNbrEntry 2 } - - - ospfNbrRtrId OBJECT-TYPE - SYNTAX RouterID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A 32-bit integer (represented as a type IpAd- - dress) uniquely identifying the neighboring - router in the Autonomous System." - DEFVAL { '00000000'H } -- 0.0.0.0 - ::= { ospfNbrEntry 3 } - - - ospfNbrOptions OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A Bit Mask corresponding to the neighbor's op- - tions field. - - Bit 0, if set, indicates that the system will - operate on Type of Service metrics other than - TOS 0. If zero, the neighbor will ignore all - metrics except the TOS 0 metric. - - Bit 1, if set, indicates that the associated - area accepts and operates on external informa- - tion; if zero, it is a stub area. - - Bit 2, if set, indicates that the system is ca- - pable of routing IP Multicast datagrams; i.e., - that it implements the Multicast Extensions to - OSPF. - - Bit 3, if set, indicates that the associated - area is an NSSA. These areas are capable of - carrying type 7 external advertisements, which - are translated into type 5 external advertise- - ments at NSSA borders." - REFERENCE - "OSPF Version 2, Section 12.1.2 Options" - DEFVAL { 0 } - ::= { ospfNbrEntry 4 } - - - ospfNbrPriority OBJECT-TYPE - SYNTAX DesignatedRouterPriority - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The priority of this neighbor in the designat- - ed router election algorithm. The value 0 sig- - nifies that the neighbor is not eligible to be- - come the designated router on this particular - network." - DEFVAL { 1 } - ::= { ospfNbrEntry 5 } - - - ospfNbrState OBJECT-TYPE - SYNTAX INTEGER { - down (1), - attempt (2), - init (3), - twoWay (4), - exchangeStart (5), - exchange (6), - loading (7), - full (8) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The State of the relationship with this Neigh- - bor." - REFERENCE - "OSPF Version 2, Section 10.1 Neighbor States" - DEFVAL { down } - ::= { ospfNbrEntry 6 } - - - ospfNbrEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times this neighbor relationship - has changed state, or an error has occurred." - ::= { ospfNbrEntry 7 } - - - ospfNbrLsRetransQLen OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The current length of the retransmission - queue." - ::= { ospfNbrEntry 8 } - - - ospfNbmaNbrStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfNbrEntry 9 } - - - ospfNbmaNbrPermanence OBJECT-TYPE - SYNTAX INTEGER { - dynamic (1), -- learned through protocol - permanent (2) -- configured address - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. 'dynamic' and 'permanent' refer to how - the neighbor became known." - DEFVAL { permanent } - ::= { ospfNbrEntry 10 } - - - ospfNbrHelloSuppressed OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates whether Hellos are being suppressed - to the neighbor" - ::= { ospfNbrEntry 11 } - - --- OSPF Virtual Neighbor Table - --- This table describes all virtual neighbors. --- Since Virtual Links are configured in the --- virtual interface table, this table is read-only. - - ospfVirtNbrTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfVirtNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A table of virtual neighbor information." - REFERENCE - "OSPF Version 2, Section 15 Virtual Links" - ::= { ospf 11 } - - - ospfVirtNbrEntry OBJECT-TYPE - SYNTAX OspfVirtNbrEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Virtual neighbor information." - INDEX { ospfVirtNbrArea, ospfVirtNbrRtrId } - ::= { ospfVirtNbrTable 1 } - -OspfVirtNbrEntry ::= - SEQUENCE { - ospfVirtNbrArea - AreaID, - ospfVirtNbrRtrId - RouterID, - ospfVirtNbrIpAddr - IpAddress, - ospfVirtNbrOptions - Integer32, - ospfVirtNbrState - INTEGER, - ospfVirtNbrEvents - Counter32, - ospfVirtNbrLsRetransQLen - Gauge32, - ospfVirtNbrHelloSuppressed - TruthValue - } - - ospfVirtNbrArea OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Transit Area Identifier." - ::= { ospfVirtNbrEntry 1 } - - - ospfVirtNbrRtrId OBJECT-TYPE - SYNTAX RouterID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A 32-bit integer uniquely identifying the - neighboring router in the Autonomous System." - ::= { ospfVirtNbrEntry 2 } - - - ospfVirtNbrIpAddr OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP address this Virtual Neighbor is us- - ing." - ::= { ospfVirtNbrEntry 3 } - - - ospfVirtNbrOptions OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "A Bit Mask corresponding to the neighbor's op- - tions field. - - Bit 1, if set, indicates that the system will - operate on Type of Service metrics other than - TOS 0. If zero, the neighbor will ignore all - metrics except the TOS 0 metric. - - Bit 2, if set, indicates that the system is - Network Multicast capable; ie, that it imple- - ments OSPF Multicast Routing." - ::= { ospfVirtNbrEntry 4 } - ospfVirtNbrState OBJECT-TYPE - SYNTAX INTEGER { - down (1), - attempt (2), - init (3), - twoWay (4), - exchangeStart (5), - exchange (6), - loading (7), - full (8) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The state of the Virtual Neighbor Relation- - ship." - ::= { ospfVirtNbrEntry 5 } - - - ospfVirtNbrEvents OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of times this virtual link has - changed its state, or an error has occurred." - ::= { ospfVirtNbrEntry 6 } - - - ospfVirtNbrLsRetransQLen OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The current length of the retransmission - queue." - ::= { ospfVirtNbrEntry 7 } - - - ospfVirtNbrHelloSuppressed OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indicates whether Hellos are being suppressed - to the neighbor" - ::= { ospfVirtNbrEntry 8 } - --- OSPF Link State Database, External - --- The Link State Database contains the Link State --- Advertisements from throughout the areas that the --- device is attached to. - --- This table is identical to the OSPF LSDB Table in --- format, but contains only External Link State --- Advertisements. The purpose is to allow external --- LSAs to be displayed once for the router rather --- than once in each non-stub area. - - ospfExtLsdbTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfExtLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "The OSPF Process's Links State Database." - REFERENCE - "OSPF Version 2, Section 12 Link State Adver- - tisements" - ::= { ospf 12 } - - - ospfExtLsdbEntry OBJECT-TYPE - SYNTAX OspfExtLsdbEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A single Link State Advertisement." - INDEX { ospfExtLsdbType, ospfExtLsdbLsid, ospfExtLsdbRouterId } - ::= { ospfExtLsdbTable 1 } - -OspfExtLsdbEntry ::= - SEQUENCE { - ospfExtLsdbType - INTEGER, - ospfExtLsdbLsid - IpAddress, - ospfExtLsdbRouterId - RouterID, - ospfExtLsdbSequence - Integer32, - ospfExtLsdbAge - Integer32, - ospfExtLsdbChecksum - Integer32, - ospfExtLsdbAdvertisement - OCTET STRING - } - - ospfExtLsdbType OBJECT-TYPE - SYNTAX INTEGER { - asExternalLink (5) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The type of the link state advertisement. - Each link state type has a separate advertise- - ment format." - REFERENCE - "OSPF Version 2, Appendix A.4.1 The Link State - Advertisement header" - ::= { ospfExtLsdbEntry 1 } - - - ospfExtLsdbLsid OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Link State ID is an LS Type Specific field - containing either a Router ID or an IP Address; - it identifies the piece of the routing domain - that is being described by the advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.4 Link State ID" - ::= { ospfExtLsdbEntry 2 } - - - ospfExtLsdbRouterId OBJECT-TYPE - SYNTAX RouterID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The 32 bit number that uniquely identifies the - originating router in the Autonomous System." - REFERENCE - "OSPF Version 2, Appendix C.1 Global parameters" - ::= { ospfExtLsdbEntry 3 } - --- Note that the OSPF Sequence Number is a 32 bit signed --- integer. It starts with the value '80000001'h, --- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h --- Thus, a typical sequence number will be very negative. - ospfExtLsdbSequence OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The sequence number field is a signed 32-bit - integer. It is used to detect old and dupli- - cate link state advertisements. The space of - sequence numbers is linearly ordered. The - larger the sequence number the more recent the - advertisement." - REFERENCE - "OSPF Version 2, Section 12.1.6 LS sequence - number" - ::= { ospfExtLsdbEntry 4 } - - - ospfExtLsdbAge OBJECT-TYPE - SYNTAX Integer32 -- Should be 0..MaxAge - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the age of the link state adver- - tisement in seconds." - REFERENCE - "OSPF Version 2, Section 12.1.1 LS age" - ::= { ospfExtLsdbEntry 5 } - - - ospfExtLsdbChecksum OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "This field is the checksum of the complete - contents of the advertisement, excepting the - age field. The age field is excepted so that - an advertisement's age can be incremented - without updating the checksum. The checksum - used is the same that is used for ISO connec- - tionless datagrams; it is commonly referred to - as the Fletcher checksum." - REFERENCE - "OSPF Version 2, Section 12.1.7 LS checksum" - ::= { ospfExtLsdbEntry 6 } - - - ospfExtLsdbAdvertisement OBJECT-TYPE - SYNTAX OCTET STRING (SIZE(36)) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The entire Link State Advertisement, including - its header." - REFERENCE - "OSPF Version 2, Section 12 Link State Adver- - tisements" - ::= { ospfExtLsdbEntry 7 } - - --- OSPF Use of the CIDR Route Table - -ospfRouteGroup OBJECT IDENTIFIER ::= { ospf 13 } - --- The IP Forwarding Table defines a number of objects for use by --- the routing protocol to externalize its information. Most of --- the variables (ipForwardDest, ipForwardMask, ipForwardPolicy, --- ipForwardNextHop, ipForwardIfIndex, ipForwardType, --- ipForwardProto, ipForwardAge, and ipForwardNextHopAS) are --- defined there. - --- Those that leave some discretion are defined here. - --- ipCidrRouteProto is, of course, ospf (13). - --- ipCidrRouteAge is the time since the route was first calculated, --- as opposed to the time since the last SPF run. - --- ipCidrRouteInfo is an OBJECT IDENTIFIER for use by the routing --- protocol. The following values shall be found there depending --- on the way the route was calculated. - -ospfIntraArea OBJECT IDENTIFIER ::= { ospfRouteGroup 1 } -ospfInterArea OBJECT IDENTIFIER ::= { ospfRouteGroup 2 } -ospfExternalType1 OBJECT IDENTIFIER ::= { ospfRouteGroup 3 } -ospfExternalType2 OBJECT IDENTIFIER ::= { ospfRouteGroup 4 } - --- ipCidrRouteMetric1 is, by definition, the primary routing --- metric. Therefore, it should be the metric that route --- selection is based on. For intra-area and inter-area routes, --- it is an OSPF metric. For External Type 1 (comparable value) --- routes, it is an OSPF metric plus the External Metric. For --- external Type 2 (non-comparable value) routes, it is the --- external metric. - --- ipCidrRouteMetric2 is, by definition, a secondary routing --- metric. Therefore, it should be the metric that breaks a tie --- among routes having equal metric1 values and the same --- calculation rule. For intra-area, inter-area routes, and --- External Type 1 (comparable value) routes, it is unused. For --- external Type 2 (non-comparable value) routes, it is the metric --- to the AS border router. - --- ipCidrRouteMetric3, ipCidrRouteMetric4, and ipCidrRouteMetric5 are --- unused. - --- --- The OSPF Area Aggregate Table --- --- This table replaces the OSPF Area Summary Table, being an --- extension of that for CIDR routers. - - ospfAreaAggregateTable OBJECT-TYPE - SYNTAX SEQUENCE OF OspfAreaAggregateEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A range of IP addresses specified by an IP - address/IP network mask pair. For example, - class B address range of X.X.X.X with a network - mask of 255.255.0.0 includes all IP addresses - from X.X.0.0 to X.X.255.255. Note that if - ranges are configured such that one range sub- - sumes another range (e.g., 10.0.0.0 mask - 255.0.0.0 and 10.1.0.0 mask 255.255.0.0), the - most specific match is the preferred one." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospf 14 } - - - ospfAreaAggregateEntry OBJECT-TYPE - SYNTAX OspfAreaAggregateEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A range of IP addresses specified by an IP - address/IP network mask pair. For example, - class B address range of X.X.X.X with a network - mask of 255.255.0.0 includes all IP addresses - from X.X.0.0 to X.X.255.255. Note that if - ranges are range configured such that one range - subsumes another range (e.g., 10.0.0.0 mask - 255.0.0.0 and 10.1.0.0 mask 255.255.0.0), the - most specific match is the preferred one." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - INDEX { ospfAreaAggregateAreaID, ospfAreaAggregateLsdbType, - ospfAreaAggregateNet, ospfAreaAggregateMask } - ::= { ospfAreaAggregateTable 1 } - - -OspfAreaAggregateEntry ::= - SEQUENCE { - ospfAreaAggregateAreaID - AreaID, - ospfAreaAggregateLsdbType - INTEGER, - ospfAreaAggregateNet - IpAddress, - ospfAreaAggregateMask - IpAddress, - ospfAreaAggregateStatus - RowStatus, - ospfAreaAggregateEffect - INTEGER - } - - ospfAreaAggregateAreaID OBJECT-TYPE - SYNTAX AreaID - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Area the Address Aggregate is to be found - within." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfAreaAggregateEntry 1 } - - - ospfAreaAggregateLsdbType OBJECT-TYPE - SYNTAX INTEGER { - summaryLink (3), - nssaExternalLink (7) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The type of the Address Aggregate. This field - specifies the Lsdb type that this Address Ag- - gregate applies to." - REFERENCE - "OSPF Version 2, Appendix A.4.1 The Link State - Advertisement header" - ::= { ospfAreaAggregateEntry 2 } - - - ospfAreaAggregateNet OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP Address of the Net or Subnet indicated - by the range." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfAreaAggregateEntry 3 } - - - ospfAreaAggregateMask OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The Subnet Mask that pertains to the Net or - Subnet." - REFERENCE - "OSPF Version 2, Appendix C.2 Area parameters" - ::= { ospfAreaAggregateEntry 4 } - - - ospfAreaAggregateStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable displays the status of the en- - try. Setting it to 'invalid' has the effect of - rendering it inoperative. The internal effect - (row removal) is implementation dependent." - ::= { ospfAreaAggregateEntry 5 } - - - ospfAreaAggregateEffect OBJECT-TYPE - SYNTAX INTEGER { - advertiseMatching (1), - doNotAdvertiseMatching (2) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Subnets subsumed by ranges either trigger the - advertisement of the indicated aggregate (ad- - vertiseMatching), or result in the subnet's not - being advertised at all outside the area." - DEFVAL { advertiseMatching } - ::= { ospfAreaAggregateEntry 6 } - - --- conformance information - -ospfConformance OBJECT IDENTIFIER ::= { ospf 15 } - -ospfGroups OBJECT IDENTIFIER ::= { ospfConformance 1 } -ospfCompliances OBJECT IDENTIFIER ::= { ospfConformance 2 } - --- compliance statements - - ospfCompliance MODULE-COMPLIANCE - STATUS current - DESCRIPTION - "The compliance statement " - MODULE -- this module - MANDATORY-GROUPS { - ospfBasicGroup, - ospfAreaGroup, - ospfStubAreaGroup, - ospfIfGroup, - ospfIfMetricGroup, - ospfVirtIfGroup, - ospfNbrGroup, - ospfVirtNbrGroup, - ospfAreaAggregateGroup - } - ::= { ospfCompliances 1 } - - --- units of conformance - - ospfBasicGroup OBJECT-GROUP - OBJECTS { - ospfRouterId, - ospfAdminStat, - ospfVersionNumber, - ospfAreaBdrRtrStatus, - ospfASBdrRtrStatus, - ospfExternLsaCount, - ospfExternLsaCksumSum, - ospfTOSSupport, - ospfOriginateNewLsas, - ospfRxNewLsas, - ospfExtLsdbLimit, - ospfMulticastExtensions, - ospfExitOverflowInterval, - ospfDemandExtensions - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems." - ::= { ospfGroups 1 } - - - ospfAreaGroup OBJECT-GROUP - OBJECTS { - ospfAreaId, - ospfImportAsExtern, - ospfSpfRuns, - ospfAreaBdrRtrCount, - ospfAsBdrRtrCount, - ospfAreaLsaCount, - ospfAreaLsaCksumSum, - ospfAreaSummary, - ospfAreaStatus - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems - supporting areas." - ::= { ospfGroups 2 } - - - ospfStubAreaGroup OBJECT-GROUP - OBJECTS { - ospfStubAreaId, - ospfStubTOS, - ospfStubMetric, - ospfStubStatus, - ospfStubMetricType - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems - supporting stub areas." - ::= { ospfGroups 3 } - - - ospfLsdbGroup OBJECT-GROUP - OBJECTS { - ospfLsdbAreaId, - ospfLsdbType, - ospfLsdbLsid, - ospfLsdbRouterId, - ospfLsdbSequence, - ospfLsdbAge, - ospfLsdbChecksum, - ospfLsdbAdvertisement - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems - that display their link state database." - ::= { ospfGroups 4 } - - - ospfAreaRangeGroup OBJECT-GROUP - OBJECTS { - ospfAreaRangeAreaId, - ospfAreaRangeNet, - ospfAreaRangeMask, - ospfAreaRangeStatus, - ospfAreaRangeEffect - } - STATUS obsolete - DESCRIPTION - "These objects are required for non-CIDR OSPF - systems that support multiple areas." - ::= { ospfGroups 5 } - - - ospfHostGroup OBJECT-GROUP - OBJECTS { - ospfHostIpAddress, - ospfHostTOS, - ospfHostMetric, - ospfHostStatus, - ospfHostAreaID - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems - that support attached hosts." - ::= { ospfGroups 6 } - - - ospfIfGroup OBJECT-GROUP - OBJECTS { - ospfIfIpAddress, - ospfAddressLessIf, - ospfIfAreaId, - ospfIfType, - ospfIfAdminStat, - ospfIfRtrPriority, - ospfIfTransitDelay, - ospfIfRetransInterval, - ospfIfHelloInterval, - ospfIfRtrDeadInterval, - ospfIfPollInterval, - ospfIfState, - ospfIfDesignatedRouter, - ospfIfBackupDesignatedRouter, - ospfIfEvents, - ospfIfAuthType, - ospfIfAuthKey, - ospfIfStatus, - ospfIfMulticastForwarding, - ospfIfDemand - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems." - ::= { ospfGroups 7 } - - - ospfIfMetricGroup OBJECT-GROUP - OBJECTS { - ospfIfMetricIpAddress, - ospfIfMetricAddressLessIf, - ospfIfMetricTOS, - ospfIfMetricValue, - ospfIfMetricStatus - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems." - ::= { ospfGroups 8 } - - - ospfVirtIfGroup OBJECT-GROUP - OBJECTS { - ospfVirtIfAreaId, - ospfVirtIfNeighbor, - ospfVirtIfTransitDelay, - ospfVirtIfRetransInterval, - ospfVirtIfHelloInterval, - ospfVirtIfRtrDeadInterval, - ospfVirtIfState, - ospfVirtIfEvents, - ospfVirtIfAuthType, - ospfVirtIfAuthKey, - ospfVirtIfStatus - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems." - ::= { ospfGroups 9 } - - - ospfNbrGroup OBJECT-GROUP - OBJECTS { - ospfNbrIpAddr, - ospfNbrAddressLessIndex, - ospfNbrRtrId, - ospfNbrOptions, - ospfNbrPriority, - ospfNbrState, - ospfNbrEvents, - ospfNbrLsRetransQLen, - ospfNbmaNbrStatus, - ospfNbmaNbrPermanence, - ospfNbrHelloSuppressed - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems." - ::= { ospfGroups 10 } - - - ospfVirtNbrGroup OBJECT-GROUP - OBJECTS { - ospfVirtNbrArea, - ospfVirtNbrRtrId, - ospfVirtNbrIpAddr, - ospfVirtNbrOptions, - ospfVirtNbrState, - ospfVirtNbrEvents, - ospfVirtNbrLsRetransQLen, - ospfVirtNbrHelloSuppressed - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems." - ::= { ospfGroups 11 } - - - ospfExtLsdbGroup OBJECT-GROUP - OBJECTS { - ospfExtLsdbType, - ospfExtLsdbLsid, - ospfExtLsdbRouterId, - ospfExtLsdbSequence, - ospfExtLsdbAge, - ospfExtLsdbChecksum, - ospfExtLsdbAdvertisement - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems - that display their link state database." - ::= { ospfGroups 12 } - - - ospfAreaAggregateGroup OBJECT-GROUP - OBJECTS { - ospfAreaAggregateAreaID, - ospfAreaAggregateLsdbType, - ospfAreaAggregateNet, - ospfAreaAggregateMask, - ospfAreaAggregateStatus, - ospfAreaAggregateEffect - } - STATUS current - DESCRIPTION - "These objects are required for OSPF systems." - ::= { ospfGroups 13 } - -END diff --git a/ospfd/OSPF-TRAP-MIB.txt b/ospfd/OSPF-TRAP-MIB.txt deleted file mode 100644 index 8a3ab990ce..0000000000 --- a/ospfd/OSPF-TRAP-MIB.txt +++ /dev/null @@ -1,443 +0,0 @@ -OSPF-TRAP-MIB DEFINITIONS ::= BEGIN - - IMPORTS - MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, IpAddress - FROM SNMPv2-SMI - MODULE-COMPLIANCE, OBJECT-GROUP - FROM SNMPv2-CONF - ospfRouterId, ospfIfIpAddress, ospfAddressLessIf, ospfIfState, - ospfVirtIfAreaId, ospfVirtIfNeighbor, ospfVirtIfState, - ospfNbrIpAddr, ospfNbrAddressLessIndex, ospfNbrRtrId, - ospfNbrState, ospfVirtNbrArea, ospfVirtNbrRtrId, ospfVirtNbrState, - ospfLsdbType, ospfLsdbLsid, ospfLsdbRouterId, ospfLsdbAreaId, - ospfExtLsdbLimit, ospf - FROM OSPF-MIB; - - ospfTrap MODULE-IDENTITY - LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995 - ORGANIZATION "IETF OSPF Working Group" - CONTACT-INFO - " Fred Baker - Postal: Cisco Systems - 519 Lado Drive - Santa Barbara, California 93111 - Tel: +1 805 681 0115 - E-Mail: fred@cisco.com - - Rob Coltun - Postal: RainbowBridge Communications - Tel: (301) 340-9416 - E-Mail: rcoltun@rainbow-bridge.com" - DESCRIPTION - "The MIB module to describe traps for the OSPF - Version 2 Protocol." - ::= { ospf 16 } - --- Trap Support Objects - --- The following are support objects for the OSPF traps. - -ospfTrapControl OBJECT IDENTIFIER ::= { ospfTrap 1 } -ospfTraps OBJECT IDENTIFIER ::= { ospfTrap 2 } - - ospfSetTrap OBJECT-TYPE - SYNTAX OCTET STRING (SIZE(4)) - MAX-ACCESS read-write - STATUS current - DESCRIPTION - "A four-octet string serving as a bit map for - the trap events defined by the OSPF traps. This - object is used to enable and disable specific - OSPF traps where a 1 in the bit field - represents enabled. The right-most bit (least - significant) represents trap 0." - ::= { ospfTrapControl 1 } - - - ospfConfigErrorType OBJECT-TYPE - SYNTAX INTEGER { - badVersion (1), - areaMismatch (2), - unknownNbmaNbr (3), -- Router is Dr eligible - unknownVirtualNbr (4), - authTypeMismatch(5), - authFailure (6), - netMaskMismatch (7), - helloIntervalMismatch (8), - deadIntervalMismatch (9), - optionMismatch (10) } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Potential types of configuration conflicts. - Used by the ospfConfigError and ospfConfigVir- - tError traps." - ::= { ospfTrapControl 2 } - - - ospfPacketType OBJECT-TYPE - SYNTAX INTEGER { - hello (1), - dbDescript (2), - lsReq (3), - lsUpdate (4), - lsAck (5) } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "OSPF packet types." - ::= { ospfTrapControl 3 } - - - ospfPacketSrc OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP address of an inbound packet that can- - not be identified by a neighbor instance." - ::= { ospfTrapControl 4 } - - --- Traps - - - ospfIfStateChange NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfIfIpAddress, - ospfAddressLessIf, - ospfIfState -- The new state - } - STATUS current - DESCRIPTION - "An ospfIfStateChange trap signifies that there - has been a change in the state of a non-virtual - OSPF interface. This trap should be generated - when the interface state regresses (e.g., goes - from Dr to Down) or progresses to a terminal - state (i.e., Point-to-Point, DR Other, Dr, or - Backup)." - ::= { ospfTraps 16 } - - - ospfVirtIfStateChange NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfVirtIfAreaId, - ospfVirtIfNeighbor, - ospfVirtIfState -- The new state - } - STATUS current - DESCRIPTION - "An ospfIfStateChange trap signifies that there - has been a change in the state of an OSPF vir- - tual interface. - This trap should be generated when the inter- - face state regresses (e.g., goes from Point- - to-Point to Down) or progresses to a terminal - state (i.e., Point-to-Point)." - ::= { ospfTraps 1 } - - - ospfNbrStateChange NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfNbrIpAddr, - ospfNbrAddressLessIndex, - ospfNbrRtrId, - ospfNbrState -- The new state - } - STATUS current - DESCRIPTION - "An ospfNbrStateChange trap signifies that - there has been a change in the state of a non- - virtual OSPF neighbor. This trap should be - generated when the neighbor state regresses - (e.g., goes from Attempt or Full to 1-Way or - Down) or progresses to a terminal state (e.g., - 2-Way or Full). When an neighbor transitions - from or to Full on non-broadcast multi-access - and broadcast networks, the trap should be gen- - erated by the designated router. A designated - router transitioning to Down will be noted by - ospfIfStateChange." - ::= { ospfTraps 2 } - - - ospfVirtNbrStateChange NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfVirtNbrArea, - ospfVirtNbrRtrId, - ospfVirtNbrState -- The new state - } - STATUS current - DESCRIPTION - "An ospfIfStateChange trap signifies that there - has been a change in the state of an OSPF vir- - tual neighbor. This trap should be generated - when the neighbor state regresses (e.g., goes - from Attempt or Full to 1-Way or Down) or - progresses to a terminal state (e.g., Full)." - ::= { ospfTraps 3 } - ospfIfConfigError NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfIfIpAddress, - ospfAddressLessIf, - ospfPacketSrc, -- The source IP address - ospfConfigErrorType, -- Type of error - ospfPacketType - } - STATUS current - DESCRIPTION - "An ospfIfConfigError trap signifies that a - packet has been received on a non-virtual in- - terface from a router whose configuration - parameters conflict with this router's confi- - guration parameters. Note that the event op- - tionMismatch should cause a trap only if it - prevents an adjacency from forming." - ::= { ospfTraps 4 } - - - ospfVirtIfConfigError NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfVirtIfAreaId, - ospfVirtIfNeighbor, - ospfConfigErrorType, -- Type of error - ospfPacketType - } - STATUS current - DESCRIPTION - "An ospfConfigError trap signifies that a pack- - et has been received on a virtual interface - from a router whose configuration parameters - conflict with this router's configuration - parameters. Note that the event optionMismatch - should cause a trap only if it prevents an ad- - jacency from forming." - ::= { ospfTraps 5 } - - - ospfIfAuthFailure NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfIfIpAddress, - ospfAddressLessIf, - ospfPacketSrc, -- The source IP address - ospfConfigErrorType, -- authTypeMismatch or - -- authFailure - ospfPacketType - } - STATUS current - DESCRIPTION - "An ospfIfAuthFailure trap signifies that a - packet has been received on a non-virtual in- - terface from a router whose authentication key - or authentication type conflicts with this - router's authentication key or authentication - type." - ::= { ospfTraps 6 } - - - ospfVirtIfAuthFailure NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfVirtIfAreaId, - ospfVirtIfNeighbor, - ospfConfigErrorType, -- authTypeMismatch or - -- authFailure - ospfPacketType - } - STATUS current - DESCRIPTION - "An ospfVirtIfAuthFailure trap signifies that a - packet has been received on a virtual interface - from a router whose authentication key or au- - thentication type conflicts with this router's - authentication key or authentication type." - ::= { ospfTraps 7 } - - - ospfIfRxBadPacket NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfIfIpAddress, - ospfAddressLessIf, - ospfPacketSrc, -- The source IP address - ospfPacketType - } - STATUS current - DESCRIPTION - "An ospfIfRxBadPacket trap signifies that an - OSPF packet has been received on a non-virtual - interface that cannot be parsed." - ::= { ospfTraps 8 } - - ospfVirtIfRxBadPacket NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfVirtIfAreaId, - ospfVirtIfNeighbor, - ospfPacketType - } - STATUS current - DESCRIPTION - "An ospfRxBadPacket trap signifies that an OSPF - packet has been received on a virtual interface - that cannot be parsed." - ::= { ospfTraps 9 } - - - ospfTxRetransmit NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfIfIpAddress, - ospfAddressLessIf, - ospfNbrRtrId, -- Destination - ospfPacketType, - ospfLsdbType, - ospfLsdbLsid, - ospfLsdbRouterId - } - STATUS current - DESCRIPTION - "An ospfTxRetransmit trap signifies than an - OSPF packet has been retransmitted on a non- - virtual interface. All packets that may be re- - transmitted are associated with an LSDB entry. - The LS type, LS ID, and Router ID are used to - identify the LSDB entry." - ::= { ospfTraps 10 } - - - ospfVirtIfTxRetransmit NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfVirtIfAreaId, - ospfVirtIfNeighbor, - ospfPacketType, - ospfLsdbType, - ospfLsdbLsid, - ospfLsdbRouterId - } - STATUS current - DESCRIPTION - "An ospfTxRetransmit trap signifies than an - OSPF packet has been retransmitted on a virtual - interface. All packets that may be retransmit- - ted are associated with an LSDB entry. The LS - type, LS ID, and Router ID are used to identify - the LSDB entry." - ::= { ospfTraps 11 } - - - ospfOriginateLsa NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfLsdbAreaId, -- 0.0.0.0 for AS Externals - ospfLsdbType, - ospfLsdbLsid, - ospfLsdbRouterId - } - STATUS current - DESCRIPTION - "An ospfOriginateLsa trap signifies that a new - LSA has been originated by this router. This - trap should not be invoked for simple refreshes - of LSAs (which happesn every 30 minutes), but - instead will only be invoked when an LSA is - (re)originated due to a topology change. Addi- - tionally, this trap does not include LSAs that - are being flushed because they have reached - MaxAge." - ::= { ospfTraps 12 } - - - ospfMaxAgeLsa NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfLsdbAreaId, -- 0.0.0.0 for AS Externals - ospfLsdbType, - ospfLsdbLsid, - ospfLsdbRouterId - } - STATUS current - DESCRIPTION - "An ospfMaxAgeLsa trap signifies that one of - the LSA in the router's link-state database has - aged to MaxAge." - ::= { ospfTraps 13 } - - - ospfLsdbOverflow NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfExtLsdbLimit - } - STATUS current - DESCRIPTION - "An ospfLsdbOverflow trap signifies that the - number of LSAs in the router's link-state data- - base has exceeded ospfExtLsdbLimit." - ::= { ospfTraps 14 } - - - ospfLsdbApproachingOverflow NOTIFICATION-TYPE - OBJECTS { - ospfRouterId, -- The originator of the trap - ospfExtLsdbLimit - } - STATUS current - DESCRIPTION - "An ospfLsdbApproachingOverflow trap signifies - that the number of LSAs in the router's link- - state database has exceeded ninety percent of - ospfExtLsdbLimit." - ::= { ospfTraps 15 } - - --- conformance information - -ospfTrapConformance OBJECT IDENTIFIER ::= { ospfTrap 3 } - -ospfTrapGroups OBJECT IDENTIFIER ::= { ospfTrapConformance 1 } -ospfTrapCompliances OBJECT IDENTIFIER ::= { ospfTrapConformance 2 } - --- compliance statements - - ospfTrapCompliance MODULE-COMPLIANCE - STATUS current - DESCRIPTION - "The compliance statement " - MODULE -- this module - MANDATORY-GROUPS { ospfTrapControlGroup } - - - GROUP ospfTrapControlGroup - DESCRIPTION - "This group is optional but recommended for all - OSPF systems" - ::= { ospfTrapCompliances 1 } - - --- units of conformance - - ospfTrapControlGroup OBJECT-GROUP - OBJECTS { - ospfSetTrap, - ospfConfigErrorType, - ospfPacketType, - ospfPacketSrc - } - STATUS current - DESCRIPTION - "These objects are required to control traps - from OSPF systems." - ::= { ospfTrapGroups 1 } - - -END diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 16347f1c5b..3efc219fcb 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -2530,8 +2530,8 @@ DEFUN (show_ip_ospf_mpls_te_link, "Interface name\n") { struct vrf *vrf; - int idx_interface = 5; - struct interface *ifp; + int idx_interface = 0; + struct interface *ifp = NULL; struct listnode *node; char *vrf_name = NULL; bool all_vrf; @@ -2543,7 +2543,7 @@ DEFUN (show_ip_ospf_mpls_te_link, vrf_name = argv[idx_vrf + 1]->arg; all_vrf = strmatch(vrf_name, "all"); } - + argv_find(argv, argc, "INTERFACE", &idx_interface); /* vrf input is provided could be all or specific vrf*/ if (vrf_name) { if (all_vrf) { @@ -2557,32 +2557,31 @@ DEFUN (show_ip_ospf_mpls_te_link, return CMD_SUCCESS; } ospf = ospf_lookup_by_inst_name(inst, vrf_name); - if (ospf == NULL || !ospf->oi_running) - return CMD_SUCCESS; - vrf = vrf_lookup_by_id(ospf->vrf_id); - FOR_ALL_INTERFACES (vrf, ifp) - show_mpls_te_link_sub(vty, ifp); + } else + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) return CMD_SUCCESS; - } - /* Show All Interfaces. */ - if (argc == 5) { - for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { - if (!ospf->oi_running) - continue; - vrf = vrf_lookup_by_id(ospf->vrf_id); - FOR_ALL_INTERFACES (vrf, ifp) - show_mpls_te_link_sub(vty, ifp); + + vrf = vrf_lookup_by_id(ospf->vrf_id); + if (!vrf) + return CMD_SUCCESS; + if (idx_interface) { + ifp = if_lookup_by_name( + argv[idx_interface]->arg, + ospf->vrf_id); + if (ifp == NULL) { + vty_out(vty, "No such interface name in vrf %s\n", + vrf->name); + return CMD_SUCCESS; } } - /* Interface name is specified. */ - else { - ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg); - if (ifp == NULL) - vty_out(vty, "No such interface name\n"); - else + if (!ifp) { + FOR_ALL_INTERFACES (vrf, ifp) show_mpls_te_link_sub(vty, ifp); + return CMD_SUCCESS; } + show_mpls_te_link_sub(vty, ifp); return CMD_SUCCESS; } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 67f5c7e890..3ab9c018ea 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -4687,7 +4687,7 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf, ospf_show_vrf_name(ospf, vty, json, use_vrf); - ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg); + ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id); if (!ifp) { if (use_json) json_object_boolean_true_add(json, "noSuchIface"); @@ -4717,34 +4717,50 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf_neighbor_int, show_ip_ospf_neighbor_int_cmd, - "show ip ospf neighbor IFNAME [json]", + "show ip ospf [vrf <NAME>] neighbor IFNAME [json]", SHOW_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR "Neighbor list\n" "Interface name\n" JSON_STR) { struct ospf *ospf; - int idx_ifname = 4; + int idx_ifname = 0; + int idx_vrf = 0; bool uj = use_json(argc, argv); - struct listnode *node = NULL; int ret = CMD_SUCCESS; struct interface *ifp = NULL; + char *vrf_name = NULL; + vrf_id_t vrf_id = VRF_DEFAULT; + struct vrf *vrf = NULL; + + if (argv_find(argv, argc, "vrf", &idx_vrf)) + vrf_name = argv[idx_vrf + 1]->arg; + if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME)) + vrf_name = NULL; + if (vrf_name) { + vrf = vrf_lookup_by_name(vrf_name); + if (vrf) + vrf_id = vrf->vrf_id; + } + ospf = ospf_lookup_by_vrf_id(vrf_id); + + if (!ospf || !ospf->oi_running) + return ret; if (!uj) show_ip_ospf_neighbour_header(vty); - ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg); - for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { - if (!ospf->oi_running) - continue; - if (!ifp || ifp->vrf_id != ospf->vrf_id) - continue; - ret = show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, - argv, uj, 0); - } + argv_find(argv, argc, "IFNAME", &idx_ifname); + ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id); + if (!ifp) + return ret; + + ret = show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, + argv, uj, 0); return ret; } @@ -5080,15 +5096,12 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, } static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, - int arg_base, - struct cmd_token **argv, + struct in_addr *router_id, bool use_json, uint8_t use_vrf) { struct listnode *node; struct ospf_neighbor *nbr; struct ospf_interface *oi; - struct in_addr router_id; - int ret; json_object *json = NULL; if (use_json) @@ -5104,19 +5117,8 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, ospf_show_vrf_name(ospf, vty, json, use_vrf); - ret = inet_aton(argv[arg_base]->arg, &router_id); - if (!ret) { - if (!use_json) - vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); - else { - vty_out(vty, "{}\n"); - json_object_free(json); - } - return CMD_WARNING; - } - for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { - if ((nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &router_id))) { + if ((nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, router_id))) { show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, json, use_json); } @@ -5132,9 +5134,9 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, return CMD_SUCCESS; } -DEFUN (show_ip_ospf_neighbor_id, +DEFPY (show_ip_ospf_neighbor_id, show_ip_ospf_neighbor_id_cmd, - "show ip ospf neighbor A.B.C.D [json]", + "show ip ospf neighbor A.B.C.D$router_id [json$json]", SHOW_STR IP_STR "OSPF information\n" @@ -5143,23 +5145,22 @@ DEFUN (show_ip_ospf_neighbor_id, JSON_STR) { struct ospf *ospf; - bool uj = use_json(argc, argv); - struct listnode *node = NULL; + struct listnode *node; int ret = CMD_SUCCESS; for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; - ret = show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv, uj, - 0); + ret = show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, + !!json, 0); } return ret; } -DEFUN (show_ip_ospf_instance_neighbor_id, +DEFPY (show_ip_ospf_instance_neighbor_id, show_ip_ospf_instance_neighbor_id_cmd, - "show ip ospf (1-65535) neighbor A.B.C.D [json]", + "show ip ospf (1-65535)$instance neighbor A.B.C.D$router_id [json$json]", SHOW_STR IP_STR "OSPF information\n" @@ -5168,13 +5169,8 @@ DEFUN (show_ip_ospf_instance_neighbor_id, "Neighbor ID\n" JSON_STR) { - int idx_number = 3; - int idx_router_id = 5; struct ospf *ospf; - unsigned short instance = 0; - bool uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); ospf = ospf_lookup_instance(instance); if (ospf == NULL) return CMD_NOT_MY_INSTANCE; @@ -5182,8 +5178,8 @@ DEFUN (show_ip_ospf_instance_neighbor_id, if (!ospf->oi_running) return CMD_SUCCESS; - return show_ip_ospf_neighbor_id_common(vty, ospf, idx_router_id, argv, - uj, 0); + return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json, + 0); } static int show_ip_ospf_neighbor_detail_common(struct vty *vty, @@ -5576,7 +5572,7 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty, vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); } - ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg); + ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id); if (!ifp) { if (!use_json) vty_out(vty, "No such interface.\n"); @@ -10648,28 +10644,45 @@ static void ospf_interface_clear(struct interface *ifp) DEFUN (clear_ip_ospf_interface, clear_ip_ospf_interface_cmd, - "clear ip ospf interface [IFNAME]", + "clear ip ospf [vrf <NAME>] interface [IFNAME]", CLEAR_STR IP_STR "OSPF information\n" + VRF_CMD_HELP_STR "Interface information\n" "Interface name\n") { - int idx_ifname = 4; + int idx_ifname = 0; + int idx_vrf = 0; struct interface *ifp; struct listnode *node; struct ospf *ospf = NULL; + char *vrf_name = NULL; + vrf_id_t vrf_id = VRF_DEFAULT; + struct vrf *vrf = NULL; - if (argc == 4) /* Clear all the ospfv2 interfaces. */ - { + if (argv_find(argv, argc, "vrf", &idx_vrf)) + vrf_name = argv[idx_vrf + 1]->arg; + if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME)) + vrf_name = NULL; + if (vrf_name) { + vrf = vrf_lookup_by_name(vrf_name); + if (vrf) + vrf_id = vrf->vrf_id; + } + if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) { + /* Clear all the ospfv2 interfaces. */ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { - struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); + if (vrf_id != ospf->vrf_id) + continue; + if (!vrf) + vrf = vrf_lookup_by_id(ospf->vrf_id); FOR_ALL_INTERFACES (vrf, ifp) ospf_interface_clear(ifp); } } else { /* Interface name is specified. */ - ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg); + ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id); if (ifp == NULL) vty_out(vty, "No such interface name\n"); else diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 83074b5ac0..3ad1b870b4 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -108,6 +108,4 @@ ospfd_ospfd_snmp_la_LIBADD = lib/libfrrsnmp.la EXTRA_DIST += \ ospfd/ChangeLog.opaque.txt \ - ospfd/OSPF-MIB.txt \ - ospfd/OSPF-TRAP-MIB.txt \ # end diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c index 3f863ebeca..0a450834e3 100644 --- a/pimd/pim_assert.c +++ b/pimd/pim_assert.c @@ -569,7 +569,7 @@ static void pim_assert_timer_set(struct pim_ifchannel *ch, int interval) ch->interface->name); } - thread_add_timer(master, on_assert_timer, ch, interval, + thread_add_timer(router->master, on_assert_timer, ch, interval, &ch->t_ifassert_timer); } diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 26932eea20..7089e21513 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2646,7 +2646,7 @@ static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim, if (json) { json_object_int_add(json, "rpfCacheRefreshDelayMsecs", - qpim_rpf_cache_refresh_delay_msec); + router->rpf_cache_refresh_delay_msec); json_object_int_add( json, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(pim->rpf_cache_refresher)); @@ -2669,7 +2669,7 @@ static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim, "RPF Cache Refresh Last: %s\n" "Nexthop Lookups: %lld\n" "Nexthop Lookups Avoided: %lld\n", - qpim_rpf_cache_refresh_delay_msec, + router->rpf_cache_refresh_delay_msec, pim_time_timer_remain_msec(pim->rpf_cache_refresher), (long long)pim->rpf_cache_refresh_requests, (long long)pim->rpf_cache_refresh_events, @@ -4408,9 +4408,12 @@ static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, struct vrf *vrf = pim->vrf; time_t now = pim_time_monotonic_sec(); char uptime[10]; + char mlag_role[80]; pim = vrf->info; + vty_out(vty, "Router MLAG Role: %s\n", + mlag_role2str(router->role, mlag_role, sizeof(mlag_role))); vty_out(vty, "Mroute socket descriptor:"); vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name); @@ -4428,7 +4431,7 @@ static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS); vty_out(vty, "\n"); - vty_out(vty, "Upstream Join Timer: %d secs\n", qpim_t_periodic); + vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic); vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME); vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable"); vty_out(vty, "PIM ECMP Rebalance: %s\n", @@ -5229,7 +5232,7 @@ DEFUN (ip_pim_joinprune_time, "Seconds\n") { PIM_DECLVAR_CONTEXT(vrf, pim); - qpim_t_periodic = atoi(argv[3]->arg); + router->t_periodic = atoi(argv[3]->arg); return CMD_SUCCESS; } @@ -5243,7 +5246,7 @@ DEFUN (no_ip_pim_joinprune_time, "Seconds\n") { PIM_DECLVAR_CONTEXT(vrf, pim); - qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; + router->t_periodic = PIM_DEFAULT_T_PERIODIC; return CMD_SUCCESS; } @@ -5256,7 +5259,7 @@ DEFUN (ip_pim_register_suppress, "Seconds\n") { PIM_DECLVAR_CONTEXT(vrf, pim); - qpim_register_suppress_time = atoi(argv[3]->arg); + router->register_suppress_time = atoi(argv[3]->arg); return CMD_SUCCESS; } @@ -5270,7 +5273,7 @@ DEFUN (no_ip_pim_register_suppress, "Seconds\n") { PIM_DECLVAR_CONTEXT(vrf, pim); - qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT; + router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT; return CMD_SUCCESS; } @@ -5339,7 +5342,7 @@ DEFUN (ip_pim_packets, "Number of packets\n") { PIM_DECLVAR_CONTEXT(vrf, pim); - qpim_packet_process = atoi(argv[3]->arg); + router->packet_process = atoi(argv[3]->arg); return CMD_SUCCESS; } @@ -5353,7 +5356,7 @@ DEFUN (no_ip_pim_packets, "Number of packets\n") { PIM_DECLVAR_CONTEXT(vrf, pim); - qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS; + router->packet_process = PIM_DEFAULT_PACKET_PROCESS; return CMD_SUCCESS; } diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 1ad71823b8..0451ab1e71 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -1157,7 +1157,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp) /* t_suppressed = t_periodic * rand(1.1, 1.4) */ ramount = 1100 + (random() % (1400 - 1100 + 1)); - t_suppressed_msec = qpim_t_periodic * ramount; + t_suppressed_msec = router->t_periodic * ramount; return t_suppressed_msec; } diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 8f6a9ece53..14ce8d7d9f 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -415,7 +415,7 @@ void reset_ifassert_state(struct pim_ifchannel *ch) THREAD_OFF(ch->t_ifassert_timer); pim_ifassert_winner_set(ch, PIM_IFASSERT_NOINFO, any, - qpim_infinite_assert_metric); + router->infinite_assert_metric); } struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp, @@ -889,8 +889,8 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr, } if (holdtime != 0xFFFF) { - thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime, - &ch->t_ifjoin_expiry_timer); + thread_add_timer(router->master, on_ifjoin_expiry_timer, ch, + holdtime, &ch->t_ifjoin_expiry_timer); } } @@ -945,11 +945,12 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, THREAD_OFF(ch->t_ifjoin_prune_pending_timer); THREAD_OFF(ch->t_ifjoin_expiry_timer); thread_add_timer_msec( - master, on_ifjoin_prune_pending_timer, ch, - jp_override_interval_msec, + router->master, on_ifjoin_prune_pending_timer, + ch, jp_override_interval_msec, &ch->t_ifjoin_prune_pending_timer); - thread_add_timer(master, on_ifjoin_expiry_timer, ch, - holdtime, &ch->t_ifjoin_expiry_timer); + thread_add_timer(router->master, on_ifjoin_expiry_timer, + ch, holdtime, + &ch->t_ifjoin_expiry_timer); pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream); } @@ -973,31 +974,35 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, be taken not to use "ch" afterwards since it would be deleted. */ THREAD_OFF(ch->t_ifjoin_prune_pending_timer); - thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch, + thread_add_timer_msec(router->master, + on_ifjoin_prune_pending_timer, ch, jp_override_interval_msec, &ch->t_ifjoin_prune_pending_timer); break; case PIM_IFJOIN_PRUNE: if (source_flags & PIM_ENCODE_RPT_BIT) { THREAD_OFF(ch->t_ifjoin_prune_pending_timer); - thread_add_timer(master, on_ifjoin_expiry_timer, ch, - holdtime, &ch->t_ifjoin_expiry_timer); + thread_add_timer(router->master, on_ifjoin_expiry_timer, + ch, holdtime, + &ch->t_ifjoin_expiry_timer); } break; case PIM_IFJOIN_PRUNE_TMP: if (source_flags & PIM_ENCODE_RPT_BIT) { ch->ifjoin_state = PIM_IFJOIN_PRUNE; THREAD_OFF(ch->t_ifjoin_expiry_timer); - thread_add_timer(master, on_ifjoin_expiry_timer, ch, - holdtime, &ch->t_ifjoin_expiry_timer); + thread_add_timer(router->master, on_ifjoin_expiry_timer, + ch, holdtime, + &ch->t_ifjoin_expiry_timer); } break; case PIM_IFJOIN_PRUNE_PENDING_TMP: if (source_flags & PIM_ENCODE_RPT_BIT) { ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING; THREAD_OFF(ch->t_ifjoin_expiry_timer); - thread_add_timer(master, on_ifjoin_expiry_timer, ch, - holdtime, &ch->t_ifjoin_expiry_timer); + thread_add_timer(router->master, on_ifjoin_expiry_timer, + ch, holdtime, + &ch->t_ifjoin_expiry_timer); } break; } diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 7a19d25a7b..cdd156b96f 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -250,8 +250,8 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp) other_querier_present_interval_msec % 1000); } - thread_add_timer_msec(master, pim_igmp_other_querier_expire, igmp, - other_querier_present_interval_msec, + thread_add_timer_msec(router->master, pim_igmp_other_querier_expire, + igmp, other_querier_present_interval_msec, &igmp->t_other_querier_timer); } @@ -603,8 +603,8 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp) startup_mode ? "startup" : "non-startup", igmp->fd); } igmp->t_igmp_query_timer = NULL; - thread_add_timer(master, pim_igmp_general_query, igmp, query_interval, - &igmp->t_igmp_query_timer); + thread_add_timer(router->master, pim_igmp_general_query, igmp, + query_interval, &igmp->t_igmp_query_timer); } void pim_igmp_general_query_off(struct igmp_sock *igmp) @@ -940,7 +940,7 @@ static void igmp_read_on(struct igmp_sock *igmp) igmp->fd); } igmp->t_igmp_read = NULL; - thread_add_read(master, pim_igmp_read, igmp, igmp->fd, + thread_add_read(router->master, pim_igmp_read, igmp, igmp->fd, &igmp->t_igmp_read); } @@ -1067,8 +1067,8 @@ void igmp_group_timer_on(struct igmp_group *group, long interval_msec, */ zassert(group->group_filtermode_isexcl); - thread_add_timer_msec(master, igmp_group_timer, group, interval_msec, - &group->t_group_timer); + thread_add_timer_msec(router->master, igmp_group_timer, group, + interval_msec, &group->t_group_timer); } struct igmp_group *find_group_by_addr(struct igmp_sock *igmp, diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 430cba76b0..b845f54f06 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -214,8 +214,8 @@ static void igmp_source_timer_on(struct igmp_group *group, source_str, group->group_igmp_sock->interface->name); } - thread_add_timer_msec(master, igmp_source_timer, source, interval_msec, - &source->t_source_timer); + thread_add_timer_msec(router->master, igmp_source_timer, source, + interval_msec, &source->t_source_timer); /* RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules @@ -1294,7 +1294,8 @@ static void group_retransmit_timer_on(struct igmp_group *group) igmp->interface->name); } - thread_add_timer_msec(master, igmp_group_retransmit, group, lmqi_msec, + thread_add_timer_msec(router->master, igmp_group_retransmit, group, + lmqi_msec, &group->t_group_query_retransmit_timer); } diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index b0d7a7b2db..092a2d76fa 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -85,7 +85,7 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) pim->spt.switchover = PIM_SPT_IMMEDIATE; pim->spt.plist = NULL; - pim_msdp_init(pim, master); + pim_msdp_init(pim, router->master); snprintf(hash_name, 64, "PIM %s RPF Hash", vrf->name); pim->rpf_hash = hash_create_size(256, pim_rpf_hash_key, pim_rpf_equal, @@ -101,9 +101,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) pim->send_v6_secondary = 1; - if (vrf->vrf_id == VRF_DEFAULT) - pimg = pim; - pim_rp_init(pim); pim_oil_init(pim); @@ -132,9 +129,6 @@ static int pim_vrf_new(struct vrf *vrf) vrf->info = (void *)pim; - if (vrf->vrf_id == VRF_DEFAULT) - pimg = pim; - pim_ssmpingd_init(pim); return 0; } diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index b447075e9a..e651356bfe 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -21,8 +21,11 @@ #ifndef __PIM_INSTANCE_H__ #define __PIM_INSTANCE_H__ +#include <mlag.h> + #include "pim_str.h" #include "pim_msdp.h" +#include "pim_assert.h" #if defined(HAVE_LINUX_MROUTE_H) #include <linux/mroute.h> @@ -35,13 +38,32 @@ #define MAXVIFS (256) #endif #endif -extern struct pim_instance *pimg; // Pim Global Instance enum pim_spt_switchover { PIM_SPT_IMMEDIATE, PIM_SPT_INFINITY, }; +struct pim_router { + struct thread_master *master; + + uint32_t debugs; + + int t_periodic; + struct pim_assert_metric infinite_assert_metric; + long rpf_cache_refresh_delay_msec; + int32_t register_suppress_time; + int packet_process; + int32_t register_probe_time; + + /* + * What is the default vrf that we work in + */ + vrf_id_t vrf_id; + + enum mlag_role role; +}; + /* Per VRF PIM DB */ struct pim_instance { vrf_id_t vrf_id; diff --git a/pimd/pim_macro.c b/pimd/pim_macro.c index 13f4240dba..908026ab14 100644 --- a/pimd/pim_macro.c +++ b/pimd/pim_macro.c @@ -295,7 +295,7 @@ pim_macro_ch_my_assert_metric_eval(const struct pim_ifchannel *ch) } } - return qpim_infinite_assert_metric; + return router->infinite_assert_metric; } /* diff --git a/pimd/pim_main.c b/pimd/pim_main.c index 50ebc4003e..dc42899c7b 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -109,7 +109,7 @@ int main(int argc, char **argv, char **envp) } } - master = frr_init(); + pim_router_init(); /* * Initializations @@ -157,7 +157,7 @@ int main(int argc, char **argv, char **envp) "PIM_UNEXPECTED_KERNEL_UPCALL: report unexpected kernel upcall"); #endif - frr_run(master); + frr_run(router->master); /* never reached */ return 0; diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index dc4c4402a1..dd9e21cae8 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -708,7 +708,7 @@ static int mroute_read(struct thread *t) result = pim_mroute_msg(pim, buf, rd, ifindex); count++; - if (count % qpim_packet_process == 0) + if (count % router->packet_process == 0) cont = 0; } /* Keep reading */ @@ -720,7 +720,7 @@ done: static void mroute_read_on(struct pim_instance *pim) { - thread_add_read(master, mroute_read, pim, pim->mroute_socket, + thread_add_read(router->master, mroute_read, pim, pim->mroute_socket, &pim->thread); } diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 7e072e6ade..a4f87fa1a6 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -1523,8 +1523,8 @@ enum pim_msdp_err pim_msdp_mg_src_add(struct pim_instance *pim, } /*********************** MSDP feature APIs *********************************/ -int pim_msdp_config_write_helper(struct pim_instance *pim, struct vty *vty, - const char *spaces) +int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty, + const char *spaces) { struct listnode *mbrnode; struct pim_msdp_mg_mbr *mbr; @@ -1553,11 +1553,6 @@ int pim_msdp_config_write_helper(struct pim_instance *pim, struct vty *vty, return count; } -int pim_msdp_config_write(struct vty *vty) -{ - return pim_msdp_config_write_helper(pimg, vty, ""); -} - /* Enable feature including active/periodic timers etc. on the first peer * config. Till then MSDP should just stay quiet. */ static void pim_msdp_enable(struct pim_instance *pim) diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index 8363d50991..6caa3181e7 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -232,9 +232,8 @@ void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str); int pim_msdp_write(struct thread *thread); char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size, bool long_format); -int pim_msdp_config_write(struct vty *vty); -int pim_msdp_config_write_helper(struct pim_instance *pim, struct vty *vty, - const char *spaces); +int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty, + const char *spaces); void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp); void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, struct prefix_sg *sg, struct in_addr rp); diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index 7997d3138a..b1f7cfd2c6 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -79,7 +79,7 @@ static int pim_msdp_sock_accept(struct thread *thread) return -1; } pim->msdp.listener.thread = NULL; - thread_add_read(master, pim_msdp_sock_accept, pim, accept_sock, + thread_add_read(router->master, pim_msdp_sock_accept, pim, accept_sock, &pim->msdp.listener.thread); /* accept client connection. */ diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index f402629653..436f2dec27 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -255,8 +255,8 @@ void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime) neigh->interface->name); } - thread_add_timer(master, on_neighbor_timer, neigh, neigh->holdtime, - &neigh->t_expire_timer); + thread_add_timer(router->master, on_neighbor_timer, neigh, + neigh->holdtime, &neigh->t_expire_timer); } static int on_neighbor_jp_timer(struct thread *t) @@ -277,8 +277,8 @@ static int on_neighbor_jp_timer(struct thread *t) rpf.rpf_addr.u.prefix4 = neigh->source_addr; pim_joinprune_send(&rpf, neigh->upstream_jp_agg); - thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic, - &neigh->jp_timer); + thread_add_timer(router->master, on_neighbor_jp_timer, neigh, + router->t_periodic, &neigh->jp_timer); return 0; } @@ -286,8 +286,8 @@ static int on_neighbor_jp_timer(struct thread *t) static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh) { THREAD_TIMER_OFF(neigh->jp_timer); - thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic, - &neigh->jp_timer); + thread_add_timer(router->master, on_neighbor_jp_timer, neigh, + router->t_periodic, &neigh->jp_timer); } static struct pim_neighbor * diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index 0696a680e7..71b0d47928 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -346,7 +346,7 @@ static int pim_sock_read(struct thread *t) } count++; - if (count % qpim_packet_process == 0) + if (count % router->packet_process == 0) cont = 0; } @@ -376,8 +376,8 @@ static void pim_sock_read_on(struct interface *ifp) pim_ifp->pim_sock_fd); } pim_ifp->t_pim_sock_read = NULL; - thread_add_read(master, pim_sock_read, ifp, pim_ifp->pim_sock_fd, - &pim_ifp->t_pim_sock_read); + thread_add_read(router->master, pim_sock_read, ifp, + pim_ifp->pim_sock_fd, &pim_ifp->t_pim_sock_read); } static int pim_sock_open(struct interface *ifp) @@ -683,7 +683,7 @@ static void hello_resched(struct interface *ifp) pim_ifp->pim_hello_period, ifp->name); } THREAD_OFF(pim_ifp->t_pim_hello_timer); - thread_add_timer(master, on_pim_hello_send, ifp, + thread_add_timer(router->master, on_pim_hello_send, ifp, pim_ifp->pim_hello_period, &pim_ifp->t_pim_hello_timer); } @@ -796,8 +796,8 @@ void pim_hello_restart_triggered(struct interface *ifp) random_msec, ifp->name); } - thread_add_timer_msec(master, on_pim_hello_send, ifp, random_msec, - &pim_ifp->t_pim_hello_timer); + thread_add_timer_msec(router->master, on_pim_hello_send, ifp, + random_msec, &pim_ifp->t_pim_hello_timer); } int pim_sock_add(struct interface *ifp) diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index c3d958428c..17bc375c12 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -339,7 +339,7 @@ static int ssmpingd_sock_read(struct thread *t) static void ssmpingd_read_on(struct ssmpingd_sock *ss) { - thread_add_read(master, ssmpingd_sock_read, ss, ss->sock_fd, + thread_add_read(router->master, ssmpingd_sock_read, ss, ss->sock_fd, &ss->t_sock_read); } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index cd5b632ded..c6ab8f5a2a 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -308,7 +308,7 @@ void join_timer_start(struct pim_upstream *up) if (PIM_DEBUG_PIM_EVENTS) { zlog_debug( "%s: starting %d sec timer for upstream (S,G)=%s", - __PRETTY_FUNCTION__, qpim_t_periodic, + __PRETTY_FUNCTION__, router->t_periodic, up->sg_str); } } @@ -317,8 +317,8 @@ void join_timer_start(struct pim_upstream *up) pim_jp_agg_add_group(nbr->upstream_jp_agg, up, 1); else { THREAD_OFF(up->t_join_timer); - thread_add_timer(master, on_join_timer, up, qpim_t_periodic, - &up->t_join_timer); + thread_add_timer(router->master, on_join_timer, up, + router->t_periodic, &up->t_join_timer); } pim_jp_agg_upstream_verification(up, true); } @@ -346,7 +346,7 @@ static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up, } THREAD_OFF(up->t_join_timer); - thread_add_timer_msec(master, on_join_timer, up, interval_msec, + thread_add_timer_msec(router->master, on_join_timer, up, interval_msec, &up->t_join_timer); } @@ -647,9 +647,9 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY; up->rpf.source_nexthop.mrib_metric_preference = - qpim_infinite_assert_metric.metric_preference; + router->infinite_assert_metric.metric_preference; up->rpf.source_nexthop.mrib_route_metric = - qpim_infinite_assert_metric.route_metric; + router->infinite_assert_metric.route_metric; up->rpf.rpf_addr.family = AF_INET; up->rpf.rpf_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY; @@ -1124,8 +1124,8 @@ void pim_upstream_keep_alive_timer_start(struct pim_upstream *up, uint32_t time) up->sg_str); } THREAD_OFF(up->t_ka_timer); - thread_add_timer(master, pim_upstream_keep_alive_timer, up, time, - &up->t_ka_timer); + thread_add_timer(router->master, pim_upstream_keep_alive_timer, up, + time, &up->t_ka_timer); /* any time keepalive is started against a SG we will have to * re-evaluate our active source database */ @@ -1145,7 +1145,7 @@ static int pim_upstream_msdp_reg_timer(struct thread *t) void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up) { THREAD_OFF(up->t_msdp_reg_timer); - thread_add_timer(master, pim_upstream_msdp_reg_timer, up, + thread_add_timer(router->master, pim_upstream_msdp_reg_timer, up, PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer); pim_msdp_sa_local_update(up); @@ -1406,8 +1406,8 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up, "%s: (S,G)=%s Starting upstream register stop timer %d", __PRETTY_FUNCTION__, up->sg_str, time); } - thread_add_timer(master, pim_upstream_register_stop_timer, up, time, - &up->t_rs_timer); + thread_add_timer(router->master, pim_upstream_register_stop_timer, up, + time, &up->t_rs_timer); } int pim_upstream_inherited_olist_decide(struct pim_instance *pim, @@ -1768,7 +1768,7 @@ void pim_upstream_init(struct pim_instance *pim) snprintf(name, 64, "PIM %s Timer Wheel", pim->vrf->name); pim->upstream_sg_wheel = - wheel_init(master, 31000, 100, pim_upstream_hash_key, + wheel_init(router->master, 31000, 100, pim_upstream_hash_key, pim_upstream_sg_running, name); snprintf(name, 64, "PIM %s Upstream Hash", diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index a347ab991c..f44b95c811 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -126,13 +126,14 @@ struct pim_upstream { */ struct thread *t_ka_timer; #define PIM_KEEPALIVE_PERIOD (210) -#define PIM_RP_KEEPALIVE_PERIOD ( 3 * qpim_register_suppress_time + qpim_register_probe_time ) +#define PIM_RP_KEEPALIVE_PERIOD \ + (3 * router->register_suppress_time + router->register_probe_time) /* on the RP we restart a timer to indicate if registers are being rxed * for * SG. This is needed by MSDP to determine its local SA cache */ struct thread *t_msdp_reg_timer; -#define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * qpim_register_suppress_time)) +#define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * router->register_suppress_time)) int64_t state_transition; /* Record current state uptime */ }; diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index a4aec710e9..f6385a0ac9 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -163,7 +163,7 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) else sprintf(spaces, "%s", " "); - writes += pim_msdp_config_write_helper(pim, vty, spaces); + writes += pim_msdp_config_write(pim, vty, spaces); if (!pim->send_v6_secondary) { vty_out(vty, "%sno ip pim send-v6-secondary\n", spaces); @@ -172,15 +172,15 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) writes += pim_rp_config_write(pim, vty, spaces); - if (qpim_register_suppress_time + if (router->register_suppress_time != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT) { vty_out(vty, "%sip pim register-suppress-time %d\n", spaces, - qpim_register_suppress_time); + router->register_suppress_time); ++writes; } - if (qpim_t_periodic != PIM_DEFAULT_T_PERIODIC) { + if (router->t_periodic != PIM_DEFAULT_T_PERIODIC) { vty_out(vty, "%sip pim join-prune-interval %d\n", spaces, - qpim_t_periodic); + router->t_periodic); ++writes; } if (pim->keep_alive_time != PIM_KEEPALIVE_PERIOD) { @@ -193,9 +193,9 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) pim->rp_keep_alive_time); ++writes; } - if (qpim_packet_process != PIM_DEFAULT_PACKET_PROCESS) { + if (router->packet_process != PIM_DEFAULT_PACKET_PROCESS) { vty_out(vty, "%sip pim packets %d\n", spaces, - qpim_packet_process); + router->packet_process); ++writes; } if (ssm->plist_name) { diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 10ea17cf1f..b7111cf7bf 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -727,11 +727,11 @@ void sched_rpf_cache_refresh(struct pim_instance *pim) if (PIM_DEBUG_ZEBRA) { zlog_debug("%s: triggering %ld msec timer", __PRETTY_FUNCTION__, - qpim_rpf_cache_refresh_delay_msec); + router->rpf_cache_refresh_delay_msec); } - thread_add_timer_msec(master, on_rpf_cache_refresh, pim, - qpim_rpf_cache_refresh_delay_msec, + thread_add_timer_msec(router->master, on_rpf_cache_refresh, pim, + router->rpf_cache_refresh_delay_msec, &pim->rpf_cache_refresher); } @@ -740,14 +740,20 @@ static void pim_zebra_connected(struct zclient *zclient) /* Send the client registration */ bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); - zclient_send_reg_requests(zclient, pimg->vrf_id); + zclient_send_reg_requests(zclient, router->vrf_id); +} + +static void pim_zebra_capabilities(struct zclient_capabilities *cap) +{ + router->role = cap->role; } void pim_zebra_init(void) { /* Socket for receiving updates from Zebra daemon */ - zclient = zclient_new(master, &zclient_options_default); + zclient = zclient_new(router->master, &zclient_options_default); + zclient->zebra_capabilities = pim_zebra_capabilities; zclient->zebra_connected = pim_zebra_connected; zclient->router_id_update = pim_router_id_update_zebra; zclient->interface_add = pim_zebra_if_add; diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index 6b45313081..0ffe313c17 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -71,7 +71,7 @@ static int zclient_lookup_connect(struct thread *t) /* Schedule connection with delay. */ static void zclient_lookup_sched(struct zclient *zlookup, int delay) { - thread_add_timer(master, zclient_lookup_connect, zlookup, delay, + thread_add_timer(router->master, zclient_lookup_connect, zlookup, delay, &zlookup->t_connect); zlog_notice("%s: zclient lookup connection scheduled for %d seconds", @@ -81,7 +81,7 @@ static void zclient_lookup_sched(struct zclient *zlookup, int delay) /* Schedule connection for now. */ static void zclient_lookup_sched_now(struct zclient *zlookup) { - thread_add_event(master, zclient_lookup_connect, zlookup, 0, + thread_add_event(router->master, zclient_lookup_connect, zlookup, 0, &zlookup->t_connect); zlog_notice("%s: zclient lookup immediate connection scheduled", @@ -120,7 +120,7 @@ void zclient_lookup_free(void) void zclient_lookup_new(void) { - zlookup = zclient_new(master, &zclient_options_default); + zlookup = zclient_new(router->master, &zclient_options_default); if (!zlookup) { flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure", __PRETTY_FUNCTION__); diff --git a/pimd/pimd.c b/pimd/pimd.c index 5d3018b2fd..b993bcdc03 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -47,17 +47,9 @@ const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS; const char *const PIM_ALL_PIM_ROUTERS = MCAST_ALL_PIM_ROUTERS; const char *const PIM_ALL_IGMP_ROUTERS = MCAST_ALL_IGMP_ROUTERS; -struct thread_master *master = NULL; -uint32_t qpim_debugs = 0; -int qpim_t_periodic = - PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */ -struct pim_assert_metric qpim_infinite_assert_metric; -long qpim_rpf_cache_refresh_delay_msec = 50; -int qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS; -struct pim_instance *pimg = NULL; - -int32_t qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT; -int32_t qpim_register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT; +DEFINE_MTYPE_STATIC(PIMD, ROUTER, "PIM Router information"); + +struct pim_router *router = NULL; void pim_prefix_list_update(struct prefix_list *plist) { @@ -82,17 +74,13 @@ static void pim_free() zclient_lookup_free(); } -void pim_init() +void pim_router_init(void) { - if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) { - flog_err( - EC_LIB_SOCKET, - "%s %s: could not solve %s to group address: errno=%d: %s", - __FILE__, __PRETTY_FUNCTION__, PIM_ALL_PIM_ROUTERS, - errno, safe_strerror(errno)); - zassert(0); - return; - } + router = XCALLOC(MTYPE_ROUTER, sizeof(*router)); + + router->debugs = 0; + router->master = frr_init(); + router->t_periodic = PIM_DEFAULT_T_PERIODIC; /* RFC 4601: 4.6.3. Assert Metrics @@ -102,11 +90,35 @@ void pim_init() return {1,infinity,infinity,0} } */ - qpim_infinite_assert_metric.rpt_bit_flag = 1; - qpim_infinite_assert_metric.metric_preference = + router->infinite_assert_metric.rpt_bit_flag = 1; + router->infinite_assert_metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX; - qpim_infinite_assert_metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX; - qpim_infinite_assert_metric.ip_address.s_addr = INADDR_ANY; + router->infinite_assert_metric.route_metric = + PIM_ASSERT_ROUTE_METRIC_MAX; + router->infinite_assert_metric.ip_address.s_addr = INADDR_ANY; + router->rpf_cache_refresh_delay_msec = 50; + router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT; + router->packet_process = PIM_DEFAULT_PACKET_PROCESS; + router->register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT; + router->vrf_id = VRF_DEFAULT; +} + +void pim_router_terminate(void) +{ + XFREE(MTYPE_ROUTER, router); +} + +void pim_init(void) +{ + if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) { + flog_err( + EC_LIB_SOCKET, + "%s %s: could not solve %s to group address: errno=%d: %s", + __FILE__, __PRETTY_FUNCTION__, PIM_ALL_PIM_ROUTERS, + errno, safe_strerror(errno)); + zassert(0); + return; + } pim_cmd_init(); } @@ -130,5 +142,6 @@ void pim_terminate() zclient_free(zclient); } + pim_router_terminate(); frr_fini(); } diff --git a/pimd/pimd.h b/pimd/pimd.h index 1b11dc3f73..73ea9f82c4 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -132,110 +132,125 @@ const char *const PIM_ALL_ROUTERS; const char *const PIM_ALL_PIM_ROUTERS; const char *const PIM_ALL_IGMP_ROUTERS; -extern struct thread_master *master; +extern struct pim_router *router; extern struct zebra_privs_t pimd_privs; -uint32_t qpim_debugs; struct in_addr qpim_all_pim_routers_addr; -int qpim_t_periodic; /* Period between Join/Prune Messages */ -struct pim_assert_metric qpim_infinite_assert_metric; -long qpim_rpf_cache_refresh_delay_msec; -extern int qpim_packet_process; extern uint8_t qpim_ecmp_enable; extern uint8_t qpim_ecmp_rebalance_enable; #define PIM_DEFAULT_PACKET_PROCESS 3 -#define PIM_JP_HOLDTIME (qpim_t_periodic * 7 / 2) +#define PIM_JP_HOLDTIME (router->t_periodic * 7 / 2) /* * Register-Stop Timer (RST(S,G)) * Default values */ -extern int32_t qpim_register_suppress_time; -extern int32_t qpim_register_probe_time; #define PIM_REGISTER_SUPPRESSION_TIME_DEFAULT (60) #define PIM_REGISTER_PROBE_TIME_DEFAULT (5) -#define PIM_DEBUG_PIM_EVENTS (qpim_debugs & PIM_MASK_PIM_EVENTS) -#define PIM_DEBUG_PIM_EVENTS_DETAIL (qpim_debugs & PIM_MASK_PIM_EVENTS_DETAIL) -#define PIM_DEBUG_PIM_PACKETS (qpim_debugs & PIM_MASK_PIM_PACKETS) -#define PIM_DEBUG_PIM_PACKETDUMP_SEND (qpim_debugs & PIM_MASK_PIM_PACKETDUMP_SEND) -#define PIM_DEBUG_PIM_PACKETDUMP_RECV (qpim_debugs & PIM_MASK_PIM_PACKETDUMP_RECV) -#define PIM_DEBUG_PIM_TRACE (qpim_debugs & PIM_MASK_PIM_TRACE) -#define PIM_DEBUG_PIM_TRACE_DETAIL (qpim_debugs & PIM_MASK_PIM_TRACE_DETAIL) -#define PIM_DEBUG_IGMP_EVENTS (qpim_debugs & PIM_MASK_IGMP_EVENTS) -#define PIM_DEBUG_IGMP_PACKETS (qpim_debugs & PIM_MASK_IGMP_PACKETS) -#define PIM_DEBUG_IGMP_TRACE (qpim_debugs & PIM_MASK_IGMP_TRACE) -#define PIM_DEBUG_IGMP_TRACE_DETAIL (qpim_debugs & PIM_MASK_IGMP_TRACE_DETAIL) -#define PIM_DEBUG_ZEBRA (qpim_debugs & PIM_MASK_ZEBRA) -#define PIM_DEBUG_SSMPINGD (qpim_debugs & PIM_MASK_SSMPINGD) -#define PIM_DEBUG_MROUTE (qpim_debugs & PIM_MASK_MROUTE) -#define PIM_DEBUG_MROUTE_DETAIL (qpim_debugs & PIM_MASK_MROUTE_DETAIL) -#define PIM_DEBUG_PIM_HELLO (qpim_debugs & PIM_MASK_PIM_HELLO) -#define PIM_DEBUG_PIM_J_P (qpim_debugs & PIM_MASK_PIM_J_P) -#define PIM_DEBUG_PIM_REG (qpim_debugs & PIM_MASK_PIM_REG) -#define PIM_DEBUG_STATIC (qpim_debugs & PIM_MASK_STATIC) -#define PIM_DEBUG_MSDP_EVENTS (qpim_debugs & PIM_MASK_MSDP_EVENTS) -#define PIM_DEBUG_MSDP_PACKETS (qpim_debugs & PIM_MASK_MSDP_PACKETS) -#define PIM_DEBUG_MSDP_INTERNAL (qpim_debugs & PIM_MASK_MSDP_INTERNAL) -#define PIM_DEBUG_PIM_NHT (qpim_debugs & PIM_MASK_PIM_NHT) -#define PIM_DEBUG_PIM_NHT_DETAIL (qpim_debugs & PIM_MASK_PIM_NHT_DETAIL) -#define PIM_DEBUG_PIM_NHT_RP (qpim_debugs & PIM_MASK_PIM_NHT_RP) -#define PIM_DEBUG_MTRACE (qpim_debugs & PIM_MASK_MTRACE) - -#define PIM_DEBUG_EVENTS (qpim_debugs & (PIM_MASK_PIM_EVENTS | PIM_MASK_IGMP_EVENTS | PIM_MASK_MSDP_EVENTS)) -#define PIM_DEBUG_PACKETS (qpim_debugs & (PIM_MASK_PIM_PACKETS | PIM_MASK_IGMP_PACKETS | PIM_MASK_MSDP_PACKETS)) -#define PIM_DEBUG_TRACE (qpim_debugs & (PIM_MASK_PIM_TRACE | PIM_MASK_IGMP_TRACE)) - -#define PIM_DO_DEBUG_PIM_EVENTS (qpim_debugs |= PIM_MASK_PIM_EVENTS) -#define PIM_DO_DEBUG_PIM_PACKETS (qpim_debugs |= PIM_MASK_PIM_PACKETS) -#define PIM_DO_DEBUG_PIM_PACKETDUMP_SEND (qpim_debugs |= PIM_MASK_PIM_PACKETDUMP_SEND) -#define PIM_DO_DEBUG_PIM_PACKETDUMP_RECV (qpim_debugs |= PIM_MASK_PIM_PACKETDUMP_RECV) -#define PIM_DO_DEBUG_PIM_TRACE (qpim_debugs |= PIM_MASK_PIM_TRACE) -#define PIM_DO_DEBUG_PIM_TRACE_DETAIL (qpim_debugs |= PIM_MASK_PIM_TRACE_DETAIL) -#define PIM_DO_DEBUG_IGMP_EVENTS (qpim_debugs |= PIM_MASK_IGMP_EVENTS) -#define PIM_DO_DEBUG_IGMP_PACKETS (qpim_debugs |= PIM_MASK_IGMP_PACKETS) -#define PIM_DO_DEBUG_IGMP_TRACE (qpim_debugs |= PIM_MASK_IGMP_TRACE) -#define PIM_DO_DEBUG_IGMP_TRACE_DETAIL (qpim_debugs |= PIM_MASK_IGMP_TRACE_DETAIL) -#define PIM_DO_DEBUG_ZEBRA (qpim_debugs |= PIM_MASK_ZEBRA) -#define PIM_DO_DEBUG_SSMPINGD (qpim_debugs |= PIM_MASK_SSMPINGD) -#define PIM_DO_DEBUG_MROUTE (qpim_debugs |= PIM_MASK_MROUTE) -#define PIM_DO_DEBUG_MROUTE_DETAIL (qpim_debugs |= PIM_MASK_MROUTE_DETAIL) -#define PIM_DO_DEBUG_PIM_HELLO (qpim_debugs |= PIM_MASK_PIM_HELLO) -#define PIM_DO_DEBUG_PIM_J_P (qpim_debugs |= PIM_MASK_PIM_J_P) -#define PIM_DO_DEBUG_PIM_REG (qpim_debugs |= PIM_MASK_PIM_REG) -#define PIM_DO_DEBUG_STATIC (qpim_debugs |= PIM_MASK_STATIC) -#define PIM_DO_DEBUG_MSDP_EVENTS (qpim_debugs |= PIM_MASK_MSDP_EVENTS) -#define PIM_DO_DEBUG_MSDP_PACKETS (qpim_debugs |= PIM_MASK_MSDP_PACKETS) -#define PIM_DO_DEBUG_MSDP_INTERNAL (qpim_debugs |= PIM_MASK_MSDP_INTERNAL) -#define PIM_DO_DEBUG_PIM_NHT (qpim_debugs |= PIM_MASK_PIM_NHT) -#define PIM_DO_DEBUG_PIM_NHT_RP (qpim_debugs |= PIM_MASK_PIM_NHT_RP) -#define PIM_DO_DEBUG_MTRACE (qpim_debugs |= PIM_MASK_MTRACE) - -#define PIM_DONT_DEBUG_PIM_EVENTS (qpim_debugs &= ~PIM_MASK_PIM_EVENTS) -#define PIM_DONT_DEBUG_PIM_PACKETS (qpim_debugs &= ~PIM_MASK_PIM_PACKETS) -#define PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND (qpim_debugs &= ~PIM_MASK_PIM_PACKETDUMP_SEND) -#define PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV (qpim_debugs &= ~PIM_MASK_PIM_PACKETDUMP_RECV) -#define PIM_DONT_DEBUG_PIM_TRACE (qpim_debugs &= ~PIM_MASK_PIM_TRACE) -#define PIM_DONT_DEBUG_PIM_TRACE_DETAIL (qpim_debugs &= ~PIM_MASK_PIM_TRACE_DETAIL) -#define PIM_DONT_DEBUG_IGMP_EVENTS (qpim_debugs &= ~PIM_MASK_IGMP_EVENTS) -#define PIM_DONT_DEBUG_IGMP_PACKETS (qpim_debugs &= ~PIM_MASK_IGMP_PACKETS) -#define PIM_DONT_DEBUG_IGMP_TRACE (qpim_debugs &= ~PIM_MASK_IGMP_TRACE) -#define PIM_DONT_DEBUG_IGMP_TRACE_DETAIL (qpim_debugs &= ~PIM_MASK_IGMP_TRACE_DETAIL) -#define PIM_DONT_DEBUG_ZEBRA (qpim_debugs &= ~PIM_MASK_ZEBRA) -#define PIM_DONT_DEBUG_SSMPINGD (qpim_debugs &= ~PIM_MASK_SSMPINGD) -#define PIM_DONT_DEBUG_MROUTE (qpim_debugs &= ~PIM_MASK_MROUTE) -#define PIM_DONT_DEBUG_MROUTE_DETAIL (qpim_debugs &= ~PIM_MASK_MROUTE_DETAIL) -#define PIM_DONT_DEBUG_PIM_HELLO (qpim_debugs &= ~PIM_MASK_PIM_HELLO) -#define PIM_DONT_DEBUG_PIM_J_P (qpim_debugs &= ~PIM_MASK_PIM_J_P) -#define PIM_DONT_DEBUG_PIM_REG (qpim_debugs &= ~PIM_MASK_PIM_REG) -#define PIM_DONT_DEBUG_STATIC (qpim_debugs &= ~PIM_MASK_STATIC) -#define PIM_DONT_DEBUG_MSDP_EVENTS (qpim_debugs &= ~PIM_MASK_MSDP_EVENTS) -#define PIM_DONT_DEBUG_MSDP_PACKETS (qpim_debugs &= ~PIM_MASK_MSDP_PACKETS) -#define PIM_DONT_DEBUG_MSDP_INTERNAL (qpim_debugs &= ~PIM_MASK_MSDP_INTERNAL) -#define PIM_DONT_DEBUG_PIM_NHT (qpim_debugs &= ~PIM_MASK_PIM_NHT) -#define PIM_DONT_DEBUG_PIM_NHT_RP (qpim_debugs &= ~PIM_MASK_PIM_NHT_RP) -#define PIM_DONT_DEBUG_MTRACE (qpim_debugs &= ~PIM_MASK_MTRACE) +#define PIM_DEBUG_PIM_EVENTS (router->debugs & PIM_MASK_PIM_EVENTS) +#define PIM_DEBUG_PIM_EVENTS_DETAIL \ + (router->debugs & PIM_MASK_PIM_EVENTS_DETAIL) +#define PIM_DEBUG_PIM_PACKETS (router->debugs & PIM_MASK_PIM_PACKETS) +#define PIM_DEBUG_PIM_PACKETDUMP_SEND \ + (router->debugs & PIM_MASK_PIM_PACKETDUMP_SEND) +#define PIM_DEBUG_PIM_PACKETDUMP_RECV \ + (router->debugs & PIM_MASK_PIM_PACKETDUMP_RECV) +#define PIM_DEBUG_PIM_TRACE (router->debugs & PIM_MASK_PIM_TRACE) +#define PIM_DEBUG_PIM_TRACE_DETAIL (router->debugs & PIM_MASK_PIM_TRACE_DETAIL) +#define PIM_DEBUG_IGMP_EVENTS (router->debugs & PIM_MASK_IGMP_EVENTS) +#define PIM_DEBUG_IGMP_PACKETS (router->debugs & PIM_MASK_IGMP_PACKETS) +#define PIM_DEBUG_IGMP_TRACE (router->debugs & PIM_MASK_IGMP_TRACE) +#define PIM_DEBUG_IGMP_TRACE_DETAIL \ + (router->debugs & PIM_MASK_IGMP_TRACE_DETAIL) +#define PIM_DEBUG_ZEBRA (router->debugs & PIM_MASK_ZEBRA) +#define PIM_DEBUG_SSMPINGD (router->debugs & PIM_MASK_SSMPINGD) +#define PIM_DEBUG_MROUTE (router->debugs & PIM_MASK_MROUTE) +#define PIM_DEBUG_MROUTE_DETAIL (router->debugs & PIM_MASK_MROUTE_DETAIL) +#define PIM_DEBUG_PIM_HELLO (router->debugs & PIM_MASK_PIM_HELLO) +#define PIM_DEBUG_PIM_J_P (router->debugs & PIM_MASK_PIM_J_P) +#define PIM_DEBUG_PIM_REG (router->debugs & PIM_MASK_PIM_REG) +#define PIM_DEBUG_STATIC (router->debugs & PIM_MASK_STATIC) +#define PIM_DEBUG_MSDP_EVENTS (router->debugs & PIM_MASK_MSDP_EVENTS) +#define PIM_DEBUG_MSDP_PACKETS (router->debugs & PIM_MASK_MSDP_PACKETS) +#define PIM_DEBUG_MSDP_INTERNAL (router->debugs & PIM_MASK_MSDP_INTERNAL) +#define PIM_DEBUG_PIM_NHT (router->debugs & PIM_MASK_PIM_NHT) +#define PIM_DEBUG_PIM_NHT_DETAIL (router->debugs & PIM_MASK_PIM_NHT_DETAIL) +#define PIM_DEBUG_PIM_NHT_RP (router->debugs & PIM_MASK_PIM_NHT_RP) +#define PIM_DEBUG_MTRACE (router->debugs & PIM_MASK_MTRACE) + +#define PIM_DEBUG_EVENTS \ + (router->debugs \ + & (PIM_MASK_PIM_EVENTS | PIM_MASK_IGMP_EVENTS \ + | PIM_MASK_MSDP_EVENTS)) +#define PIM_DEBUG_PACKETS \ + (router->debugs \ + & (PIM_MASK_PIM_PACKETS | PIM_MASK_IGMP_PACKETS \ + | PIM_MASK_MSDP_PACKETS)) +#define PIM_DEBUG_TRACE \ + (router->debugs & (PIM_MASK_PIM_TRACE | PIM_MASK_IGMP_TRACE)) + +#define PIM_DO_DEBUG_PIM_EVENTS (router->debugs |= PIM_MASK_PIM_EVENTS) +#define PIM_DO_DEBUG_PIM_PACKETS (router->debugs |= PIM_MASK_PIM_PACKETS) +#define PIM_DO_DEBUG_PIM_PACKETDUMP_SEND \ + (router->debugs |= PIM_MASK_PIM_PACKETDUMP_SEND) +#define PIM_DO_DEBUG_PIM_PACKETDUMP_RECV \ + (router->debugs |= PIM_MASK_PIM_PACKETDUMP_RECV) +#define PIM_DO_DEBUG_PIM_TRACE (router->debugs |= PIM_MASK_PIM_TRACE) +#define PIM_DO_DEBUG_PIM_TRACE_DETAIL \ + (router->debugs |= PIM_MASK_PIM_TRACE_DETAIL) +#define PIM_DO_DEBUG_IGMP_EVENTS (router->debugs |= PIM_MASK_IGMP_EVENTS) +#define PIM_DO_DEBUG_IGMP_PACKETS (router->debugs |= PIM_MASK_IGMP_PACKETS) +#define PIM_DO_DEBUG_IGMP_TRACE (router->debugs |= PIM_MASK_IGMP_TRACE) +#define PIM_DO_DEBUG_IGMP_TRACE_DETAIL \ + (router->debugs |= PIM_MASK_IGMP_TRACE_DETAIL) +#define PIM_DO_DEBUG_ZEBRA (router->debugs |= PIM_MASK_ZEBRA) +#define PIM_DO_DEBUG_SSMPINGD (router->debugs |= PIM_MASK_SSMPINGD) +#define PIM_DO_DEBUG_MROUTE (router->debugs |= PIM_MASK_MROUTE) +#define PIM_DO_DEBUG_MROUTE_DETAIL (router->debugs |= PIM_MASK_MROUTE_DETAIL) +#define PIM_DO_DEBUG_PIM_HELLO (router->debugs |= PIM_MASK_PIM_HELLO) +#define PIM_DO_DEBUG_PIM_J_P (router->debugs |= PIM_MASK_PIM_J_P) +#define PIM_DO_DEBUG_PIM_REG (router->debugs |= PIM_MASK_PIM_REG) +#define PIM_DO_DEBUG_STATIC (router->debugs |= PIM_MASK_STATIC) +#define PIM_DO_DEBUG_MSDP_EVENTS (router->debugs |= PIM_MASK_MSDP_EVENTS) +#define PIM_DO_DEBUG_MSDP_PACKETS (router->debugs |= PIM_MASK_MSDP_PACKETS) +#define PIM_DO_DEBUG_MSDP_INTERNAL (router->debugs |= PIM_MASK_MSDP_INTERNAL) +#define PIM_DO_DEBUG_PIM_NHT (router->debugs |= PIM_MASK_PIM_NHT) +#define PIM_DO_DEBUG_PIM_NHT_RP (router->debugs |= PIM_MASK_PIM_NHT_RP) +#define PIM_DO_DEBUG_MTRACE (router->debugs |= PIM_MASK_MTRACE) + +#define PIM_DONT_DEBUG_PIM_EVENTS (router->debugs &= ~PIM_MASK_PIM_EVENTS) +#define PIM_DONT_DEBUG_PIM_PACKETS (router->debugs &= ~PIM_MASK_PIM_PACKETS) +#define PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND \ + (router->debugs &= ~PIM_MASK_PIM_PACKETDUMP_SEND) +#define PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV \ + (router->debugs &= ~PIM_MASK_PIM_PACKETDUMP_RECV) +#define PIM_DONT_DEBUG_PIM_TRACE (router->debugs &= ~PIM_MASK_PIM_TRACE) +#define PIM_DONT_DEBUG_PIM_TRACE_DETAIL \ + (router->debugs &= ~PIM_MASK_PIM_TRACE_DETAIL) +#define PIM_DONT_DEBUG_IGMP_EVENTS (router->debugs &= ~PIM_MASK_IGMP_EVENTS) +#define PIM_DONT_DEBUG_IGMP_PACKETS (router->debugs &= ~PIM_MASK_IGMP_PACKETS) +#define PIM_DONT_DEBUG_IGMP_TRACE (router->debugs &= ~PIM_MASK_IGMP_TRACE) +#define PIM_DONT_DEBUG_IGMP_TRACE_DETAIL \ + (router->debugs &= ~PIM_MASK_IGMP_TRACE_DETAIL) +#define PIM_DONT_DEBUG_ZEBRA (router->debugs &= ~PIM_MASK_ZEBRA) +#define PIM_DONT_DEBUG_SSMPINGD (router->debugs &= ~PIM_MASK_SSMPINGD) +#define PIM_DONT_DEBUG_MROUTE (router->debugs &= ~PIM_MASK_MROUTE) +#define PIM_DONT_DEBUG_MROUTE_DETAIL (router->debugs &= ~PIM_MASK_MROUTE_DETAIL) +#define PIM_DONT_DEBUG_PIM_HELLO (router->debugs &= ~PIM_MASK_PIM_HELLO) +#define PIM_DONT_DEBUG_PIM_J_P (router->debugs &= ~PIM_MASK_PIM_J_P) +#define PIM_DONT_DEBUG_PIM_REG (router->debugs &= ~PIM_MASK_PIM_REG) +#define PIM_DONT_DEBUG_STATIC (router->debugs &= ~PIM_MASK_STATIC) +#define PIM_DONT_DEBUG_MSDP_EVENTS (router->debugs &= ~PIM_MASK_MSDP_EVENTS) +#define PIM_DONT_DEBUG_MSDP_PACKETS (router->debugs &= ~PIM_MASK_MSDP_PACKETS) +#define PIM_DONT_DEBUG_MSDP_INTERNAL (router->debugs &= ~PIM_MASK_MSDP_INTERNAL) +#define PIM_DONT_DEBUG_PIM_NHT (router->debugs &= ~PIM_MASK_PIM_NHT) +#define PIM_DONT_DEBUG_PIM_NHT_RP (router->debugs &= ~PIM_MASK_PIM_NHT_RP) +#define PIM_DONT_DEBUG_MTRACE (router->debugs &= ~PIM_MASK_MTRACE) + +void pim_router_init(void); +void pim_router_terminate(void); void pim_init(void); void pim_terminate(void); diff --git a/ripd/RIPv2-MIB.txt b/ripd/RIPv2-MIB.txt deleted file mode 100644 index 6c92fb5f0c..0000000000 --- a/ripd/RIPv2-MIB.txt +++ /dev/null @@ -1,530 +0,0 @@ - RIPv2-MIB DEFINITIONS ::= BEGIN - - IMPORTS - MODULE-IDENTITY, OBJECT-TYPE, Counter32, - TimeTicks, IpAddress FROM SNMPv2-SMI - TEXTUAL-CONVENTION, RowStatus FROM SNMPv2-TC - MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF - mib-2 FROM RFC1213-MIB; - - -- This MIB module uses the extended OBJECT-TYPE macro as - -- defined in [9]. - - rip2 MODULE-IDENTITY - LAST-UPDATED "9407272253Z" -- Wed Jul 27 22:53:04 PDT 1994 - ORGANIZATION "IETF RIP-II Working Group" - CONTACT-INFO - " Fred Baker - Postal: Cisco Systems - 519 Lado Drive - Santa Barbara, California 93111 - Tel: +1 805 681 0115 - E-Mail: fbaker@cisco.com - - Postal: Gary Malkin - Xylogics, Inc. - 53 Third Avenue - Burlington, MA 01803 - - Phone: (617) 272-8140 - EMail: gmalkin@Xylogics.COM" - DESCRIPTION - "The MIB module to describe the RIP2 Version 2 Protocol" - ::= { mib-2 23 } - - -- RIP-2 Management Information Base - - -- the RouteTag type represents the contents of the - -- Route Domain field in the packet header or route entry. - -- The use of the Route Domain is deprecated. - - RouteTag ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "the RouteTag type represents the contents of the Route Domain - field in the packet header or route entry" - SYNTAX OCTET STRING (SIZE (2)) - ---4.1 Global Counters - --- The RIP-2 Globals Group. --- Implementation of this group is mandatory for systems --- which implement RIP-2. - --- These counters are intended to facilitate debugging quickly --- changing routes or failing neighbors - -rip2Globals OBJECT IDENTIFIER ::= { rip2 1 } - - rip2GlobalRouteChanges OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of route changes made to the IP Route - Database by RIP. This does not include the refresh - of a route's age." - ::= { rip2Globals 1 } - - rip2GlobalQueries OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of responses sent to RIP queries - from other systems." - ::= { rip2Globals 2 } - ---4.2 RIP Interface Tables - --- RIP Interfaces Groups --- Implementation of these Groups is mandatory for systems --- which implement RIP-2. - --- The RIP Interface Status Table. - - rip2IfStatTable OBJECT-TYPE - SYNTAX SEQUENCE OF Rip2IfStatEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A list of subnets which require separate - status monitoring in RIP." - ::= { rip2 2 } - - rip2IfStatEntry OBJECT-TYPE - SYNTAX Rip2IfStatEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A Single Routing Domain in a single Subnet." - INDEX { rip2IfStatAddress } - ::= { rip2IfStatTable 1 } - - Rip2IfStatEntry ::= - SEQUENCE { - rip2IfStatAddress - IpAddress, - rip2IfStatRcvBadPackets - Counter32, - rip2IfStatRcvBadRoutes - Counter32, - rip2IfStatSentUpdates - Counter32, - rip2IfStatStatus - RowStatus - } - - rip2IfStatAddress OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP Address of this system on the indicated - subnet. For unnumbered interfaces, the value 0.0.0.N, - where the least significant 24 bits (N) is the ifIndex - for the IP Interface in network byte order." - ::= { rip2IfStatEntry 1 } - - rip2IfStatRcvBadPackets OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of RIP response packets received by - the RIP process which were subsequently discarded - for any reason (e.g. a version 0 packet, or an - unknown command type)." - ::= { rip2IfStatEntry 2 } - - rip2IfStatRcvBadRoutes OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of routes, in valid RIP packets, - which were ignored for any reason (e.g. unknown - address family, or invalid metric)." - ::= { rip2IfStatEntry 3 } - - rip2IfStatSentUpdates OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of triggered RIP updates actually - sent on this interface. This explicitly does - NOT include full updates sent containing new - information." - ::= { rip2IfStatEntry 4 } - - rip2IfStatStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Writing invalid has the effect of deleting - this interface." - ::= { rip2IfStatEntry 5 } - --- The RIP Interface Configuration Table. - - rip2IfConfTable OBJECT-TYPE - SYNTAX SEQUENCE OF Rip2IfConfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A list of subnets which require separate - configuration in RIP." - ::= { rip2 3 } - - rip2IfConfEntry OBJECT-TYPE - SYNTAX Rip2IfConfEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A Single Routing Domain in a single Subnet." - INDEX { rip2IfConfAddress } - ::= { rip2IfConfTable 1 } - - Rip2IfConfEntry ::= - SEQUENCE { - rip2IfConfAddress - IpAddress, - rip2IfConfDomain - RouteTag, - rip2IfConfAuthType - INTEGER, - rip2IfConfAuthKey - OCTET STRING (SIZE(0..16)), - rip2IfConfSend - INTEGER, - rip2IfConfReceive - INTEGER, - rip2IfConfDefaultMetric - INTEGER, - rip2IfConfStatus - RowStatus, - rip2IfConfSrcAddress - IpAddress - } - - rip2IfConfAddress OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP Address of this system on the indicated - subnet. For unnumbered interfaces, the value 0.0.0.N, - where the least significant 24 bits (N) is the ifIndex - for the IP Interface in network byte order." - ::= { rip2IfConfEntry 1 } - - rip2IfConfDomain OBJECT-TYPE - SYNTAX RouteTag - MAX-ACCESS read-create - STATUS obsolete - DESCRIPTION - "Value inserted into the Routing Domain field - of all RIP packets sent on this interface." - DEFVAL { '0000'h } - ::= { rip2IfConfEntry 2 } - - rip2IfConfAuthType OBJECT-TYPE - SYNTAX INTEGER { - noAuthentication (1), - simplePassword (2), - md5 (3) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The type of Authentication used on this - interface." - DEFVAL { noAuthentication } - ::= { rip2IfConfEntry 3 } - - rip2IfConfAuthKey OBJECT-TYPE - SYNTAX OCTET STRING (SIZE(0..16)) - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The value to be used as the Authentication Key - whenever the corresponding instance of - rip2IfConfAuthType has a value other than - noAuthentication. A modification of the corresponding - instance of rip2IfConfAuthType does not modify - the rip2IfConfAuthKey value. If a string shorter - than 16 octets is supplied, it will be left- - justified and padded to 16 octets, on the right, - with nulls (0x00). - - Reading this object always results in an OCTET - STRING of length zero; authentication may not - be bypassed by reading the MIB object." - DEFVAL { ''h } - ::= { rip2IfConfEntry 4 } - - rip2IfConfSend OBJECT-TYPE - SYNTAX INTEGER { - doNotSend (1), - ripVersion1 (2), - rip1Compatible (3), - ripVersion2 (4), - ripV1Demand (5), - ripV2Demand (6) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "What the router sends on this interface. - ripVersion1 implies sending RIP updates compliant - with RFC 1058. rip1Compatible implies - broadcasting RIP-2 updates using RFC 1058 route - subsumption rules. ripVersion2 implies - multicasting RIP-2 updates. ripV1Demand indicates - the use of Demand RIP on a WAN interface under RIP - Version 1 rules. ripV2Demand indicates the use of - Demand RIP on a WAN interface under Version 2 rules." - DEFVAL { rip1Compatible } - ::= { rip2IfConfEntry 5 } - - rip2IfConfReceive OBJECT-TYPE - SYNTAX INTEGER { - rip1 (1), - rip2 (2), - rip1OrRip2 (3), - doNotRecieve (4) - } - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This indicates which version of RIP updates - are to be accepted. Note that rip2 and - rip1OrRip2 implies reception of multicast - packets." - DEFVAL { rip1OrRip2 } - ::= { rip2IfConfEntry 6 } - - rip2IfConfDefaultMetric OBJECT-TYPE - SYNTAX INTEGER ( 0..15 ) - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "This variable indicates the metric that is to - be used for the default route entry in RIP updates - originated on this interface. A value of zero - indicates that no default route should be - originated; in this case, a default route via - another router may be propagated." - ::= { rip2IfConfEntry 7 } - - rip2IfConfStatus OBJECT-TYPE - SYNTAX RowStatus - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "Writing invalid has the effect of deleting - this interface." - ::= { rip2IfConfEntry 8 } - - rip2IfConfSrcAddress OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-create - STATUS current - DESCRIPTION - "The IP Address this system will use as a source - address on this interface. If it is a numbered - interface, this MUST be the same value as - rip2IfConfAddress. On unnumbered interfaces, - it must be the value of rip2IfConfAddress for - some interface on the system." - ::= { rip2IfConfEntry 9 } - ---4.3 Peer Table - --- Peer Table - --- The RIP Peer Group --- Implementation of this Group is Optional - --- This group provides information about active peer --- relationships intended to assist in debugging. An --- active peer is a router from which a valid RIP --- updated has been heard in the last 180 seconds. - - rip2PeerTable OBJECT-TYPE - SYNTAX SEQUENCE OF Rip2PeerEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "A list of RIP Peers." - ::= { rip2 4 } - - rip2PeerEntry OBJECT-TYPE - SYNTAX Rip2PeerEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information regarding a single routing peer." - INDEX { rip2PeerAddress, rip2PeerDomain } - ::= { rip2PeerTable 1 } - - Rip2PeerEntry ::= - SEQUENCE { - rip2PeerAddress - IpAddress, - rip2PeerDomain - RouteTag, - rip2PeerLastUpdate - TimeTicks, - rip2PeerVersion - INTEGER, - rip2PeerRcvBadPackets - Counter32, - rip2PeerRcvBadRoutes - Counter32 - } - - rip2PeerAddress OBJECT-TYPE - SYNTAX IpAddress - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The IP Address that the peer is using as its source - address. Note that on an unnumbered link, this may - not be a member of any subnet on the system." - ::= { rip2PeerEntry 1 } - - rip2PeerDomain OBJECT-TYPE - SYNTAX RouteTag - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value in the Routing Domain field in RIP - packets received from the peer. As domain suuport - is deprecated, this must be zero." - ::= { rip2PeerEntry 2 } - - rip2PeerLastUpdate OBJECT-TYPE - SYNTAX TimeTicks - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The value of sysUpTime when the most recent - RIP update was received from this system." - ::= { rip2PeerEntry 3 } - - rip2PeerVersion OBJECT-TYPE - SYNTAX INTEGER ( 0..255 ) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The RIP version number in the header of the - last RIP packet received." - ::= { rip2PeerEntry 4 } - - rip2PeerRcvBadPackets OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of RIP response packets from this - peer discarded as invalid." - ::= { rip2PeerEntry 5 } - - - rip2PeerRcvBadRoutes OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of routes from this peer that were - ignored because the entry format was invalid." - ::= { rip2PeerEntry 6 } - --- conformance information - -rip2Conformance OBJECT IDENTIFIER ::= { rip2 5 } - -rip2Groups OBJECT IDENTIFIER ::= { rip2Conformance 1 } -rip2Compliances OBJECT IDENTIFIER ::= { rip2Conformance 2 } - --- compliance statements -rip2Compliance MODULE-COMPLIANCE - STATUS current - DESCRIPTION - "The compliance statement " - MODULE -- this module - MANDATORY-GROUPS { - rip2GlobalGroup, - rip2IfStatGroup, - rip2IfConfGroup, - rip2PeerGroup - } - GROUP rip2GlobalGroup - DESCRIPTION - "This group defines global controls for RIP-II systems." - GROUP rip2IfStatGroup - DESCRIPTION - "This group defines interface statistics for RIP-II systems." - GROUP rip2IfConfGroup - DESCRIPTION - "This group defines interface configuration for RIP-II systems." - GROUP rip2PeerGroup - DESCRIPTION - "This group defines peer information for RIP-II systems." - ::= { rip2Compliances 1 } - --- units of conformance - -rip2GlobalGroup OBJECT-GROUP - OBJECTS { - rip2GlobalRouteChanges, - rip2GlobalQueries - } - STATUS current - DESCRIPTION - "This group defines global controls for RIP-II systems." - ::= { rip2Groups 1 } -rip2IfStatGroup OBJECT-GROUP - OBJECTS { - rip2IfStatAddress, - rip2IfStatRcvBadPackets, - rip2IfStatRcvBadRoutes, - rip2IfStatSentUpdates, - rip2IfStatStatus - } - STATUS current - DESCRIPTION - "This group defines interface statistics for RIP-II systems." - ::= { rip2Groups 2 } -rip2IfConfGroup OBJECT-GROUP - OBJECTS { - rip2IfConfAddress, - rip2IfConfAuthType, - rip2IfConfAuthKey, - rip2IfConfSend, - rip2IfConfReceive, - rip2IfConfDefaultMetric, - rip2IfConfStatus, - rip2IfConfSrcAddress - } - STATUS current - DESCRIPTION - "This group defines interface configuration for RIP-II systems." - ::= { rip2Groups 3 } -rip2PeerGroup OBJECT-GROUP - OBJECTS { - rip2PeerAddress, - rip2PeerDomain, - rip2PeerLastUpdate, - rip2PeerVersion, - rip2PeerRcvBadPackets, - rip2PeerRcvBadRoutes - } - STATUS current - DESCRIPTION - "This group defines peer information for RIP-II systems." - ::= { rip2Groups 4 } -END diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index e0e5d95895..5bb81ef157 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -210,7 +210,8 @@ DEFPY (rip_distance_source, { if (!no) { nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY, + distance_str); nb_cli_enqueue_change(vty, "./access-list", acl ? NB_OP_MODIFY : NB_OP_DELETE, acl); } else diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c index 2ce289e38f..3356d99c2a 100644 --- a/ripd/rip_debug.c +++ b/ripd/rip_debug.c @@ -204,13 +204,6 @@ static int config_write_debug(struct vty *vty) return write; } -void rip_debug_reset(void) -{ - rip_debug_event = 0; - rip_debug_packet = 0; - rip_debug_zebra = 0; -} - void rip_debug_init(void) { rip_debug_event = 0; diff --git a/ripd/rip_debug.h b/ripd/rip_debug.h index c3b15d2e15..3d819ccd0b 100644 --- a/ripd/rip_debug.h +++ b/ripd/rip_debug.h @@ -47,6 +47,5 @@ extern unsigned long rip_debug_packet; extern unsigned long rip_debug_zebra; extern void rip_debug_init(void); -extern void rip_debug_reset(void); #endif /* _ZEBRA_RIP_DEBUG_H */ diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 3d11ba1464..96b1cd8938 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -531,15 +531,6 @@ static void rip_interface_reset(struct rip_interface *ri) rip_interface_clean(ri); } -void rip_interfaces_reset(void) -{ - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); - struct interface *ifp; - - FOR_ALL_INTERFACES (vrf, ifp) - rip_interface_reset(ifp->info); -} - int rip_if_down(struct interface *ifp) { struct route_node *rp; diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c index 421b0afe38..4e445bd46d 100644 --- a/ripd/rip_northbound.c +++ b/ripd/rip_northbound.c @@ -170,6 +170,7 @@ static int ripd_instance_distance_source_create(enum nb_event event, return NB_OK; yang_dnode_get_ipv4p(&prefix, dnode, "./prefix"); + apply_mask_ipv4(&prefix); /* Get RIP distance node. */ rn = route_node_get(rip_distance_table, (struct prefix *)&prefix); @@ -317,6 +318,7 @@ static int ripd_instance_network_create(enum nb_event event, return NB_OK; yang_dnode_get_ipv4p(&p, dnode, NULL); + apply_mask_ipv4((struct prefix_ipv4 *)&p); return rip_enable_network_add(&p); } @@ -330,6 +332,7 @@ static int ripd_instance_network_delete(enum nb_event event, return NB_OK; yang_dnode_get_ipv4p(&p, dnode, NULL); + apply_mask_ipv4((struct prefix_ipv4 *)&p); return rip_enable_network_delete(&p); } @@ -605,10 +608,9 @@ ripd_instance_redistribute_route_map_delete(enum nb_event event, type = yang_dnode_get_enum(dnode, "../protocol"); - if (rip->route_map[type].name) { - free(rip->route_map[type].name); - rip->route_map[type].name = NULL; - } + free(rip->route_map[type].name); + rip->route_map[type].name = NULL; + rip->route_map[type].map = NULL; return NB_OK; } @@ -667,6 +669,7 @@ static int ripd_instance_static_route_create(enum nb_event event, return NB_OK; yang_dnode_get_ipv4p(&p, dnode, NULL); + apply_mask_ipv4(&p); memset(&nh, 0, sizeof(nh)); nh.type = NEXTHOP_TYPE_IPV4; @@ -685,6 +688,7 @@ static int ripd_instance_static_route_delete(enum nb_event event, return NB_OK; yang_dnode_get_ipv4p(&p, dnode, NULL); + apply_mask_ipv4(&p); rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0); diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c index b69b2466d5..b34f944c9e 100644 --- a/ripd/rip_routemap.c +++ b/ripd/rip_routemap.c @@ -517,11 +517,6 @@ static struct route_map_rule_cmd route_set_tag_cmd = { #define MATCH_STR "Match values from routing table\n" #define SET_STR "Set values in destination routing protocol\n" -void rip_route_map_reset() -{ - ; -} - /* Route-map init */ void rip_route_map_init() { diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 20f543a258..fff8681775 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -147,11 +147,6 @@ static int rip_zebra_read_route(int command, struct zclient *zclient, return 0; } -void rip_zclient_reset(void) -{ - zclient_reset(zclient); -} - void rip_redistribute_conf_update(int type) { zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, diff --git a/ripd/ripd.c b/ripd/ripd.c index 4a6765308e..0ce5324057 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -68,6 +68,9 @@ static void rip_output_process(struct connected *, struct sockaddr_in *, int, static int rip_triggered_update(struct thread *); static int rip_update_jitter(unsigned long); +static void rip_distribute_update(struct distribute_ctx *ctx, + struct distribute *dist); + /* RIP output routes type. */ enum { rip_all_route, rip_changed_route }; @@ -328,7 +331,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, } /* All interface filter check. */ - dist = distribute_lookup(NULL); + dist = distribute_lookup(rip->distribute_ctx, NULL); if (dist) { if (dist->list[distribute]) { alist = access_list_lookup(AFI_IP, @@ -2702,7 +2705,13 @@ int rip_create(int socket) /* Create read and timer thread. */ rip_event(RIP_READ, rip->sock); rip_event(RIP_UPDATE_EVENT, 1); - + /* Distribute list install. */ + rip->distribute_ctx = distribute_list_ctx_create( + vrf_lookup_by_id(VRF_DEFAULT)); + distribute_list_add_hook(rip->distribute_ctx, + rip_distribute_update); + distribute_list_delete_hook(rip->distribute_ctx, + rip_distribute_update); return 0; } @@ -3121,7 +3130,7 @@ DEFUN (show_ip_rip_status, vty_out(vty, " garbage collect after %u seconds\n", rip->garbage_time); /* Filtering status show. */ - config_show_distribute(vty); + config_show_distribute(vty, rip->distribute_ctx); /* Default metric information. */ vty_out(vty, " Default redistribution metric is %u\n", @@ -3215,7 +3224,8 @@ static int config_write_rip(struct vty *vty) nb_cli_show_dnode_cmds(vty, dnode, false); /* Distribute configuration. */ - write += config_write_distribute(vty); + write += config_write_distribute(vty, + rip->distribute_ctx); /* Interface routemap configuration */ write += config_write_if_rmap(vty); @@ -3227,7 +3237,8 @@ static int config_write_rip(struct vty *vty) static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1}; /* Distribute-list update functions. */ -static void rip_distribute_update(struct distribute *dist) +static void rip_distribute_update(struct distribute_ctx *ctx, + struct distribute *dist) { struct interface *ifp; struct rip_interface *ri; @@ -3288,9 +3299,11 @@ void rip_distribute_update_interface(struct interface *ifp) { struct distribute *dist; - dist = distribute_lookup(ifp->name); + if (!rip) + return; + dist = distribute_lookup(rip->distribute_ctx, ifp->name); if (dist) - rip_distribute_update(dist); + rip_distribute_update(rip->distribute_ctx, dist); } /* Update all interface's distribute list. */ @@ -3364,9 +3377,10 @@ void rip_clean(void) if (rip->route_map[i].name) free(rip->route_map[i].name); - XFREE(MTYPE_ROUTE_TABLE, rip->table); - XFREE(MTYPE_ROUTE_TABLE, rip->neighbor); + route_table_finish(rip->table); + route_table_finish(rip->neighbor); + distribute_list_delete(&rip->distribute_ctx); XFREE(MTYPE_RIP, rip); rip = NULL; } @@ -3390,7 +3404,6 @@ static void rip_if_rmap_update(struct if_rmap *if_rmap) return; ri = ifp->info; - if (if_rmap->routemap[IF_RMAP_IN]) { rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]); if (rmap) @@ -3472,8 +3485,6 @@ void rip_init(void) /* Distribute list install. */ distribute_list_init(RIP_NODE); - distribute_list_add_hook(rip_distribute_update); - distribute_list_delete_hook(rip_distribute_update); /* Route-map */ rip_route_map_init(); diff --git a/ripd/ripd.h b/ripd/ripd.h index d4fb230a20..7b8fe3a906 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -23,6 +23,7 @@ #include "hook.h" #include "nexthop.h" +#include "distribute.h" #include "rip_memory.h" /* RIP version number. */ @@ -150,6 +151,9 @@ struct rip { bool metric_config; uint8_t metric; } route_map[ZEBRA_ROUTE_MAX]; + + /* For distribute-list container */ + struct distribute_ctx *distribute_ctx; }; /* RIP routing table entry which belong to rip_packet. */ @@ -376,17 +380,14 @@ extern void rip_init(void); extern void rip_clean(void); extern void rip_clean_network(void); extern void rip_interfaces_clean(void); -extern void rip_interfaces_reset(void); extern int rip_passive_nondefault_set(const char *ifname); extern int rip_passive_nondefault_unset(const char *ifname); extern void rip_passive_nondefault_clean(void); extern void rip_if_init(void); extern void rip_if_down_all(void); extern void rip_route_map_init(void); -extern void rip_route_map_reset(void); extern void rip_zclient_init(struct thread_master *); extern void rip_zclient_stop(void); -extern void rip_zclient_reset(void); extern int if_check_address(struct in_addr addr); extern int rip_create(int socket); diff --git a/ripd/subdir.am b/ripd/subdir.am index ed74047cce..1c2f8d64c8 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -9,9 +9,6 @@ dist_examples_DATA += ripd/ripd.conf.sample vtysh_scan += \ $(top_srcdir)/ripd/rip_cli.c \ $(top_srcdir)/ripd/rip_debug.c \ - $(top_srcdir)/ripd/rip_interface.c \ - $(top_srcdir)/ripd/rip_offset.c \ - $(top_srcdir)/ripd/rip_zebra.c \ $(top_srcdir)/ripd/ripd.c \ # end @@ -59,5 +56,3 @@ ripd_ripd_snmp_la_SOURCES = ripd/rip_snmp.c ripd_ripd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 ripd_ripd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic ripd_ripd_snmp_la_LIBADD = lib/libfrrsnmp.la - -EXTRA_DIST += ripd/RIPv2-MIB.txt diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c new file mode 100644 index 0000000000..a187e80fd7 --- /dev/null +++ b/ripngd/ripng_cli.c @@ -0,0 +1,489 @@ +/* + * Copyright (C) 1998 Kunihiro Ishiguro + * Copyright (C) 2018 NetDEF, Inc. + * Renato Westphal + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "if.h" +#include "vrf.h" +#include "log.h" +#include "prefix.h" +#include "command.h" +#include "northbound_cli.h" +#include "libfrr.h" + +#include "ripngd/ripngd.h" +#include "ripngd/ripng_cli.h" +#ifndef VTYSH_EXTRACT_PL +#include "ripngd/ripng_cli_clippy.c" +#endif + +/* + * XPath: /frr-ripngd:ripngd/instance + */ +DEFPY_NOSH (router_ripng, + router_ripng_cmd, + "router ripng", + "Enable a routing process\n" + "Make RIPng instance command\n") +{ + int ret; + + nb_cli_enqueue_change(vty, "/frr-ripngd:ripngd/instance", NB_OP_CREATE, + NULL); + + ret = nb_cli_apply_changes(vty, NULL); + if (ret == CMD_SUCCESS) + VTY_PUSH_XPATH(RIPNG_NODE, "/frr-ripngd:ripngd/instance"); + + return ret; +} + +DEFPY (no_router_ripng, + no_router_ripng_cmd, + "no router ripng", + NO_STR + "Enable a routing process\n" + "Make RIPng instance command\n") +{ + nb_cli_enqueue_change(vty, "/frr-ripngd:ripngd/instance", NB_OP_DELETE, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, "!\n"); + vty_out(vty, "router ripng\n"); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/allow-ecmp + */ +DEFPY (ripng_allow_ecmp, + ripng_allow_ecmp_cmd, + "[no] allow-ecmp", + NO_STR + "Allow Equal Cost MultiPath\n") +{ + nb_cli_enqueue_change(vty, "./allow-ecmp", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_allow_ecmp(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " allow-ecmp\n"); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/default-information-originate + */ +DEFPY (ripng_default_information_originate, + ripng_default_information_originate_cmd, + "[no] default-information originate", + NO_STR + "Default route information\n" + "Distribute default route\n") +{ + nb_cli_enqueue_change(vty, "./default-information-originate", + NB_OP_MODIFY, no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_default_information_originate(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " default-information originate\n"); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/default-metric + */ +DEFPY (ripng_default_metric, + ripng_default_metric_cmd, + "default-metric (1-16)", + "Set a metric of redistribute routes\n" + "Default metric\n") +{ + nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY, + default_metric_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY (no_ripng_default_metric, + no_ripng_default_metric_cmd, + "no default-metric [(1-16)]", + NO_STR + "Set a metric of redistribute routes\n" + "Default metric\n") +{ + nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_default_metric(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " default-metric %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/network + */ +DEFPY (ripng_network_prefix, + ripng_network_prefix_cmd, + "[no] network X:X::X:X/M", + NO_STR + "RIPng enable on specified interface or network.\n" + "IPv6 network\n") +{ + nb_cli_enqueue_change(vty, "./network", + no ? NB_OP_DELETE : NB_OP_CREATE, network_str); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_network_prefix(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/interface + */ +DEFPY (ripng_network_if, + ripng_network_if_cmd, + "[no] network WORD", + NO_STR + "RIPng enable on specified interface or network.\n" + "Interface name\n") +{ + nb_cli_enqueue_change(vty, "./interface", + no ? NB_OP_DELETE : NB_OP_CREATE, network); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_network_interface(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/offset-list + */ +DEFPY (ripng_offset_list, + ripng_offset_list_cmd, + "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]", + NO_STR + "Modify RIPng metric\n" + "Access-list name\n" + "For incoming updates\n" + "For outgoing updates\n" + "Metric value\n" + "Interface to match\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl); + nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY, + metric_str); + } else + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + + return nb_cli_apply_changes( + vty, "./offset-list[interface='%s'][direction='%s']", + ifname ? ifname : "*", direction); +} + +void cli_show_ripng_offset_list(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const char *interface; + + interface = yang_dnode_get_string(dnode, "./interface"); + + vty_out(vty, " offset-list %s %s %s", + yang_dnode_get_string(dnode, "./access-list"), + yang_dnode_get_string(dnode, "./direction"), + yang_dnode_get_string(dnode, "./metric")); + if (!strmatch(interface, "*")) + vty_out(vty, " %s", interface); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/passive-interface + */ +DEFPY (ripng_passive_interface, + ripng_passive_interface_cmd, + "[no] passive-interface IFNAME", + NO_STR + "Suppress routing updates on an interface\n" + "Interface name\n") +{ + nb_cli_enqueue_change(vty, "./passive-interface", + no ? NB_OP_DELETE : NB_OP_CREATE, ifname); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_passive_interface(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " passive-interface %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/redistribute + */ +DEFPY (ripng_redistribute, + ripng_redistribute_cmd, + "[no] redistribute " FRR_REDIST_STR_RIPNGD "$protocol [{metric (0-16)|route-map WORD}]", + NO_STR + REDIST_STR + FRR_REDIST_HELP_STR_RIPNGD + "Metric\n" + "Metric value\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./route-map", + route_map ? NB_OP_MODIFY : NB_OP_DELETE, + route_map); + nb_cli_enqueue_change(vty, "./metric", + metric_str ? NB_OP_MODIFY : NB_OP_DELETE, + metric_str); + } else + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + + return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']", + protocol); +} + +void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " redistribute %s", + yang_dnode_get_string(dnode, "./protocol")); + if (yang_dnode_exists(dnode, "./metric")) + vty_out(vty, " metric %s", + yang_dnode_get_string(dnode, "./metric")); + if (yang_dnode_exists(dnode, "./route-map")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./route-map")); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/static-route + */ +DEFPY (ripng_route, + ripng_route_cmd, + "[no] route X:X::X:X/M", + NO_STR + "Static route setup\n" + "Set static RIPng route announcement\n") +{ + nb_cli_enqueue_change(vty, "./static-route", + no ? NB_OP_DELETE : NB_OP_CREATE, route_str); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_route(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/aggregate-addres + */ +DEFPY (ripng_aggregate_address, + ripng_aggregate_address_cmd, + "[no] aggregate-address X:X::X:X/M", + NO_STR + "Set aggregate RIPng route announcement\n" + "Aggregate network\n") +{ + nb_cli_enqueue_change(vty, "./aggregate-address", + no ? NB_OP_DELETE : NB_OP_CREATE, + aggregate_address_str); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_aggregate_address(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " aggregate-address %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/timers + */ +DEFPY (ripng_timers, + ripng_timers_cmd, + "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage", + "RIPng timers setup\n" + "Basic timer\n" + "Routing table update timer value in second. Default is 30.\n" + "Routing information timeout timer. Default is 180.\n" + "Garbage collection timer. Default is 120.\n") +{ + nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, + update_str); + nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, + timeout_str); + nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, + garbage_str); + + return nb_cli_apply_changes(vty, "./timers"); +} + +DEFPY (no_ripng_timers, + no_ripng_timers_cmd, + "no timers basic [(1-65535) (1-65535) (1-65535)]", + NO_STR + "RIPng timers setup\n" + "Basic timer\n" + "Routing table update timer value in second. Default is 30.\n" + "Routing information timeout timer. Default is 180.\n" + "Garbage collection timer. Default is 120.\n") +{ + nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, "./timers"); +} + +void cli_show_ripng_timers(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " timers basic %s %s %s\n", + yang_dnode_get_string(dnode, "./update-interval"), + yang_dnode_get_string(dnode, "./holddown-interval"), + yang_dnode_get_string(dnode, "./flush-interval")); +} + +/* + * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon + */ +DEFPY (ipv6_ripng_split_horizon, + ipv6_ripng_split_horizon_cmd, + "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]", + NO_STR + IPV6_STR + "Routing Information Protocol\n" + "Perform split horizon\n" + "With poisoned-reverse\n") +{ + const char *value; + + if (no) + value = "disabled"; + else if (poisoned_reverse) + value = "poison-reverse"; + else + value = "simple"; + + nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value); + + return nb_cli_apply_changes(vty, "./frr-ripngd:ripng"); +} + +void cli_show_ipv6_ripng_split_horizon(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + int value; + + value = yang_dnode_get_enum(dnode, NULL); + switch (value) { + case RIPNG_NO_SPLIT_HORIZON: + vty_out(vty, " no ipv6 ripng split-horizon\n"); + break; + case RIPNG_SPLIT_HORIZON: + vty_out(vty, " ipv6 ripng split-horizon\n"); + break; + case RIPNG_SPLIT_HORIZON_POISONED_REVERSE: + vty_out(vty, " ipv6 ripng split-horizon poisoned-reverse\n"); + break; + } +} + +/* + * XPath: /frr-ripngd:clear-ripng-route + */ +DEFPY (clear_ipv6_rip, + clear_ipv6_rip_cmd, + "clear ipv6 ripng", + CLEAR_STR + IPV6_STR + "Clear IPv6 RIP database\n") +{ + return nb_cli_rpc("/frr-ripngd:clear-ripng-route", NULL, NULL); +} + +void ripng_cli_init(void) +{ + install_element(CONFIG_NODE, &router_ripng_cmd); + install_element(CONFIG_NODE, &no_router_ripng_cmd); + + install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd); + install_element(RIPNG_NODE, &ripng_default_information_originate_cmd); + install_element(RIPNG_NODE, &ripng_default_metric_cmd); + install_element(RIPNG_NODE, &no_ripng_default_metric_cmd); + install_element(RIPNG_NODE, &ripng_network_prefix_cmd); + install_element(RIPNG_NODE, &ripng_network_if_cmd); + install_element(RIPNG_NODE, &ripng_offset_list_cmd); + install_element(RIPNG_NODE, &ripng_passive_interface_cmd); + install_element(RIPNG_NODE, &ripng_redistribute_cmd); + install_element(RIPNG_NODE, &ripng_route_cmd); + install_element(RIPNG_NODE, &ripng_aggregate_address_cmd); + install_element(RIPNG_NODE, &ripng_timers_cmd); + install_element(RIPNG_NODE, &no_ripng_timers_cmd); + + install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd); + + install_element(ENABLE_NODE, &clear_ipv6_rip_cmd); +} diff --git a/ripngd/ripng_cli.h b/ripngd/ripng_cli.h new file mode 100644 index 0000000000..d95747e0f8 --- /dev/null +++ b/ripngd/ripng_cli.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 1998 Kunihiro Ishiguro + * Copyright (C) 2018 NetDEF, Inc. + * Renato Westphal + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FRR_RIPNG_CLI_H_ +#define _FRR_RIPNG_CLI_H_ + +extern void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_allow_ecmp(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_default_information_originate(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_default_metric(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_network_prefix(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_network_interface(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_offset_list(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_passive_interface(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_route(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_aggregate_address(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_timers(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ipv6_ripng_split_horizon(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); + +#endif /* _FRR_RIPNG_CLI_H_ */ diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c index c8cad23add..c56ff12627 100644 --- a/ripngd/ripng_debug.c +++ b/ripngd/ripng_debug.c @@ -207,13 +207,6 @@ static int config_write_debug(struct vty *vty) return write; } -void ripng_debug_reset() -{ - ripng_debug_event = 0; - ripng_debug_packet = 0; - ripng_debug_zebra = 0; -} - void ripng_debug_init() { ripng_debug_event = 0; diff --git a/ripngd/ripng_debug.h b/ripngd/ripng_debug.h index 8124a1a0c9..81cb0f9c7e 100644 --- a/ripngd/ripng_debug.h +++ b/ripngd/ripng_debug.h @@ -45,6 +45,5 @@ extern unsigned long ripng_debug_packet; extern unsigned long ripng_debug_zebra; extern void ripng_debug_init(void); -extern void ripng_debug_reset(void); #endif /* _ZEBRA_RIPNG_DEBUG_H */ diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index a1d25f2961..4d14fbab64 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -36,6 +36,7 @@ #include "privs.h" #include "vrf.h" #include "lib_errors.h" +#include "northbound_cli.h" #include "ripngd/ripngd.h" #include "ripngd/ripng_debug.h" @@ -323,37 +324,6 @@ void ripng_interface_clean(void) } } -void ripng_interface_reset(void) -{ - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); - struct interface *ifp; - struct ripng_interface *ri; - - FOR_ALL_INTERFACES (vrf, ifp) { - ri = ifp->info; - - ri->enable_network = 0; - ri->enable_interface = 0; - ri->running = 0; - - ri->split_horizon = RIPNG_NO_SPLIT_HORIZON; - ri->split_horizon_default = RIPNG_NO_SPLIT_HORIZON; - - ri->list[RIPNG_FILTER_IN] = NULL; - ri->list[RIPNG_FILTER_OUT] = NULL; - - ri->prefix[RIPNG_FILTER_IN] = NULL; - ri->prefix[RIPNG_FILTER_OUT] = NULL; - - if (ri->t_wakeup) { - thread_cancel(ri->t_wakeup); - ri->t_wakeup = NULL; - } - - ri->passive = 0; - } -} - static void ripng_apply_address_add(struct connected *ifc) { struct prefix_ipv6 address; @@ -543,7 +513,7 @@ static int ripng_enable_network_lookup2(struct connected *connected) } /* Add RIPng enable network. */ -static int ripng_enable_network_add(struct prefix *p) +int ripng_enable_network_add(struct prefix *p) { struct agg_node *node; @@ -551,18 +521,18 @@ static int ripng_enable_network_add(struct prefix *p) if (node->info) { agg_unlock_node(node); - return -1; + return NB_ERR_INCONSISTENCY; } else node->info = (void *)1; /* XXX: One should find a better solution than a generic one */ ripng_enable_apply_all(); - return 1; + return NB_OK; } /* Delete RIPng enable network. */ -static int ripng_enable_network_delete(struct prefix *p) +int ripng_enable_network_delete(struct prefix *p) { struct agg_node *node; @@ -576,9 +546,10 @@ static int ripng_enable_network_delete(struct prefix *p) /* Unlock lookup lock. */ agg_unlock_node(node); - return 1; + return NB_OK; } - return -1; + + return NB_ERR_INCONSISTENCY; } /* Lookup function. */ @@ -595,30 +566,30 @@ static int ripng_enable_if_lookup(const char *ifname) } /* Add interface to ripng_enable_if. */ -static int ripng_enable_if_add(const char *ifname) +int ripng_enable_if_add(const char *ifname) { int ret; ret = ripng_enable_if_lookup(ifname); if (ret >= 0) - return -1; + return NB_ERR_INCONSISTENCY; vector_set(ripng_enable_if, strdup(ifname)); ripng_enable_apply_all(); - return 1; + return NB_OK; } /* Delete interface from ripng_enable_if. */ -static int ripng_enable_if_delete(const char *ifname) +int ripng_enable_if_delete(const char *ifname) { int index; char *str; index = ripng_enable_if_lookup(ifname); if (index < 0) - return -1; + return NB_ERR_INCONSISTENCY; str = vector_slot(ripng_enable_if, index); free(str); @@ -626,7 +597,7 @@ static int ripng_enable_if_delete(const char *ifname) ripng_enable_apply_all(); - return 1; + return NB_OK; } /* Wake up interface. */ @@ -830,26 +801,26 @@ static void ripng_passive_interface_apply_all(void) } /* Passive interface. */ -static int ripng_passive_interface_set(struct vty *vty, const char *ifname) +int ripng_passive_interface_set(const char *ifname) { if (ripng_passive_interface_lookup(ifname) >= 0) - return CMD_WARNING_CONFIG_FAILED; + return NB_ERR_INCONSISTENCY; vector_set(Vripng_passive_interface, strdup(ifname)); ripng_passive_interface_apply_all(); - return CMD_SUCCESS; + return NB_OK; } -static int ripng_passive_interface_unset(struct vty *vty, const char *ifname) +int ripng_passive_interface_unset(const char *ifname) { int i; char *str; i = ripng_passive_interface_lookup(ifname); if (i < 0) - return CMD_WARNING_CONFIG_FAILED; + return NB_ERR_INCONSISTENCY; str = vector_slot(Vripng_passive_interface, i); free(str); @@ -857,7 +828,7 @@ static int ripng_passive_interface_unset(struct vty *vty, const char *ifname) ripng_passive_interface_apply_all(); - return CMD_SUCCESS; + return NB_OK; } /* Free all configured RIP passive-interface settings. */ @@ -875,7 +846,7 @@ void ripng_passive_interface_clean(void) } /* Write RIPng enable network and interface to the vty. */ -int ripng_network_write(struct vty *vty, int config_mode) +int ripng_network_write(struct vty *vty) { unsigned int i; const char *ifname; @@ -887,8 +858,7 @@ int ripng_network_write(struct vty *vty, int config_mode) node = agg_route_next(node)) if (node->info) { struct prefix *p = &node->p; - vty_out(vty, "%s%s/%d\n", - config_mode ? " network " : " ", + vty_out(vty, " %s/%d\n", inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); } @@ -896,148 +866,11 @@ int ripng_network_write(struct vty *vty, int config_mode) /* Write enable interface. */ for (i = 0; i < vector_active(ripng_enable_if); i++) if ((ifname = vector_slot(ripng_enable_if, i)) != NULL) - vty_out(vty, "%s%s\n", - config_mode ? " network " : " ", ifname); - - /* Write passive interface. */ - if (config_mode) - for (i = 0; i < vector_active(Vripng_passive_interface); i++) - if ((ifname = vector_slot(Vripng_passive_interface, i)) - != NULL) - vty_out(vty, " passive-interface %s\n", ifname); + vty_out(vty, " %s\n", ifname); return 0; } -/* RIPng enable on specified interface or matched network. */ -DEFUN (ripng_network, - ripng_network_cmd, - "network IF_OR_ADDR", - "RIPng enable on specified interface or network.\n" - "Interface or address\n") -{ - int idx_if_or_addr = 1; - int ret; - struct prefix p; - - ret = str2prefix(argv[idx_if_or_addr]->arg, &p); - - /* Given string is IPv6 network or interface name. */ - if (ret) - ret = ripng_enable_network_add(&p); - else - ret = ripng_enable_if_add(argv[idx_if_or_addr]->arg); - - if (ret < 0) { - vty_out(vty, "There is same network configuration %s\n", - argv[idx_if_or_addr]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -/* RIPng enable on specified interface or matched network. */ -DEFUN (no_ripng_network, - no_ripng_network_cmd, - "no network IF_OR_ADDR", - NO_STR - "RIPng enable on specified interface or network.\n" - "Interface or address\n") -{ - int idx_if_or_addr = 2; - int ret; - struct prefix p; - - ret = str2prefix(argv[idx_if_or_addr]->arg, &p); - - /* Given string is interface name. */ - if (ret) - ret = ripng_enable_network_delete(&p); - else - ret = ripng_enable_if_delete(argv[idx_if_or_addr]->arg); - - if (ret < 0) { - vty_out(vty, "can't find network %s\n", - argv[idx_if_or_addr]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (ipv6_ripng_split_horizon, - ipv6_ripng_split_horizon_cmd, - "ipv6 ripng split-horizon", - IPV6_STR - "Routing Information Protocol\n" - "Perform split horizon\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ripng_interface *ri; - - ri = ifp->info; - - ri->split_horizon = RIPNG_SPLIT_HORIZON; - return CMD_SUCCESS; -} - -DEFUN (ipv6_ripng_split_horizon_poisoned_reverse, - ipv6_ripng_split_horizon_poisoned_reverse_cmd, - "ipv6 ripng split-horizon poisoned-reverse", - IPV6_STR - "Routing Information Protocol\n" - "Perform split horizon\n" - "With poisoned-reverse\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ripng_interface *ri; - - ri = ifp->info; - - ri->split_horizon = RIPNG_SPLIT_HORIZON_POISONED_REVERSE; - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_ripng_split_horizon, - no_ipv6_ripng_split_horizon_cmd, - "no ipv6 ripng split-horizon [poisoned-reverse]", - NO_STR - IPV6_STR - "Routing Information Protocol\n" - "Perform split horizon\n" - "With poisoned-reverse\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ripng_interface *ri; - - ri = ifp->info; - - ri->split_horizon = RIPNG_NO_SPLIT_HORIZON; - return CMD_SUCCESS; -} - -DEFUN (ripng_passive_interface, - ripng_passive_interface_cmd, - "passive-interface IFNAME", - "Suppress routing updates on an interface\n" - "Interface name\n") -{ - int idx_ifname = 1; - return ripng_passive_interface_set(vty, argv[idx_ifname]->arg); -} - -DEFUN (no_ripng_passive_interface, - no_ripng_passive_interface_cmd, - "no passive-interface IFNAME", - NO_STR - "Suppress routing updates on an interface\n" - "Interface name\n") -{ - int idx_ifname = 2; - return ripng_passive_interface_unset(vty, argv[idx_ifname]->arg); -} - static struct ripng_interface *ri_new(void) { struct ripng_interface *ri; @@ -1047,8 +880,8 @@ static struct ripng_interface *ri_new(void) Relay or SMDS is enabled, the default value for split-horizon is off. But currently Zebra does detect Frame Relay or SMDS interface. So all interface is set to split horizon. */ - ri->split_horizon_default = RIPNG_SPLIT_HORIZON; - ri->split_horizon = ri->split_horizon_default; + ri->split_horizon = + yang_get_default_enum("%s/split-horizon", RIPNG_IFACE); return ri; } @@ -1072,44 +905,22 @@ static int interface_config_write(struct vty *vty) { struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct interface *ifp; - struct ripng_interface *ri; int write = 0; FOR_ALL_INTERFACES (vrf, ifp) { - ri = ifp->info; + struct lyd_node *dnode; - /* Do not display the interface if there is no - * configuration about it. - **/ - if ((!ifp->desc) - && (ri->split_horizon == ri->split_horizon_default)) + dnode = yang_dnode_get( + running_config->dnode, + "/frr-interface:lib/interface[name='%s'][vrf='%s']", + ifp->name, vrf->name); + if (dnode == NULL) continue; - vty_frame(vty, "interface %s\n", ifp->name); - if (ifp->desc) - vty_out(vty, " description %s\n", ifp->desc); - - /* Split horizon. */ - if (ri->split_horizon != ri->split_horizon_default) { - switch (ri->split_horizon) { - case RIPNG_SPLIT_HORIZON: - vty_out(vty, " ipv6 ripng split-horizon\n"); - break; - case RIPNG_SPLIT_HORIZON_POISONED_REVERSE: - vty_out(vty, - " ipv6 ripng split-horizon poisoned-reverse\n"); - break; - case RIPNG_NO_SPLIT_HORIZON: - default: - vty_out(vty, " no ipv6 ripng split-horizon\n"); - break; - } - } - - vty_endframe(vty, "!\n"); - - write++; + write = 1; + nb_cli_show_dnode_cmds(vty, dnode, false); } + return write; } @@ -1137,14 +948,4 @@ void ripng_if_init() /* Install interface node. */ install_node(&interface_node, interface_config_write); if_cmd_init(); - - install_element(RIPNG_NODE, &ripng_network_cmd); - install_element(RIPNG_NODE, &no_ripng_network_cmd); - install_element(RIPNG_NODE, &ripng_passive_interface_cmd); - install_element(RIPNG_NODE, &no_ripng_passive_interface_cmd); - - install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd); - install_element(INTERFACE_NODE, - &ipv6_ripng_split_horizon_poisoned_reverse_cmd); - install_element(INTERFACE_NODE, &no_ipv6_ripng_split_horizon_cmd); } diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index 98df7ef12d..10e19efe77 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -72,13 +72,9 @@ static struct frr_daemon_info ripngd_di; static void sighup(void) { zlog_info("SIGHUP received"); - ripng_clean(); - ripng_reset(); /* Reload config file. */ vty_read_config(NULL, ripngd_di.config_file, config_default); - - /* Try to return to normal operation. */ } /* SIGINT handler. */ @@ -120,6 +116,7 @@ struct quagga_signal_t ripng_signals[] = { static const struct frr_yang_module_info *ripngd_yang_modules[] = { &frr_interface_info, + &frr_ripngd_info, }; FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT, @@ -177,6 +174,7 @@ int main(int argc, char **argv) /* RIPngd inits. */ ripng_init(); + ripng_cli_init(); zebra_init(master); ripng_peer_init(); diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c new file mode 100644 index 0000000000..7993714e8d --- /dev/null +++ b/ripngd/ripng_northbound.c @@ -0,0 +1,1001 @@ +/* + * Copyright (C) 1998 Kunihiro Ishiguro + * Copyright (C) 2018 NetDEF, Inc. + * Renato Westphal + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "if.h" +#include "vrf.h" +#include "log.h" +#include "prefix.h" +#include "table.h" +#include "command.h" +#include "routemap.h" +#include "agg_table.h" +#include "northbound.h" +#include "libfrr.h" + +#include "ripngd/ripngd.h" +#include "ripngd/ripng_route.h" +#include "ripngd/ripng_cli.h" + +/* + * XPath: /frr-ripngd:ripngd/instance + */ +static int ripngd_instance_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + int socket; + + switch (event) { + case NB_EV_VALIDATE: + break; + case NB_EV_PREPARE: + socket = ripng_make_socket(); + if (socket < 0) + return NB_ERR_RESOURCE; + resource->fd = socket; + break; + case NB_EV_ABORT: + socket = resource->fd; + close(socket); + break; + case NB_EV_APPLY: + socket = resource->fd; + ripng_create(socket); + break; + } + + return NB_OK; +} + +static int ripngd_instance_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + if (event != NB_EV_APPLY) + return NB_OK; + + ripng_clean(); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/allow-ecmp + */ +static int ripngd_instance_allow_ecmp_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + if (event != NB_EV_APPLY) + return NB_OK; + + ripng->ecmp = yang_dnode_get_bool(dnode, NULL); + if (!ripng->ecmp) + ripng_ecmp_disable(); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/default-information-originate + */ +static int ripngd_instance_default_information_originate_modify( + enum nb_event event, const struct lyd_node *dnode, + union nb_resource *resource) +{ + bool default_information; + struct prefix_ipv6 p; + + if (event != NB_EV_APPLY) + return NB_OK; + + default_information = yang_dnode_get_bool(dnode, NULL); + str2prefix_ipv6("::/0", &p); + if (default_information) { + ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT, + &p, 0, NULL, 0); + } else { + ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, + RIPNG_ROUTE_DEFAULT, &p, 0); + } + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/default-metric + */ +static int ripngd_instance_default_metric_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + if (event != NB_EV_APPLY) + return NB_OK; + + ripng->default_metric = yang_dnode_get_uint8(dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/network + */ +static int ripngd_instance_network_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct prefix p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6((struct prefix_ipv6 *)&p); + + return ripng_enable_network_add(&p); +} + +static int ripngd_instance_network_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + struct prefix p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6((struct prefix_ipv6 *)&p); + + return ripng_enable_network_delete(&p); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/interface + */ +static int ripngd_instance_interface_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + const char *ifname; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifname = yang_dnode_get_string(dnode, NULL); + + return ripng_enable_if_add(ifname); +} + +static int ripngd_instance_interface_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + const char *ifname; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifname = yang_dnode_get_string(dnode, NULL); + + return ripng_enable_if_delete(ifname); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/offset-list + */ +static int ripngd_instance_offset_list_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + const char *ifname; + struct ripng_offset_list *offset; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifname = yang_dnode_get_string(dnode, "./interface"); + + offset = ripng_offset_list_new(ifname); + yang_dnode_set_entry(dnode, offset); + + return NB_OK; +} + +static int ripngd_instance_offset_list_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + int direct; + struct ripng_offset_list *offset; + + if (event != NB_EV_APPLY) + return NB_OK; + + direct = yang_dnode_get_enum(dnode, "./direction"); + + offset = yang_dnode_get_entry(dnode, true); + if (offset->direct[direct].alist_name) { + free(offset->direct[direct].alist_name); + offset->direct[direct].alist_name = NULL; + } + if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL + && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name == NULL) + ripng_offset_list_del(offset); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list + */ +static int +ripngd_instance_offset_list_access_list_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + int direct; + struct ripng_offset_list *offset; + const char *alist_name; + + if (event != NB_EV_APPLY) + return NB_OK; + + direct = yang_dnode_get_enum(dnode, "../direction"); + alist_name = yang_dnode_get_string(dnode, NULL); + + offset = yang_dnode_get_entry(dnode, true); + if (offset->direct[direct].alist_name) + free(offset->direct[direct].alist_name); + offset->direct[direct].alist_name = strdup(alist_name); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/offset-list/metric + */ +static int +ripngd_instance_offset_list_metric_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + int direct; + uint8_t metric; + struct ripng_offset_list *offset; + + if (event != NB_EV_APPLY) + return NB_OK; + + direct = yang_dnode_get_enum(dnode, "../direction"); + metric = yang_dnode_get_uint8(dnode, NULL); + + offset = yang_dnode_get_entry(dnode, true); + offset->direct[direct].metric = metric; + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/passive-interface + */ +static int +ripngd_instance_passive_interface_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + const char *ifname; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifname = yang_dnode_get_string(dnode, NULL); + + return ripng_passive_interface_set(ifname); +} + +static int +ripngd_instance_passive_interface_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + const char *ifname; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifname = yang_dnode_get_string(dnode, NULL); + + return ripng_passive_interface_unset(ifname); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/redistribute + */ +static int ripngd_instance_redistribute_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + return NB_OK; +} + +static int ripngd_instance_redistribute_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + int type; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "./protocol"); + + ripng_redistribute_conf_delete(type); + + return NB_OK; +} + +static void +ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode) +{ + int type; + + type = yang_dnode_get_enum(dnode, "./protocol"); + ripng_redistribute_conf_update(type); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map + */ +static int +ripngd_instance_redistribute_route_map_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + int type; + const char *rmap_name; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + rmap_name = yang_dnode_get_string(dnode, NULL); + + if (ripng->route_map[type].name) + free(ripng->route_map[type].name); + ripng->route_map[type].name = strdup(rmap_name); + ripng->route_map[type].map = route_map_lookup_by_name(rmap_name); + + return NB_OK; +} + +static int +ripngd_instance_redistribute_route_map_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + int type; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + + free(ripng->route_map[type].name); + ripng->route_map[type].name = NULL; + ripng->route_map[type].map = NULL; + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/redistribute/metric + */ +static int +ripngd_instance_redistribute_metric_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + int type; + uint8_t metric; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + metric = yang_dnode_get_uint8(dnode, NULL); + + ripng->route_map[type].metric_config = true; + ripng->route_map[type].metric = metric; + + return NB_OK; +} + +static int +ripngd_instance_redistribute_metric_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + int type; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + + ripng->route_map[type].metric_config = false; + ripng->route_map[type].metric = 0; + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/static-route + */ +static int ripngd_instance_static_route_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct prefix_ipv6 p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6(&p); + + ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0, + NULL, 0); + + return NB_OK; +} + +static int ripngd_instance_static_route_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + struct prefix_ipv6 p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6(&p); + + ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/aggregate-address + */ +static int +ripngd_instance_aggregate_address_create(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct prefix_ipv6 p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6(&p); + + ripng_aggregate_add((struct prefix *)&p); + + return NB_OK; +} + +static int +ripngd_instance_aggregate_address_delete(enum nb_event event, + const struct lyd_node *dnode) +{ + struct prefix_ipv6 p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6(&p); + + ripng_aggregate_delete((struct prefix *)&p); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/timers + */ +static void ripngd_instance_timers_apply_finish(const struct lyd_node *dnode) +{ + /* Reset update timer thread. */ + ripng_event(RIPNG_UPDATE_EVENT, 0); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval + */ +static int +ripngd_instance_timers_flush_interval_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + if (event != NB_EV_APPLY) + return NB_OK; + + ripng->garbage_time = yang_dnode_get_uint16(dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval + */ +static int +ripngd_instance_timers_holddown_interval_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + if (event != NB_EV_APPLY) + return NB_OK; + + ripng->timeout_time = yang_dnode_get_uint16(dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/instance/timers/update-interval + */ +static int +ripngd_instance_timers_update_interval_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + if (event != NB_EV_APPLY) + return NB_OK; + + ripng->update_time = yang_dnode_get_uint16(dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor + */ +static const void * +ripngd_state_neighbors_neighbor_get_next(const void *parent_list_entry, + const void *list_entry) +{ + struct listnode *node; + + if (list_entry == NULL) + node = listhead(peer_list); + else + node = listnextnode((struct listnode *)list_entry); + + return node; +} + +static int ripngd_state_neighbors_neighbor_get_keys(const void *list_entry, + struct yang_list_keys *keys) +{ + const struct listnode *node = list_entry; + const struct ripng_peer *peer = listgetdata(node); + + keys->num = 1; + (void)inet_ntop(AF_INET6, &peer->addr, keys->key[0], + sizeof(keys->key[0])); + + return NB_OK; +} + +static const void * +ripngd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry, + const struct yang_list_keys *keys) +{ + struct in6_addr address; + struct ripng_peer *peer; + struct listnode *node; + + yang_str2ipv6(keys->key[0], &address); + + for (ALL_LIST_ELEMENTS_RO(peer_list, node, peer)) { + if (IPV6_ADDR_SAME(&peer->addr, &address)) + return node; + } + + return NULL; +} + +/* + * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/address + */ +static struct yang_data * +ripngd_state_neighbors_neighbor_address_get_elem(const char *xpath, + const void *list_entry) +{ + const struct listnode *node = list_entry; + const struct ripng_peer *peer = listgetdata(node); + + return yang_data_new_ipv6(xpath, &peer->addr); +} + +/* + * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/last-update + */ +static struct yang_data * +ripngd_state_neighbors_neighbor_last_update_get_elem(const char *xpath, + const void *list_entry) +{ + /* TODO: yang:date-and-time is tricky */ + return NULL; +} + +/* + * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd + */ +static struct yang_data * +ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem( + const char *xpath, const void *list_entry) +{ + const struct listnode *node = list_entry; + const struct ripng_peer *peer = listgetdata(node); + + return yang_data_new_uint32(xpath, peer->recv_badpackets); +} + +/* + * XPath: /frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd + */ +static struct yang_data * +ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath, + const void *list_entry) +{ + const struct listnode *node = list_entry; + const struct ripng_peer *peer = listgetdata(node); + + return yang_data_new_uint32(xpath, peer->recv_badroutes); +} + +/* + * XPath: /frr-ripngd:ripngd/state/routes/route + */ +static const void * +ripngd_state_routes_route_get_next(const void *parent_list_entry, + const void *list_entry) +{ + struct agg_node *rn; + + if (ripng == NULL) + return NULL; + + if (list_entry == NULL) + rn = agg_route_top(ripng->table); + else + rn = agg_route_next((struct agg_node *)list_entry); + while (rn && rn->info == NULL) + rn = agg_route_next(rn); + + return rn; +} + +static int ripngd_state_routes_route_get_keys(const void *list_entry, + struct yang_list_keys *keys) +{ + const struct agg_node *rn = list_entry; + + keys->num = 1; + (void)prefix2str(&rn->p, keys->key[0], sizeof(keys->key[0])); + + return NB_OK; +} + +static const void * +ripngd_state_routes_route_lookup_entry(const void *parent_list_entry, + const struct yang_list_keys *keys) +{ + struct prefix prefix; + struct agg_node *rn; + + yang_str2ipv6p(keys->key[0], &prefix); + + rn = agg_node_lookup(ripng->table, &prefix); + if (!rn || !rn->info) + return NULL; + + agg_unlock_node(rn); + + return rn; +} + +/* + * XPath: /frr-ripngd:ripngd/state/routes/route/prefix + */ +static struct yang_data * +ripngd_state_routes_route_prefix_get_elem(const char *xpath, + const void *list_entry) +{ + const struct agg_node *rn = list_entry; + const struct ripng_info *rinfo = listnode_head(rn->info); + + return yang_data_new_ipv6p(xpath, &rinfo->rp->p); +} + +/* + * XPath: /frr-ripngd:ripngd/state/routes/route/next-hop + */ +static struct yang_data * +ripngd_state_routes_route_next_hop_get_elem(const char *xpath, + const void *list_entry) +{ + const struct agg_node *rn = list_entry; + const struct ripng_info *rinfo = listnode_head(rn->info); + + return yang_data_new_ipv6(xpath, &rinfo->nexthop); +} + +/* + * XPath: /frr-ripngd:ripngd/state/routes/route/interface + */ +static struct yang_data * +ripngd_state_routes_route_interface_get_elem(const char *xpath, + const void *list_entry) +{ + const struct agg_node *rn = list_entry; + const struct ripng_info *rinfo = listnode_head(rn->info); + + return yang_data_new_string( + xpath, ifindex2ifname(rinfo->ifindex, VRF_DEFAULT)); +} + +/* + * XPath: /frr-ripngd:ripngd/state/routes/route/metric + */ +static struct yang_data * +ripngd_state_routes_route_metric_get_elem(const char *xpath, + const void *list_entry) +{ + const struct agg_node *rn = list_entry; + const struct ripng_info *rinfo = listnode_head(rn->info); + + return yang_data_new_uint8(xpath, rinfo->metric); +} + +/* + * XPath: /frr-ripngd:clear-ripng-route + */ +static int clear_ripng_route_rpc(const char *xpath, const struct list *input, + struct list *output) +{ + struct agg_node *rp; + struct ripng_info *rinfo; + struct list *list; + struct listnode *listnode; + + /* Clear received RIPng routes */ + for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) { + list = rp->info; + if (list == NULL) + continue; + + for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { + if (!ripng_route_rte(rinfo)) + continue; + + if (CHECK_FLAG(rinfo->flags, RIPNG_RTF_FIB)) + ripng_zebra_ipv6_delete(rp); + break; + } + + if (rinfo) { + RIPNG_TIMER_OFF(rinfo->t_timeout); + RIPNG_TIMER_OFF(rinfo->t_garbage_collect); + listnode_delete(list, rinfo); + ripng_info_free(rinfo); + } + + if (list_isempty(list)) { + list_delete(&list); + rp->info = NULL; + agg_unlock_node(rp); + } + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon + */ +static int +lib_interface_ripng_split_horizon_modify(enum nb_event event, + const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct interface *ifp; + struct ripng_interface *ri; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifp = yang_dnode_get_entry(dnode, true); + ri = ifp->info; + ri->split_horizon = yang_dnode_get_enum(dnode, NULL); + + return NB_OK; +} + +/* clang-format off */ +const struct frr_yang_module_info frr_ripngd_info = { + .name = "frr-ripngd", + .nodes = { + { + .xpath = "/frr-ripngd:ripngd/instance", + .cbs.create = ripngd_instance_create, + .cbs.delete = ripngd_instance_delete, + .cbs.cli_show = cli_show_router_ripng, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/allow-ecmp", + .cbs.modify = ripngd_instance_allow_ecmp_modify, + .cbs.cli_show = cli_show_ripng_allow_ecmp, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/default-information-originate", + .cbs.modify = ripngd_instance_default_information_originate_modify, + .cbs.cli_show = cli_show_ripng_default_information_originate, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/default-metric", + .cbs.modify = ripngd_instance_default_metric_modify, + .cbs.cli_show = cli_show_ripng_default_metric, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/network", + .cbs.create = ripngd_instance_network_create, + .cbs.delete = ripngd_instance_network_delete, + .cbs.cli_show = cli_show_ripng_network_prefix, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/interface", + .cbs.create = ripngd_instance_interface_create, + .cbs.delete = ripngd_instance_interface_delete, + .cbs.cli_show = cli_show_ripng_network_interface, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/offset-list", + .cbs.create = ripngd_instance_offset_list_create, + .cbs.delete = ripngd_instance_offset_list_delete, + .cbs.cli_show = cli_show_ripng_offset_list, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/offset-list/access-list", + .cbs.modify = ripngd_instance_offset_list_access_list_modify, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/offset-list/metric", + .cbs.modify = ripngd_instance_offset_list_metric_modify, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/passive-interface", + .cbs.create = ripngd_instance_passive_interface_create, + .cbs.delete = ripngd_instance_passive_interface_delete, + .cbs.cli_show = cli_show_ripng_passive_interface, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/redistribute", + .cbs.create = ripngd_instance_redistribute_create, + .cbs.delete = ripngd_instance_redistribute_delete, + .cbs.apply_finish = ripngd_instance_redistribute_apply_finish, + .cbs.cli_show = cli_show_ripng_redistribute, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/redistribute/route-map", + .cbs.modify = ripngd_instance_redistribute_route_map_modify, + .cbs.delete = ripngd_instance_redistribute_route_map_delete, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/redistribute/metric", + .cbs.modify = ripngd_instance_redistribute_metric_modify, + .cbs.delete = ripngd_instance_redistribute_metric_delete, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/static-route", + .cbs.create = ripngd_instance_static_route_create, + .cbs.delete = ripngd_instance_static_route_delete, + .cbs.cli_show = cli_show_ripng_route, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/aggregate-address", + .cbs.create = ripngd_instance_aggregate_address_create, + .cbs.delete = ripngd_instance_aggregate_address_delete, + .cbs.cli_show = cli_show_ripng_aggregate_address, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/timers", + .cbs.apply_finish = ripngd_instance_timers_apply_finish, + .cbs.cli_show = cli_show_ripng_timers, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/timers/flush-interval", + .cbs.modify = ripngd_instance_timers_flush_interval_modify, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/timers/holddown-interval", + .cbs.modify = ripngd_instance_timers_holddown_interval_modify, + }, + { + .xpath = "/frr-ripngd:ripngd/instance/timers/update-interval", + .cbs.modify = ripngd_instance_timers_update_interval_modify, + }, + { + .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor", + .cbs.get_next = ripngd_state_neighbors_neighbor_get_next, + .cbs.get_keys = ripngd_state_neighbors_neighbor_get_keys, + .cbs.lookup_entry = ripngd_state_neighbors_neighbor_lookup_entry, + }, + { + .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/address", + .cbs.get_elem = ripngd_state_neighbors_neighbor_address_get_elem, + }, + { + .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/last-update", + .cbs.get_elem = ripngd_state_neighbors_neighbor_last_update_get_elem, + }, + { + .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-packets-rcvd", + .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem, + }, + { + .xpath = "/frr-ripngd:ripngd/state/neighbors/neighbor/bad-routes-rcvd", + .cbs.get_elem = ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem, + }, + { + .xpath = "/frr-ripngd:ripngd/state/routes/route", + .cbs.get_next = ripngd_state_routes_route_get_next, + .cbs.get_keys = ripngd_state_routes_route_get_keys, + .cbs.lookup_entry = ripngd_state_routes_route_lookup_entry, + }, + { + .xpath = "/frr-ripngd:ripngd/state/routes/route/prefix", + .cbs.get_elem = ripngd_state_routes_route_prefix_get_elem, + }, + { + .xpath = "/frr-ripngd:ripngd/state/routes/route/next-hop", + .cbs.get_elem = ripngd_state_routes_route_next_hop_get_elem, + }, + { + .xpath = "/frr-ripngd:ripngd/state/routes/route/interface", + .cbs.get_elem = ripngd_state_routes_route_interface_get_elem, + }, + { + .xpath = "/frr-ripngd:ripngd/state/routes/route/metric", + .cbs.get_elem = ripngd_state_routes_route_metric_get_elem, + }, + { + .xpath = "/frr-ripngd:clear-ripng-route", + .cbs.rpc = clear_ripng_route_rpc, + }, + { + .xpath = "/frr-interface:lib/interface/frr-ripngd:ripng/split-horizon", + .cbs.modify = lib_interface_ripng_split_horizon_modify, + .cbs.cli_show = cli_show_ipv6_ripng_split_horizon, + }, + { + .xpath = NULL, + }, + } +}; diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c index 32b81b5480..278df75892 100644 --- a/ripngd/ripng_offset.c +++ b/ripngd/ripng_offset.c @@ -33,165 +33,49 @@ #include "ripngd/ripngd.h" -#define RIPNG_OFFSET_LIST_IN 0 -#define RIPNG_OFFSET_LIST_OUT 1 -#define RIPNG_OFFSET_LIST_MAX 2 - -struct ripng_offset_list { - char *ifname; - - struct { - char *alist_name; - /* struct access_list *alist; */ - int metric; - } direct[RIPNG_OFFSET_LIST_MAX]; -}; - static struct list *ripng_offset_list_master; -static int strcmp_safe(const char *s1, const char *s2) -{ - if (s1 == NULL && s2 == NULL) - return 0; - if (s1 == NULL) - return -1; - if (s2 == NULL) - return 1; - return strcmp(s1, s2); -} +#define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name) +#define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].metric) + +#define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name) +#define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric) -static struct ripng_offset_list *ripng_offset_list_new(void) +struct ripng_offset_list *ripng_offset_list_new(const char *ifname) { struct ripng_offset_list *new; new = XCALLOC(MTYPE_RIPNG_OFFSET_LIST, sizeof(struct ripng_offset_list)); + new->ifname = strdup(ifname); + listnode_add_sort(ripng_offset_list_master, new); + return new; } -static void ripng_offset_list_free(struct ripng_offset_list *offset) +void ripng_offset_list_del(struct ripng_offset_list *offset) { + listnode_delete(ripng_offset_list_master, offset); + if (OFFSET_LIST_IN_NAME(offset)) + free(OFFSET_LIST_IN_NAME(offset)); + if (OFFSET_LIST_OUT_NAME(offset)) + free(OFFSET_LIST_OUT_NAME(offset)); + free(offset->ifname); XFREE(MTYPE_RIPNG_OFFSET_LIST, offset); } -static struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname) +struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname) { struct ripng_offset_list *offset; struct listnode *node, *nnode; for (ALL_LIST_ELEMENTS(ripng_offset_list_master, node, nnode, offset)) { - if (strcmp_safe(offset->ifname, ifname) == 0) + if (strcmp(offset->ifname, ifname) == 0) return offset; } return NULL; } -static struct ripng_offset_list *ripng_offset_list_get(const char *ifname) -{ - struct ripng_offset_list *offset; - - offset = ripng_offset_list_lookup(ifname); - if (offset) - return offset; - - offset = ripng_offset_list_new(); - if (ifname) - offset->ifname = strdup(ifname); - listnode_add_sort(ripng_offset_list_master, offset); - - return offset; -} - -static int ripng_offset_list_set(struct vty *vty, const char *alist, - const char *direct_str, const char *metric_str, - const char *ifname) -{ - int direct; - int metric; - struct ripng_offset_list *offset; - - /* Check direction. */ - if (strncmp(direct_str, "i", 1) == 0) - direct = RIPNG_OFFSET_LIST_IN; - else if (strncmp(direct_str, "o", 1) == 0) - direct = RIPNG_OFFSET_LIST_OUT; - else { - vty_out(vty, "Invalid direction: %s\n", direct_str); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check metric. */ - metric = atoi(metric_str); - if (metric < 0 || metric > 16) { - vty_out(vty, "Invalid metric: %s\n", metric_str); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Get offset-list structure with interface name. */ - offset = ripng_offset_list_get(ifname); - - if (offset->direct[direct].alist_name) - free(offset->direct[direct].alist_name); - offset->direct[direct].alist_name = strdup(alist); - offset->direct[direct].metric = metric; - - return CMD_SUCCESS; -} - -static int ripng_offset_list_unset(struct vty *vty, const char *alist, - const char *direct_str, - const char *metric_str, const char *ifname) -{ - int direct; - int metric; - struct ripng_offset_list *offset; - - /* Check direction. */ - if (strncmp(direct_str, "i", 1) == 0) - direct = RIPNG_OFFSET_LIST_IN; - else if (strncmp(direct_str, "o", 1) == 0) - direct = RIPNG_OFFSET_LIST_OUT; - else { - vty_out(vty, "Invalid direction: %s\n", direct_str); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check metric. */ - metric = atoi(metric_str); - if (metric < 0 || metric > 16) { - vty_out(vty, "Invalid metric: %s\n", metric_str); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Get offset-list structure with interface name. */ - offset = ripng_offset_list_lookup(ifname); - - if (offset) { - if (offset->direct[direct].alist_name) - free(offset->direct[direct].alist_name); - offset->direct[direct].alist_name = NULL; - - if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL - && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name - == NULL) { - listnode_delete(ripng_offset_list_master, offset); - if (offset->ifname) - free(offset->ifname); - ripng_offset_list_free(offset); - } - } else { - vty_out(vty, "Can't find offset-list\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return CMD_SUCCESS; -} - -#define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name) -#define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].metric) - -#define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name) -#define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric) - /* If metric is modifed return 1. */ int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp, uint8_t *metric) @@ -214,7 +98,7 @@ int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp, return 0; } /* Look up offset-list without interface name. */ - offset = ripng_offset_list_lookup(NULL); + offset = ripng_offset_list_lookup("*"); if (offset && OFFSET_LIST_IN_NAME(offset)) { alist = access_list_lookup(AFI_IP6, OFFSET_LIST_IN_NAME(offset)); @@ -253,7 +137,7 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp, } /* Look up offset-list without interface name. */ - offset = ripng_offset_list_lookup(NULL); + offset = ripng_offset_list_lookup("*"); if (offset && OFFSET_LIST_OUT_NAME(offset)) { alist = access_list_lookup(AFI_IP6, OFFSET_LIST_OUT_NAME(offset)); @@ -269,95 +153,10 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp, return 0; } -DEFUN (ripng_offset_list, - ripng_offset_list_cmd, - "offset-list WORD <in|out> (0-16)", - "Modify RIPng metric\n" - "Access-list name\n" - "For incoming updates\n" - "For outgoing updates\n" - "Metric value\n") -{ - int idx_word = 1; - int idx_in_out = 2; - int idx_number = 3; - return ripng_offset_list_set(vty, argv[idx_word]->arg, - argv[idx_in_out]->arg, - argv[idx_number]->arg, NULL); -} - -DEFUN (ripng_offset_list_ifname, - ripng_offset_list_ifname_cmd, - "offset-list WORD <in|out> (0-16) IFNAME", - "Modify RIPng metric\n" - "Access-list name\n" - "For incoming updates\n" - "For outgoing updates\n" - "Metric value\n" - "Interface to match\n") -{ - int idx_word = 1; - int idx_in_out = 2; - int idx_number = 3; - int idx_ifname = 4; - return ripng_offset_list_set( - vty, argv[idx_word]->arg, argv[idx_in_out]->arg, - argv[idx_number]->arg, argv[idx_ifname]->arg); -} - -DEFUN (no_ripng_offset_list, - no_ripng_offset_list_cmd, - "no offset-list WORD <in|out> (0-16)", - NO_STR - "Modify RIPng metric\n" - "Access-list name\n" - "For incoming updates\n" - "For outgoing updates\n" - "Metric value\n") -{ - int idx_word = 2; - int idx_in_out = 3; - int idx_number = 4; - return ripng_offset_list_unset(vty, argv[idx_word]->arg, - argv[idx_in_out]->arg, - argv[idx_number]->arg, NULL); -} - -DEFUN (no_ripng_offset_list_ifname, - no_ripng_offset_list_ifname_cmd, - "no offset-list WORD <in|out> (0-16) IFNAME", - NO_STR - "Modify RIPng metric\n" - "Access-list name\n" - "For incoming updates\n" - "For outgoing updates\n" - "Metric value\n" - "Interface to match\n") -{ - int idx_word = 2; - int idx_in_out = 3; - int idx_number = 4; - int idx_ifname = 5; - return ripng_offset_list_unset( - vty, argv[idx_word]->arg, argv[idx_in_out]->arg, - argv[idx_number]->arg, argv[idx_ifname]->arg); -} - static int offset_list_cmp(struct ripng_offset_list *o1, struct ripng_offset_list *o2) { - return strcmp_safe(o1->ifname, o2->ifname); -} - -static void offset_list_del(struct ripng_offset_list *offset) -{ - if (OFFSET_LIST_IN_NAME(offset)) - free(OFFSET_LIST_IN_NAME(offset)); - if (OFFSET_LIST_OUT_NAME(offset)) - free(OFFSET_LIST_OUT_NAME(offset)); - if (offset->ifname) - free(offset->ifname); - ripng_offset_list_free(offset); + return strcmp(o1->ifname, o2->ifname); } void ripng_offset_init(void) @@ -365,12 +164,7 @@ void ripng_offset_init(void) ripng_offset_list_master = list_new(); ripng_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp; - ripng_offset_list_master->del = (void (*)(void *))offset_list_del; - - install_element(RIPNG_NODE, &ripng_offset_list_cmd); - install_element(RIPNG_NODE, &ripng_offset_list_ifname_cmd); - install_element(RIPNG_NODE, &no_ripng_offset_list_cmd); - install_element(RIPNG_NODE, &no_ripng_offset_list_ifname_cmd); + ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del; } void ripng_offset_clean(void) @@ -380,45 +174,5 @@ void ripng_offset_clean(void) ripng_offset_list_master = list_new(); ripng_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp; - ripng_offset_list_master->del = (void (*)(void *))offset_list_del; -} - -int config_write_ripng_offset_list(struct vty *vty) -{ - struct listnode *node, *nnode; - struct ripng_offset_list *offset; - - for (ALL_LIST_ELEMENTS(ripng_offset_list_master, node, nnode, offset)) { - if (!offset->ifname) { - if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name) - vty_out(vty, " offset-list %s in %d\n", - offset->direct[RIPNG_OFFSET_LIST_IN] - .alist_name, - offset->direct[RIPNG_OFFSET_LIST_IN] - .metric); - if (offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name) - vty_out(vty, " offset-list %s out %d\n", - offset->direct[RIPNG_OFFSET_LIST_OUT] - .alist_name, - offset->direct[RIPNG_OFFSET_LIST_OUT] - .metric); - } else { - if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name) - vty_out(vty, " offset-list %s in %d %s\n", - offset->direct[RIPNG_OFFSET_LIST_IN] - .alist_name, - offset->direct[RIPNG_OFFSET_LIST_IN] - .metric, - offset->ifname); - if (offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name) - vty_out(vty, " offset-list %s out %d %s\n", - offset->direct[RIPNG_OFFSET_LIST_OUT] - .alist_name, - offset->direct[RIPNG_OFFSET_LIST_OUT] - .metric, - offset->ifname); - } - } - - return 0; + ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del; } diff --git a/ripngd/ripng_routemap.c b/ripngd/ripng_routemap.c index a18332516e..9a9e346a59 100644 --- a/ripngd/ripng_routemap.c +++ b/ripngd/ripng_routemap.c @@ -337,12 +337,6 @@ static struct route_map_rule_cmd route_set_tag_cmd = { #define MATCH_STR "Match values from routing table\n" #define SET_STR "Set values in destination routing protocol\n" -void ripng_route_map_reset() -{ - /* XXX ??? */ - ; -} - void ripng_route_map_init() { route_map_init(); diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index f2b69c85a7..e3f42edf51 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -141,26 +141,19 @@ static int ripng_zebra_read_route(int command, struct zclient *zclient, return 0; } -void ripng_zclient_reset(void) +void ripng_redistribute_conf_update(int type) { - zclient_reset(zclient); + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, + VRF_DEFAULT); } -static int ripng_redistribute_unset(int type) +void ripng_redistribute_conf_delete(int type) { - - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT)) - return CMD_SUCCESS; - - vrf_bitmap_set(zclient->redist[AFI_IP6][type], VRF_DEFAULT); - if (zclient->sock > 0) zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT); ripng_redistribute_withdraw(type); - - return CMD_SUCCESS; } int ripng_redistribute_check(int type) @@ -168,206 +161,25 @@ int ripng_redistribute_check(int type) return vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT); } -static void ripng_redistribute_metric_set(int type, int metric) -{ - ripng->route_map[type].metric_config = 1; - ripng->route_map[type].metric = metric; -} - -static int ripng_redistribute_metric_unset(int type) -{ - ripng->route_map[type].metric_config = 0; - ripng->route_map[type].metric = 0; - return 0; -} - -static void ripng_redistribute_routemap_set(int type, const char *name) -{ - if (ripng->route_map[type].name) - free(ripng->route_map[type].name); - - ripng->route_map[type].name = strdup(name); - ripng->route_map[type].map = route_map_lookup_by_name(name); -} - -static void ripng_redistribute_routemap_unset(int type) -{ - if (ripng->route_map[type].name) - free(ripng->route_map[type].name); - - ripng->route_map[type].name = NULL; - ripng->route_map[type].map = NULL; -} - -/* Redistribution types */ -static struct { - int type; - int str_min_len; - const char *str; -} redist_type[] = {{ZEBRA_ROUTE_KERNEL, 1, "kernel"}, - {ZEBRA_ROUTE_CONNECT, 1, "connected"}, - {ZEBRA_ROUTE_STATIC, 1, "static"}, - {ZEBRA_ROUTE_OSPF6, 1, "ospf6"}, - {ZEBRA_ROUTE_BGP, 2, "bgp"}, - {ZEBRA_ROUTE_VNC, 1, "vnc"}, - {0, 0, NULL}}; - void ripng_redistribute_clean() { - int i; - - for (i = 0; redist_type[i].str; i++) { - if (vrf_bitmap_check( - zclient->redist[AFI_IP6][redist_type[i].type], - VRF_DEFAULT)) { - if (zclient->sock > 0) - zebra_redistribute_send( - ZEBRA_REDISTRIBUTE_DELETE, zclient, - AFI_IP6, redist_type[i].type, 0, - VRF_DEFAULT); - - vrf_bitmap_unset( - zclient->redist[AFI_IP6][redist_type[i].type], - VRF_DEFAULT); - - /* Remove the routes from RIPng table. */ - ripng_redistribute_withdraw(redist_type[i].type); - } - } -} - -DEFUN (ripng_redistribute_type, - ripng_redistribute_type_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD, - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD) -{ - int type; - - char *proto = argv[argc - 1]->text; - type = proto_redistnum(AFI_IP6, proto); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; -} - -DEFUN (no_ripng_redistribute_type, - no_ripng_redistribute_type_cmd, - "no redistribute " FRR_REDIST_STR_RIPNGD " [metric (0-16)] [route-map WORD]", - NO_STR - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Metric\n" - "Metric value\n" - "Route map reference\n" - "Pointer to route-map entries\n") -{ - int type; - - char *proto = argv[2]->text; - type = proto_redistnum(AFI_IP6, proto); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ripng_redistribute_metric_unset(type); - ripng_redistribute_routemap_unset(type); - return ripng_redistribute_unset(type); -} - - -DEFUN (ripng_redistribute_type_metric, - ripng_redistribute_type_metric_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16)", - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Metric\n" - "Metric value\n") -{ - int idx_protocol = 1; - int idx_number = 3; - int type; - int metric; - - metric = atoi(argv[idx_number]->arg); - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); - return CMD_WARNING_CONFIG_FAILED; - } - - ripng_redistribute_metric_set(type, metric); - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; -} - -DEFUN (ripng_redistribute_type_routemap, - ripng_redistribute_type_routemap_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD " route-map WORD", - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Route map reference\n" - "Pointer to route-map entries\n") -{ - int idx_protocol = 1; - int idx_word = 3; - int type; - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); + for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT)) + continue; - if (type < 0) { - vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); - return CMD_WARNING_CONFIG_FAILED; - } + if (zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, + zclient, AFI_IP6, i, 0, + VRF_DEFAULT); - ripng_redistribute_routemap_set(type, argv[idx_word]->text); - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; -} + vrf_bitmap_unset(zclient->redist[AFI_IP6][i], VRF_DEFAULT); -DEFUN (ripng_redistribute_type_metric_routemap, - ripng_redistribute_type_metric_routemap_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16) route-map WORD", - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Metric\n" - "Metric value\n" - "Route map reference\n" - "Pointer to route-map entries\n") -{ - int idx_protocol = 1; - int idx_number = 3; - int idx_word = 5; - int type; - int metric; - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - metric = atoi(argv[idx_number]->arg); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); - return CMD_WARNING_CONFIG_FAILED; + /* Remove the routes from RIP table. */ + ripng_redistribute_withdraw(i); } - - ripng_redistribute_metric_set(type, metric); - ripng_redistribute_routemap_set(type, argv[idx_word]->text); - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; } -void ripng_redistribute_write(struct vty *vty, int config_mode) +void ripng_redistribute_write(struct vty *vty) { int i; @@ -377,31 +189,7 @@ void ripng_redistribute_write(struct vty *vty, int config_mode) VRF_DEFAULT)) continue; - if (!config_mode) { - vty_out(vty, " %s", zebra_route_string(i)); - continue; - } - - if (ripng->route_map[i].metric_config) { - if (ripng->route_map[i].name) - vty_out(vty, - " redistribute %s metric %d route-map %s\n", - zebra_route_string(i), - ripng->route_map[i].metric, - ripng->route_map[i].name); - else - vty_out(vty, " redistribute %s metric %d\n", - zebra_route_string(i), - ripng->route_map[i].metric); - } else { - if (ripng->route_map[i].name) - vty_out(vty, " redistribute %s route-map %s\n", - zebra_route_string(i), - ripng->route_map[i].name); - else - vty_out(vty, " redistribute %s\n", - zebra_route_string(i)); - } + vty_out(vty, " %s", zebra_route_string(i)); } } @@ -426,14 +214,6 @@ void zebra_init(struct thread_master *master) zclient->interface_address_delete = ripng_interface_address_delete; zclient->redistribute_route_add = ripng_zebra_read_route; zclient->redistribute_route_del = ripng_zebra_read_route; - - /* Install command elements to ripng node */ - install_element(RIPNG_NODE, &ripng_redistribute_type_cmd); - install_element(RIPNG_NODE, &ripng_redistribute_type_routemap_cmd); - install_element(RIPNG_NODE, &ripng_redistribute_type_metric_cmd); - install_element(RIPNG_NODE, - &ripng_redistribute_type_metric_routemap_cmd); - install_element(RIPNG_NODE, &no_ripng_redistribute_type_cmd); } void ripng_zebra_stop(void) diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 2cbbbae7f5..ae8e8ab7d9 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -36,6 +36,7 @@ #include "if_rmap.h" #include "privs.h" #include "lib_errors.h" +#include "northbound_cli.h" #include "ripngd/ripngd.h" #include "ripngd/ripng_route.h" @@ -51,6 +52,9 @@ enum { ripng_all_route, ripng_changed_route, }; +static void ripng_distribute_update(struct distribute_ctx *ctx, + struct distribute *dist); + /* Prototypes. */ void ripng_output_process(struct interface *, struct sockaddr_in6 *, int); @@ -65,7 +69,7 @@ struct ripng_nexthop { struct in6_addr address; }; -static int ripng_route_rte(struct ripng_info *rinfo) +int ripng_route_rte(struct ripng_info *rinfo) { return (rinfo->type == ZEBRA_ROUTE_RIPNG && rinfo->sub_type == RIPNG_ROUTE_RTE); @@ -87,7 +91,7 @@ void ripng_info_free(struct ripng_info *rinfo) } /* Create ripng socket. */ -static int ripng_make_socket(void) +int ripng_make_socket(void) { int ret; int sock; @@ -618,7 +622,7 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p, } /* All interface filter check. */ - dist = distribute_lookup(NULL); + dist = distribute_lookup(ripng->distribute_ctx, NULL); if (dist) { if (dist->list[distribute]) { alist = access_list_lookup(AFI_IP6, @@ -1778,7 +1782,7 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, } /* Create new RIPng instance and set it to global variable. */ -static int ripng_create(void) +int ripng_create(int socket) { /* ripng should be NULL. */ assert(ripng == NULL); @@ -1788,10 +1792,15 @@ static int ripng_create(void) /* Default version and timer values. */ ripng->version = RIPNG_V1; - ripng->update_time = RIPNG_UPDATE_TIMER_DEFAULT; - ripng->timeout_time = RIPNG_TIMEOUT_TIMER_DEFAULT; - ripng->garbage_time = RIPNG_GARBAGE_TIMER_DEFAULT; - ripng->default_metric = RIPNG_DEFAULT_METRIC_DEFAULT; + ripng->update_time = yang_get_default_uint32( + "%s/timers/update-interval", RIPNG_INSTANCE); + ripng->timeout_time = yang_get_default_uint32( + "%s/timers/holddown-interval", RIPNG_INSTANCE); + ripng->garbage_time = yang_get_default_uint32( + "%s/timers/flush-interval", RIPNG_INSTANCE); + ripng->default_metric = + yang_get_default_uint8("%s/default-metric", RIPNG_INSTANCE); + ripng->ecmp = yang_get_default_bool("%s/allow-ecmp", RIPNG_INSTANCE); /* Make buffer. */ ripng->ibuf = stream_new(RIPNG_MAX_PACKET_SIZE * 5); @@ -1799,13 +1808,16 @@ static int ripng_create(void) /* Initialize RIPng routig table. */ ripng->table = agg_table_init(); - ripng->route = agg_table_init(); - ripng->aggregate = agg_table_init(); + /* Distribute list install. */ + ripng->distribute_ctx = distribute_list_ctx_create( + vrf_lookup_by_id(VRF_DEFAULT)); + distribute_list_add_hook(ripng->distribute_ctx, + ripng_distribute_update); + distribute_list_delete_hook(ripng->distribute_ctx, + ripng_distribute_update); /* Make socket. */ - ripng->sock = ripng_make_socket(); - if (ripng->sock < 0) - return ripng->sock; + ripng->sock = socket; /* Threads. */ ripng_event(RIPNG_READ, ripng->sock); @@ -2060,16 +2072,16 @@ DEFUN (show_ipv6_ripng_status, return CMD_SUCCESS; vty_out(vty, "Routing Protocol is \"RIPng\"\n"); - vty_out(vty, " Sending updates every %ld seconds with +/-50%%,", + vty_out(vty, " Sending updates every %u seconds with +/-50%%,", ripng->update_time); vty_out(vty, " next due in %lu seconds\n", thread_timer_remain_second(ripng->t_update)); - vty_out(vty, " Timeout after %ld seconds,", ripng->timeout_time); - vty_out(vty, " garbage collect after %ld seconds\n", + vty_out(vty, " Timeout after %u seconds,", ripng->timeout_time); + vty_out(vty, " garbage collect after %u seconds\n", ripng->garbage_time); /* Filtering status show. */ - config_show_distribute(vty); + config_show_distribute(vty, ripng->distribute_ctx); /* Default metric information. */ vty_out(vty, " Default redistribution metric is %d\n", @@ -2077,7 +2089,7 @@ DEFUN (show_ipv6_ripng_status, /* Redistribute information. */ vty_out(vty, " Redistributing:"); - ripng_redistribute_write(vty, 0); + ripng_redistribute_write(vty); vty_out(vty, "\n"); vty_out(vty, " Default version control: send version %d,", @@ -2099,7 +2111,7 @@ DEFUN (show_ipv6_ripng_status, } vty_out(vty, " Routing for Networks:\n"); - ripng_network_write(vty, 0); + ripng_network_write(vty); vty_out(vty, " Routing Information Sources:\n"); vty_out(vty, @@ -2109,245 +2121,6 @@ DEFUN (show_ipv6_ripng_status, return CMD_SUCCESS; } -DEFUN (clear_ipv6_rip, - clear_ipv6_rip_cmd, - "clear ipv6 ripng", - CLEAR_STR - IPV6_STR - "Clear IPv6 RIP database\n") -{ - struct agg_node *rp; - struct ripng_info *rinfo; - struct list *list; - struct listnode *listnode; - - /* Clear received RIPng routes */ - for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) { - list = rp->info; - if (list == NULL) - continue; - - for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { - if (!ripng_route_rte(rinfo)) - continue; - - if (CHECK_FLAG(rinfo->flags, RIPNG_RTF_FIB)) - ripng_zebra_ipv6_delete(rp); - break; - } - - if (rinfo) { - RIPNG_TIMER_OFF(rinfo->t_timeout); - RIPNG_TIMER_OFF(rinfo->t_garbage_collect); - listnode_delete(list, rinfo); - ripng_info_free(rinfo); - } - - if (list_isempty(list)) { - list_delete(&list); - rp->info = NULL; - agg_unlock_node(rp); - } - } - - return CMD_SUCCESS; -} - -DEFUN_NOSH (router_ripng, - router_ripng_cmd, - "router ripng", - "Enable a routing process\n" - "Make RIPng instance command\n") -{ - int ret; - - vty->node = RIPNG_NODE; - - if (!ripng) { - ret = ripng_create(); - - /* Notice to user we couldn't create RIPng. */ - if (ret < 0) { - zlog_warn("can't create RIPng"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - return CMD_SUCCESS; -} - -DEFUN (no_router_ripng, - no_router_ripng_cmd, - "no router ripng", - NO_STR - "Enable a routing process\n" - "Make RIPng instance command\n") -{ - if (ripng) - ripng_clean(); - return CMD_SUCCESS; -} - -DEFUN (ripng_route, - ripng_route_cmd, - "route IPV6ADDR", - "Static route setup\n" - "Set static RIPng route announcement\n") -{ - int idx_ipv6addr = 1; - int ret; - struct prefix_ipv6 p; - struct agg_node *rp; - - ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg, - (struct prefix_ipv6 *)&p); - if (ret <= 0) { - vty_out(vty, "Malformed address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - apply_mask_ipv6(&p); - - rp = agg_node_get(ripng->route, (struct prefix *)&p); - if (rp->info) { - vty_out(vty, "There is already same static route.\n"); - agg_unlock_node(rp); - return CMD_WARNING; - } - rp->info = (void *)1; - - ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0, - NULL, 0); - - return CMD_SUCCESS; -} - -DEFUN (no_ripng_route, - no_ripng_route_cmd, - "no route IPV6ADDR", - NO_STR - "Static route setup\n" - "Delete static RIPng route announcement\n") -{ - int idx_ipv6addr = 2; - int ret; - struct prefix_ipv6 p; - struct agg_node *rp; - - ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg, - (struct prefix_ipv6 *)&p); - if (ret <= 0) { - vty_out(vty, "Malformed address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - apply_mask_ipv6(&p); - - rp = agg_node_lookup(ripng->route, (struct prefix *)&p); - if (!rp) { - vty_out(vty, "Can't find static route.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0); - agg_unlock_node(rp); - - rp->info = NULL; - agg_unlock_node(rp); - - return CMD_SUCCESS; -} - -DEFUN (ripng_aggregate_address, - ripng_aggregate_address_cmd, - "aggregate-address X:X::X:X/M", - "Set aggregate RIPng route announcement\n" - "Aggregate network\n") -{ - int idx_ipv6_prefixlen = 1; - int ret; - struct prefix p; - struct agg_node *node; - - ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg, - (struct prefix_ipv6 *)&p); - if (ret <= 0) { - vty_out(vty, "Malformed address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check aggregate alredy exist or not. */ - node = agg_node_get(ripng->aggregate, &p); - if (node->info) { - vty_out(vty, "There is already same aggregate route.\n"); - agg_unlock_node(node); - return CMD_WARNING; - } - node->info = (void *)1; - - ripng_aggregate_add(&p); - - return CMD_SUCCESS; -} - -DEFUN (no_ripng_aggregate_address, - no_ripng_aggregate_address_cmd, - "no aggregate-address X:X::X:X/M", - NO_STR - "Delete aggregate RIPng route announcement\n" - "Aggregate network\n") -{ - int idx_ipv6_prefixlen = 2; - int ret; - struct prefix p; - struct agg_node *rn; - - ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg, - (struct prefix_ipv6 *)&p); - if (ret <= 0) { - vty_out(vty, "Malformed address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rn = agg_node_lookup(ripng->aggregate, &p); - if (!rn) { - vty_out(vty, "Can't find aggregate route.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - agg_unlock_node(rn); - rn->info = NULL; - agg_unlock_node(rn); - - ripng_aggregate_delete(&p); - - return CMD_SUCCESS; -} - -DEFUN (ripng_default_metric, - ripng_default_metric_cmd, - "default-metric (1-16)", - "Set a metric of redistribute routes\n" - "Default metric\n") -{ - int idx_number = 1; - if (ripng) { - ripng->default_metric = atoi(argv[idx_number]->arg); - } - return CMD_SUCCESS; -} - -DEFUN (no_ripng_default_metric, - no_ripng_default_metric_cmd, - "no default-metric [(1-16)]", - NO_STR - "Set a metric of redistribute routes\n" - "Default metric\n") -{ - if (ripng) { - ripng->default_metric = RIPNG_DEFAULT_METRIC_DEFAULT; - } - return CMD_SUCCESS; -} - - #if 0 /* RIPng update timer setup. */ DEFUN (ripng_update_timer, @@ -2451,58 +2224,6 @@ DEFUN (no_ripng_garbage_timer, } #endif /* 0 */ -DEFUN (ripng_timers, - ripng_timers_cmd, - "timers basic (0-65535) (0-65535) (0-65535)", - "RIPng timers setup\n" - "Basic timer\n" - "Routing table update timer value in second. Default is 30.\n" - "Routing information timeout timer. Default is 180.\n" - "Garbage collection timer. Default is 120.\n") -{ - int idx_number = 2; - int idx_number_2 = 3; - int idx_number_3 = 4; - unsigned long update; - unsigned long timeout; - unsigned long garbage; - - update = strtoul(argv[idx_number]->arg, NULL, 10); - timeout = strtoul(argv[idx_number_2]->arg, NULL, 10); - garbage = strtoul(argv[idx_number_3]->arg, NULL, 10); - - /* Set each timer value. */ - ripng->update_time = update; - ripng->timeout_time = timeout; - ripng->garbage_time = garbage; - - /* Reset update timer thread. */ - ripng_event(RIPNG_UPDATE_EVENT, 0); - - return CMD_SUCCESS; -} - -DEFUN (no_ripng_timers, - no_ripng_timers_cmd, - "no timers basic [(0-65535) (0-65535) (0-65535)]", - NO_STR - "RIPng timers setup\n" - "Basic timer\n" - "Routing table update timer value in second. Default is 30.\n" - "Routing information timeout timer. Default is 180.\n" - "Garbage collection timer. Default is 120.\n") -{ - /* Set each timer value to the default. */ - ripng->update_time = RIPNG_UPDATE_TIMER_DEFAULT; - ripng->timeout_time = RIPNG_TIMEOUT_TIMER_DEFAULT; - ripng->garbage_time = RIPNG_GARBAGE_TIMER_DEFAULT; - - /* Reset update timer thread. */ - ripng_event(RIPNG_UPDATE_EVENT, 0); - - return CMD_SUCCESS; -} - #if 0 DEFUN (show_ipv6_protocols, show_ipv6_protocols_cmd, @@ -2530,48 +2251,8 @@ DEFUN (show_ipv6_protocols, } #endif -/* Please be carefull to use this command. */ -DEFUN (ripng_default_information_originate, - ripng_default_information_originate_cmd, - "default-information originate", - "Default route information\n" - "Distribute default route\n") -{ - struct prefix_ipv6 p; - - if (!ripng->default_information) { - ripng->default_information = 1; - - str2prefix_ipv6("::/0", &p); - ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT, - &p, 0, NULL, 0); - } - - return CMD_SUCCESS; -} - -DEFUN (no_ripng_default_information_originate, - no_ripng_default_information_originate_cmd, - "no default-information originate", - NO_STR - "Default route information\n" - "Distribute default route\n") -{ - struct prefix_ipv6 p; - - if (ripng->default_information) { - ripng->default_information = 0; - - str2prefix_ipv6("::/0", &p); - ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, - RIPNG_ROUTE_DEFAULT, &p, 0); - } - - return CMD_SUCCESS; -} - /* Update ECMP routes to zebra when ECMP is disabled. */ -static void ripng_ecmp_disable(void) +void ripng_ecmp_disable(void) { struct agg_node *rp; struct ripng_info *rinfo, *tmp_rinfo; @@ -2608,109 +2289,25 @@ static void ripng_ecmp_disable(void) } } -DEFUN (ripng_allow_ecmp, - ripng_allow_ecmp_cmd, - "allow-ecmp", - "Allow Equal Cost MultiPath\n") -{ - if (ripng->ecmp) { - vty_out(vty, "ECMP is already enabled.\n"); - return CMD_WARNING; - } - - ripng->ecmp = 1; - zlog_info("ECMP is enabled."); - return CMD_SUCCESS; -} - -DEFUN (no_ripng_allow_ecmp, - no_ripng_allow_ecmp_cmd, - "no allow-ecmp", - NO_STR - "Allow Equal Cost MultiPath\n") -{ - if (!ripng->ecmp) { - vty_out(vty, "ECMP is already disabled.\n"); - return CMD_WARNING; - } - - ripng->ecmp = 0; - zlog_info("ECMP is disabled."); - ripng_ecmp_disable(); - return CMD_SUCCESS; -} - /* RIPng configuration write function. */ static int ripng_config_write(struct vty *vty) { - int ripng_network_write(struct vty *, int); - void ripng_redistribute_write(struct vty *, int); + struct lyd_node *dnode; int write = 0; - struct agg_node *rp; - if (ripng) { + dnode = yang_dnode_get(running_config->dnode, + "/frr-ripngd:ripngd/instance"); + if (dnode) { + nb_cli_show_dnode_cmds(vty, dnode, false); - /* 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 */ + config_write_distribute(vty, + ripng->distribute_ctx); - write += config_write_distribute(vty); + config_write_if_rmap(vty); - write += config_write_if_rmap(vty); - - write++; + write = 1; } + return write; } @@ -2719,7 +2316,8 @@ static struct cmd_node cmd_ripng_node = { RIPNG_NODE, "%s(config-router)# ", 1, }; -static void ripng_distribute_update(struct distribute *dist) +static void ripng_distribute_update(struct distribute_ctx *ctx, + struct distribute *dist) { struct interface *ifp; struct ripng_interface *ri; @@ -2780,9 +2378,11 @@ void ripng_distribute_update_interface(struct interface *ifp) { struct distribute *dist; - dist = distribute_lookup(ifp->name); + if (!ripng) + return; + dist = distribute_lookup(ripng->distribute_ctx, ifp->name); if (dist) - ripng_distribute_update(dist); + ripng_distribute_update(ripng->distribute_ctx, dist); } /* Update all interface's distribute list. */ @@ -2855,33 +2455,16 @@ void ripng_clean() ripng->sock = -1; } - /* Static RIPng route configuration. */ - for (rp = agg_route_top(ripng->route); rp; - rp = agg_route_next(rp)) - if (rp->info) { - rp->info = NULL; - agg_unlock_node(rp); - } - - /* RIPng aggregated prefixes */ - for (rp = agg_route_top(ripng->aggregate); rp; - rp = agg_route_next(rp)) - if (rp->info) { - rp->info = NULL; - agg_unlock_node(rp); - } - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) if (ripng->route_map[i].name) free(ripng->route_map[i].name); - XFREE(MTYPE_ROUTE_TABLE, ripng->table); - XFREE(MTYPE_ROUTE_TABLE, ripng->route); - XFREE(MTYPE_ROUTE_TABLE, ripng->aggregate); + agg_table_finish(ripng->table); stream_free(ripng->ibuf); stream_free(ripng->obuf); + distribute_list_delete(&ripng->distribute_ctx); XFREE(MTYPE_RIPNG, ripng); ripng = NULL; } /* if (ripng) */ @@ -2893,25 +2476,6 @@ void ripng_clean() ripng_redistribute_clean(); } -/* Reset all values to the default settings. */ -void ripng_reset() -{ - /* Call ripd related reset functions. */ - ripng_debug_reset(); - ripng_route_map_reset(); - - /* Call library reset functions. */ - vty_reset(); - access_list_reset(); - prefix_list_reset(); - - distribute_list_reset(); - - ripng_interface_reset(); - - ripng_zclient_reset(); -} - static void ripng_if_rmap_update(struct if_rmap *if_rmap) { struct interface *ifp; @@ -2987,22 +2551,8 @@ void ripng_init() install_element(VIEW_NODE, &show_ipv6_ripng_cmd); install_element(VIEW_NODE, &show_ipv6_ripng_status_cmd); - install_element(ENABLE_NODE, &clear_ipv6_rip_cmd); - - install_element(CONFIG_NODE, &router_ripng_cmd); - install_element(CONFIG_NODE, &no_router_ripng_cmd); - install_default(RIPNG_NODE); - install_element(RIPNG_NODE, &ripng_route_cmd); - install_element(RIPNG_NODE, &no_ripng_route_cmd); - install_element(RIPNG_NODE, &ripng_aggregate_address_cmd); - install_element(RIPNG_NODE, &no_ripng_aggregate_address_cmd); - - install_element(RIPNG_NODE, &ripng_default_metric_cmd); - install_element(RIPNG_NODE, &no_ripng_default_metric_cmd); - install_element(RIPNG_NODE, &ripng_timers_cmd); - install_element(RIPNG_NODE, &no_ripng_timers_cmd); #if 0 install_element (VIEW_NODE, &show_ipv6_protocols_cmd); install_element (RIPNG_NODE, &ripng_update_timer_cmd); @@ -3013,13 +2563,6 @@ void ripng_init() install_element (RIPNG_NODE, &no_ripng_garbage_timer_cmd); #endif /* 0 */ - install_element(RIPNG_NODE, &ripng_default_information_originate_cmd); - install_element(RIPNG_NODE, - &no_ripng_default_information_originate_cmd); - - install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd); - install_element(RIPNG_NODE, &no_ripng_allow_ecmp_cmd); - ripng_if_init(); ripng_debug_init(); @@ -3035,8 +2578,6 @@ void ripng_init() /* Distribute list install. */ distribute_list_init(RIPNG_NODE); - distribute_list_add_hook(ripng_distribute_update); - distribute_list_delete_hook(ripng_distribute_update); /* Route-map for interface. */ ripng_route_map_init(); diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index 1095a33494..1db7a83b11 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -24,6 +24,7 @@ #include <zclient.h> #include <vty.h> +#include <distribute.h> #include "ripng_memory.h" @@ -43,11 +44,6 @@ #define RIPNG_METRIC_NEXTHOP 0xff #define RIPNG_GROUP "ff02::9" -/* RIPng timers. */ -#define RIPNG_UPDATE_TIMER_DEFAULT 30 -#define RIPNG_TIMEOUT_TIMER_DEFAULT 180 -#define RIPNG_GARBAGE_TIMER_DEFAULT 120 - /* RIPng peer timeout value. */ #define RIPNG_PEER_TIMER_DEFAULT 180 @@ -77,9 +73,6 @@ #define RIPNG_DEFAULT_ACCEPT_NONE 1 #define RIPNG_DEFAULT_ACCEPT 2 -/* Default value for "default-metric" command. */ -#define RIPNG_DEFAULT_METRIC_DEFAULT 1 - /* For max RTE calculation. */ #ifndef IPV6_HDRLEN #define IPV6_HDRLEN 40 @@ -89,6 +82,10 @@ #define IFMINMTU 576 #endif /* IFMINMTU */ +/* YANG paths */ +#define RIPNG_INSTANCE "/frr-ripngd:ripngd/instance" +#define RIPNG_IFACE "/frr-interface:lib/interface/frr-ripngd:ripng" + /* RIPng structure. */ struct ripng { /* RIPng socket. */ @@ -97,12 +94,11 @@ struct ripng { /* RIPng Parameters.*/ uint8_t command; uint8_t version; - unsigned long update_time; - unsigned long timeout_time; - unsigned long garbage_time; + uint16_t update_time; + uint16_t timeout_time; + uint16_t garbage_time; int max_mtu; - int default_metric; - int default_information; + uint8_t default_metric; /* Input/output buffer of RIPng. */ struct stream *ibuf; @@ -111,12 +107,6 @@ struct ripng { /* RIPng routing information base. */ struct agg_table *table; - /* RIPng only static route information. */ - struct agg_table *route; - - /* RIPng aggregate route information. */ - struct agg_table *aggregate; - /* RIPng threads. */ struct thread *t_read; struct thread *t_write; @@ -130,15 +120,18 @@ struct ripng { struct thread *t_triggered_interval; /* RIPng ECMP flag */ - unsigned int ecmp; + bool ecmp; /* For redistribute route map. */ struct { char *name; struct route_map *map; - int metric_config; - uint32_t metric; + bool metric_config; + uint8_t metric; } route_map[ZEBRA_ROUTE_MAX]; + + /* For distribute-list container */ + struct distribute_ctx *distribute_ctx; }; /* Routing table entry. */ @@ -247,7 +240,6 @@ struct ripng_interface { /* Split horizon flag. */ split_horizon_policy_t split_horizon; - split_horizon_policy_t split_horizon_default; /* For filter type slot. */ #define RIPNG_FILTER_IN 0 @@ -325,30 +317,46 @@ enum ripng_event { } \ } while (0) +#define RIPNG_OFFSET_LIST_IN 0 +#define RIPNG_OFFSET_LIST_OUT 1 +#define RIPNG_OFFSET_LIST_MAX 2 + +struct ripng_offset_list { + char *ifname; + + struct { + char *alist_name; + /* struct access_list *alist; */ + uint8_t metric; + } direct[RIPNG_OFFSET_LIST_MAX]; +}; + /* Extern variables. */ extern struct ripng *ripng; +extern struct list *peer_list; extern struct zebra_privs_t ripngd_privs; extern struct thread_master *master; /* Prototypes. */ extern void ripng_init(void); -extern void ripng_reset(void); extern void ripng_clean(void); extern void ripng_clean_network(void); extern void ripng_interface_clean(void); -extern void ripng_interface_reset(void); +extern int ripng_enable_network_add(struct prefix *p); +extern int ripng_enable_network_delete(struct prefix *p); +extern int ripng_enable_if_add(const char *ifname); +extern int ripng_enable_if_delete(const char *ifname); +extern int ripng_passive_interface_set(const char *ifname); +extern int ripng_passive_interface_unset(const char *ifname); extern void ripng_passive_interface_clean(void); extern void ripng_if_init(void); extern void ripng_route_map_init(void); -extern void ripng_route_map_reset(void); extern void ripng_terminate(void); /* zclient_init() is done by ripng_zebra.c:zebra_init() */ extern void zebra_init(struct thread_master *); extern void ripng_zebra_stop(void); -extern void ripng_zclient_reset(void); -extern void ripng_offset_init(void); - -extern int config_write_ripng_offset_list(struct vty *); +extern void ripng_redistribute_conf_update(int type); +extern void ripng_redistribute_conf_delete(int type); extern void ripng_peer_init(void); extern void ripng_peer_update(struct sockaddr_in6 *, uint8_t); @@ -358,12 +366,18 @@ extern void ripng_peer_display(struct vty *); extern struct ripng_peer *ripng_peer_lookup(struct in6_addr *); extern struct ripng_peer *ripng_peer_lookup_next(struct in6_addr *); +extern struct ripng_offset_list *ripng_offset_list_new(const char *ifname); +extern void ripng_offset_list_del(struct ripng_offset_list *offset); +extern struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname); +extern struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname); extern int ripng_offset_list_apply_in(struct prefix_ipv6 *, struct interface *, uint8_t *); extern int ripng_offset_list_apply_out(struct prefix_ipv6 *, struct interface *, uint8_t *); +extern void ripng_offset_init(void); extern void ripng_offset_clean(void); +extern int ripng_route_rte(struct ripng_info *rinfo); extern struct ripng_info *ripng_info_new(void); extern void ripng_info_free(struct ripng_info *rinfo); extern void ripng_event(enum ripng_event, int); @@ -374,6 +388,7 @@ extern void ripng_redistribute_delete(int, int, struct prefix_ipv6 *, ifindex_t); extern void ripng_redistribute_withdraw(int type); +extern void ripng_ecmp_disable(void); extern void ripng_distribute_update_interface(struct interface *); extern void ripng_if_rmap_update_interface(struct interface *); @@ -382,7 +397,7 @@ extern void ripng_zebra_ipv6_delete(struct agg_node *node); extern void ripng_redistribute_clean(void); extern int ripng_redistribute_check(int); -extern void ripng_redistribute_write(struct vty *, int); +extern void ripng_redistribute_write(struct vty *); extern int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p, struct in6_addr *nexthop, uint16_t tag, @@ -406,10 +421,16 @@ extern int ripng_interface_address_add(int command, struct zclient *, extern int ripng_interface_address_delete(int command, struct zclient *, zebra_size_t, vrf_id_t); -extern int ripng_network_write(struct vty *, int); +extern int ripng_create(int socket); +extern int ripng_make_socket(void); +extern int ripng_network_write(struct vty *); extern struct ripng_info *ripng_ecmp_add(struct ripng_info *); extern struct ripng_info *ripng_ecmp_replace(struct ripng_info *); extern struct ripng_info *ripng_ecmp_delete(struct ripng_info *); +/* Northbound. */ +extern void ripng_cli_init(void); +extern const struct frr_yang_module_info frr_ripngd_info; + #endif /* _ZEBRA_RIPNG_RIPNGD_H */ diff --git a/ripngd/subdir.am b/ripngd/subdir.am index 8f834a1d29..d401e9bbf6 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -6,21 +6,21 @@ if RIPNGD noinst_LIBRARIES += ripngd/libripng.a sbin_PROGRAMS += ripngd/ripngd vtysh_scan += \ + $(top_srcdir)/ripngd/ripng_cli.c \ $(top_srcdir)/ripngd/ripng_debug.c \ - $(top_srcdir)/ripngd/ripng_interface.c \ - $(top_srcdir)/ripngd/ripng_offset.c \ - $(top_srcdir)/ripngd/ripng_zebra.c \ $(top_srcdir)/ripngd/ripngd.c \ # end man8 += $(MANBUILD)/ripngd.8 endif ripngd_libripng_a_SOURCES = \ + ripngd/ripng_cli.c \ ripngd/ripng_debug.c \ ripngd/ripng_interface.c \ ripngd/ripng_memory.c \ ripngd/ripng_nexthop.c \ ripngd/ripng_offset.c \ + ripngd/ripng_northbound.c \ ripngd/ripng_peer.c \ ripngd/ripng_route.c \ ripngd/ripng_routemap.c \ @@ -28,7 +28,11 @@ ripngd_libripng_a_SOURCES = \ ripngd/ripngd.c \ # end +ripngd/ripng_cli_clippy.c: $(CLIPPY_DEPS) +ripngd/ripng_cli.$(OBJEXT): ripngd/ripng_cli_clippy.c + noinst_HEADERS += \ + ripngd/ripng_cli.h \ ripngd/ripng_debug.h \ ripngd/ripng_memory.h \ ripngd/ripng_nexthop.h \ @@ -40,5 +44,8 @@ ripngd_ripngd_LDADD = ripngd/libripng.a lib/libfrr.la @LIBCAP@ ripngd_ripngd_SOURCES = \ ripngd/ripng_main.c \ # end +nodist_ripngd_ripngd_SOURCES = \ + yang/frr-ripngd.yang.c \ + # end dist_examples_DATA += ripngd/ripngd.conf.sample diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c index 20cdd21e7d..175a276089 100644 --- a/sharpd/sharp_main.c +++ b/sharpd/sharp_main.c @@ -42,6 +42,7 @@ #include "distribute.h" #include "libfrr.h" #include "routemap.h" +#include "nexthop_group.h" #include "sharp_zebra.h" #include "sharp_vty.h" @@ -150,6 +151,7 @@ int main(int argc, char **argv, char **envp) master = frr_init(); + nexthop_group_init(NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL); access_list_init(); diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 797e336c2d..d0a34c0f93 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -28,6 +28,7 @@ #include "log.h" #include "vrf.h" #include "zclient.h" +#include "nexthop_group.h" #include "sharpd/sharp_zebra.h" #include "sharpd/sharp_vty.h" @@ -39,6 +40,14 @@ extern uint32_t total_routes; extern uint32_t installed_routes; extern uint32_t removed_routes; +uint8_t inst; +struct prefix prefix; +struct prefix orig_prefix; +struct nexthop nhop; +struct nexthop_group nhop_group; +uint32_t rts; +int32_t repeat; + DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd, "sharp watch nexthop X:X::X:X$nhop", "Sharp routing Protocol\n" @@ -81,7 +90,7 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, DEFPY (install_routes, install_routes_cmd, - "sharp install routes A.B.C.D$start nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6> (1-1000000)$routes [instance (0-255)$instance]", + "sharp install routes A.B.C.D$start <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]", "Sharp routing Protocol\n" "install some routes\n" "Routes to install\n" @@ -89,40 +98,57 @@ DEFPY (install_routes, "Nexthop to use(Can be an IPv4 or IPv6 address)\n" "V4 Nexthop address to use\n" "V6 Nexthop address to use\n" + "Nexthop-Group to use\n" + "The Name of the nexthop-group\n" "How many to create\n" "Instance to use\n" - "Instance\n") + "Instance\n" + "Should we repeat this command\n" + "How many times to repeat this command\n") { - int i; - struct prefix p; - struct nexthop nhop; - uint32_t temp; - total_routes = routes; installed_routes = 0; - memset(&p, 0, sizeof(p)); - memset(&nhop, 0, sizeof(nhop)); - - p.family = AF_INET; - p.prefixlen = 32; - p.u.prefix4 = start; + if (rpt >= 2) + repeat = rpt * 2; + else + repeat = 0; - if (nexthop4.s_addr != INADDR_ANY) { - nhop.gate.ipv4 = nexthop4; - nhop.type = NEXTHOP_TYPE_IPV4; + memset(&prefix, 0, sizeof(prefix)); + memset(&orig_prefix, 0, sizeof(orig_prefix)); + memset(&nhop, 0, sizeof(nhop)); + memset(&nhop_group, 0, sizeof(nhop_group)); + + prefix.family = AF_INET; + prefix.prefixlen = 32; + prefix.u.prefix4 = start; + orig_prefix = prefix; + + if (nexthop_group) { + struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group); + if (!nhgc) { + vty_out(vty, + "Specified Nexthop Group: %s does not exist\n", + nexthop_group); + return CMD_WARNING; + } + + nhop_group.nexthop = nhgc->nhg.nexthop; } else { - memcpy(&nhop.gate.ipv6, &nexthop6, IPV6_MAX_BYTELEN); - nhop.type = NEXTHOP_TYPE_IPV6; + if (nexthop4.s_addr != INADDR_ANY) { + nhop.gate.ipv4 = nexthop4; + nhop.type = NEXTHOP_TYPE_IPV4; + } else { + nhop.gate.ipv6 = nexthop6; + nhop.type = NEXTHOP_TYPE_IPV6; + } + + nhop_group.nexthop = &nhop; } - zlog_debug("Inserting %ld routes", routes); - - temp = ntohl(p.u.prefix4.s_addr); - for (i = 0; i < routes; i++) { - route_add(&p, (uint8_t)instance, &nhop); - p.u.prefix4.s_addr = htonl(++temp); - } + inst = instance; + rts = routes; + sharp_install_routes_helper(&prefix, inst, &nhop_group, rts); return CMD_SUCCESS; } @@ -168,25 +194,18 @@ DEFPY (remove_routes, "instance to use\n" "Value of instance\n") { - int i; - struct prefix p; - uint32_t temp; total_routes = routes; removed_routes = 0; - memset(&p, 0, sizeof(p)); + memset(&prefix, 0, sizeof(prefix)); - p.family = AF_INET; - p.prefixlen = 32; - p.u.prefix4 = start; + prefix.family = AF_INET; + prefix.prefixlen = 32; + prefix.u.prefix4 = start; - zlog_debug("Removing %ld routes", routes); - - temp = ntohl(p.u.prefix4.s_addr); - for (i = 0; i < routes; i++) { - route_delete(&p, (uint8_t)instance); - p.u.prefix4.s_addr = htonl(++temp); - } + inst = instance; + rts = routes; + sharp_remove_routes_helper(&prefix, inst, rts); return CMD_SUCCESS; } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index f752009eb8..37591fa41f 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -34,6 +34,7 @@ #include "plist.h" #include "log.h" #include "nexthop.h" +#include "nexthop_group.h" #include "sharp_zebra.h" @@ -131,6 +132,59 @@ static int interface_state_down(int command, struct zclient *zclient, extern uint32_t total_routes; extern uint32_t installed_routes; extern uint32_t removed_routes; +extern int32_t repeat; +extern struct prefix orig_prefix; +extern struct nexthop_group nhop_group; +extern uint8_t inst; + +void sharp_install_routes_helper(struct prefix *p, uint8_t instance, + struct nexthop_group *nhg, + uint32_t routes) +{ + uint32_t temp, i; + + zlog_debug("Inserting %u routes", routes); + + temp = ntohl(p->u.prefix4.s_addr); + for (i = 0; i < routes; i++) { + route_add(p, (uint8_t)instance, nhg); + p->u.prefix4.s_addr = htonl(++temp); + } +} + +void sharp_remove_routes_helper(struct prefix *p, uint8_t instance, + uint32_t routes) +{ + uint32_t temp, i; + + zlog_debug("Removing %u routes", routes); + + temp = ntohl(p->u.prefix4.s_addr); + for (i = 0; i < routes; i++) { + route_delete(p, (uint8_t)instance); + p->u.prefix4.s_addr = htonl(++temp); + } +} + +static void handle_repeated(bool installed) +{ + struct prefix p = orig_prefix; + repeat--; + + if (repeat <= 0) + return; + + if (installed) { + removed_routes = 0; + sharp_remove_routes_helper(&p, inst, total_routes); + } + + if (!installed) { + installed_routes = 0; + sharp_install_routes_helper(&p, inst, &nhop_group, + total_routes); + } +} static int route_notify_owner(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) @@ -145,8 +199,10 @@ static int route_notify_owner(int command, struct zclient *zclient, switch (note) { case ZAPI_ROUTE_INSTALLED: installed_routes++; - if (total_routes == installed_routes) + if (total_routes == installed_routes) { zlog_debug("Installed All Items"); + handle_repeated(true); + } break; case ZAPI_ROUTE_FAIL_INSTALL: zlog_debug("Failed install of route"); @@ -156,8 +212,10 @@ static int route_notify_owner(int command, struct zclient *zclient, break; case ZAPI_ROUTE_REMOVED: removed_routes++; - if (total_routes == removed_routes) + if (total_routes == removed_routes) { zlog_debug("Removed all Items"); + handle_repeated(false); + } break; case ZAPI_ROUTE_REMOVE_FAIL: zlog_debug("Route removal Failure"); @@ -176,10 +234,12 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label) zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); } -void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh) +void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg) { struct zapi_route api; struct zapi_nexthop *api_nh; + struct nexthop *nh; + int i = 0; memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; @@ -191,12 +251,35 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh) SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api_nh = &api.nexthops[0]; - api_nh->vrf_id = VRF_DEFAULT; - api_nh->gate = nh->gate; - api_nh->type = nh->type; - api_nh->ifindex = nh->ifindex; - api.nexthop_num = 1; + for (ALL_NEXTHOPS_PTR(nhg, nh)) { + api_nh = &api.nexthops[i]; + api_nh->vrf_id = VRF_DEFAULT; + api_nh->type = nh->type; + switch (nh->type) { + case NEXTHOP_TYPE_IPV4: + api_nh->gate = nh->gate; + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + api_nh->gate = nh->gate; + api_nh->ifindex = nh->ifindex; + break; + case NEXTHOP_TYPE_IFINDEX: + api_nh->ifindex = nh->ifindex; + break; + case NEXTHOP_TYPE_IPV6: + memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + api_nh->ifindex = nh->ifindex; + memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16); + break; + case NEXTHOP_TYPE_BLACKHOLE: + api_nh->bh_type = nh->bh_type; + break; + } + i++; + } + api.nexthop_num = i; zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); } diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 58438ed01d..7326056cae 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -25,7 +25,14 @@ extern void sharp_zebra_init(void); extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label); -extern void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh); +extern void route_add(struct prefix *p, uint8_t instance, + struct nexthop_group *nhg); extern void route_delete(struct prefix *p, uint8_t instance); extern void sharp_zebra_nexthop_watch(struct prefix *p, bool watch); + +extern void sharp_install_routes_helper(struct prefix *p, uint8_t instance, + struct nexthop_group *nhg, + uint32_t routes); +extern void sharp_remove_routes_helper(struct prefix *p, uint8_t instance, + uint32_t routes); #endif diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 1e23f597b0..d6db60d3ed 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -154,11 +154,11 @@ static int route_notify_owner(int command, struct zclient *zclient, uint32_t table_id; char buf[PREFIX_STRLEN]; - prefix2str(&p, buf, sizeof(buf)); - if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, ¬e)) return -1; + prefix2str(&p, buf, sizeof(buf)); + switch (note) { case ZAPI_ROUTE_FAIL_INSTALL: zlog_warn("%s: Route %s failed to install for table: %u", diff --git a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv4-post6.1.ref b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv4-post6.1.ref new file mode 100644 index 0000000000..d36d045397 --- /dev/null +++ b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv4-post6.1.ref @@ -0,0 +1,9 @@ +BGP table version is 1, local router ID is 192.168.0.1, vrf id 0 +Default local pref 100, local AS 100 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +*> 192.168.0.0/24 0.0.0.0 0 32768 i diff --git a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_post6.1.ref b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_post6.1.ref new file mode 100644 index 0000000000..de91b247d8 --- /dev/null +++ b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_post6.1.ref @@ -0,0 +1,9 @@ +BGP table version is 1, local router ID is 192.168.0.1, vrf id 0 +Default local pref 100, local AS 100 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +*> fc00::/64 :: 0 32768 i diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1-post6.1.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1-post6.1.ref new file mode 100644 index 0000000000..2cf87487ab --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1-post6.1.ref @@ -0,0 +1,42 @@ +BGP table version is XXX, local router ID is 172.30.1.1, vrf id - +Default local pref 100, local AS 100 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +* 10.0.1.0/24 172.16.1.5 0 65005 i +* 172.16.1.2 0 65002 i +*> 172.16.1.1 0 65001 i +*> 10.101.0.0/24 172.16.1.1 100 0 65001 i +*> 10.101.1.0/24 172.16.1.1 100 0 65001 i +*> 10.101.2.0/24 172.16.1.1 100 0 65001 i +*> 10.101.3.0/24 172.16.1.1 100 0 65001 i +*> 10.101.4.0/24 172.16.1.1 100 0 65001 i +*> 10.101.5.0/24 172.16.1.1 100 0 65001 i +*> 10.101.6.0/24 172.16.1.1 100 0 65001 i +*> 10.101.7.0/24 172.16.1.1 100 0 65001 i +*> 10.101.8.0/24 172.16.1.1 100 0 65001 i +*> 10.101.9.0/24 172.16.1.1 100 0 65001 i +*> 10.102.0.0/24 172.16.1.2 100 0 65002 i +*> 10.102.1.0/24 172.16.1.2 100 0 65002 i +*> 10.102.2.0/24 172.16.1.2 100 0 65002 i +*> 10.102.3.0/24 172.16.1.2 100 0 65002 i +*> 10.102.4.0/24 172.16.1.2 100 0 65002 i +*> 10.102.5.0/24 172.16.1.2 100 0 65002 i +*> 10.102.6.0/24 172.16.1.2 100 0 65002 i +*> 10.102.7.0/24 172.16.1.2 100 0 65002 i +*> 10.102.8.0/24 172.16.1.2 100 0 65002 i +*> 10.102.9.0/24 172.16.1.2 100 0 65002 i +*> 10.105.0.0/24 172.16.1.5 100 0 65005 i +*> 10.105.1.0/24 172.16.1.5 100 0 65005 i +*> 10.105.2.0/24 172.16.1.5 100 0 65005 i +*> 10.105.3.0/24 172.16.1.5 100 0 65005 i +*> 10.105.4.0/24 172.16.1.5 100 0 65005 i +*> 10.105.5.0/24 172.16.1.5 100 0 65005 i +*> 10.105.6.0/24 172.16.1.5 100 0 65005 i +*> 10.105.7.0/24 172.16.1.5 100 0 65005 i +*> 10.105.8.0/24 172.16.1.5 100 0 65005 i +*> 10.105.9.0/24 172.16.1.5 100 0 65005 i +*> 172.20.0.0/28 0.0.0.0 0 32768 i diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2-post6.1.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2-post6.1.ref new file mode 100644 index 0000000000..9d1b948b5c --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2-post6.1.ref @@ -0,0 +1,31 @@ +BGP table version is XXX, local router ID is 172.30.1.1, vrf id - +Default local pref 100, local AS 100 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +* 10.0.1.0/24 172.16.1.4 0 65004 i +*> 172.16.1.3 0 65003 i +*> 10.103.0.0/24 172.16.1.3 100 0 65003 i +*> 10.103.1.0/24 172.16.1.3 100 0 65003 i +*> 10.103.2.0/24 172.16.1.3 100 0 65003 i +*> 10.103.3.0/24 172.16.1.3 100 0 65003 i +*> 10.103.4.0/24 172.16.1.3 100 0 65003 i +*> 10.103.5.0/24 172.16.1.3 100 0 65003 i +*> 10.103.6.0/24 172.16.1.3 100 0 65003 i +*> 10.103.7.0/24 172.16.1.3 100 0 65003 i +*> 10.103.8.0/24 172.16.1.3 100 0 65003 i +*> 10.103.9.0/24 172.16.1.3 100 0 65003 i +*> 10.104.0.0/24 172.16.1.4 100 0 65004 i +*> 10.104.1.0/24 172.16.1.4 100 0 65004 i +*> 10.104.2.0/24 172.16.1.4 100 0 65004 i +*> 10.104.3.0/24 172.16.1.4 100 0 65004 i +*> 10.104.4.0/24 172.16.1.4 100 0 65004 i +*> 10.104.5.0/24 172.16.1.4 100 0 65004 i +*> 10.104.6.0/24 172.16.1.4 100 0 65004 i +*> 10.104.7.0/24 172.16.1.4 100 0 65004 i +*> 10.104.8.0/24 172.16.1.4 100 0 65004 i +*> 10.104.9.0/24 172.16.1.4 100 0 65004 i +*> 172.20.0.0/28 0.0.0.0 9999 32768 100 100 100 100 100 i diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3-post6.1.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3-post6.1.ref new file mode 100644 index 0000000000..8b66fa67ec --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3-post6.1.ref @@ -0,0 +1,42 @@ +BGP table version is XXX, local router ID is 172.30.1.1, vrf id - +Default local pref 100, local AS 100 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +* 10.0.1.0/24 172.16.1.8 0 65008 i +* 172.16.1.7 0 65007 i +*> 172.16.1.6 0 65006 i +*> 10.106.0.0/24 172.16.1.6 100 0 65006 i +*> 10.106.1.0/24 172.16.1.6 100 0 65006 i +*> 10.106.2.0/24 172.16.1.6 100 0 65006 i +*> 10.106.3.0/24 172.16.1.6 100 0 65006 i +*> 10.106.4.0/24 172.16.1.6 100 0 65006 i +*> 10.106.5.0/24 172.16.1.6 100 0 65006 i +*> 10.106.6.0/24 172.16.1.6 100 0 65006 i +*> 10.106.7.0/24 172.16.1.6 100 0 65006 i +*> 10.106.8.0/24 172.16.1.6 100 0 65006 i +*> 10.106.9.0/24 172.16.1.6 100 0 65006 i +*> 10.107.0.0/24 172.16.1.7 100 0 65007 i +*> 10.107.1.0/24 172.16.1.7 100 0 65007 i +*> 10.107.2.0/24 172.16.1.7 100 0 65007 i +*> 10.107.3.0/24 172.16.1.7 100 0 65007 i +*> 10.107.4.0/24 172.16.1.7 100 0 65007 i +*> 10.107.5.0/24 172.16.1.7 100 0 65007 i +*> 10.107.6.0/24 172.16.1.7 100 0 65007 i +*> 10.107.7.0/24 172.16.1.7 100 0 65007 i +*> 10.107.8.0/24 172.16.1.7 100 0 65007 i +*> 10.107.9.0/24 172.16.1.7 100 0 65007 i +*> 10.108.0.0/24 172.16.1.8 100 0 65008 i +*> 10.108.1.0/24 172.16.1.8 100 0 65008 i +*> 10.108.2.0/24 172.16.1.8 100 0 65008 i +*> 10.108.3.0/24 172.16.1.8 100 0 65008 i +*> 10.108.4.0/24 172.16.1.8 100 0 65008 i +*> 10.108.5.0/24 172.16.1.8 100 0 65008 i +*> 10.108.6.0/24 172.16.1.8 100 0 65008 i +*> 10.108.7.0/24 172.16.1.8 100 0 65008 i +*> 10.108.8.0/24 172.16.1.8 100 0 65008 i +*> 10.108.9.0/24 172.16.1.8 100 0 65008 i +*> 172.20.0.0/28 0.0.0.0 0 32768 i diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf index fc301e13d7..05eac758f1 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf @@ -20,7 +20,7 @@ router bgp 5226 neighbor 2.2.2.2 activate exit-address-family ! - rfp holddown-factor 100 + rfp holddown-factor 0 ! vnc defaults rd auto:vn:123 diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf index 0066f65a40..67b26e3a50 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf @@ -18,7 +18,7 @@ router bgp 5226 neighbor 2.2.2.2 activate exit-address-family ! - rfp holddown-factor 100 + rfp holddown-factor 0 ! vnc defaults rd auto:vn:123 diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf index 67c06506b5..2ba5c74e5b 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf @@ -19,7 +19,7 @@ router bgp 5226 neighbor 2.2.2.2 activate exit-address-family ! - rfp holddown-factor 100 + rfp holddown-factor 0 ! vnc defaults rd auto:vn:123 diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf index eb8d703a35..f7f5e2ee96 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf @@ -20,7 +20,7 @@ router bgp 5226 neighbor 2.2.2.2 activate exit-address-family ! - rfp holddown-factor 100 + rfp holddown-factor 0 rfp full-table-download off ! vnc defaults diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf index 61164c6948..17e351988d 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf @@ -18,7 +18,7 @@ router bgp 5226 neighbor 2.2.2.2 activate exit-address-family ! - rfp holddown-factor 100 + rfp holddown-factor 0 rfp full-table-download off ! vnc defaults diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf index 4294274d3d..0b8808cb80 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf @@ -19,7 +19,7 @@ router bgp 5226 neighbor 2.2.2.2 activate exit-address-family ! - rfp holddown-factor 100 + rfp holddown-factor 0 rfp full-table-download off ! vnc defaults diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index 25edfe0324..8688a13aef 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -908,7 +908,7 @@ class TopoExaBGP(TopoHost): # Disable linter branch warning. It is expected to have these here. # pylint: disable=R0912 -def diagnose_env(): +def diagnose_env_linux(): """ Run diagnostics in the running environment. Returns `True` when everything is ok, otherwise `False`. @@ -1066,3 +1066,14 @@ def diagnose_env(): logger.removeHandler(fhandler) return ret + +def diagnose_env_freebsd(): + return True + +def diagnose_env(): + if sys.platform.startswith("linux"): + return diagnose_env_linux() + elif sys.platform.startswith("freebsd"): + return diagnose_env_freebsd() + + return False diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index e9b8d34ec3..84358b94bc 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -336,7 +336,7 @@ def normalize_text(text): return text -def module_present(module, load=True): +def module_present_linux(module, load): """ Returns whether `module` is present. @@ -352,6 +352,15 @@ def module_present(module, load=True): else: return True +def module_present_freebsd(module, load): + return True + +def module_present(module, load=True): + if sys.platform.startswith("linux"): + return module_present_linux(module, load) + elif sys.platform.startswith("freebsd"): + return module_present_freebsd(module, load) + def version_cmp(v1, v2): """ Compare two version strings and returns: @@ -572,7 +581,10 @@ def addRouter(topo, name): '/var/run/frr', '/var/run/quagga', '/var/log'] - return topo.addNode(name, cls=Router, privateDirs=MyPrivateDirs) + if sys.platform.startswith("linux"): + return topo.addNode(name, cls=LinuxRouter, privateDirs=MyPrivateDirs) + elif sys.platform.startswith("freebsd"): + return topo.addNode(name, cls=FreeBSDRouter, privateDirs=MyPrivateDirs) def set_sysctl(node, sysctl, value): "Set a sysctl value and return None on success or an error string" @@ -594,21 +606,6 @@ def assert_sysctl(node, sysctl, value): "Set and assert that the sysctl is set with the specified value." assert set_sysctl(node, sysctl, value) is None -class LinuxRouter(Node): - "A Node with IPv4/IPv6 forwarding enabled." - - def config(self, **params): - super(LinuxRouter, self).config(**params) - # Enable forwarding on the router - assert_sysctl(self, 'net.ipv4.ip_forward', 1) - assert_sysctl(self, 'net.ipv6.conf.all.forwarding', 1) - def terminate(self): - """ - Terminate generic LinuxRouter Mininet instance - """ - set_sysctl(self, 'net.ipv4.ip_forward', 0) - set_sysctl(self, 'net.ipv6.conf.all.forwarding', 0) - super(LinuxRouter, self).terminate() class Router(Node): "A Node with IPv4/IPv6 forwarding enabled and Quagga as Routing Engine" @@ -622,7 +619,7 @@ class Router(Node): self.daemons = {'zebra': 0, 'ripd': 0, 'ripngd': 0, 'ospfd': 0, 'ospf6d': 0, 'isisd': 0, 'bgpd': 0, 'pimd': 0, 'ldpd': 0, 'eigrpd': 0, 'nhrpd': 0, 'staticd': 0, - 'bfdd': 0} + 'bfdd': 0, 'sharpd': 0} self.daemons_options = {'zebra': ''} self.reportCores = True self.version = None @@ -669,17 +666,6 @@ class Router(Node): if params.get('routertype') is not None: self.routertype = self.params.get('routertype') - # Enable forwarding on the router - assert_sysctl(self, 'net.ipv4.ip_forward', 1) - assert_sysctl(self, 'net.ipv6.conf.all.forwarding', 1) - # Enable coredumps - assert_sysctl(self, 'kernel.core_uses_pid', 1) - assert_sysctl(self, 'fs.suid_dumpable', 1) - #this applies to the kernel not the namespace... - #original on ubuntu 17.x, but apport won't save as in namespace - # |/usr/share/apport/apport %p %s %c %d %P - corefile = '%e_core-sig_%s-pid_%p.dmp' - assert_sysctl(self, 'kernel.core_pattern', corefile) self.cmd('ulimit -c unlimited') # Set ownership of config files self.cmd('chown {0}:{0}vty /etc/{0}'.format(self.routertype)) @@ -1075,6 +1061,40 @@ class Router(Node): if leakfound: leakfile.close() +class LinuxRouter(Router): + "A Linux Router Node with IPv4/IPv6 forwarding enabled." + + def __init__(self, name, **params): + Router.__init__(self, name, **params) + + def config(self, **params): + Router.config(self, **params) + # Enable forwarding on the router + assert_sysctl(self, 'net.ipv4.ip_forward', 1) + assert_sysctl(self, 'net.ipv6.conf.all.forwarding', 1) + # Enable coredumps + assert_sysctl(self, 'kernel.core_uses_pid', 1) + assert_sysctl(self, 'fs.suid_dumpable', 1) + #this applies to the kernel not the namespace... + #original on ubuntu 17.x, but apport won't save as in namespace + # |/usr/share/apport/apport %p %s %c %d %P + corefile = '%e_core-sig_%s-pid_%p.dmp' + assert_sysctl(self, 'kernel.core_pattern', corefile) + + def terminate(self): + """ + Terminate generic LinuxRouter Mininet instance + """ + set_sysctl(self, 'net.ipv4.ip_forward', 0) + set_sysctl(self, 'net.ipv6.conf.all.forwarding', 0) + Router.terminate(self) + +class FreeBSDRouter(Router): + "A FreeBSD Router Node with IPv4/IPv6 forwarding enabled." + + def __init__(eslf, name, **params): + Router.__init__(Self, name, **params) + class LegacySwitch(OVSSwitch): "A Legacy Switch without OpenFlow" diff --git a/tools/etc/frr/vtysh.conf b/tools/etc/frr/vtysh.conf index 80ceb00891..e0ab9cb6f3 100644 --- a/tools/etc/frr/vtysh.conf +++ b/tools/etc/frr/vtysh.conf @@ -1,2 +1 @@ service integrated-vtysh-config -username cumulus nopassword diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 3b41b57d68..c48c8b97ad 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -974,8 +974,8 @@ def compare_context_objects(newconf, running): delete_bgpd = True lines_to_del.append((running_ctx_keys, None)) - # We cannot do 'no interface' in FRR, and so deal with it - elif running_ctx_keys[0].startswith('interface'): + # We cannot do 'no interface' or 'no vrf' in FRR, and so deal with it + elif running_ctx_keys[0].startswith('interface') or running_ctx_keys[0].startswith('vrf'): for line in running_ctx.lines: lines_to_del.append((running_ctx_keys, line)) diff --git a/tools/frr.service b/tools/frr.service index 03112bd7cd..c7568593b3 100644 --- a/tools/frr.service +++ b/tools/frr.service @@ -1,5 +1,6 @@ [Unit] Description=FRRouting +Documentation=https://frrouting.readthedocs.io/en/latest/setup.html After=networking.service OnFailure=heartbeat-failed@%n.service @@ -17,5 +18,6 @@ LimitNOFILE=1024 ExecStart=/usr/lib/frr/frrinit.sh start ExecStop=/usr/lib/frr/frrinit.sh stop ExecReload=/usr/lib/frr/frrinit.sh reload + [Install] WantedBy=network-online.target diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in index 7278e3f9df..fa2fdc94b2 100644 --- a/tools/frrcommon.sh.in +++ b/tools/frrcommon.sh.in @@ -83,7 +83,7 @@ daemon_list() { for daemon in $DAEMONS; do eval cfg=\$$daemon eval inst=\$${daemon}_instances - [ "$daemon" = zebra ] && cfg=yes + [ "$daemon" = zebra -o "$daemon" = staticd ] && cfg=yes if [ -n "$cfg" -a "$cfg" != "no" -a "$cfg" != "0" ]; then debug "$daemon enabled" enabled="$enabled $daemon" @@ -135,6 +135,10 @@ daemon_start() { 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" diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 596f01738a..2b48f1f360 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -109,7 +109,7 @@ sub scan_file { $protocol = "VTYSH_ZEBRA"; } elsif ($file =~ /lib\/nexthop_group\.c$/) { - $protocol = "VTYSH_PBRD"; + $protocol = "VTYSH_PBRD | VTYSH_SHARPD"; } elsif ($file =~ /lib\/plist\.c$/) { if ($defun_array[1] =~ m/ipv6/) { diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 2327f2b46d..6cf45789dd 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2110,7 +2110,7 @@ DEFSH(VTYSH_ZEBRA, vtysh_no_logicalrouter_cmd, "The Name Space\n" "The file name in " NS_RUN_DIR ", or a full pathname\n") -DEFUNSH(VTYSH_PBRD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, +DEFUNSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, "nexthop-group NAME", "Nexthop Group configuration\n" "Name of the Nexthop Group\n") @@ -2119,7 +2119,8 @@ DEFUNSH(VTYSH_PBRD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, return CMD_SUCCESS; } -DEFSH(VTYSH_PBRD, vtysh_no_nexthop_group_cmd, "no nexthop-group NAME", +DEFSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_no_nexthop_group_cmd, + "no nexthop-group NAME", NO_STR "Nexthop Group Configuration\n" "Name of the Nexthop Group\n") diff --git a/yang/confd/confd.frr-ripngd.yang b/yang/confd/confd.frr-ripngd.yang new file mode 100644 index 0000000000..5d876ff4d3 --- /dev/null +++ b/yang/confd/confd.frr-ripngd.yang @@ -0,0 +1,22 @@ +module confd.frr-ripngd { + namespace "urn:dummy"; + prefix "dummy"; + + import tailf-common { + prefix tailf; + } + import frr-ripngd { + prefix frr-ripngd; + } + + tailf:annotate-module "frr-ripngd" { + tailf:annotate-statement "container[name='ripngd']" { + tailf:annotate-statement "container[name='state']" { + tailf:callpoint "state"; + } + } + tailf:annotate-statement "rpc[name='clear-ripng-route']" { + tailf:actionpoint "actionpoint"; + } + } +} diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang new file mode 100644 index 0000000000..32b4d3acf6 --- /dev/null +++ b/yang/frr-isisd.yang @@ -0,0 +1,1404 @@ +module frr-isisd { + yang-version 1.1; + namespace "http://frrouting.org/yang/isisd"; + prefix frr-isisd; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import frr-interface { + prefix frr-interface; + } + + import frr-route-types { + prefix frr-route-types; + } + + organization + "Free Range Routing"; + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> FRR Development + List: <mailto:dev@lists.frrouting.org>"; + description + "This module defines a model for managing FRR isisd daemon."; + + revision 2018-07-26 { + description + "Initial revision."; + reference + "ISO/IEC 10589:2002."; + } + + typedef level { + type enumeration { + enum "level-1" { + value 1; + description + "This enum indicates L1-only capability."; + } + enum "level-2" { + value 2; + description + "This enum indicates L2-only capability."; + } + enum "level-1-2" { + value 3; + description + "This enum indicates capability for both levels."; + } + } + description + "This type defines IS-IS level of an object."; + } + + typedef network-type { + type enumeration { + enum "unknown" { + value 0; + description + "Unknown network type. Only valid as a state."; + } + enum "broadcast" { + value 1; + description + "Broadcast circuit network-type."; + } + enum "point-to-point" { + value 2; + description + "Point-to-point circuit network-type."; + } + enum "loopback" { + value 3; + description + "Loopback circuit network-type. Only valid as a state."; + } + } + } + + typedef lsp-id { + type string { + pattern "[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}\\.[0-9][0-9]-[0-9][0-9]"; + } + description + "This type defines the IS-IS LSP ID format using a + pattern, An example LSP ID is 0143.0438.AeF0.02-01"; + } + + typedef system-id { + type string { + pattern "[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}"; + } + description + "This type defines IS-IS system-id using a pattern, + An example system-id is 0143.0438.AeF0"; + } + + typedef net-address { + type string { + pattern "[a-fA-F0-9]{2}(\\.[a-fA-F0-9]{4}){3,9}\\.[a-fA-F0-9]{2}"; + } + description + "This type defines an OSI NET address using a pattern, + An example net-address is 49.0123.6452.1972.00"; + } + + typedef if-state-type { + type enumeration { + enum "up" { + value 0; + description + "Up state."; + } + enum "down" { + value 1; + description + "Down state"; + } + } + description + "This type defines the state of an interface"; + } + + typedef adj-state-type { + type enumeration { + enum "up" { + value 0; + description + "State indicates the adjacency is established."; + } + enum "down" { + value 1; + description + "State indicates the adjacency is NOT established."; + } + enum "init" { + value 2; + description + "State indicates the adjacency is establishing."; + } + enum "failed" { + value 3; + description + "State indicates the adjacency is failed."; + } + } + description + "This type defines states of an adjacency"; + } + + typedef metric-style-type { + type enumeration { + enum "narrow" { + value 0; + description + "This enum describes narrow metric style"; + reference + "RFC1195"; + } + enum "wide" { + value 1; + description + "This enum describes wide metric style"; + reference + "RFC5305"; + } + enum "transition" { + value 2; + description + "This enum describes transition metric style"; + } + } + } + + grouping redistribute-attributes { + description + "Common optional attributes of any redistribute entry."; + choice attribute { + leaf route-map { + type string { + length "1..max"; + } + description + "Applies the conditions of the specified route-map to routes that + are redistributed into this routing instance."; + } + + leaf metric { + type uint32 { + range "0..16777215"; + } + default "0"; + description + "Metric used for the redistributed route. If 0, + the default-metric attribute is used instead."; + } + } + } + + grouping redistribute-default { + description + "Redistribution of default route within a level."; + leaf always { + type boolean; + default "false"; + description + "Always advertise default route."; + } + + uses redistribute-attributes; + } + + grouping isis-password { + description + "Authentication attributes or an IS-IS area or domain."; + leaf password { + type string { + length "1..254"; + } + mandatory true; + description + "Actual password."; + } + + leaf password-type { + type enumeration { + enum "clear" { + value 1; + description + "Clear-text password type."; + } + enum "md5" { + value 54; + description + "MD5 password type."; + } + } + mandatory true; + description + "Type of password used."; + } + } + + grouping isis-area-password { + uses isis-password; + + leaf authenticate-snp { + type enumeration { + enum "none" { + value 0; + description + "No SNP authentication."; + } + enum "send-only" { + value 1; + description + "Send authenticated PDUs but do not check on receiving."; + } + enum "validate" { + value 3; + description + "Send authenticated PDUs and check on receiving."; + } + } + default "none"; + description + "SNP PDUs authentication."; + } + } + + grouping notification-instance-hdr { + description + "Instance specific IS-IS notification data grouping"; + leaf routing-instance { + type string; + description + "Name of the routing-instance instance."; + } + + leaf routing-protocol-name { + type string; + description + "Name of the IS-IS instance."; + } + + leaf isis-level { + type level; + description + "IS-IS level of the instance."; + } + } + + grouping notification-interface-hdr { + description + "Interface specific IS-IS notification data grouping"; + leaf interface-name { + type string; + description + "IS-IS interface name"; + } + + leaf interface-level { + type level; + description + "IS-IS level of the interface."; + } + + leaf extended-circuit-id { + type uint32; + description + "Eextended circuit-id of the interface."; + } + } + + container isis { + description + "Configuration of the IS-IS routing daemon."; + list instance { + key "area-tag"; + description + "IS-IS routing instance."; + leaf area-tag { + type string; + description + "Area-tag associated to this routing instance."; + } + + leaf is-type { + type level; + default "level-1"; + description + "Level of the IS-IS routing instance (OSI only)."; + } + + leaf-list area-address { + type net-address; + max-elements 3; + description + "List of OSI NET addresses for this protocol instance."; + } + + leaf dynamic-hostname { + type boolean; + default "true"; + description + "Dynamic hostname support for IS-IS."; + } + + leaf attached { + type boolean; + default "false"; + description + "If true, identify as L1/L2 router for inter-area traffic."; + } + + leaf overload { + type boolean; + default "false"; + description + "If true, avoid any transit traffic."; + } + + leaf metric-style { + type metric-style-type; + must ". = 'wide' or count(../multi-topology/*) = 0"; + default "wide"; + description + "Define the style of TLVs metric supported."; + } + + leaf purge-originator { + type boolean; + default "false"; + description + "Use the RFC 6232 purge-originator."; + reference + "RFC6232"; + } + + container lsp { + description + "Configuration of Link-State Packets (LSP) parameters"; + leaf mtu { + type uint16 { + range "128..4352"; + } + default "1497"; + description + "MTU of an LSP."; + } + + container refresh-interval { + description + ""; + leaf level-1 { + type uint16; + units "seconds"; + default "900"; + description + "LSP refresh interval for level-1."; + } + + leaf level-2 { + type uint16; + units "seconds"; + default "900"; + description + "LSP refresh interval for level-2."; + } + } + + container maximum-lifetime { + description + "Maximum LSP lifetime."; + leaf level-1 { + type uint16 { + range "350..65535"; + } + units "seconds"; + must ". >= ../../refresh-interval/level-1 + 300"; + default "1200"; + description + "Maximum LSP lifetime for level-1."; + } + + leaf level-2 { + type uint16 { + range "350..65535"; + } + units "seconds"; + must ". >= ../../refresh-interval/level-2 + 300"; + default "1200"; + description + "Maximum LSP lifetime for level-2."; + } + } + + container generation-interval { + description + "Minimum LSP regeneration interval."; + leaf level-1 { + type uint16 { + range "1..120"; + } + units "seconds"; + must ". < ../../refresh-interval/level-1"; + default "30"; + description + "Minimum time allowed before level-1 LSP retransmissions."; + } + + leaf level-2 { + type uint16 { + range "1..120"; + } + units "seconds"; + must ". < ../../refresh-interval/level-2"; + default "30"; + description + "Minimum time allowed before level-2 LSP retransmissions."; + } + } + } + + container spf { + description + "Parameters related to the Shortest Path First algorithm."; + container ietf-backoff-delay { + presence "Present if IETF SPF back-off delay is enabled."; + description + "SPF back-off delay algorithm parameters (see RFC 8405)."; + leaf init-delay { + type uint16 { + range "0..60000"; + } + units "msec"; + mandatory true; + description + "Delay used while in QUIET state"; + } + + leaf short-delay { + type uint16 { + range "0..60000"; + } + units "msec"; + mandatory true; + description + "Delay used while in SHORT_WAIT state"; + } + + leaf long-delay { + type uint16 { + range "0..60000"; + } + units "msec"; + mandatory true; + description + "Delay used while in LONG_WAIT state"; + } + + leaf hold-down { + type uint16 { + range "0..60000"; + } + units "msec"; + mandatory true; + description + "Time with no received IGP events before considering IGP stable"; + } + + leaf time-to-learn { + type uint16 { + range "0..60000"; + } + units "msec"; + mandatory true; + description + "Maximum duration needed to learn all the events related to a + single failure"; + } + } + + container minimum-interval { + description + "Minimum interval between consecutive executions of the + SPF algorithm."; + leaf level-1 { + type uint16 { + range "1..120"; + } + units "seconds"; + default "1"; + description + "Minimum time between consecutive level-1 SPFs."; + } + + leaf level-2 { + type uint16 { + range "1..120"; + } + units "seconds"; + default "1"; + description + "Minimum time between consecutive level-2 SPFs."; + } + } + } + + container area-password { + presence "Present if authentication is required for IS level-1."; + description + "Authentication password for an IS-IS area."; + uses isis-area-password; + } + + container domain-password { + presence "Present if authentication is required for IS level-2."; + description + "Authentication password for an IS-IS domain."; + uses isis-area-password; + } + + container default-information-originate { + description + "Distribution of default information."; + list ipv4 { + key "level"; + description + "Distribute default route for IPv4."; + leaf level { + type level; + must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))"; + } + + uses redistribute-default; + } + + list ipv6 { + key "level"; + description + "Distribute default route for IPv6."; + leaf level { + type level; + must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))"; + } + + uses redistribute-default; + } + } + + container redistribute { + description + "Redistributes routes learned from other routing protocols."; + list ipv4 { + key "protocol level"; + description + "IPv4 route redistribution."; + leaf protocol { + type frr-route-types:frr-route-types-v4; + must ". != \"isis\""; + description + "Originating routing protocol for the IPv4 routes."; + } + + leaf level { + type level; + must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))"; + description + "IS-IS level into which the routes should be redistributed."; + } + + uses redistribute-attributes; + } + + list ipv6 { + key "protocol level"; + description + "IPv6 route redistribution."; + leaf protocol { + type frr-route-types:frr-route-types-v6; + must ". != \"isis\""; + description + "Originating routing protocol for the IPv6 routes."; + } + + leaf level { + type level; + must "(. != \"level-1-2\") and ((../../../is-type = \"level-1-2\") or (. = ../../../is-type))"; + description + "IS-IS level into which the routes should be redistributed."; + } + + uses redistribute-attributes; + } + } + + container multi-topology { + description + "IS-IS topologies configured for this area."; + container ipv4-multicast { + presence "Present if a separate IPv4-multicast topology is configured for this area."; + description + "IPv4 multicast topology."; + leaf overload { + type boolean; + default "false"; + } + } + + container ipv4-management { + presence "Present if a separate IPv4-management topology is configured for this area."; + description + "IPv4 management topology."; + leaf overload { + type boolean; + default "false"; + } + } + + container ipv6-unicast { + presence "Present if a separate IPv6-unicast topology is configured for this area."; + description + "IPv6 unicast topology."; + leaf overload { + type boolean; + default "false"; + } + } + + container ipv6-multicast { + presence "Present if a separate IPv6-multicast topology is configured for this area."; + description + "IPv6 multicast topology."; + leaf overload { + type boolean; + default "false"; + } + } + + container ipv6-management { + presence "Present if a separate IPv6-management topology is configured for this area."; + description + "IPv6 management topology."; + leaf overload { + type boolean; + default "false"; + } + } + + container ipv6-dstsrc { + presence "Present if a separate IPv6 destination-source topology is configured for this area."; + description + "IPv6 destination-source topology."; + leaf overload { + type boolean; + default "false"; + } + } + } + + leaf log-adjacency-changes { + type boolean; + default "false"; + description + "Log changes to the IS-IS adjacencies in this area."; + } + } + + container mpls-te { + presence "Present if MPLS-TE is enabled."; + description + "Enable MPLS-TE functionality."; + leaf router-address { + type inet:ipv4-address; + description + "Stable IP address of the advertising router."; + } + } + } + + augment "/frr-interface:lib/frr-interface:interface" { + description + "Extends interface model with IS-IS related parameters."; + container isis { + presence "Present if an IS-IS circuit is defined for this interface."; + description + "IS-IS interface parameters."; + leaf area-tag { + type string; + mandatory true; + description + "Area-tag associated to this circuit."; + } + + leaf circuit-type { + type level; + default "level-1-2"; + description + "IS-type of this circuit."; + } + + leaf ipv4-routing { + type boolean; + default "false"; + description + "Routing IS-IS IPv4 traffic over this circuit."; + } + + leaf ipv6-routing { + type boolean; + default "false"; + description + "Routing IS-IS IPv6 traffic over this circuit."; + } + + container csnp-interval { + description + "Complete Sequence Number PDU (CSNP) generation interval."; + leaf level-1 { + type uint16 { + range "1..600"; + } + units "seconds"; + default "10"; + description + "CNSP interval for level-1"; + } + + leaf level-2 { + type uint16 { + range "1..600"; + } + units "seconds"; + default "10"; + description + "CNSP interval for level-2"; + } + } + + container psnp-interval { + description + "Partial Sequence Number PDU (PSNP) generation interval."; + leaf level-1 { + type uint16 { + range "1..120"; + } + units "seconds"; + default "2"; + description + "PNSP interval for level-1"; + } + + leaf level-2 { + type uint16 { + range "1..120"; + } + units "seconds"; + default "2"; + description + "PCNSP interval for level-2"; + } + } + + container hello { + description + "Parameters related to IS-IS hello PDUs."; + leaf padding { + type boolean; + default "true"; + description + "Add padding to IS-IS hello PDUs."; + } + + container interval { + description + "Interval between consecutive hello messages."; + leaf level-1 { + type uint32 { + range "1..600"; + } + units "seconds"; + default "3"; + description + "Holding time for level-1; interval will depend on multiplier."; + } + + leaf level-2 { + type uint32 { + range "1..600"; + } + units "seconds"; + default "3"; + description + "Holding time for level-2; interval will depend on multiplier."; + } + } + + container multiplier { + description + "Multiplier for the hello messages holding time."; + leaf level-1 { + type uint16 { + range "2..100"; + } + default "10"; + description + "Multiplier for the hello holding time."; + } + + leaf level-2 { + type uint16 { + range "2..100"; + } + default "10"; + description + "Multiplier for the hello holding time."; + } + } + } + + container metric { + description + "Default metric for this IS-IS circuit."; + leaf level-1 { + type uint32 { + range "0..16777215"; + } + must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'"; + default "10"; + description + "Default level-1 metric for this IS-IS circuit."; + } + + leaf level-2 { + type uint32 { + range "0..16777215"; + } + must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'"; + default "10"; + description + "Default level-2 metric for this IS-IS circuit."; + } + } + + container priority { + description + "Priority for Designated Router election."; + leaf level-1 { + type uint8 { + range "0..127"; + } + default "64"; + description + "Level-1 priority for this IS-IS circuit."; + } + + leaf level-2 { + type uint8 { + range "0..127"; + } + default "64"; + description + "Level-2 priority for this IS-IS circuit."; + } + } + + leaf network-type { + type network-type; + default "broadcast"; + must "(. = \"point-to-point\") or (. = \"broadcast\")"; + description + "Explicitly configured type of IS-IS circuit (broadcast or point-to-point)."; + } + + leaf passive { + type boolean; + default "false"; + description + "Interface is in passive mode."; + } + + container password { + presence "Present if a password is set for this IS interface."; + uses isis-password; + } + + leaf disable-three-way-handshake { + type boolean; + default "false"; + description + "Disables three-way handshake when creating new adjacencies."; + } + + container multi-topology { + description + "IS-IS topologies configured on this circuit."; + leaf ipv4-unicast { + type boolean; + default "true"; + description + "IPv4 unicast topology."; + } + + leaf ipv4-multicast { + type boolean; + default "true"; + description + "IPv4 multicast topology."; + } + + leaf ipv4-management { + type boolean; + default "true"; + description + "IPv4 management topology."; + } + + leaf ipv6-unicast { + type boolean; + default "true"; + description + "IPv6 unicast topology."; + } + + leaf ipv6-multicast { + type boolean; + default "true"; + description + "IPv6 multicast topology."; + } + + leaf ipv6-management { + type boolean; + default "true"; + description + "IPv6 management topology."; + } + + leaf ipv6-dstsrc { + type boolean; + default "true"; + description + "IPv6 destination-source topology."; + } + } + } + } + + notification database-overload { + description + "This notification is sent when an IS-IS instance + overload state changes."; + uses notification-instance-hdr; + + leaf overload { + type enumeration { + enum "off" { + value 0; + description + "Indicates IS-IS instance has left overload state"; + } + enum "on" { + value 1; + description + "Indicates IS-IS instance has entered overload state"; + } + } + description + "New overload state of the IS-IS instance"; + } + } + + notification lsp-too-large { + description + "This notification is sent when we attempt to propagate + an LSP that is larger than the dataLinkBlockSize for the + circuit. The notification generation must be throttled + with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf pdu-size { + type uint32; + description + "Size of the LSP PDU"; + } + + leaf lsp-id { + type lsp-id; + description + "LSP ID"; + } + } + + notification if-state-change { + description + "This notification is sent when an interface + state change is detected."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf state { + type if-state-type; + description + "Interface state."; + } + } + + notification corrupted-lsp-detected { + description + "This notification is sent when we find that + an LSP that was stored in memory has become + corrupted."; + uses notification-instance-hdr; + + leaf lsp-id { + type lsp-id; + description + "LSP ID"; + } + } + + notification attempt-to-exceed-max-sequence { + description + "This notification is sent when the system + wraps the 32-bit sequence counter of an LSP."; + uses notification-instance-hdr; + + leaf lsp-id { + type lsp-id; + description + "LSP ID"; + } + } + + notification id-len-mismatch { + description + "This notification is sent when we receive a PDU + with a different value for the System ID length. + The notification generation must be throttled + with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf pdu-field-len { + type uint8; + description + "Size of the ID length in the received PDU"; + } + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + } + + notification max-area-addresses-mismatch { + description + "This notification is sent when we receive a PDU + with a different value for the Maximum Area Addresses. + The notification generation must be throttled + with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf max-area-addresses { + type uint8; + description + "Received number of supported areas"; + } + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + } + + notification own-lsp-purge { + description + "This notification is sent when the system receives + a PDU with its own system ID and zero age."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf lsp-id { + type lsp-id; + description + "LSP ID"; + } + } + + notification sequence-number-skipped { + description + "This notification is sent when the system receives a + PDU with its own system ID and different contents. The + system has to reoriginate the LSP with a higher sequence + number."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf lsp-id { + type lsp-id; + description + "LSP ID"; + } + } + + notification authentication-type-failure { + description + "This notification is sent when the system receives a + PDU with the wrong authentication type field. + The notification generation must be throttled + with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + } + + notification authentication-failure { + description + "This notification is sent when the system receives + a PDU with the wrong authentication information. + The notification generation must be throttled with + with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + } + + notification version-skew { + description + "This notification is sent when the system receives a + PDU with a different protocol version number. + The notification generation must be throttled + with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf protocol-version { + type uint8; + description + "Protocol version received in the PDU."; + } + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + } + + notification area-mismatch { + description + "This notification is sent when the system receives a + Hello PDU from an IS that does not share any area + address. The notification generation must be throttled + with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + } + + notification rejected-adjacency { + description + "This notification is sent when the system receives a + Hello PDU from an IS but does not establish an adjacency + for some reason. The notification generation must be + throttled with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + + leaf reason { + type string; + description + "The system may provide a reason to reject the + adjacency. If the reason is not available, + an empty string will be returned."; + } + } + + notification lsp-error-detected { + description + "This notification is sent when the system receives an + LSP with a parse error. The notification generation must + be throttled with at least 5 seconds betweeen successive + notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf lsp-id { + type lsp-id; + description + "LSP ID."; + } + + leaf raw-pdu { + type binary; + description + "Received raw PDU."; + } + + leaf error-offset { + type uint32; + description + "If the problem is a malformed TLV, the error-offset + points to the start of the TLV. If the problem is with + the LSP header, the error-offset points to the errant + byte"; + } + + leaf tlv-type { + type uint8; + description + "If the problem is a malformed TLV, the tlv-type is set + to the type value of the suspicious TLV. Otherwise, + this leaf is not present."; + } + } + + notification adjacency-state-change { + description + "This notification is sent when an IS-IS adjacency + moves to Up state or to Down state."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf neighbor { + type string; + description + "Name of the neighbor. If the name of the neighbor is + not available, it is not returned."; + } + + leaf neighbor-system-id { + type system-id; + description + "Neighbor system-id"; + } + + leaf state { + type adj-state-type; + description + "New state of the IS-IS adjacency."; + } + + leaf reason { + type string; + description + "If the adjacency is going to DOWN, this leaf provides + a reason for the adjacency going down. The reason is + provided as a text. If the adjacency is going to UP, no + reason is provided."; + } + } + + notification lsp-received { + description + "This notification is sent when an LSP is received. + The notification generation must be throttled with at + least 5 seconds betweeen successive notifications."; + uses notification-instance-hdr; + + uses notification-interface-hdr; + + leaf lsp-id { + type lsp-id; + description + "LSP ID"; + } + + leaf sequence { + type uint32; + description + "Sequence number of the received LSP."; + } + + leaf received-timestamp { + type yang:timestamp; + description + "Timestamp when the LSP was received."; + } + + leaf neighbor-system-id { + type system-id; + description + "Neighbor system-id of LSP sender"; + } + } + + notification lsp-generation { + description + "This notification is sent when an LSP is regenerated. + The notification generation must be throttled with at + least 5 seconds betweeen successive notifications."; + uses notification-instance-hdr; + + leaf lsp-id { + type lsp-id; + description + "LSP ID"; + } + + leaf sequence { + type uint32; + description + "Sequence number of the received LSP."; + } + + leaf send-timestamp { + type yang:timestamp; + description + "Timestamp when our LSP was regenerated."; + } + } +} diff --git a/yang/frr-ripngd.yang b/yang/frr-ripngd.yang new file mode 100644 index 0000000000..0cc5f18a5f --- /dev/null +++ b/yang/frr-ripngd.yang @@ -0,0 +1,321 @@ +module frr-ripngd { + yang-version 1.1; + namespace "http://frrouting.org/yang/ripngd"; + prefix frr-ripngd; + + import ietf-inet-types { + prefix inet; + } + import ietf-yang-types { + prefix yang; + } + import frr-interface { + prefix frr-interface; + } + import frr-route-types { + prefix frr-route-types; + } + + organization + "Free Range Routing"; + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + description + "This module defines a model for managing FRR ripngd daemon."; + + revision 2018-11-27 { + description + "Initial revision."; + reference + "RFC 2080: RIPng for IPv6."; + } + + container ripngd { + /* + * Global configuration data + */ + container instance { + presence "Present if the RIPng protocol is enabled."; + description + "RIPng routing instance."; + + leaf allow-ecmp { + type boolean; + default "false"; + description + "Allow equal-cost multi-path."; + } + leaf default-information-originate { + type boolean; + default "false"; + description + "Control distribution of default route."; + } + leaf default-metric { + type uint8 { + range "1..16"; + } + default "1"; + description + "Default metric of redistributed routes."; + } + leaf-list network { + type inet:ipv6-prefix; + description + "Enable RIPng on the specified IPv6 network."; + } + leaf-list interface { + type string { + length "1..16"; + } + description + "Enable RIPng on the specified interface."; + } + list offset-list { + key "interface direction"; + description + "Offset-list to modify route metric."; + leaf interface { + type string; + description + "Interface to match. Use '*' to match all interfaces."; + } + leaf direction { + type enumeration { + enum in { + value 0; + description + "Incoming updates."; + } + enum out { + value 1; + description + "Outgoing updates."; + } + } + description + "Incoming or outgoing updates."; + } + leaf access-list { + type string; + mandatory true; + description + "Access-list name."; + } + leaf metric { + type uint8 { + range "0..16"; + } + mandatory true; + description + "Route metric."; + } + } + leaf-list passive-interface { + type string { + length "1..16"; + } + description + "A list of interfaces where the sending of RIPng packets + is disabled."; + } + list redistribute { + key "protocol"; + description + "Redistributes routes learned from other routing protocols."; + leaf protocol { + type frr-route-types:frr-route-types-v6; + description + "Routing protocol."; + must '. != "ripng"'; + } + leaf route-map { + type string { + length "1..max"; + } + description + "Applies the conditions of the specified route-map to + routes that are redistributed into the RIPng routing + instance."; + } + leaf metric { + type uint8 { + range "0..16"; + } + description + "Metric used for the redistributed route. If a metric is + not specified, the metric configured with the + default-metric attribute in RIPng router configuration is + used. If the default-metric attribute has not been + configured, the default metric for redistributed routes + is 0."; + } + } + leaf-list static-route { + type inet:ipv6-prefix; + description + "RIPng static routes."; + } + leaf-list aggregate-address { + type inet:ipv6-prefix; + description + "RIPng aggregate route announcement."; + } + container timers { + description + "Settings of basic timers"; + leaf flush-interval { + type uint16 { + range "1..65535"; + } + units "seconds"; + default "120"; + description + "Interval before a route is flushed from the routing + table."; + } + leaf holddown-interval { + type uint16 { + range "1..65535"; + } + units "seconds"; + default "180"; + description + "Interval before better routes are released."; + } + leaf update-interval { + type uint16 { + range "1..65535"; + } + units "seconds"; + default "30"; + description + "Interval at which RIPng updates are sent."; + } + } + } + + /* + * Operational data. + */ + container state { + config false; + description + "Operational data."; + + container neighbors { + description + "Neighbor information."; + list neighbor { + key "address"; + description + "A RIPng neighbor."; + leaf address { + type inet:ipv6-address; + description + "IPv6 address that a RIPng neighbor is using as its + source address."; + } + leaf last-update { + type yang:date-and-time; + description + "The time when the most recent RIPng update was + received from this neighbor."; + } + leaf bad-packets-rcvd { + type yang:counter32; + description + "The number of RIPng invalid packets received from + this neighbor which were subsequently discarded + for any reason (e.g. a version 0 packet, or an + unknown command type)."; + } + leaf bad-routes-rcvd { + type yang:counter32; + description + "The number of routes received from this neighbor, + in valid RIPng packets, which were ignored for any + reason (e.g. unknown address family, or invalid + metric)."; + } + } + } + container routes { + description + "Route information."; + list route { + key "prefix"; + description + "A RIPng IPv6 route."; + leaf prefix { + type inet:ipv6-prefix; + description + "IPv6 address and prefix length, in the format + specified in RFC6991."; + } + leaf next-hop { + type inet:ipv6-address; + description + "Next hop IPv6 address."; + } + leaf interface { + type string; + description + "The interface that the route uses."; + } + leaf metric { + type uint8 { + range "0..16"; + } + description + "Route metric."; + } + } + } + } + } + + /* + * Per-interface configuration data + */ + augment "/frr-interface:lib/frr-interface:interface" { + container ripng { + description + "RIPng interface parameters."; + leaf split-horizon { + type enumeration { + enum "disabled" { + value 0; + description + "Disables split-horizon processing."; + } + enum "simple" { + value 1; + description + "Enables simple split-horizon processing."; + } + enum "poison-reverse" { + value 2; + description + "Enables split-horizon processing with poison + reverse."; + } + } + default "simple"; + description + "Controls RIPng split-horizon processing on the specified + interface."; + } + } + } + + /* + * RPCs + */ + rpc clear-ripng-route { + description + "Clears RIPng routes from the IPv6 routing table and routes + redistributed into the RIPng protocol."; + } +} diff --git a/yang/subdir.am b/yang/subdir.am index 07bd225780..c95ec4dbff 100644 --- a/yang/subdir.am +++ b/yang/subdir.am @@ -27,3 +27,11 @@ dist_yangmodels_DATA += yang/frr-route-types.yang if RIPD dist_yangmodels_DATA += yang/frr-ripd.yang endif + +if RIPNGD +dist_yangmodels_DATA += yang/frr-ripngd.yang +endif + +if ISISD +dist_yangmodels_DATA += yang/frr-isisd.yang +endif diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index f4bd193569..4e49c1fc58 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -399,7 +399,7 @@ static int get_iflink_speed(struct interface *interface) (char *)&ifdata); } if (rc < 0) { - if (IS_ZEBRA_DEBUG_KERNEL) + if (errno != EOPNOTSUPP && IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "IOCTL failure to read interface %s speed: %d %s", ifname, errno, safe_strerror(errno)); diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index afc3985854..360f596b8f 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -784,7 +784,8 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - zlog_err("%s error: message truncated", + flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR, + "%s error: message truncated", nl->name); return -1; } @@ -820,14 +821,6 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), continue; } - if (h->nlmsg_len - < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR, - "%s error: message truncated", - nl->name); - return -1; - } - /* Deal with errors that occur because of races * in link handling */ if (zns->is_cmd diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 8a7cb0e528..84b06e579f 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -139,7 +139,9 @@ const struct message rtm_type_str[] = {{RTM_ADD, "RTM_ADD"}, {RTM_LOSING, "RTM_LOSING"}, {RTM_REDIRECT, "RTM_REDIRECT"}, {RTM_MISS, "RTM_MISS"}, +#ifdef RTM_LOCK {RTM_LOCK, "RTM_LOCK"}, +#endif /* RTM_LOCK */ #ifdef OLDADD {RTM_OLDADD, "RTM_OLDADD"}, #endif /* RTM_OLDADD */ @@ -230,7 +232,9 @@ int dplane_routing_sock = -1; /* Yes I'm checking ugly routing socket behavior. */ /* #define DEBUG */ +size_t _rta_get(caddr_t sap, void *destp, size_t destlen, bool checkaf); size_t rta_get(caddr_t sap, void *dest, size_t destlen); +size_t rta_getattr(caddr_t sap, void *destp, size_t destlen); size_t rta_getsdlname(caddr_t sap, void *dest, short *destlen); /* Supported address family check. */ @@ -243,9 +247,10 @@ static inline int af_check(int family) return 0; } -size_t rta_get(caddr_t sap, void *destp, size_t destlen) +size_t _rta_get(caddr_t sap, void *destp, size_t destlen, bool checkaf) { struct sockaddr *sa = (struct sockaddr *)sap; + struct sockaddr_dl *sdl; uint8_t *dest = destp; size_t tlen, copylen; @@ -256,7 +261,21 @@ size_t rta_get(caddr_t sap, void *destp, size_t destlen) copylen = tlen = SAROUNDUP(sap); #endif /* !HAVE_STRUCT_SOCKADDR_SA_LEN */ - if (copylen > 0 && dest != NULL && af_check(sa->sa_family)) { + if (copylen > 0 && dest != NULL) { + if (checkaf && af_check(sa->sa_family) == 0) + return tlen; + /* + * Handle sockaddr_dl corner case: + * RTA_NETMASK might be AF_LINK, but it doesn't anything + * relevant (e.g. zeroed out fields). Check for this + * case and avoid warning log message. + */ + if (sa->sa_family == AF_LINK) { + sdl = (struct sockaddr_dl *)sa; + if (sdl->sdl_index == 0 || sdl->sdl_nlen == 0) + copylen = sizeof(*sdl) - sizeof(sdl->sdl_data); + } + if (copylen > destlen) { zlog_warn("%s: destination buffer too small (%lu vs %lu)", __func__, copylen, destlen); @@ -268,6 +287,16 @@ size_t rta_get(caddr_t sap, void *destp, size_t destlen) return tlen; } +size_t rta_get(caddr_t sap, void *destp, size_t destlen) +{ + return _rta_get(sap, destp, destlen, true); +} + +size_t rta_getattr(caddr_t sap, void *destp, size_t destlen) +{ + return _rta_get(sap, destp, destlen, false); +} + size_t rta_getsdlname(caddr_t sap, void *destp, short *destlen) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)sap; @@ -682,7 +711,7 @@ static void ifam_read_mesg(struct ifa_msghdr *ifm, union sockunion *addr, pnt += rta_get(pnt, &gateway, sizeof(gateway)); break; case RTA_NETMASK: - pnt += rta_get(pnt, mask, sizeof(*mask)); + pnt += rta_getattr(pnt, mask, sizeof(*mask)); break; case RTA_IFP: pnt += rta_getsdlname(pnt, ifname, ifnlen); @@ -740,7 +769,7 @@ static void ifam_read_mesg(struct ifa_msghdr *ifm, union sockunion *addr, /* Assert read up end point matches to end point */ pnt = (caddr_t)ROUNDUP((size_t)pnt); - if (pnt != end) + if (pnt != (caddr_t)ROUNDUP((size_t)end)) zlog_debug("ifam_read() doesn't read all socket data"); } @@ -918,6 +947,9 @@ void rtm_read(struct rt_msghdr *rtm) char ifname[INTERFACE_NAMSIZ + 1]; short ifnlen = 0; struct nexthop nh; + struct prefix p; + ifindex_t ifindex = 0; + afi_t afi; zebra_flags = 0; @@ -951,10 +983,6 @@ void rtm_read(struct rt_msghdr *rtm) if (flags & RTF_PROTO1) SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE); - /* This is persistent route. */ - if (flags & RTF_STATIC) - SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC); - memset(&nh, 0, sizeof(nh)); nh.vrf_id = VRF_DEFAULT; @@ -967,9 +995,14 @@ void rtm_read(struct rt_msghdr *rtm) nh.bh_type = BLACKHOLE_NULL; } - if (dest.sa.sa_family == AF_INET) { - struct prefix p; + /* + * Ignore our own messages. + */ + if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) + return; + if (dest.sa.sa_family == AF_INET) { + afi = AFI_IP; p.family = AF_INET; p.u.prefix4 = dest.sin.sin_addr; if (flags & RTF_HOST) @@ -977,146 +1010,12 @@ void rtm_read(struct rt_msghdr *rtm) else p.prefixlen = ip_masklen(mask.sin.sin_addr); - /* Catch self originated messages and match them against our - * current RIB. - * At the same time, ignore unconfirmed messages, they should be - * tracked - * by rtm_write() and kernel_rtm_ipv4(). - */ - if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) { - char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN]; - int ret; - if (!IS_ZEBRA_DEBUG_RIB) - return; - ret = rib_lookup_ipv4_route((struct prefix_ipv4 *)&p, - &gate, VRF_DEFAULT); - prefix2str(&p, buf, sizeof(buf)); - switch (rtm->rtm_type) { - case RTM_ADD: - case RTM_GET: - case RTM_CHANGE: - /* The kernel notifies us about a new route in - FIB created by us. - Do we have a correspondent entry in our RIB? - */ - switch (ret) { - case ZEBRA_RIB_NOTFOUND: - zlog_debug( - "%s: %s %s: desync: RR isn't yet in RIB, while already in FIB", - __func__, - lookup_msg(rtm_type_str, - rtm->rtm_type, NULL), - buf); - break; - case ZEBRA_RIB_FOUND_CONNECTED: - case ZEBRA_RIB_FOUND_NOGATE: - inet_ntop(AF_INET, &gate.sin.sin_addr, - gate_buf, INET_ADDRSTRLEN); - zlog_debug( - "%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)", - __func__, - lookup_msg(rtm_type_str, - rtm->rtm_type, NULL), - buf, gate_buf); - break; - case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR - */ - zlog_debug( - "%s: %s %s: done Ok", __func__, - lookup_msg(rtm_type_str, - rtm->rtm_type, NULL), - buf); - rib_lookup_and_dump( - (struct prefix_ipv4 *)&p, - VRF_DEFAULT); - return; - break; - } - break; - case RTM_DELETE: - /* The kernel notifies us about a route deleted - by us. Do we still - have it in the RIB? Do we have anything - instead? */ - switch (ret) { - case ZEBRA_RIB_FOUND_EXACT: - zlog_debug( - "%s: %s %s: desync: RR is still in RIB, while already not in FIB", - __func__, - lookup_msg(rtm_type_str, - rtm->rtm_type, NULL), - buf); - rib_lookup_and_dump( - (struct prefix_ipv4 *)&p, - VRF_DEFAULT); - break; - case ZEBRA_RIB_FOUND_CONNECTED: - case ZEBRA_RIB_FOUND_NOGATE: - zlog_debug( - "%s: %s %s: desync: RR is still in RIB, plus gate differs", - __func__, - lookup_msg(rtm_type_str, - rtm->rtm_type, NULL), - buf); - rib_lookup_and_dump( - (struct prefix_ipv4 *)&p, - VRF_DEFAULT); - break; - case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */ - zlog_debug( - "%s: %s %s: done Ok", __func__, - lookup_msg(rtm_type_str, - rtm->rtm_type, NULL), - buf); - rib_lookup_and_dump( - (struct prefix_ipv4 *)&p, - VRF_DEFAULT); - return; - break; - } - break; - default: - zlog_debug( - "%s: %s: warning: loopback RTM of type %s received", - __func__, buf, - lookup_msg(rtm_type_str, rtm->rtm_type, - NULL)); - } - return; - } - - /* Change, delete the old prefix, we have no further information - * to specify the route really - */ - if (rtm->rtm_type == RTM_CHANGE) - rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0, 0, true); - if (!nh.type) { nh.type = NEXTHOP_TYPE_IPV4; nh.gate.ipv4 = gate.sin.sin_addr; } - - if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD - || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, 0, 0, 0); - else - rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, 0, true); - } - if (dest.sa.sa_family == AF_INET6) { - /* One day we might have a debug section here like one in the - * IPv4 case above. Just ignore own messages at the moment. - */ - if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) - return; - struct prefix p; - ifindex_t ifindex = 0; - + } else if (dest.sa.sa_family == AF_INET6) { + afi = AFI_IP6; p.family = AF_INET6; p.u.prefix6 = dest.sin6.sin6_addr; if (flags & RTF_HOST) @@ -1131,31 +1030,29 @@ void rtm_read(struct rt_msghdr *rtm) } #endif /* KAME */ - /* CHANGE: delete the old prefix, we have no further information - * to specify the route really - */ - if (rtm->rtm_type == RTM_CHANGE) - rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0, 0, true); - if (!nh.type) { nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX : NEXTHOP_TYPE_IPV6; nh.gate.ipv6 = gate.sin6.sin6_addr; nh.ifindex = ifindex; } + } else + return; - if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD - || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, 0, 0, 0); - else - rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, 0, true); - } + /* + * CHANGE: delete the old prefix, we have no further information + * to specify the route really + */ + if (rtm->rtm_type == RTM_CHANGE) + rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, + 0, zebra_flags, &p, NULL, NULL, 0, 0, 0, true); + if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD + || rtm->rtm_type == RTM_CHANGE) + rib_add(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, + zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0); + else + rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, + 0, zebra_flags, &p, NULL, &nh, 0, 0, 0, true); } /* Interface function for the kernel routing table updates. Support diff --git a/zebra/main.c b/zebra/main.c index 90d3dbc180..b54c36c109 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -407,10 +407,7 @@ int main(int argc, char **argv) /* * Initialize NS( and implicitly the VRF module), and make kernel * routing socket. */ - zebra_ns_init(); - if (vrf_default_name_configured) - vrf_set_default_name(vrf_default_name_configured, - true); + zebra_ns_init((const char *)vrf_default_name_configured); zebra_vty_init(); access_list_init(); prefix_list_init(); diff --git a/zebra/rib.h b/zebra/rib.h index 97eae79f03..ae25a0e679 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -282,8 +282,6 @@ extern enum multicast_mode multicast_mode_ipv4_get(void); extern void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id); extern void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id); -extern int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate, - vrf_id_t vrf_id); #define ZEBRA_RIB_LOOKUP_ERROR -1 #define ZEBRA_RIB_FOUND_EXACT 0 #define ZEBRA_RIB_FOUND_NOGATE 1 diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index cb9ef8e36f..8ce963b37b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1584,7 +1584,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) } /* Singlepath case. */ - if (nexthop_num == 1 || multipath_num == 1) { + if (nexthop_num == 1) { nexthop_num = 0; for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) { /* @@ -1676,9 +1676,6 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) nexthop_num = 0; for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) { - if (nexthop_num >= multipath_num) - break; - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) { /* This only works for IPv4 now */ @@ -1876,12 +1873,6 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx) if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); - - /* If we're only allowed a single nh, don't - * continue. - */ - if (multipath_num == 1) - break; } } } @@ -2698,7 +2689,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp) /* Fill nexthops (paths) based on single-path or multipath. The paths * chosen depend on the operation. */ - if (nexthop_num == 1 || multipath_num == 1) { + if (nexthop_num == 1) { routedesc = "single-path"; _netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc); @@ -2745,9 +2736,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp) if (!nexthop) continue; - if (nexthop_num >= multipath_num) - break; - if ((cmd == RTM_NEWROUTE && (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED) && CHECK_FLAG(nexthop->flags, diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 19d41a402e..29e9bf82f0 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -89,170 +89,6 @@ static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label, } #endif -/* Interface between zebra message and rtm message. */ -static int kernel_rtm_ipv4(int cmd, const struct prefix *p, - const struct nexthop_group *ng, uint32_t metric) - -{ - struct sockaddr_in *mask = NULL; - struct sockaddr_in sin_dest, sin_mask, sin_gate; -#ifdef __OpenBSD__ - struct sockaddr_mpls smpls; -#endif - union sockunion *smplsp = NULL; - struct nexthop *nexthop; - int nexthop_num = 0; - ifindex_t ifindex = 0; - int gate = 0; - int error; - char prefix_buf[PREFIX_STRLEN]; - enum blackhole_type bh_type = BLACKHOLE_UNSPEC; - - if (IS_ZEBRA_DEBUG_RIB) - prefix2str(p, prefix_buf, sizeof(prefix_buf)); - memset(&sin_dest, 0, sizeof(struct sockaddr_in)); - sin_dest.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin_dest.sin_len = sizeof(struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - sin_dest.sin_addr = p->u.prefix4; - - memset(&sin_mask, 0, sizeof(struct sockaddr_in)); - - memset(&sin_gate, 0, sizeof(struct sockaddr_in)); - sin_gate.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin_gate.sin_len = sizeof(struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - - /* Make gateway. */ - for (ALL_NEXTHOPS_PTR(ng, nexthop)) { - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - continue; - - gate = 0; - char gate_buf[INET_ADDRSTRLEN] = "NULL"; - - /* - * XXX We need to refrain from kernel operations in some cases, - * but this if statement seems overly cautious - what about - * other than ADD and DELETE? - */ - if ((cmd == RTM_ADD && NEXTHOP_IS_ACTIVE(nexthop->flags)) - || (cmd == RTM_DELETE)) { - if (nexthop->type == NEXTHOP_TYPE_IPV4 - || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { - sin_gate.sin_addr = nexthop->gate.ipv4; - gate = 1; - } - if (nexthop->type == NEXTHOP_TYPE_IFINDEX - || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) - ifindex = nexthop->ifindex; - if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) { - struct in_addr loopback; - loopback.s_addr = htonl(INADDR_LOOPBACK); - sin_gate.sin_addr = loopback; - bh_type = nexthop->bh_type; - gate = 1; - } - - if (gate && p->prefixlen == 32) - mask = NULL; - else { - masklen2ip(p->prefixlen, &sin_mask.sin_addr); - sin_mask.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin_mask.sin_len = - sin_masklen(sin_mask.sin_addr); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - mask = &sin_mask; - } - -#ifdef __OpenBSD__ - if (nexthop->nh_label - && !kernel_rtm_add_labels(nexthop->nh_label, - &smpls)) - continue; - smplsp = (union sockunion *)&smpls; -#endif - - error = rtm_write(cmd, (union sockunion *)&sin_dest, - (union sockunion *)mask, - gate ? (union sockunion *)&sin_gate - : NULL, - smplsp, ifindex, bh_type, metric); - - if (IS_ZEBRA_DEBUG_KERNEL) { - if (!gate) { - zlog_debug( - "%s: %s: attention! gate not found for re", - __func__, prefix_buf); - } else - inet_ntop(AF_INET, &sin_gate.sin_addr, - gate_buf, INET_ADDRSTRLEN); - } - - switch (error) { - /* We only flag nexthops as being in FIB if rtm_write() - * did its work. */ - case ZEBRA_ERR_NOERROR: - nexthop_num++; - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug( - "%s: %s: successfully did NH %s", - __func__, prefix_buf, gate_buf); - - if (cmd == RTM_ADD) - SET_FLAG(nexthop->flags, - NEXTHOP_FLAG_FIB); - - break; - - /* The only valid case for this error is kernel's - * failure to install - * a multipath route, which is common for FreeBSD. This - * should be - * ignored silently, but logged as an error otherwise. - */ - case ZEBRA_ERR_RTEXIST: - if (cmd != RTM_ADD) - flog_err( - EC_LIB_SYSTEM_CALL, - "%s: rtm_write() returned %d for command %d", - __func__, error, cmd); - continue; - - /* Note any unexpected status returns */ - default: - flog_err( - EC_LIB_SYSTEM_CALL, - "%s: %s: rtm_write() unexpectedly returned %d for command %s", - __func__, - prefix2str(p, prefix_buf, - sizeof(prefix_buf)), - error, - lookup_msg(rtm_type_str, cmd, NULL)); - break; - } - } /* if (cmd and flags make sense) */ - else if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: odd command %s for flags %d", __func__, - lookup_msg(rtm_type_str, cmd, NULL), - nexthop->flags); - } /* for (ALL_NEXTHOPS(...))*/ - - /* If there was no useful nexthop, then complain. */ - if (nexthop_num == 0) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: No useful nexthops were found in RIB prefix %s", - __func__, prefix2str(p, prefix_buf, - sizeof(prefix_buf))); - return 1; - } - - return 0; /*XXX*/ -} - #ifdef SIN6_LEN /* Calculate sin6_len value for netmask socket value. */ static int sin6_masklen(struct in6_addr mask) @@ -278,11 +114,11 @@ static int sin6_masklen(struct in6_addr mask) #endif /* SIN6_LEN */ /* Interface between zebra message and rtm message. */ -static int kernel_rtm_ipv6(int cmd, const struct prefix *p, - const struct nexthop_group *ng, uint32_t metric) +static int kernel_rtm(int cmd, const struct prefix *p, + const struct nexthop_group *ng, uint32_t metric) + { - struct sockaddr_in6 *mask; - struct sockaddr_in6 sin_dest, sin_mask, sin_gate; + union sockunion sin_dest, sin_mask, sin_gate; #ifdef __OpenBSD__ struct sockaddr_mpls smpls; #endif @@ -290,48 +126,81 @@ static int kernel_rtm_ipv6(int cmd, const struct prefix *p, struct nexthop *nexthop; int nexthop_num = 0; ifindex_t ifindex = 0; - int gate = 0; + bool gate = false; int error; + char prefix_buf[PREFIX_STRLEN]; enum blackhole_type bh_type = BLACKHOLE_UNSPEC; - memset(&sin_dest, 0, sizeof(struct sockaddr_in6)); - sin_dest.sin6_family = AF_INET6; -#ifdef SIN6_LEN - sin_dest.sin6_len = sizeof(struct sockaddr_in6); -#endif /* SIN6_LEN */ - sin_dest.sin6_addr = p->u.prefix6; + if (IS_ZEBRA_DEBUG_RIB) + prefix2str(p, prefix_buf, sizeof(prefix_buf)); + + /* + * We only have the ability to ADD or DELETE at this point + * in time. + */ + if (cmd != RTM_ADD && cmd != RTM_DELETE) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: %s odd command %s for flags %d", + __func__, prefix_buf, + lookup_msg(rtm_type_str, cmd, NULL), + nexthop->flags); + return 0; + } - memset(&sin_mask, 0, sizeof(struct sockaddr_in6)); + memset(&sin_dest, 0, sizeof(sin_dest)); + memset(&sin_gate, 0, sizeof(sin_gate)); + memset(&sin_mask, 0, sizeof(sin_mask)); - memset(&sin_gate, 0, sizeof(struct sockaddr_in6)); - sin_gate.sin6_family = AF_INET6; + switch (p->family) { + case AF_INET: + sin_dest.sin.sin_family = AF_INET; +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + sin_dest.sin.sin_len = sizeof(sin_dest); + sin_gate.sin.sin_len = sizeof(sin_gate); +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + sin_dest.sin.sin_addr = p->u.prefix4; + sin_gate.sin.sin_family = AF_INET; + break; + case AF_INET6: + sin_dest.sin6.sin6_family = AF_INET6; +#ifdef SIN6_LEN + sin_dest.sin6.sin6_len = sizeof(sin_dest); +#endif /* SIN6_LEN */ + sin_dest.sin6.sin6_addr = p->u.prefix6; + sin_gate.sin6.sin6_family = AF_INET6; #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin_gate.sin6_len = sizeof(struct sockaddr_in6); + sin_gate.sin6.sin6_len = sizeof(sin_gate); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + break; + } /* Make gateway. */ for (ALL_NEXTHOPS_PTR(ng, nexthop)) { - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + /* + * We only want to use the actual good nexthops + */ + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE) || + !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) continue; - gate = 0; - - if ((cmd == RTM_ADD && NEXTHOP_IS_ACTIVE(nexthop->flags)) - || (cmd == RTM_DELETE)) { - if (nexthop->type == NEXTHOP_TYPE_IPV6 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { - sin_gate.sin6_addr = nexthop->gate.ipv6; - gate = 1; - } - if (nexthop->type == NEXTHOP_TYPE_IFINDEX - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) - ifindex = nexthop->ifindex; - - if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) - bh_type = nexthop->bh_type; - } + smplsp = NULL; + gate = false; + char gate_buf[INET_ADDRSTRLEN] = "NULL"; -/* Under kame set interface index to link local address. */ + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + sin_gate.sin.sin_addr = nexthop->gate.ipv4; + sin_gate.sin.sin_family = AF_INET; + ifindex = nexthop->ifindex; + gate = true; + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + sin_gate.sin6.sin6_addr = nexthop->gate.ipv6; + sin_gate.sin6.sin6_family = AF_INET6; + ifindex = nexthop->ifindex; +/* Under kame set interface index to link local address */ #ifdef KAME #define SET_IN6_LINKLOCAL_IFINDEX(a, i) \ @@ -340,19 +209,49 @@ static int kernel_rtm_ipv6(int cmd, const struct prefix *p, (a).s6_addr[3] = (i)&0xff; \ } while (0) - if (gate && IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6_addr)) - SET_IN6_LINKLOCAL_IFINDEX(sin_gate.sin6_addr, ifindex); + if (IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6.sin6_addr)) + SET_IN6_LINKLOCAL_IFINDEX( + sin_gate.sin6.sin6_addr, + ifindex); #endif /* KAME */ - if (gate && p->prefixlen == 128) - mask = NULL; - else { - masklen2ip6(p->prefixlen, &sin_mask.sin6_addr); - sin_mask.sin6_family = AF_INET6; + gate = true; + break; + case NEXTHOP_TYPE_IFINDEX: + ifindex = nexthop->ifindex; + break; + case NEXTHOP_TYPE_BLACKHOLE: + bh_type = nexthop->bh_type; + switch (p->family) { + case AFI_IP: { + struct in_addr loopback; + loopback.s_addr = htonl(INADDR_LOOPBACK); + sin_gate.sin.sin_addr = loopback; + gate = true; + } + break; + case AFI_IP6: + break; + } + } + + switch (p->family) { + case AF_INET: + masklen2ip(p->prefixlen, &sin_mask.sin.sin_addr); + sin_mask.sin.sin_family = AF_INET; +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + sin_mask.sin.sin_len = sin_masklen( + sin_mask.sin.sin_addr); +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + break; + case AF_INET6: + masklen2ip6(p->prefixlen, &sin_mask.sin6.sin6_addr); + sin_mask.sin6.sin6_family = AF_INET6; #ifdef SIN6_LEN - sin_mask.sin6_len = sin6_masklen(sin_mask.sin6_addr); + sin_mask.sin6.sin6_len = sin6_masklen( + sin_mask.sin6.sin6_addr); #endif /* SIN6_LEN */ - mask = &sin_mask; + break; } #ifdef __OpenBSD__ @@ -361,41 +260,69 @@ static int kernel_rtm_ipv6(int cmd, const struct prefix *p, continue; smplsp = (union sockunion *)&smpls; #endif + error = rtm_write(cmd, &sin_dest, &sin_mask, + gate ? &sin_gate : NULL, smplsp, + ifindex, bh_type, metric); + + if (IS_ZEBRA_DEBUG_KERNEL) { + if (!gate) { + zlog_debug("%s: %s: attention! gate not found for re", + __func__, prefix_buf); + } else + inet_ntop(p->family == AFI_IP ? AF_INET + : AF_INET6, + &sin_gate.sin.sin_addr, + gate_buf, INET_ADDRSTRLEN); + } + switch (error) { + /* We only flag nexthops as being in FIB if + * rtm_write() did its work. */ + case ZEBRA_ERR_NOERROR: + nexthop_num++; + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: %s: successfully did NH %s", + __func__, prefix_buf, gate_buf); + if (cmd == RTM_ADD) + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + break; + + /* The only valid case for this error is + * kernel's failure to install a multipath + * route, which is common for FreeBSD. This + * should be ignored silently, but logged as an error + * otherwise. + */ + case ZEBRA_ERR_RTEXIST: + if (cmd != RTM_ADD) + flog_err(EC_LIB_SYSTEM_CALL, + "%s: rtm_write() returned %d for command %d", + __func__, error, cmd); + continue; - error = rtm_write(cmd, (union sockunion *)&sin_dest, - (union sockunion *)mask, - gate ? (union sockunion *)&sin_gate : NULL, - smplsp, ifindex, bh_type, metric); - - /* Update installed nexthop info on success */ - if ((cmd == RTM_ADD) && (error == ZEBRA_ERR_NOERROR)) - SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); - - nexthop_num++; - } + /* Note any unexpected status returns */ + default: + flog_err(EC_LIB_SYSTEM_CALL, + "%s: %s: rtm_write() unexpectedly returned %d for command %s", + __func__, + prefix2str(p, prefix_buf, + sizeof(prefix_buf)), + error, lookup_msg(rtm_type_str, cmd, NULL)); + break; + } + } /* for (ALL_NEXTHOPS(...))*/ - /* If there is no useful nexthop then return. */ + /* If there was no useful nexthop, then complain. */ if (nexthop_num == 0) { if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("kernel_rtm_ipv6(): No useful nexthop."); + zlog_debug("%s: No useful nexthops were found in RIB prefix %s", + __func__, prefix2str(p, prefix_buf, + sizeof(prefix_buf))); return 1; } return 0; /*XXX*/ } -static int kernel_rtm(int cmd, const struct prefix *p, - const struct nexthop_group *ng, uint32_t metric) -{ - switch (PREFIX_FAMILY(p)) { - case AF_INET: - return kernel_rtm_ipv4(cmd, p, ng, metric); - case AF_INET6: - return kernel_rtm_ipv6(cmd, p, ng, metric); - } - return 0; -} - /* * Update or delete a prefix from the kernel, * using info from a dataplane context struct. diff --git a/zebra/subdir.am b/zebra/subdir.am index b8f5e0d409..23c3cd4239 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -10,6 +10,7 @@ vtysh_scan += \ $(top_srcdir)/zebra/interface.c \ $(top_srcdir)/zebra/router-id.c \ $(top_srcdir)/zebra/rtadv.c \ + $(top_srcdir)/zebra/zebra_mlag.c \ $(top_srcdir)/zebra/zebra_mpls_vty.c \ $(top_srcdir)/zebra/zebra_ptm.c \ $(top_srcdir)/zebra/zebra_pw.c \ @@ -64,6 +65,7 @@ zebra_zebra_SOURCES = \ zebra/rtread_sysctl.c \ zebra/rule_netlink.c \ zebra/rule_socket.c \ + zebra/zebra_mlag.c \ zebra/zebra_l2.c \ zebra/zebra_memory.c \ zebra/zebra_dplane.c \ @@ -93,10 +95,12 @@ zebra_zebra_SOURCES = \ zebra/zebra_errors.c \ # end +zebra/zebra_mlag_clippy.c: $(CLIPPY_DEPS) +zebra/zebra_mlag.$(OBJEXT): zebra/zebra_mlag_clippy.c + zebra/zebra_vty_clippy.c: $(CLIPPY_DEPS) zebra/zebra_vty.$(OBJEXT): zebra/zebra_vty_clippy.c - zebra/zebra_routemap_clippy.c: $(CLIPPY_DEPS) zebra/zebra_routemap.$(OBJEXT): zebra/zebra_routemap_clippy.c @@ -119,6 +123,7 @@ noinst_HEADERS += \ zebra/rt_netlink.h \ zebra/rtadv.h \ zebra/rule_netlink.h \ + zebra/zebra_mlag.h \ zebra/zebra_fpm_private.h \ zebra/zebra_l2.h \ zebra/zebra_dplane.h \ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 9b84a6e58a..faa0eb90e4 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -63,6 +63,7 @@ #include "zebra/table_manager.h" #include "zebra/zapi_msg.h" #include "zebra/zebra_errors.h" +#include "zebra/zebra_mlag.h" /* Encoding helpers -------------------------------------------------------- */ @@ -432,8 +433,8 @@ int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp, zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id); - /* Fill in the ifIndex of the interface and its new VRF (id) */ - stream_putl(s, ifp->ifindex); + /* Fill in the name of the interface and its new VRF (id) */ + stream_put(s, ifp->name, INTERFACE_NAMSIZ); stream_putl(s, vrf_id); /* Write packet size. */ @@ -1187,6 +1188,7 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS) unsigned short l = 0; struct prefix p; uint16_t flags; + uint32_t label = MPLS_INVALID_LABEL; uint32_t label_index = MPLS_INVALID_LABEL_INDEX; s = msg; @@ -1229,12 +1231,15 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS) l += 5; STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen)); l += PSIZE(p.prefixlen); - if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) { + if (flags & ZEBRA_FEC_REGISTER_LABEL) { + STREAM_GETL(s, label); + l += 4; + } else if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) { STREAM_GETL(s, label_index); l += 4; - } else - label_index = MPLS_INVALID_LABEL_INDEX; - zebra_mpls_fec_register(zvrf, &p, label_index, client); + } + + zebra_mpls_fec_register(zvrf, &p, label, label_index, client); } stream_failure: @@ -1653,6 +1658,7 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf) zclient_create_header(s, ZEBRA_CAPABILITIES, zvrf->vrf->vrf_id); stream_putc(s, mpls_enabled); stream_putl(s, multipath_num); + stream_putc(s, zebra_mlag_get_role()); stream_putw_at(s, 0, stream_get_endp(s)); zserv_send_message(client, s); diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index b6b2e64600..1336850510 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -24,7 +24,7 @@ #include "lib/prefix.h" #include "lib/nexthop.h" #include "lib/nexthop_group.h" -#include "lib/openbsd-queue.h" +#include "lib/queue.h" #include "zebra/zebra_ns.h" #include "zebra/rib.h" #include "zebra/zserv.h" diff --git a/zebra/zebra_errors.c b/zebra/zebra_errors.c index 32f6653832..d7c17829cd 100644 --- a/zebra/zebra_errors.c +++ b/zebra/zebra_errors.c @@ -86,6 +86,12 @@ static struct log_ref ferr_zebra_err[] = { .suggestion = "Notify a developer.", }, { + .code = EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT, + .title = "Refused to add FEC for MPLS client with both label index and label specified", + .description = "A client requested a label binding for a new FEC specifying a label index and a label at the same time.", + .suggestion = "Notify a developer.", + }, + { .code = EC_ZEBRA_FEC_RM_FAILED, .title = "Failed to remove FEC for MPLS client", .description = "Zebra was unable to find and remove a FEC in its internal table.", diff --git a/zebra/zebra_errors.h b/zebra/zebra_errors.h index cf2d6a7cf5..c3cdc4ed42 100644 --- a/zebra/zebra_errors.h +++ b/zebra/zebra_errors.h @@ -37,6 +37,7 @@ enum zebra_log_refs { EC_ZEBRA_DP_INVALID_RC, EC_ZEBRA_WQ_NONEXISTENT, EC_ZEBRA_FEC_ADD_FAILED, + EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT, EC_ZEBRA_FEC_RM_FAILED, EC_ZEBRA_IRDP_LEN_MISMATCH, EC_ZEBRA_RNH_UNKNOWN_FAMILY, diff --git a/zebra/zebra_mlag.c b/zebra/zebra_mlag.c new file mode 100644 index 0000000000..35be07c024 --- /dev/null +++ b/zebra/zebra_mlag.c @@ -0,0 +1,83 @@ +/* Zebra Mlag Code. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR 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, or (at your option) any + * later version. + * + * FRR 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 FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include "zebra.h" + +#include "command.h" +#include "hook.h" + +#include "zebra/zebra_mlag.h" + +#ifndef VTYSH_EXTRACT_PL +#include "zebra/zebra_mlag_clippy.c" +#endif + +enum mlag_role role = MLAG_ROLE_NONE; + +enum mlag_role zebra_mlag_get_role(void) +{ + return role; +} + +DEFUN_HIDDEN (show_mlag, + show_mlag_cmd, + "show zebra mlag", + SHOW_STR + ZEBRA_STR + "The mlag role on this machine\n") +{ + char buf[80]; + + vty_out(vty, "MLag is configured to: %s\n", + mlag_role2str(role, buf, sizeof(buf))); + + return CMD_SUCCESS; +} + +DEFPY_HIDDEN (test_mlag, + test_mlag_cmd, + "test zebra mlag <none$none|primary$primary|secondary$secondary>", + "Test code\n" + ZEBRA_STR + "Modify the Mlag state\n" + "Mlag is not setup on the machine\n" + "Mlag is setup to be primary\n" + "Mlag is setup to be the secondary\n") +{ + if (none) + role = MLAG_ROLE_NONE; + if (primary) + role = MLAG_ROLE_PRIMARY; + if (secondary) + role = MLAG_ROLE_SECONDARY; + + return CMD_SUCCESS; +} + +void zebra_mlag_init(void) +{ + install_element(VIEW_NODE, &show_mlag_cmd); + install_element(ENABLE_NODE, &test_mlag_cmd); +} + +void zebra_mlag_terminate(void) +{ +} diff --git a/zebra/zebra_mlag.h b/zebra/zebra_mlag.h new file mode 100644 index 0000000000..c5c147c833 --- /dev/null +++ b/zebra/zebra_mlag.h @@ -0,0 +1,31 @@ +/* Zebra mlag header. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR 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, or (at your option) any + * later version. + * + * FRR 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 FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#ifndef __ZEBRA_MLAG_H__ +#define __ZEBRA_MLAG_H__ + +#include "mlag.h" + +void zebra_mlag_init(void); +void zebra_mlag_terminate(void); + +enum mlag_role zebra_mlag_get_role(void); +#endif diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 5fe0116158..c0764cd4b8 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1813,17 +1813,22 @@ int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn, * NOTE: If there is a manually configured label binding, that is used. * Otherwise, if a label index is specified, it means we have to allocate the * label from a locally configured label block (SRGB), if one exists and index - * is acceptable. + * is acceptable. If no label index then just register the specified label. + * NOTE2: Either label or label_index is expected to be set to MPLS_INVALID_* + * by the calling function. Register requests with both will be rejected. */ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, - uint32_t label_index, struct zserv *client) + uint32_t label, uint32_t label_index, + struct zserv *client) { struct route_table *table; zebra_fec_t *fec; char buf[BUFSIZ]; - int new_client; - int label_change = 0; + bool new_client; + bool label_change = false; uint32_t old_label; + bool have_label_index = (label_index != MPLS_INVALID_LABEL_INDEX); + bool is_configured_fec = false; /* indicate statically configured FEC */ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))]; if (!table) @@ -1832,12 +1837,20 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, if (IS_ZEBRA_DEBUG_MPLS) prefix2str(p, buf, BUFSIZ); + if (label != MPLS_INVALID_LABEL && have_label_index) { + flog_err( + EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT, + "Rejecting FEC register for %s with both label %u and Label Index %u specified, client %s", + buf, label, label_index, + zebra_route_string(client->proto)); + return -1; + } + /* Locate FEC */ fec = fec_find(table, p); if (!fec) { - fec = fec_add(table, p, MPLS_INVALID_LABEL, 0, label_index); + fec = fec_add(table, p, label, 0, label_index); if (!fec) { - prefix2str(p, buf, BUFSIZ); flog_err( EC_ZEBRA_FEC_ADD_FAILED, "Failed to add FEC %s upon register, client %s", @@ -1846,16 +1859,19 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, } old_label = MPLS_INVALID_LABEL; - new_client = 1; + new_client = true; } else { + /* Check if the FEC has been statically defined in the config */ + is_configured_fec = fec->flags & FEC_FLAG_CONFIGURED; /* Client may register same FEC with different label index. */ new_client = (listnode_lookup(fec->client_list, client) == NULL); - if (!new_client && fec->label_index == label_index) + if (!new_client && fec->label_index == label_index + && fec->label == label) /* Duplicate register */ return 0; - /* Save current label, update label index */ + /* Save current label, update the FEC */ old_label = fec->label; fec->label_index = label_index; } @@ -1864,21 +1880,29 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, listnode_add(fec->client_list, client); if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug("FEC %s Label Index %u %s by client %s", buf, - label_index, new_client ? "registered" : "updated", - zebra_route_string(client->proto)); - - /* If not a configured FEC, derive the local label (from label index) - * or reset it. + zlog_debug("FEC %s label%s %u %s by client %s%s", buf, + have_label_index ? " index" : "", + have_label_index ? label_index : label, + new_client ? "registered" : "updated", + zebra_route_string(client->proto), + is_configured_fec + ? ", but using statically configured label" + : ""); + + /* If not a statically configured FEC, derive the local label + * from label index or use the provided label */ - if (!(fec->flags & FEC_FLAG_CONFIGURED)) { - fec_derive_label_from_index(zvrf, fec); + if (!is_configured_fec) { + if (have_label_index) + fec_derive_label_from_index(zvrf, fec); + else + fec->label = label; /* If no label change, exit. */ if (fec->label == old_label) return 0; - label_change = 1; + label_change = true; } /* If new client or label change, update client and install or uninstall @@ -2106,8 +2130,8 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p) if (IS_ZEBRA_DEBUG_MPLS) { prefix2str(p, buf, BUFSIZ); - zlog_debug("Delete fec %s label index %u", buf, - fec->label_index); + zlog_debug("Delete fec %s label %u label index %u", buf, + fec->label, fec->label_index); } old_label = fec->label; diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index 86bee129cf..c250fc4058 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -191,16 +191,9 @@ int zebra_mpls_lsp_install(struct zebra_vrf *zvrf, struct route_node *rn, int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *re); -/* - * Registration from a client for the label binding for a FEC. If a binding - * already exists, it is informed to the client. - * NOTE: If there is a manually configured label binding, that is used. - * Otherwise, if aa label index is specified, it means we have to allocate the - * label from a locally configured label block (SRGB), if one exists and index - * is acceptable. - */ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, - uint32_t label_index, struct zserv *client); + uint32_t label, uint32_t label_index, + struct zserv *client); /* * Deregistration from a client for the label binding for a FEC. The FEC diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 3f69b98413..a6b17303b9 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -215,6 +215,12 @@ static int zebra_ns_ready_read(struct thread *t) if (err < 0) return zebra_ns_continue_read(zns_info, stop_retry); + /* check default name is not already set */ + if (strmatch(VRF_DEFAULT_NAME, basename(netnspath))) { + zlog_warn("NS notify : NS %s is already default VRF." + "Cancel VRF Creation", basename(netnspath)); + return zebra_ns_continue_read(zns_info, 1); + } if (zebra_ns_notify_is_default_netns(basename(netnspath))) { zlog_warn( "NS notify : NS %s is default VRF." @@ -252,8 +258,6 @@ static int zebra_ns_notify_read(struct thread *t) if (!(event->mask & (IN_CREATE | IN_DELETE))) continue; - if (event->mask & IN_DELETE) - return zebra_ns_delete(event->name); if (offsetof(struct inotify_event, name) + event->len >= sizeof(buf)) { @@ -268,6 +272,9 @@ static int zebra_ns_notify_read(struct thread *t) break; } + if (event->mask & IN_DELETE) + return zebra_ns_delete(event->name); + netnspath = ns_netns_pathname(NULL, event->name); if (!netnspath) continue; @@ -310,6 +317,12 @@ void zebra_ns_notify_parse(void) dent->d_name); continue; } + /* check default name is not already set */ + if (strmatch(VRF_DEFAULT_NAME, basename(dent->d_name))) { + zlog_warn("NS notify : NS %s is already default VRF." + "Cancel VRF Creation", dent->d_name); + continue; + } if (zebra_ns_notify_is_default_netns(dent->d_name)) { zlog_warn( "NS notify : NS %s is default VRF." diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 965c8c206c..0c743d8678 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -73,10 +73,10 @@ static int zebra_ns_new(struct ns *ns) zns = zebra_ns_alloc(); ns->info = zns; zns->ns = ns; + zns->ns_id = ns->ns_id; /* Do any needed per-NS data structure allocation. */ zns->if_table = route_table_init(); - zebra_vxlan_ns_init(zns); return 0; } @@ -142,7 +142,6 @@ int zebra_ns_enable(ns_id_t ns_id, void **info) static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete) { route_table_finish(zns->if_table); - zebra_vxlan_ns_disable(zns); #if defined(HAVE_RTADV) rtadv_terminate(zns); #endif @@ -184,7 +183,7 @@ int zebra_ns_final_shutdown(struct ns *ns) return 0; } -int zebra_ns_init(void) +int zebra_ns_init(const char *optional_default_name) { ns_id_t ns_id; ns_id_t ns_id_external; @@ -201,7 +200,6 @@ int zebra_ns_init(void) /* Do any needed per-NS data structure allocation. */ dzns->if_table = route_table_init(); - zebra_vxlan_ns_init(dzns); /* Register zebra VRF callbacks, create and activate default VRF. */ zebra_vrf_init(); @@ -209,6 +207,10 @@ int zebra_ns_init(void) /* Default NS is activated */ zebra_ns_enable(ns_id_external, (void **)&dzns); + if (optional_default_name) + vrf_set_default_name(optional_default_name, + true); + if (vrf_is_backend_netns()) { ns_add_hook(NS_NEW_HOOK, zebra_ns_new); ns_add_hook(NS_ENABLE_HOOK, zebra_ns_enabled); diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index d3592f8f30..01af64c17b 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -60,7 +60,7 @@ struct zebra_ns { struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id); -int zebra_ns_init(void); +int zebra_ns_init(const char *optional_default_name); int zebra_ns_enable(ns_id_t ns_id, void **info); int zebra_ns_disabled(struct ns *ns); int zebra_ns_early_shutdown(struct ns *ns); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index f2d07310ee..b7f97ac612 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -73,31 +73,32 @@ extern int allow_delete; static const struct { int key; int distance; + uint8_t meta_q_map; } route_info[ZEBRA_ROUTE_MAX] = { - [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0}, - [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0}, - [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0}, - [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1}, - [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120}, - [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120}, - [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110}, - [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110}, - [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115}, - [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}, - [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255}, - [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90}, - [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10}, - [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255}, - [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255}, - [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150}, - [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150}, - [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20}, - [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20}, - [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20}, - [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20}, - [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20}, - [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100}, - [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150}, + [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 4}, + [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 0}, + [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 0}, + [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 1}, + [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 2}, + [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 2}, + [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 2}, + [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 2}, + [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 2}, + [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 3}, + [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 4}, + [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 2}, + [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 2}, + [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 4}, + [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 4}, + [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 1}, + [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 4}, + [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 3}, + [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 3}, + [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 3}, + [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 3}, + [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 3}, + [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 2}, + [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 4}, /* no entry/default: 150 */ }; @@ -412,7 +413,7 @@ static void nexthop_set_resolved(afi_t afi, const struct nexthop *newhop, /* If force flag is not set, do not modify falgs at all for uninstall the route from FIB. */ static int nexthop_active(afi_t afi, struct route_entry *re, - struct nexthop *nexthop, int set, + struct nexthop *nexthop, bool set, struct route_node *top) { struct prefix p; @@ -808,84 +809,6 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id) return NULL; } -/* - * This clone function, unlike its original rib_lookup_ipv4(), checks - * if specified IPv4 route record (prefix/mask -> gate) exists in - * the whole RIB and has ROUTE_ENTRY_SELECTED_FIB set. - * - * Return values: - * -1: error - * 0: exact match found - * 1: a match was found with a different gate - * 2: connected route found - * 3: no matches found - */ -int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate, - vrf_id_t vrf_id) -{ - struct route_table *table; - struct route_node *rn; - struct route_entry *match = NULL; - struct nexthop *nexthop; - int nexthops_active; - rib_dest_t *dest; - - /* Lookup table. */ - table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); - if (!table) - return ZEBRA_RIB_LOOKUP_ERROR; - - /* Scan the RIB table for exactly matching RIB entry. */ - rn = route_node_lookup(table, (struct prefix *)p); - - /* No route for this prefix. */ - if (!rn) - return ZEBRA_RIB_NOTFOUND; - - /* Unlock node. */ - route_unlock_node(rn); - dest = rib_dest_from_rnode(rn); - - /* Find out if a "selected" RR for the discovered RIB entry exists ever. - */ - if (dest && dest->selected_fib - && !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED)) - match = dest->selected_fib; - - /* None such found :( */ - if (!match) - return ZEBRA_RIB_NOTFOUND; - - if (match->type == ZEBRA_ROUTE_CONNECT) - return ZEBRA_RIB_FOUND_CONNECTED; - - /* Ok, we have a cood candidate, let's check it's nexthop list... */ - nexthops_active = 0; - for (ALL_NEXTHOPS(match->ng, nexthop)) - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) { - nexthops_active = 1; - if (nexthop->gate.ipv4.s_addr == sockunion2ip(qgate)) - return ZEBRA_RIB_FOUND_EXACT; - if (IS_ZEBRA_DEBUG_RIB) { - char gate_buf[INET_ADDRSTRLEN], - qgate_buf[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &nexthop->gate.ipv4.s_addr, - gate_buf, INET_ADDRSTRLEN); - inet_ntop(AF_INET, &sockunion2ip(qgate), - qgate_buf, INET_ADDRSTRLEN); - zlog_debug("%s: qgate == %s, %s == %s", - __func__, qgate_buf, - nexthop->rparent ? "rgate" : "gate", - gate_buf); - } - } - - if (nexthops_active) - return ZEBRA_RIB_FOUND_NOGATE; - - return ZEBRA_RIB_NOTFOUND; -} - #define RIB_SYSTEM_ROUTE(R) \ ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT) @@ -904,7 +827,7 @@ int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate, static unsigned nexthop_active_check(struct route_node *rn, struct route_entry *re, - struct nexthop *nexthop, int set) + struct nexthop *nexthop, bool set) { struct interface *ifp; route_map_result_t ret = RMAP_MATCH; @@ -1031,7 +954,7 @@ static unsigned nexthop_active_check(struct route_node *rn, */ static int nexthop_active_update(struct route_node *rn, struct route_entry *re, - int set) + bool set) { struct nexthop *nexthop; union g_addr prev_src; @@ -1049,7 +972,18 @@ static int nexthop_active_update(struct route_node *rn, struct route_entry *re, prev_src = nexthop->rmap_src; prev_active = CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); prev_index = nexthop->ifindex; - if ((new_active = nexthop_active_check(rn, re, nexthop, set))) + /* + * We need to respect the multipath_num here + * as that what we should be able to install from + * a multipath perpsective should not be a data plane + * decision point. + */ + new_active = nexthop_active_check(rn, re, nexthop, set); + if (new_active && re->nexthop_active_num >= multipath_num) { + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + new_active = 0; + } + if (new_active) re->nexthop_active_num++; /* Don't allow src setting on IPv6 addr for now */ if (prev_active != new_active || prev_index != nexthop->ifindex @@ -1322,7 +1256,7 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, /* Update real nexthop. This may actually determine if nexthop is active * or not. */ - if (!nexthop_active_update(rn, new, 1)) { + if (!nexthop_active_update(rn, new, true)) { UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED); return; } @@ -1383,7 +1317,7 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, * down, causing the kernel to delete routes without sending DELROUTE * notifications */ - if (!nexthop_active_update(rn, old, 1) && + if (!nexthop_active_update(rn, old, true) && (RIB_KERNEL_ROUTE(old))) SET_FLAG(old->status, ROUTE_ENTRY_REMOVED); else @@ -1408,7 +1342,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, /* Update the nexthop; we could determine here that nexthop is * inactive. */ - if (nexthop_active_update(rn, new, 1)) + if (nexthop_active_update(rn, new, true)) nh_active = 1; /* If nexthop is active, install the selected route, if @@ -1533,7 +1467,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, /* Update prior route. */ if (new != old) { /* Set real nexthop. */ - nexthop_active_update(rn, old, 1); + nexthop_active_update(rn, old, true); UNSET_FLAG(old->status, ROUTE_ENTRY_CHANGED); } @@ -1682,7 +1616,7 @@ static void rib_process(struct route_node *rn) * recursive NHs. */ if (!CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED) - && !nexthop_active_update(rn, re, 0)) { + && !nexthop_active_update(rn, re, false)) { if (re->type == ZEBRA_ROUTE_TABLE) { /* XXX: HERE BE DRAGONS!!!!! * In all honesty, I have not yet figured out @@ -1774,7 +1708,7 @@ static void rib_process(struct route_node *rn) if (old_selected != new_selected || selected_changed) { if (new_selected && new_selected != new_fib) { - nexthop_active_update(rn, new_selected, 1); + nexthop_active_update(rn, new_selected, true); UNSET_FLAG(new_selected->status, ROUTE_ENTRY_CHANGED); } @@ -1950,7 +1884,7 @@ static void rib_process_after(struct zebra_dplane_ctx *ctx) zvrf->removals++; } else { zsend_route_notify_owner_ctx(ctx, - ZAPI_ROUTE_FAIL_INSTALL); + ZAPI_ROUTE_REMOVE_FAIL); zlog_warn("%u:%s: Route Deletion failure", dplane_ctx_get_vrf(ctx), @@ -2210,36 +2144,6 @@ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data) return mq->size ? WQ_REQUEUE : WQ_SUCCESS; } -/* - * Map from rib types to queue type (priority) in meta queue - */ -static const uint8_t meta_queue_map[ZEBRA_ROUTE_MAX] = { - [ZEBRA_ROUTE_SYSTEM] = 4, - [ZEBRA_ROUTE_KERNEL] = 0, - [ZEBRA_ROUTE_CONNECT] = 0, - [ZEBRA_ROUTE_STATIC] = 1, - [ZEBRA_ROUTE_RIP] = 2, - [ZEBRA_ROUTE_RIPNG] = 2, - [ZEBRA_ROUTE_OSPF] = 2, - [ZEBRA_ROUTE_OSPF6] = 2, - [ZEBRA_ROUTE_ISIS] = 2, - [ZEBRA_ROUTE_BGP] = 3, - [ZEBRA_ROUTE_PIM] = 4, // Shouldn't happen but for safety - [ZEBRA_ROUTE_EIGRP] = 2, - [ZEBRA_ROUTE_NHRP] = 2, - [ZEBRA_ROUTE_HSLS] = 4, - [ZEBRA_ROUTE_OLSR] = 4, - [ZEBRA_ROUTE_TABLE] = 1, - [ZEBRA_ROUTE_LDP] = 4, - [ZEBRA_ROUTE_VNC] = 3, - [ZEBRA_ROUTE_VNC_DIRECT] = 3, - [ZEBRA_ROUTE_VNC_DIRECT_RH] = 3, - [ZEBRA_ROUTE_BGP_DIRECT] = 3, - [ZEBRA_ROUTE_BGP_DIRECT_EXT] = 3, - [ZEBRA_ROUTE_BABEL] = 2, - [ZEBRA_ROUTE_ALL] = 4, // Shouldn't happen but for safety -}; - /* Look into the RN and queue it into one or more priority queues, * increasing the size for each data push done. */ @@ -2248,7 +2152,7 @@ static void rib_meta_queue_add(struct meta_queue *mq, struct route_node *rn) struct route_entry *re; RNODE_FOREACH_RE (rn, re) { - uint8_t qindex = meta_queue_map[re->type]; + uint8_t qindex = route_info[re->type].meta_q_map; struct zebra_vrf *zvrf; /* Invariant: at this point we always have rn->info set. */ @@ -2362,6 +2266,7 @@ static void rib_queue_init(struct zebra_t *zebra) /* XXX: TODO: These should be runtime configurable via vty */ zebra->ribq->spec.max_retries = 3; zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; + zebra->ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME; if (!(zebra->mq = meta_queue_new())) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index e92cd8bb8a..c3781888b1 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -178,11 +178,15 @@ void zebra_free_rnh(struct rnh *rnh) XFREE(MTYPE_RNH, rnh); } -void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type) +static void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type) { struct route_node *rn; - if (!rnh || (rnh->flags & ZEBRA_NHT_DELETED) || !(rn = rnh->node)) + if (!list_isempty(rnh->client_list) + || !list_isempty(rnh->zebra_pseudowire_list)) + return; + + if ((rnh->flags & ZEBRA_NHT_DELETED) || !(rn = rnh->node)) return; if (IS_ZEBRA_DEBUG_NHT) { @@ -233,9 +237,7 @@ void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client, rnh_str(rnh, buf, sizeof(buf)), type); } listnode_delete(rnh->client_list, client); - if (list_isempty(rnh->client_list) - && list_isempty(rnh->zebra_pseudowire_list)) - zebra_delete_rnh(rnh, type); + zebra_delete_rnh(rnh, type); } /* XXX move this utility function elsewhere? */ @@ -291,9 +293,7 @@ void zebra_deregister_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw) listnode_delete(rnh->zebra_pseudowire_list, pw); pw->rnh = NULL; - if (list_isempty(rnh->client_list) - && list_isempty(rnh->zebra_pseudowire_list)) - zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE); + zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE); } /* Apply the NHT route-map for a client to the route (and nexthops) @@ -528,8 +528,7 @@ static void zebra_rnh_process_pbr_tables(int family, */ static bool rnh_nexthop_valid(const struct nexthop *nh) { - return ((CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB) - || CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) + return (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB) && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)); } @@ -581,8 +580,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, int family, /* Just being SELECTED isn't quite enough - must * have an installed nexthop to be useful. */ - for (nexthop = re->ng.nexthop; nexthop; - nexthop = nexthop->next) { + for (ALL_NEXTHOPS(re->ng, nexthop)) { if (rnh_nexthop_valid(nexthop)) break; } @@ -915,7 +913,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, num = 0; nump = stream_get_endp(s); stream_putc(s, 0); - for (nh = re->ng.nexthop; nh; nh = nh->next) + for (ALL_NEXTHOPS(re->ng, nh)) if (rnh_nexthop_valid(nh)) { stream_putl(s, nh->vrf_id); stream_putc(s, nh->type); diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 33302f0ee2..ed1fe9b756 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -72,7 +72,6 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type); extern void zebra_free_rnh(struct rnh *rnh); -extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type); extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vrfid); extern void zebra_register_rnh_pseudowire(vrf_id_t, struct zebra_pw *); diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index afe3c708a0..ae18a0d290 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -24,6 +24,8 @@ #include "zebra_router.h" #include "zebra_memory.h" #include "zebra_pbr.h" +#include "zebra_vxlan.h" +#include "zebra_mlag.h" struct zebra_router zrouter; @@ -157,6 +159,9 @@ void zebra_router_terminate(void) zebra_router_free_table(zrt); } + zebra_vxlan_disable(); + zebra_mlag_terminate(); + hash_clean(zrouter.rules_hash, zebra_pbr_rules_free); hash_free(zrouter.rules_hash); @@ -170,7 +175,8 @@ void zebra_router_terminate(void) void zebra_router_init(void) { - zrouter.l3vni_table = NULL; + zebra_vxlan_init(); + zebra_mlag_init(); zrouter.rules_hash = hash_create_size(8, zebra_pbr_rules_hash_key, zebra_pbr_rules_hash_equal, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index e6cc802d08..8b06d2ae11 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -948,6 +948,39 @@ DEFUN (show_ip_nht, return CMD_SUCCESS; } +DEFPY (show_ip_import_check, + show_ip_import_check_cmd, + "show <ip$ipv4|ipv6$ipv6> import-check [vrf NAME$vrf_name|vrf all$vrf_all]", + SHOW_STR + IP_STR + IP6_STR + "IP import check tracking table\n" + VRF_CMD_HELP_STR + VRF_ALL_CMD_HELP_STR) +{ + afi_t afi = ipv4 ? AFI_IP : AFI_IP6; + vrf_id_t vrf_id = VRF_DEFAULT; + + if (vrf_all) { + struct vrf *vrf; + struct zebra_vrf *zvrf; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) + if ((zvrf = vrf->info) != NULL) { + vty_out(vty, "\nVRF %s:\n", + zvrf_name(zvrf)); + zebra_print_rnh_table(zvrf_id(zvrf), + afi, vty, + RNH_NEXTHOP_TYPE); + } + return CMD_SUCCESS; + } + if (vrf_name) + VRF_GET_ID(vrf_id, vrf_name, false); + + zebra_print_rnh_table(vrf_id, afi, vty, RNH_IMPORT_CHECK_TYPE); + return CMD_SUCCESS; +} DEFUN (show_ip_nht_vrf_all, show_ip_nht_vrf_all_cmd, @@ -2907,6 +2940,7 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_route_detail_cmd); install_element(VIEW_NODE, &show_route_summary_cmd); install_element(VIEW_NODE, &show_ip_nht_cmd); + install_element(VIEW_NODE, &show_ip_import_check_cmd); install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd); install_element(VIEW_NODE, &show_ipv6_nht_cmd); install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index ed1c185f1a..b55ca60c00 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -412,7 +412,7 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, * this MAC update. */ if (zvrf->dad_freeze) - *is_dup_detect = false; + *is_dup_detect = true; return; } @@ -464,11 +464,6 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, if (is_local) mac->dad_count++; - zlog_debug("%s: MAC DAD %s dad_count %u ", - __PRETTY_FUNCTION__, - prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->dad_count); - if (mac->dad_count >= zvrf->dad_max_moves) { flog_warn(EC_ZEBRA_DUP_MAC_DETECTED, "VNI %u: MAC %s detected as duplicate during %s VTEP %s", @@ -521,11 +516,11 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, &mac->dad_mac_auto_recovery_timer); } - /* Do not inform to client (BGPd), + /* In case of local update, do not inform to client (BGPd), * upd_neigh for neigh sequence change. */ if (zvrf->dad_freeze) - *is_dup_detect = false; + *is_dup_detect = true; } } @@ -5176,11 +5171,11 @@ static void process_remote_macip_add(vni_t vni, do_dad, &is_dup_detect, false); - zvni_process_neigh_on_remote_mac_add(zvni, mac); - - /* Install the entry. */ - if (!is_dup_detect) + if (!is_dup_detect) { + zvni_process_neigh_on_remote_mac_add(zvni, mac); + /* Install the entry. */ zvni_mac_install(zvni, mac); + } } /* Update seq number. */ @@ -6386,7 +6381,8 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, * to BGP. Similarly remote macip update, neigh needs to be * installed locally. */ - if (nbr->dad_count) { + if (zvrf->dad_freeze && + CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) { if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) ZEBRA_NEIGH_SET_INACTIVE(nbr); else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) @@ -6406,6 +6402,10 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, mac->dad_dup_detect_time = 0; THREAD_OFF(mac->dad_mac_auto_recovery_timer); + /* warn-only action return */ + if (!zvrf->dad_freeze) + return CMD_SUCCESS; + /* Local: Notify Peer VTEPs, Remote: Install the entry */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { /* Inform to BGP */ @@ -7412,6 +7412,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, bool mac_sticky = false; bool inform_client = false; bool upd_neigh = false; + bool is_dup_detect = false; struct in_addr vtep_ip = {.s_addr = 0}; /* We are interested in MACs only on ports or (port, VLAN) that @@ -7559,8 +7560,12 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac, vtep_ip, do_dad, - &inform_client, + &is_dup_detect, true); + if (is_dup_detect) { + inform_client = false; + upd_neigh = false; + } } } @@ -8395,7 +8400,7 @@ int zebra_vxlan_if_add(struct interface *ifp) "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u", vni, vlan_if ? vrf_id_to_name(vlan_if->vrf_id) - : "Default", + : VRF_DEFAULT_NAME, ifp->name, ifp->ifindex, vxl->access_vlan, inet_ntoa(vxl->vtep_ip), zif->brslave_info.bridge_ifindex); @@ -8864,14 +8869,14 @@ void zebra_vxlan_close_tables(struct zebra_vrf *zvrf) } /* init the l3vni table */ -void zebra_vxlan_ns_init(struct zebra_ns *zns) +void zebra_vxlan_init(void) { zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp, "Zebra VRF L3 VNI table"); } /* free l3vni table */ -void zebra_vxlan_ns_disable(struct zebra_ns *zns) +void zebra_vxlan_disable(void) { hash_free(zrouter.l3vni_table); } @@ -8971,7 +8976,7 @@ static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t) /* Remove all IPs as duplicate associcated with this MAC */ for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) { - if (nbr->dad_count) { + if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) { if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) ZEBRA_NEIGH_SET_INACTIVE(nbr); else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index eafc481200..c50664a28b 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -183,8 +183,8 @@ extern int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, extern void zebra_vxlan_init_tables(struct zebra_vrf *zvrf); extern void zebra_vxlan_close_tables(struct zebra_vrf *); extern void zebra_vxlan_cleanup_tables(struct zebra_vrf *); -extern void zebra_vxlan_ns_init(struct zebra_ns *zns); -extern void zebra_vxlan_ns_disable(struct zebra_ns *zns); +extern void zebra_vxlan_init(void); +extern void zebra_vxlan_disable(void); extern void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac, struct ipaddr *ip, diff --git a/zebra/zserv.c b/zebra/zserv.c index b40e9e2af5..a48505a514 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -492,8 +492,8 @@ static int zserv_process_messages(struct thread *thread) struct zserv *client = THREAD_ARG(thread); struct stream *msg; struct stream_fifo *cache = stream_fifo_new(); - uint32_t p2p = zebrad.packets_to_process; + bool need_resched = false; pthread_mutex_lock(&client->ibuf_mtx); { @@ -505,6 +505,12 @@ static int zserv_process_messages(struct thread *thread) } msg = NULL; + + /* Need to reschedule processing work if there are still + * packets in the fifo. + */ + if (stream_fifo_head(client->ibuf_fifo)) + need_resched = true; } pthread_mutex_unlock(&client->ibuf_mtx); @@ -516,6 +522,10 @@ static int zserv_process_messages(struct thread *thread) stream_fifo_free(cache); + /* Reschedule ourselves if necessary */ + if (need_resched) + zserv_event(client, ZSERV_PROCESS_MESSAGES); + return 0; } @@ -628,6 +638,7 @@ void zserv_close_client(struct zserv *client) thread_cancel_event(zebrad.master, client); THREAD_OFF(client->t_cleanup); + THREAD_OFF(client->t_process); /* destroy pthread */ frr_pthread_destroy(client->pthread); @@ -828,7 +839,7 @@ void zserv_event(struct zserv *client, enum zserv_event event) break; case ZSERV_PROCESS_MESSAGES: thread_add_event(zebrad.master, zserv_process_messages, client, - 0, NULL); + 0, &client->t_process); break; case ZSERV_HANDLE_CLIENT_FAIL: thread_add_event(zebrad.master, zserv_handle_client_fail, diff --git a/zebra/zserv.h b/zebra/zserv.h index f7967f54f0..f0b8934ae1 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -73,6 +73,9 @@ struct zserv { struct thread *t_read; struct thread *t_write; + /* Event for message processing, for the main pthread */ + struct thread *t_process; + /* Threads for the main pthread */ struct thread *t_cleanup; @@ -184,6 +187,7 @@ struct zebra_t { /* rib work queue */ #define ZEBRA_RIB_PROCESS_HOLD_TIME 10 +#define ZEBRA_RIB_PROCESS_RETRY_TIME 1 struct work_queue *ribq; struct meta_queue *mq; |
