summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE.md9
-rw-r--r--babeld/babel_filter.c7
-rw-r--r--babeld/babel_interface.c9
-rw-r--r--babeld/babeld.c29
-rw-r--r--babeld/babeld.h4
-rw-r--r--bgpd/BGP4-MIB.txt929
-rw-r--r--bgpd/bgp_attr.c8
-rw-r--r--bgpd/bgp_evpn.c17
-rw-r--r--bgpd/bgp_evpn_vty.c34
-rw-r--r--bgpd/bgp_flowspec_util.c25
-rw-r--r--bgpd/bgp_flowspec_util.h4
-rw-r--r--bgpd/bgp_label.c137
-rw-r--r--bgpd/bgp_label.h8
-rw-r--r--bgpd/bgp_labelpool.h1
-rw-r--r--bgpd/bgp_nexthop.c48
-rw-r--r--bgpd/bgp_nht.c11
-rw-r--r--bgpd/bgp_packet.c10
-rw-r--r--bgpd/bgp_pbr.c2
-rw-r--r--bgpd/bgp_pbr.h3
-rw-r--r--bgpd/bgp_route.c74
-rw-r--r--bgpd/bgp_routemap.c40
-rw-r--r--bgpd/bgp_rpki.c3
-rw-r--r--bgpd/bgp_snmp.c4
-rw-r--r--bgpd/bgp_vty.c5
-rw-r--r--bgpd/bgpd.c2
-rw-r--r--bgpd/bgpd.conf.sample4
-rw-r--r--bgpd/bgpd.h2
-rw-r--r--bgpd/subdir.am2
-rw-r--r--debianpkg/frr.postinst15
-rw-r--r--doc/developer/workflow.rst6
-rw-r--r--doc/user/conf.py2
-rw-r--r--doc/user/index.rst20
-rw-r--r--doc/user/installation.rst12
-rw-r--r--doc/user/sharp.rst10
-rw-r--r--doc/user/zebra.rst6
-rw-r--r--eigrpd/EIGRP-MIB.txt1321
-rw-r--r--eigrpd/eigrp_dump.c5
-rw-r--r--eigrpd/eigrp_filter.c12
-rw-r--r--eigrpd/eigrp_filter.h3
-rw-r--r--eigrpd/eigrp_main.c2
-rw-r--r--eigrpd/eigrp_network.c4
-rw-r--r--eigrpd/eigrp_structs.h7
-rw-r--r--eigrpd/eigrp_vty.c29
-rw-r--r--eigrpd/eigrpd.c24
-rw-r--r--eigrpd/subdir.am2
-rw-r--r--fpm/subdir.am4
-rw-r--r--isisd/isis_adjacency.c5
-rw-r--r--isisd/isis_circuit.c98
-rw-r--r--isisd/isis_circuit.h2
-rw-r--r--isisd/isis_cli.c2024
-rw-r--r--isisd/isis_cli.h125
-rw-r--r--isisd/isis_lsp.c15
-rw-r--r--isisd/isis_main.c22
-rw-r--r--isisd/isis_northbound.c3232
-rw-r--r--isisd/isis_pdu.c196
-rw-r--r--isisd/isis_redist.c87
-rw-r--r--isisd/isis_redist.h4
-rw-r--r--isisd/isis_te.c141
-rw-r--r--isisd/isis_tlvs.c16
-rw-r--r--isisd/isis_tlvs.h11
-rw-r--r--isisd/isis_vty_common.c903
-rw-r--r--isisd/isis_vty_common.h6
-rw-r--r--isisd/isis_vty_fabricd.c906
-rw-r--r--isisd/isis_vty_isisd.c858
-rw-r--r--isisd/isisd.c112
-rw-r--r--isisd/isisd.h56
-rw-r--r--isisd/subdir.am15
-rw-r--r--ldpd/ldpe.c18
-rw-r--r--ldpd/socket.c13
-rw-r--r--lib/distribute.c155
-rw-r--r--lib/distribute.h36
-rw-r--r--lib/hook.c26
-rw-r--r--lib/hook.h28
-rw-r--r--lib/lib_errors.c26
-rw-r--r--lib/lib_errors.h5
-rw-r--r--lib/mlag.c41
-rw-r--r--lib/mlag.h32
-rw-r--r--lib/module.c26
-rw-r--r--lib/module.h26
-rw-r--r--lib/northbound.c39
-rw-r--r--lib/northbound_cli.c15
-rw-r--r--lib/northbound_cli.h2
-rw-r--r--lib/subdir.am2
-rw-r--r--lib/vrf.c2
-rw-r--r--lib/vty.h2
-rw-r--r--lib/workqueue.c29
-rw-r--r--lib/workqueue.h5
-rw-r--r--lib/yang.c4
-rw-r--r--lib/yang_wrappers.c8
-rw-r--r--lib/zclient.c13
-rw-r--r--lib/zclient.h7
-rw-r--r--lib/zebra.h52
-rw-r--r--ospf6d/OSPFv3-MIB.txt3951
-rw-r--r--ospfd/OSPF-MIB.txt2723
-rw-r--r--ospfd/OSPF-TRAP-MIB.txt443
-rw-r--r--ospfd/ospf_te.c45
-rw-r--r--ospfd/ospf_vty.c115
-rw-r--r--ospfd/subdir.am2
-rw-r--r--pimd/pim_assert.c2
-rw-r--r--pimd/pim_cmd.c21
-rw-r--r--pimd/pim_iface.c2
-rw-r--r--pimd/pim_ifchannel.c33
-rw-r--r--pimd/pim_igmp.c14
-rw-r--r--pimd/pim_igmpv3.c7
-rw-r--r--pimd/pim_instance.c8
-rw-r--r--pimd/pim_instance.h24
-rw-r--r--pimd/pim_macro.c2
-rw-r--r--pimd/pim_main.c4
-rw-r--r--pimd/pim_mroute.c4
-rw-r--r--pimd/pim_msdp.c9
-rw-r--r--pimd/pim_msdp.h5
-rw-r--r--pimd/pim_msdp_socket.c2
-rw-r--r--pimd/pim_neighbor.c12
-rw-r--r--pimd/pim_pim.c12
-rw-r--r--pimd/pim_ssmpingd.c2
-rw-r--r--pimd/pim_upstream.c24
-rw-r--r--pimd/pim_upstream.h5
-rw-r--r--pimd/pim_vty.c14
-rw-r--r--pimd/pim_zebra.c16
-rw-r--r--pimd/pim_zlookup.c6
-rw-r--r--pimd/pimd.c63
-rw-r--r--pimd/pimd.h193
-rw-r--r--ripd/RIPv2-MIB.txt530
-rw-r--r--ripd/rip_cli.c3
-rw-r--r--ripd/rip_debug.c7
-rw-r--r--ripd/rip_debug.h1
-rw-r--r--ripd/rip_interface.c9
-rw-r--r--ripd/rip_northbound.c12
-rw-r--r--ripd/rip_routemap.c5
-rw-r--r--ripd/rip_zebra.c5
-rw-r--r--ripd/ripd.c35
-rw-r--r--ripd/ripd.h7
-rw-r--r--ripd/subdir.am5
-rw-r--r--ripngd/ripng_cli.c489
-rw-r--r--ripngd/ripng_cli.h58
-rw-r--r--ripngd/ripng_debug.c7
-rw-r--r--ripngd/ripng_debug.h1
-rw-r--r--ripngd/ripng_interface.c267
-rw-r--r--ripngd/ripng_main.c6
-rw-r--r--ripngd/ripng_northbound.c1001
-rw-r--r--ripngd/ripng_offset.c292
-rw-r--r--ripngd/ripng_routemap.c6
-rw-r--r--ripngd/ripng_zebra.c252
-rw-r--r--ripngd/ripngd.c559
-rw-r--r--ripngd/ripngd.h85
-rw-r--r--ripngd/subdir.am13
-rw-r--r--sharpd/sharp_main.c2
-rw-r--r--sharpd/sharp_vty.c97
-rw-r--r--sharpd/sharp_zebra.c101
-rw-r--r--sharpd/sharp_zebra.h9
-rw-r--r--staticd/static_zebra.c4
-rw-r--r--tests/topotests/all-protocol-startup/r1/show_bgp_ipv4-post6.1.ref9
-rw-r--r--tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_post6.1.ref9
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1-post6.1.ref42
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2-post6.1.ref31
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3-post6.1.ref42
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf2
-rw-r--r--tests/topotests/lib/topogen.py13
-rw-r--r--tests/topotests/lib/topotest.py78
-rw-r--r--tools/etc/frr/vtysh.conf1
-rwxr-xr-xtools/frr-reload.py4
-rw-r--r--tools/frr.service2
-rw-r--r--tools/frrcommon.sh.in6
-rwxr-xr-xvtysh/extract.pl.in2
-rw-r--r--vtysh/vtysh.c5
-rw-r--r--yang/confd/confd.frr-ripngd.yang22
-rw-r--r--yang/frr-isisd.yang1404
-rw-r--r--yang/frr-ripngd.yang321
-rw-r--r--yang/subdir.am8
-rw-r--r--zebra/if_netlink.c2
-rw-r--r--zebra/kernel_netlink.c11
-rw-r--r--zebra/kernel_socket.c225
-rw-r--r--zebra/main.c5
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/rt_netlink.c16
-rw-r--r--zebra/rt_socket.c389
-rw-r--r--zebra/subdir.am7
-rw-r--r--zebra/zapi_msg.c18
-rw-r--r--zebra/zebra_dplane.h2
-rw-r--r--zebra/zebra_errors.c6
-rw-r--r--zebra/zebra_errors.h1
-rw-r--r--zebra/zebra_mlag.c83
-rw-r--r--zebra/zebra_mlag.h31
-rw-r--r--zebra/zebra_mpls.c64
-rw-r--r--zebra/zebra_mpls.h11
-rw-r--r--zebra/zebra_netns_notify.c17
-rw-r--r--zebra/zebra_ns.c10
-rw-r--r--zebra/zebra_ns.h2
-rw-r--r--zebra/zebra_rib.c193
-rw-r--r--zebra/zebra_rnh.c24
-rw-r--r--zebra/zebra_rnh.h1
-rw-r--r--zebra/zebra_router.c8
-rw-r--r--zebra/zebra_vty.c34
-rw-r--r--zebra/zebra_vxlan.c41
-rw-r--r--zebra/zebra_vxlan.h4
-rw-r--r--zebra/zserv.c15
-rw-r--r--zebra/zserv.h4
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 \
diff --git a/lib/vrf.c b/lib/vrf.c
index 8409a1c9a1..0c82f6a3cd 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -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;
diff --git a/lib/vty.h b/lib/vty.h
index ad4dc273b9..79b1bd5e93 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -43,7 +43,7 @@ struct vty_error {
};
struct vty_cfg_change {
- const char *xpath;
+ char xpath[XPATH_MAXLEN];
enum nb_operation operation;
const char *value;
};
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, &note))
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;