summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2018-09-12 21:58:39 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2018-09-12 21:58:39 +0200
commite991eff5b5773e8a85c3f4c4f92c09fe30cf680b (patch)
treeab98bf44cfc7611ad7cc699396674554f150db43
parentzebra: fix includes (diff)
parentMerge pull request #3005 from patrasar/indentation_warnings (diff)
downloadfrr-e991eff5b5773e8a85c3f4c4f92c09fe30cf680b.tar.xz
frr-e991eff5b5773e8a85c3f4c4f92c09fe30cf680b.zip
Merge remote-tracking branch 'frr/master' into warnings
Conflicts: zebra/if_ioctl_solaris.c zebra/rtread_getmsg.c Signed-off-by: David Lamparter <equinox@diac24.net>
-rw-r--r--.gitignore132
-rw-r--r--AUTHORS6
-rw-r--r--ChangeLog4
-rw-r--r--Makefile.am62
-rw-r--r--NEWS2574
-rw-r--r--README16
-rw-r--r--README.md74
-rw-r--r--babeld/babel_filter.c4
-rw-r--r--babeld/kernel.c4
-rw-r--r--babeld/neighbour.c4
-rw-r--r--babeld/net.c4
-rw-r--r--babeld/resend.c4
-rw-r--r--babeld/source.c4
-rw-r--r--babeld/subdir.am5
-rw-r--r--babeld/util.c4
-rw-r--r--bfdd/.gitignore1
-rw-r--r--bfdd/bfd_packet.c2
-rw-r--r--bfdd/ptm_adapter.c2
-rw-r--r--bfdd/subdir.am2
-rw-r--r--bgpd/.gitignore15
-rw-r--r--bgpd/Makefile10
-rw-r--r--bgpd/Makefile.am140
-rw-r--r--bgpd/bgp_flowspec.c4
-rw-r--r--bgpd/bgp_route.c9
-rw-r--r--bgpd/bgp_rpki.c2
-rw-r--r--bgpd/rfapi/rfapi.c3
-rw-r--r--bgpd/rfapi/rfapi_ap.c2
-rw-r--r--bgpd/rfapi/rfapi_descriptor_rfp_utils.c3
-rw-r--r--bgpd/rfapi/rfapi_import.c2
-rw-r--r--bgpd/rfapi/rfapi_monitor.c2
-rw-r--r--bgpd/rfapi/rfapi_rib.c2
-rw-r--r--bgpd/rfapi/rfapi_vty.c3
-rw-r--r--bgpd/rfp-example/librfp/Makefile10
-rw-r--r--bgpd/rfp-example/librfp/Makefile.am40
-rw-r--r--bgpd/rfp-example/librfp/rfp_example.c4
-rw-r--r--bgpd/rfp-example/librfp/subdir.am17
-rw-r--r--bgpd/rfp-example/rfptest/Makefile10
-rw-r--r--bgpd/rfp-example/rfptest/Makefile.am52
-rw-r--r--bgpd/rfp-example/rfptest/rfptest.c3
-rw-r--r--bgpd/rfp-example/rfptest/subdir.am20
-rw-r--r--bgpd/subdir.am221
-rw-r--r--common.am61
-rwxr-xr-xconfigure.ac224
-rw-r--r--debianpkg/frr-doc.docs4
-rw-r--r--doc/.gitignore6
-rw-r--r--doc/developer/building-frr-for-centos6.rst15
-rw-r--r--doc/developer/building-frr-for-centos7.rst8
-rw-r--r--doc/developer/building-frr-for-fedora24.rst8
-rw-r--r--doc/developer/cli.rst2
-rw-r--r--doc/manpages/common-options.rst1
-rw-r--r--doc/manpages/conf.py1
-rw-r--r--doc/manpages/fabricd.rst38
-rw-r--r--doc/manpages/index.rst1
-rw-r--r--doc/manpages/subdir.am82
-rw-r--r--doc/mpls/.gitignore5
-rw-r--r--doc/user/fabricd.rst404
-rw-r--r--doc/user/index.rst1
-rw-r--r--doc/user/installation.rst4
-rw-r--r--doc/user/isisd.rst8
-rw-r--r--doc/user/setup.rst3
-rw-r--r--doc/user/subdir.am1
-rw-r--r--eigrpd/.gitignore16
-rw-r--r--eigrpd/eigrp_fsm.c2
-rw-r--r--eigrpd/subdir.am6
-rw-r--r--fpm/.gitignore15
-rw-r--r--fpm/subdir.am10
-rw-r--r--init/.gitignore6
-rw-r--r--isisd/.gitignore14
-rw-r--r--isisd/fabricd.c717
-rw-r--r--isisd/fabricd.conf.sample27
-rw-r--r--isisd/fabricd.h49
-rw-r--r--isisd/isis_adjacency.c21
-rw-r--r--isisd/isis_bpf.c4
-rw-r--r--isisd/isis_circuit.c163
-rw-r--r--isisd/isis_circuit.h24
-rw-r--r--isisd/isis_lsp.c170
-rw-r--r--isisd/isis_lsp.h4
-rw-r--r--isisd/isis_lsp_hash.c89
-rw-r--r--isisd/isis_main.c13
-rw-r--r--isisd/isis_mt.c2
-rw-r--r--isisd/isis_pdu.c181
-rw-r--r--isisd/isis_pdu.h6
-rw-r--r--isisd/isis_redist.c92
-rw-r--r--isisd/isis_spf.c473
-rw-r--r--isisd/isis_spf.h3
-rw-r--r--isisd/isis_spf_private.h362
-rw-r--r--isisd/isis_te.c44
-rw-r--r--isisd/isis_tlvs.c476
-rw-r--r--isisd/isis_tlvs.h60
-rw-r--r--isisd/isis_tx_queue.c182
-rw-r--r--isisd/isis_tx_queue.h (renamed from isisd/isis_lsp_hash.h)43
-rw-r--r--isisd/isis_vty.c2165
-rw-r--r--isisd/isis_vty_common.c960
-rw-r--r--isisd/isis_vty_common.h38
-rw-r--r--isisd/isis_vty_fabricd.c94
-rw-r--r--isisd/isis_vty_isisd.c858
-rw-r--r--isisd/isis_zebra.c10
-rw-r--r--isisd/isisd.c308
-rw-r--r--isisd/isisd.h25
-rw-r--r--isisd/subdir.am103
-rw-r--r--ldpd/.gitignore15
-rw-r--r--ldpd/lde.c4
-rw-r--r--ldpd/pfkey.c4
-rw-r--r--ldpd/subdir.am2
-rw-r--r--lib/.gitignore39
-rw-r--r--lib/command.c4
-rw-r--r--lib/command.h2
-rw-r--r--lib/command_lex.l5
-rw-r--r--lib/csv.c7
-rw-r--r--lib/defun_lex.l7
-rw-r--r--lib/ferr.c6
-rw-r--r--lib/frr_pthread.c13
-rw-r--r--lib/frr_pthread.h4
-rw-r--r--lib/frrstr.c4
-rw-r--r--lib/grammar_sandbox.c4
-rw-r--r--lib/grammar_sandbox_main.c4
-rw-r--r--lib/hook.c4
-rw-r--r--lib/if.c66
-rw-r--r--lib/imsg-buffer.c19
-rw-r--r--lib/imsg.c3
-rw-r--r--lib/lib_errors.c4
-rw-r--r--lib/libfrr.c29
-rw-r--r--lib/log.c4
-rw-r--r--lib/memory.c3
-rw-r--r--lib/memory_vty.c2
-rw-r--r--lib/openbsd-tree.c4
-rw-r--r--lib/ptm_lib.c5
-rw-r--r--lib/queue.h13
-rw-r--r--lib/route_types.txt2
-rw-r--r--lib/skiplist.c1
-rw-r--r--lib/stream.c8
-rw-r--r--lib/strlcat.c6
-rw-r--r--lib/strlcpy.c6
-rw-r--r--lib/subdir.am42
-rw-r--r--lib/vrf.c10
-rw-r--r--lib/vty.c2
-rw-r--r--lib/zebra.h2
-rw-r--r--m4/.gitignore12
-rw-r--r--m4/pkg.m42
-rw-r--r--nhrpd/.gitignore1
-rw-r--r--nhrpd/linux.c4
-rw-r--r--nhrpd/netlink_arp.c4
-rw-r--r--nhrpd/netlink_gre.c4
-rw-r--r--nhrpd/nhrp_event.c4
-rw-r--r--nhrpd/nhrp_interface.c4
-rw-r--r--nhrpd/nhrp_main.c4
-rw-r--r--nhrpd/nhrp_packet.c4
-rw-r--r--nhrpd/nhrp_peer.c4
-rw-r--r--nhrpd/nhrp_route.c4
-rw-r--r--nhrpd/nhrp_shortcut.c4
-rw-r--r--nhrpd/resolver.c4
-rw-r--r--nhrpd/subdir.am2
-rw-r--r--nhrpd/vici.c4
-rw-r--r--nhrpd/zbuf.c5
-rw-r--r--nhrpd/znl.c4
-rw-r--r--ospf6d/.gitignore16
-rw-r--r--ospf6d/ospf6_asbr.c3
-rw-r--r--ospf6d/ospf6_lsa.c27
-rw-r--r--ospf6d/ospf6_lsa.h23
-rw-r--r--ospf6d/ospf6_neighbor.c2
-rw-r--r--ospf6d/ospf6_route.c2
-rw-r--r--ospf6d/ospf6_top.c15
-rw-r--r--ospf6d/subdir.am18
-rw-r--r--ospfclient/.gitignore15
-rw-r--r--ospfclient/subdir.am1
-rw-r--r--ospfd/.gitignore15
-rw-r--r--ospfd/ospf_snmp.c1
-rw-r--r--ospfd/ospf_sr.c4
-rw-r--r--ospfd/subdir.am11
-rw-r--r--pbrd/.gitignore14
-rw-r--r--pbrd/subdir.am5
-rw-r--r--pimd/.gitignore14
-rw-r--r--pimd/mtracebis.c4
-rw-r--r--pimd/mtracebis_netlink.c4
-rw-r--r--pimd/mtracebis_routeget.c4
-rw-r--r--pimd/pim_cmd.c93
-rw-r--r--pimd/pim_igmp_mtrace.c2
-rw-r--r--pimd/pim_igmp_stats.c4
-rw-r--r--pimd/pim_vty.c2
-rw-r--r--pimd/subdir.am3
-rw-r--r--pkgsrc/.gitignore7
-rw-r--r--ports/.gitignore6
-rw-r--r--ports/files/.gitignore6
-rw-r--r--ports/pkg/.gitignore6
-rw-r--r--python/clidef.py2
-rw-r--r--qpb/.gitignore15
-rw-r--r--qpb/qpb_allocator.c4
-rw-r--r--qpb/subdir.am35
-rw-r--r--redhat/.gitignore8
-rw-r--r--redhat/README.rpm_build.md12
-rw-r--r--redhat/daemons2
-rwxr-xr-xredhat/frr.init2
-rw-r--r--redhat/frr.logrotate8
-rw-r--r--redhat/frr.spec.in19
-rw-r--r--ripd/.gitignore15
-rw-r--r--ripd/subdir.am9
-rw-r--r--ripngd/.gitignore15
-rw-r--r--ripngd/subdir.am8
-rw-r--r--sharpd/.gitignore15
-rw-r--r--sharpd/sharp_vty.c15
-rw-r--r--sharpd/subdir.am2
-rw-r--r--snapcraft/.gitignore1
-rw-r--r--solaris/.gitignore3
-rw-r--r--staticd/static_vty.c18
-rw-r--r--staticd/subdir.am2
-rw-r--r--tests/.gitignore18
-rw-r--r--tests/Makefile10
-rw-r--r--tests/Makefile.am235
-rw-r--r--tests/helpers/python/frrtest.py10
-rw-r--r--tests/isisd/test_fuzz_isis_tlv.c8
-rw-r--r--tests/isisd/test_fuzz_isis_tlv_tests.h.gzbin233035 -> 222030 bytes
-rw-r--r--tests/isisd/test_isis_vertex_queue.c44
-rw-r--r--tests/lib/cli/test_cli.c2
-rw-r--r--tests/lib/cli/test_cli.py1
-rw-r--r--tests/ospf6d/test_lsdb.c2
-rw-r--r--tests/subdir.am295
-rw-r--r--tests/test_lblmgr.c4
-rw-r--r--tools/.gitignore8
-rw-r--r--tools/etc/iproute2/rt_protos.d/frr.conf1
-rwxr-xr-xtools/frr1
-rw-r--r--tools/permutations.c4
-rw-r--r--tools/start-stop-daemon.c35
-rw-r--r--vtysh/.gitignore13
-rw-r--r--vtysh/Makefile10
-rw-r--r--vtysh/Makefile.am178
-rwxr-xr-xvtysh/extract.pl.in43
-rw-r--r--vtysh/subdir.am37
-rw-r--r--vtysh/vtysh.c59
-rw-r--r--vtysh/vtysh.h7
-rw-r--r--vtysh/vtysh_config.c3
-rw-r--r--vtysh/vtysh_main.c10
-rw-r--r--watchfrr/.gitignore15
-rw-r--r--watchfrr/subdir.am2
-rw-r--r--zebra/.gitignore12
-rw-r--r--zebra/if_ioctl_solaris.c6
-rw-r--r--zebra/if_netlink.c67
-rw-r--r--zebra/interface.c33
-rw-r--r--zebra/interface.h2
-rw-r--r--zebra/rt_netlink.c8
-rw-r--r--zebra/rt_netlink.h1
-rw-r--r--zebra/rtread_getmsg.c1
-rw-r--r--zebra/subdir.am20
-rw-r--r--zebra/zebra_fpm_protobuf.c1
-rw-r--r--zebra/zebra_rib.c65
-rw-r--r--zebra/zebra_vxlan.c3
245 files changed, 6961 insertions, 7477 deletions
diff --git a/.gitignore b/.gitignore
index c5fd0ced9..8c62f0553 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,87 +1,87 @@
-compile
-config.log
-config.h
-config.cache
-config.status
-config.guess
-config.sub
-ltmain.sh
-stamp-h
-stamp-h[0-9]*
+### autoconf/automake root stuff
+
+/compile
+/config.log
+/config.h
+/config.cache
+/config.status
+/config.guess
+/config.sub
+/ltmain.sh
+/stamp-h
+/stamp-h[0-9]*
*-stamp
-Makefile
-INSTALL
+/INSTALL
+/depcomp
+/missing
+/install-sh
+/mkinstalldirs
+/ylwrap
+/autom4te*.cache
+/configure.lineno
+/configure
+/config.h.in
+/confdefs.h
+/conftest
+/conftest.err
+/aclocal.m4
+/libtool
+
+/Makefile
+/Makefile.in
+
+### autoconf/automake subdir stuff
+
.deps
-depcomp
-missing
-install-sh
-mkinstalldirs
-ylwrap
-autom4te*.cache
-configure.lineno
-configure
-config.h.in
-confdefs.h
-conftest
-conftest.err
-aclocal.m4
-Makefile.in
-*.tar.gz
-*.tar.gz.asc
+.libs
+
+### build outputs
+
+*.o
+*.lo
+*.a
+*.la
+*.so
+*.loT
+*.pb.h
+*.pb-c.h
+*.pb-c.c
+*_clippy.c
+
+### dist
+
*.tar.?z
+*.tar.?z.asc
+*.tar.asc
+*.deb
+*.ddeb
+*.dsc
+*.changes
+
+### other garbage
+
.nfs*
-libtool
-.libs
.arch-inventory
.arch-ids
{arch}
build
+.cache
.msg
.rebase-*
*~
-*.o
-*.loT
-m4/*.m4
-!m4/ax_sys_weak_alias.m4
-!m4/ax_compare_version.m4
-!m4/ax_prog_perl_modules.m4
-!m4/pkg.m4
-debian/autoreconf.after
-debian/autoreconf.before
-debian/files
-debian/frr-dbg.debhelper.log
-debian/frr-dbg.substvars
-debian/frr-dbg/
-debian/frr-doc.debhelper.log
-debian/frr-doc.substvars
-debian/frr-doc/
-debian/frr.debhelper.log
-debian/frr.postinst.debhelper
-debian/frr.postrm.debhelper
-debian/frr.prerm.debhelper
-debian/frr.substvars
-debian/frr/
-debian/tmp/
-*.deb
-*.ddeb
-*.dsc
-*.changes
-*.pyc
+*.bak
*.swp
+*.pyc
+__pycache__
+*.patch
+*.diff
cscope.*
-*.pb.h
-*.pb-c.h
-*.pb-c.c
TAGS
tags
GTAGS
GSYMS
GRTAGS
GPATH
-*.la
-*.lo
compile_commands.json
.dirstamp
-
-# clippy generated source
-*_clippy.c
+refix
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 61867a860..000000000
--- a/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-Kunihiro Ishiguro <kunihiro@zebra.org>
-Toshiaki Takada <takada@zebra.org>
-Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
-Alex D. Zinin <azinin@hotmail.com>
-Gleb Natapov <gleb@nbase.co.il>
-Akihiro Mizutani <mizutani@dml.com>
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index ec7e6cdde..000000000
--- a/ChangeLog
+++ /dev/null
@@ -1,4 +0,0 @@
-ChangeLog information for FRRouting is for now recorded in source-code
-management system. Please see:
-
- http://www.frrouting.org/
diff --git a/Makefile.am b/Makefile.am
index b9003b835..fb052a8de 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,10 +1,19 @@
## Process this file with automake to produce Makefile.in.
AUTOMAKE_OPTIONS = subdir-objects 1.12
-include common.am
+ACLOCAL_AMFLAGS = -I m4
-AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \
- -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib
+AM_CFLAGS = \
+ $(SAN_FLAGS) \
+ $(WERROR) \
+ # end
+AM_CPPFLAGS = \
+ -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \
+ -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib
+AM_LDFLAGS = \
+ -export-dynamic \
+ $(SAN_FLAGS) \
+ # end
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
LIBCAP = @LIBCAP@
@@ -83,6 +92,7 @@ pkginclude_HEADERS =
nodist_pkginclude_HEADERS =
dist_examples_DATA =
man_MANS =
+vtysh_scan =
## libtool, the self-made GNU scourge
## ... this should fix relinking
@@ -106,6 +116,9 @@ include tools/subdir.am
include debianpkg/subdir.am
include solaris/subdir.am
+include bgpd/subdir.am
+include bgpd/rfp-example/librfp/subdir.am
+include bgpd/rfp-example/rfptest/subdir.am
include ripd/subdir.am
include ripngd/subdir.am
include ospfd/subdir.am
@@ -122,16 +135,8 @@ include pbrd/subdir.am
include staticd/subdir.am
include bfdd/subdir.am
-SUBDIRS = . @LIBRFP@ @RFPTEST@ \
- @BGPD@ \
- @VTYSH@ \
- tests
-
-DIST_SUBDIRS = . bgpd \
- vtysh tests \
- bgpd/rfp-example/librfp \
- bgpd/rfp-example/rfptest \
- # end
+include vtysh/subdir.am
+include tests/subdir.am
if PKGSRC
rcdir=@pkgsrcrcdir@
@@ -147,6 +152,7 @@ endif
EXTRA_DIST += \
aclocal.m4 \
+ README.md \
m4/README.txt \
\
python/clidef.py \
@@ -169,17 +175,37 @@ EXTRA_DIST += \
snapcraft/helpers \
snapcraft/snap \
\
- vtysh/Makefile.am \
- vtysh/Makefile.in \
- \
+ babeld/Makefile \
+ bgpd/Makefile \
+ bgpd/rfp-example/librfp/Makefile \
+ bgpd/rfp-example/rfptest/Makefile \
doc/Makefile \
doc/developer/Makefile \
doc/manpages/Makefile \
doc/user/Makefile \
+ eigrpd/Makefile \
+ fpm/Makefile \
+ isisd/Makefile \
+ ldpd/Makefile \
+ lib/Makefile \
+ nhrpd/Makefile \
+ ospf6d/Makefile \
+ ospfclient/Makefile \
+ ospfd/Makefile \
+ pbrd/Makefile \
+ pimd/Makefile \
+ ports/Makefile \
+ qpb/Makefile \
+ ripd/Makefile \
+ ripngd/Makefile \
+ staticd/Makefile \
+ tests/Makefile \
+ tools/Makefile \
+ vtysh/Makefile \
+ watchfrr/Makefile \
+ zebra/Makefile \
# end
-ACLOCAL_AMFLAGS = -I m4
-
noinst_HEADERS += defaults.h
indent:
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 8f9dd7a11..000000000
--- a/NEWS
+++ /dev/null
@@ -1,2574 +0,0 @@
-Note: this file lists major user-visible changes only.
-
-* Changes in Quagga 0.99.24
-
-User-visible changes:
-- [pimd] New daemon: pimd provides IPv4 PIM-SSM multicast routing.
-- [bgpd] New feature: "next-hop-self all" to override nexthop on iBGP route
- reflector setups.
-- [bgpd] route-maps have a new action "set ipv6 next-hop peer-address"
-- [bgpd] route-maps have a new action "set as-path prepend last-as"
-- [bgpd] Update validity checking (particularly MP-BGP / IPv6 routes) was
- touched up significantly. Please report possible bugs.
-- [ripd] New feature: RIP for IPv4 now supports equal-cost multipath (ECMP)
-- [zebra] Multicast RIB support has been extended. It still is IPv4 only.
-- [zebra] "no link-detect" is now printed in configurations since it won't
- be the default anymore soon. To retain current behaviour, re-save your
- configuration after updating to 0.99.24.
-
-Distributor-visible changes:
-- --enable-pimd is added to enable pimd. It is considered experimental, though
- unless the distribution target is embedded systems with little flash, there
- is no reason to not include it in packages.
-- --disable-ipv6 no longer exists as an option. It's 2015, your C library
- really needs to have IPv6 support by now.
-- --disable-netlink no longer exists as an option. It didn't work anyway.
-- --disable-solaris no longer exists as an option. It only controlled some
- init scripts.
-- --enable-isisd is now the default.
-- mrlg.cgi is no longer included (it was severely outdated). It can be found
- independently at http://mrlg.op-sec.us/
-- build on Linux with the musl C library should now work
-
-* Changes in Quagga 0.99.23
-
-Known issues:
-- [bgpd] setting an extcommunity in a route map on a route that already has
- an extcommunity attribute will cause bgpd to crash. This issue will be
- fixed in a followup minor release.
-
-User-visible changes:
-- [lib] Performance enhancements on hashes and timers.
-- [bgpd] New feature: iBGP TTL security.
-- [bgpd] New feature: relaxed bestpath criteria for multipath and improved
- display of multipath routes in "show ip bgp". Scripts parsing this output
- may need to be updated.
-- [bgpd] Multiprotocol peerings over IPv6 now try to find a more appropriate
- IPv4 nexthop by looking at the interface.
-- [ospf6d] A large amount of changes has been merged for ospf6d. Careful
- evaluation prior to deployment is recommended.
-- [zebra] Recursive route support has been overhauled. Scripts parsing
- "show ip route" output may need adaptation.
-- [zebra] IPv6 address management has been improved regarding tentative
- addresses. This is visible in that a freshly configured address will not
- immediately be marked as usable.
-- [*] a lot of bugs have been fixed, please refer to the git log
-
-* Changes in Quagga 0.99.22
-
-- [bgpd] The semantics of default-originate route-map have changed.
- The route-map is now used to advertise the default route conditionally.
- The old behaviour which allowed to set attributes on the originated
- default route is no longer supported.
-- [bgpd] There is now a replace-as option to neighbor ... local-as ...
- no-prepend. For details, refer to the user documentation.
-- [zebra] An FPM interface has been added. This provides an alternate
- interface to routing information and is geared at OpenFlow & co.
-- [snmp] AgentX is now supported; the old smux backend is considered
- deprecated. ospf6d has also had OSPFV3-MIB added.
-- [*] several issues with configuration save/load/apply have been fixed,
- in particular on ospf "max-metric router-lsa administrative" and
- "distribute-list", bgpd "no neighbor activate", isisd "metric-style",
-- [*] a lot of bugs have been fixed, please refer to the git log
-
-* Changes in Quagga 0.99.21
-
-- [bgpd] BGP multipath support has been merged
-- [bgpd] SAFI (Multicast topology) support has been extended to propagate
- the topology to zebra.
-- [bgpd] AS path limit functionality has been removed
-- [babeld] a new routing daemon implementing the BABEL ad-hoc mesh routing
- protocol has been merged.
-- [isisd] a major overhaul has been picked up. Please note that isisd is
- STILL NOT SUITABLE FOR PRODUCTION USE.
-- [*] a lot of bugs have been fixed, please refer to the git log
-
-* Changes in Quagga 0.99.10
-
-- [bgpd] 4-byte AS support added
-- [bgpd] MRT format changes to version 2. Those relying on
- bgpd MRT table dumps may need to update their tools.
-- [bgpd] Added new route-map set statement: "as-path exclude"
-- Zebra RIB updates queue has evolved into a multi-level
- structure to address RIB consistency issues.
-
-* Changes in Quagga 0.99.2
-
-- [bgpd] Work queues added to bgpd to split up update processing,
- particularly beneficial when a peer session goes down. AS_PATH
- parsing rewritten to be clearer, more robust and ready for 4-byte.
-
-- [ripd] Simple authentication is no longer the default authentication
- mode for ripd. The default is now no-authentication. Any setups which
- used simple authentication will probably need to update their
- configuration manually.
-
-- [ospfd] 1s dead-interval with sub-second Hellos feature added.
- SPF timers now specified in milliseconds, and with adaptive
- hold-time support. RFC3137 Stub-router support added. Default ABR
- type is now 'cisco'.
-
-- Solaris least privileges support added.
-
-* Changes in Quagga 0.99.1
-
-- Zserv is now buffered via threads and non-blocking in most cases for both
- clients and zebra, which should improve responsiveness of daemons when
- they must send many messages to zebra.
-
-- 'show thread cpu' now displays both cpu+system and wall-clock time,
- where getrusage() is available.
-
-- Background threads added and workqueue API added, with a
- 'show work-queues' command. Thread scheduling improved slightly.
-
-- Zebra now has a work-queue for RIB processing. See 'show work-queues' in
- the zebra daemon vty.
-
-- Support for interface renaming on Linux netlink systems.
-
-- GNU Zebra bgpd merges, including BGP Graceful-restart and "match ip
- route-source" command.
-
-- Automatic logging of backtraces should daemons crash to assist in
- diagnosis. See the documentation for more information on configuring
- logging correctly, and set --enable-gcc-rdynamic if compiling with gcc.
-
-* Changes in Quagga 0.98.0
-
-- Logging facilities upgraded. One can now specify a severity level
- for each logging destination. And a new "show logging" command gives
- thorough information on the current logging system configuration.
-
-- Watchquagga daemon added. This is not well tested yet. Please try
- monitor mode first before enabling restart features. It is important
- to make sure that the various timers are configured with appropriate
- values for your site.
-
-- BGP route-server support added. See the texinfo documentation.
-
-- OSPF API initialisation is disabled by default even if compiled in. You
- can enable it with -a/--apiserver command line switch.
-
-- "write-config integrated" vtysh command replaced with "service
- integrated-vtysh-config" command.
-
-- Router id is now handled by zebra daemon and all daemons receive changes
- from it. Router id can be overriden in daemons' configurations of course.
- To fix common router id in zebra daemon you can either install non-127
- address on loopback or use "router-id x.x.x.x" command.
-
-- "secondary" keyword is removed from ip address configuration. All
- supported OS'es have their own vision what's secondary address and
- how to handle it.
-
-- Zebra no longer enables forwarding by default. If you rely on zebra to
- enable forwarding make sure to add '<ip|ip6> forwarding' statements
- to your zebra configuration file.
-
-- All libraries are built and used shared, on platforms where libtool
- supports shared libraries.
-
-- Router advertisement syntax is changed. In usual cases (if you didn't do
- any fancy stuff) it's enough to change lines in configuration from:
- "ipv6 nd prefix-advertisement X:X:X:X::/X 2592000 604800 autoconfig on-link"
- to:
- "ipv6 nd prefix X:X:X:X::/X"
-
- All router advertisement options are documented in texi documentation.
-
-- --enable-nssa configure switch is removed. NSSA support is stable enough.
-
-- Daemons don't look at current directory for config file any more.
-
-* Changes in Quagga 0.96.5
-
-- include files are installed in $(prefix)/include/quagga. Programs
- building against these includes should -I$(prefix)/include and e.g.
- #include <quagga/routemap.h>
-
-- New option --enable-exampledir puts example files in a separate
- directory from $(sysconfdir), easing NetBSD pkgsrc hierarchy rules
- compliance.
-
-- New configure options --enable-configfile-mask and
- --enable-logfile-mask to set umask values for config and log
- values. Masks default to 0600, matching previous behavior.
-
-- Import current CVS isisd from SourceForge, then merge it with
- the Quagga's Framework.
-
-* Changes in Quagga 0.96.4
-
-- Further fixes to ospfd, some relating to the PtP revert. Interface
-lookups should be a lot more robust now.
-
-- Fix for a remote triggerable crash in vty layer.
-
-- Improvements to ripd, and addition of split horizon support.
-
-- Improved bgpd table support, now dumps at time of day intervals rather
-than time from startup intervals. Much improved support for IPv6 table
-dumps. show commands for views improved.
-
-* Changes in Quagga 0.96.3
-
-- revert the 'generic PtP' patch. Means Quagga will no longer work with
-FreeSWAN, however, on the plus side this gets rid of a lot of niggly bugs
-which the PtP patch introduced.
-
-* Changes in Quagga 0.96.2
-
-- Fix crash in ospfd
-
-* Changes in Quagga 0.96.1
-
-- Iron out problem with the privileges definitions
-
-* Changes in Quagga 0.96
-
-- Privilege support, daemons now run with the minimal privileges needed, see
- the documentation for details.
-
-- NSSA ABR support in ospfd.
-
-- OSPF-API support merged in.
-
-- 6WIND patch merged in.
-
-* Changes in zebra-0.93
-
-* Changes in bgpd
-
-** Configuration is changed to new format.
-
-* Changes in ospfd
-
-** Crush bugs which reported on Zebra ML is fixed.
-
-** Opaque LSA and TE LSA support is added by KDD R&D Laboratories,
- Inc.
-
-* Chages in ospf6d
-
-** Many bugs are fixed.
-
-* Changes in zebra-0.92a
-
-* Changes in bgpd
-
-** Fix "^$" community list bug.
-
-** Below command's Address Family specific configurations are added
-
- nexthop-self
- route-reflector-client
- route-server-client
- soft-reconfiguration inbound
-
-* Changes in zebra
-
-** Treat kernel type routes as EGP routes.
-
-* Changes in zebra-0.92
-
-** Overall security is improved. Default umask is 0077.
-
-* Changes in ripd
-
-** If output interface is in simple password authentication mode,
-substruct one from rtemax.
-
-* Changes in bgpd
-
-** IPv4 multicast and IPv6 unicast configuration is changed to so
-called new config. All of AFI and SAFI specific configuration is
-moved to "address-family" node. When you have many IPv6 only
-configuration, you will see many "no neighbor X:X::X:X activate" line
-in your configuration to disable IPv4 unicast NLRI exchange. In that
-case please use "no bgp default ipv4-unicast" command to suppress the
-output. Until zebra-0.93, old config is still left for compatibility.
-
-Old config
-==========
-router bgp 7675
- bgp router-id 10.0.0.1
- redistribute connected
- network 192.168.0.0/24
- neighbor 10.0.0.2 remote-as 7675
- ipv6 bgp network 3ffe:506::/33
- ipv6 bgp network 3ffe:1800:e800::/40
- ipv6 bgp aggregate-address 3ffe:506::/32
- ipv6 bgp redistribute connected
- ipv6 bgp neighbor 3ffe:506:1000::2 remote-as 1
-
-New config
-==========
-router bgp 7675
- bgp router-id 10.0.0.1
- network 192.168.0.0/24
- redistribute connected
- neighbor 10.0.0.2 remote-as 7675
- neighbor 3ffe:506:1000::2 remote-as 1
- no neighbor 3ffe:506:1000::2 activate
-!
- address-family ipv6
- network 3ffe:506::/33
- network 3ffe:1800:e800::/40
- aggregate-address 3ffe:506::/32
- redistribute connected
- neighbor 3ffe:506:1000::2 activate
- exit-address-family
-
-* Changes in ospfd
-
-** Internal interface treatment is changed. Now ospfd can handle
-multiple IP address for an interface.
-
-** Redistribution of loopback interface's address works fine.
-
-* Changes in zebra-0.91
-
-** --enable-oldrib configure option is removed.
-
-** HAVE_IF_PSEUDO part is removed. Same feature is now supported by
-default.
-
-* Changes in ripd
-
-** When redistributed route is withdrawn, perform poisoned reverse.
-
-* Changes in zebra
-
-** When interface's address is removed, kernel route pointing out to
-the address is removed.
-
-** IPv6 RIB is now based upon new RIB code.
-
-** zebra can handle same connected route to one interface.
-
-** New command for interface address. Currently this commands are
-only supported on GNU/Linux with netlink interface.
-
-"ip address A.B.C.D secondary"
-"ip address A.B.C.D label LABEL"
-
-* Changes in bgpd
-
-** BGP flap dampening bugs are fixed.
-
-** BGP non-blocking TCP connection bug is fixed.
-
-** "show ip bgp summary" shows AS path and community entry number.
-
-** New commands have been added.
- "show ip bgp cidr-only"
- "show ip bgp ipv4 (unicast|multicast) cidr-only"
- "show ip bgp A.B.C.D/M longer-prefixes"
- "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M longer-prefixes"
- "show ipv6 bgp X:X::X:X/M longer-prefixes"
- "show ipv6 mbgp X:X::X:X/M longer-prefixes"
-
-** IPv6 IBGP nexthop change is monitored.
-
-** Unknown transitive attribute is passed with partial flag bit on.
-
-* Changes in ospfd
-
-** Fix bug of LSA MaxAge flood.
-
-** Fix bug of NSSA codes.
-
-* Changes in zebra-0.90
-
-** From this beta release, --enable-unixdomain and --enable-newrib
-becomes default. So both options are removed from configure.in. To
-revert old behavior please specify below option.
-
---enable-tcp-zebra # TCP/IP socket is used for protocol daemon and zebra.
---enable-oldrib # Turn on old RIB implementation.
-
-Old RIB implementation will be removed in zebra-0.91.
-
-** From this beta release --enable-multipath is supported. This
-option is only effective on GNU/Linux kernel with
-CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_ROUTE_MULTIPATH is set.
-
---enable-multipath=ARG # ARG must be digit. When ARG is 0 unlimit multipath number.
-
-** From this release we do not include guile files.
-
-* Changes in lib
-
-** newlist.[ch] is merged with linklist.[ch].
-
-** Now Zebra works on MacOS X public beta.
-
-** Access-list can have remark. "access-list WORD remark LINE" define
-remark for specified access-list.
-
-** Key of key-chain is sorted by it's idetifier value.
-
-** prefix-list rule is slightly changed. The rule of "len <= ge-value
-<= le-value" is changed to "len < ge-value <= le-value".
-
-** According to above prefix-list rule change, add automatic
-conversion function of an old rule. ex.) 10.0.0.0/8 ge 8 -> 10.0.0.0/8
-le 32
-
-** SMUX can handle SNMP trap.
-
-** In our event library, event thread is executed before any other
-thread like timer, read and write event.
-
-** Robust method for writing configuration file and recover from
-backing up config file.
-
-** Display "end" at the end of configuration.
-
-** Fix memory leak in vtysh_read().
-
-** Fix memroy leak about access-list and prefix-list name.
-
-* Changes in zebra
-
-** UNIX domain socket server of zebra protocol is added.
-
-** Fix PointoPoint interface network bug. The destination network
-should be installed into routing table instead of local network.
-
-** Metric value is reflected to kernel routing table.
-
-** "show ip route" display uptime of RIP,OSPF,BGP routes.
-
-** New RIB implementation is added.
-
-Now we have enhanced RIB (routing information base) implementation in
-zebra. New RIB has many new features and fixed some bugs which exist
-in old RIB code.
-
-*** Static route with distance value
-
- Static route can be specified with administrative distance. The
- distance value 255 means it is not installed into the kernel.
- Default value of distance for static route is 1.
-
- ip route A.B.C.D/M A.B.C.D <1-255>
- ip route A.B.C.D/M IFNAME <1-255>
-
- If the least distance value's route's nexthop are unreachable,
- select the least distance value route which has reachable nexthop is
- selected.
-
- ip route 0.0.0.0/0 10.0.0.1
- ip route 0.0.0.0/0 11.0.0.1 2
-
- In this case, when 10.0.0.1 is unreachable and 11.0.0.1 is
- reachable. The route with nexthop 11.0.0.1 will be installed into
- forwarding table.
-
- zebra> show ip route
- S>* 0.0.0.0/0 [2/0] via 11.0.0.1
- S 0.0.0.0/0 [1/0] via 10.0.0.1 inactive
-
- If the nexthop is unreachable "inactive" is displayed. You can
- specify any string to IFNAME. There is no need of the interface is
- there when you configure the route.
-
- ip route 1.1.1.1/32 ppp0
-
- When ppp0 comes up, the route is installed properly.
-
-*** Multiple nexthop routes for one prefix
-
- Multiple nexthop routes can be specified for one prefix. Even the
- kernel support only one nexthop for one prefix user can configure
- multiple nexthop.
-
- When you configure routes like below, prefix 10.0.0.1 has three
- nexthop.
-
- ip route 10.0.0.1/32 10.0.0.2
- ip route 10.0.0.1/32 10.0.0.3
- ip route 10.0.0.1/32 eth0
-
- If there is no route to 10.0.0.2 and 10.0.0.3. And interface eth0
- is reachable, then the last route is installed into the kernel.
-
- zebra> show ip route
- S> 10.0.0.1/32 [1/0] via 10.0.0.2 inactive
- via 10.0.0.3 inactive
- * is directly connected, eth0
-
- '*' means this nexthop is installed into the kernel.
-
-*** Multipath (more than one nexthop for one prefix) can be installed into the kernel.
-
- When the kernel support multipath, zebra can install multipath
- routes into the kernel. Before doing that please make it sure that
- setting --enable-multipath=ARG to configure script. ARG must be digit
- value. When specify 0 to ARG, there is no limitation of the number
- of the multipath. Currently only GNU/Linux with netlink interface is
- supported.
-
- ip route 10.0.0.1/32 10.0.0.2
- ip route 10.0.0.1/32 10.0.0.3
- ip route 10.0.0.1/32 eth0
-
- zebra> show ip route
- S>* 10.0.0.1/32 [1/0] via 10.0.0.2
- * via 10.0.0.3
- is directly connected, eth0
-
-*** Kernel message delete installed route.
-
- After zebra install static or dynamic route into the kernel.
-
- R>* 0.0.0.0/0 [120/3] via 10.0.0.1
-
- If you delete this route outside zebra, old zebra does not reinstall
- route again. Now the route is re-processed and properly reinstall the
- static or dynamic route into the kernel.
-
-** GNU/Linux netlink socket handling is improved to fix race condition
-between kernel message and user command responce.
-
-* Changes in bgpd
-
-** Add show neighbor's routes command.
-
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes"
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) routes"
- "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) routes"
- "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) routes"
-
-** BGP passive peer support problem is fixed.
-
-** Redistributed IGP nexthop is passed to BGP nexthop.
-
-** On multiaccess media, if the nexthop is reachable nexthop is passed
-as it is.
-
-** Remove zebra-0.88 compatibility commands.
-
- "match ip prefix-list WORD"
- "match ipv6 prefix-list WORD"
-
- Instead of above please use below commands.
-
- "match ip address prefix-list WORD"
- "match ipv6 address prefix-list WORD"
-
-** Fix bug of holdtimer is not reset when bgp cleared.
-
-** "show ip bgp summary" display peer establish/drop count.
-
-** Change "match ip next-hop" argument from IP address to access-list
-name.
-
-** When "bgp enforce-first-as" is enabled, check EBGP peer's update
-has it's AS number in the first AS number in AS sequence.
-
-** New route-map command "set community-delete COMMUNITY-LIST" is
-added. Community matched the CoMMUNITY-LIST is removed from the
-community.
-
-** BGP-MIB implementation is finished.
-
-** When BGP connection comes from unconfigured IP address, close
-socket immediately.
-
-** Do not compare router ID when the routes comes from EBGP peer.
-When originator ID is same, take shorter cluster-list route. If
-cluster-list is same take smaller IP address neighbor's route.
-
-** Add "bgp bestpath as-path ignore" command. When this option is
-set, do not concider AS path length when route selection.
-
-** Add "bgp bestpath compare-routerid". When this option is set,
-compare router ID when the routes comes from EBGP peer.
-
-** Add "bgp deterministic-med" process.
-
-** BGP flap dampening feature is added.
-
-** When IBGP nexthop is changed, it is reflected to RIB.
-
-** Change "neighbor route-refresh" command to "neighbor capability
-route-refresh".
-
-* Changes in ripd
-
-** Change "match ip next-hop" argument from IP address to access-list
-name.
-
-** "no ip rip (send|receive)" command accept version number argument.
-
-** Memory leak related classfull network generation is fixed.
-
-** When a route is in garbage collection process (invalid with metric
-16) and a router receives the same route with valid metric then route
-was not installed into zebra rib, but only into ripd rib. Moreover ,
-it will never get into zebra rib, because ripd wrongly assumes it's
-already there.
-
-* Change in ospfd
-
-** Fix bug of refreshing default route.
-
-** --enable-nssa turn on undergoing NSSA feature.
-
-** Fix bug of Hello packet's option is not properly set when interface
-comes up.
-
-** Reduce unconditional logging.
-
-** Add nexthop to OSPF path only when it is not there.
-
-** When there is no DR on network (suppose you have only one router
-with interface priority 0). It's router LSA does not contain the link
-information about this network.
-
-** When you change a priority of interface from/to 0
-ISM_NeighborChange event should be scheduled in order to elect new
-DR/BDR on the network.
-
-** When we add some LSA into retransmit list we need to check whether
-the present old LSA in retransmit list is not more recent than the new
-one.
-
-** In states Loading and Full the slave must resend its last Database
-Description packet in response to duplicate Database Description
-packets received from the master. For this reason the slave must wait
-RouterDeadInterval seconds before freeing the last Database
-Description packet. Reception of a Database Description packet from
-the master after this interval will generate a SeqNumberMismatch
-neighbor event. RFC2328 Section 10.8
-
-** Virtual link can not configured in stub area.
-
-** Clear a ls_upd_queue queue of the interface when interface goes
-down.
-
-** "no router ospf" unregister redistribution requests from zebra.
-
-** New command for virtual-link configuration is added.
-
- "area A.B.C.D virtual-link A.B.C.D"
- "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535>"
- "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535> authentication-key AUTH_KEY"
- "area A.B.C.D virtual-link A.B.C.D authentication-key AUTH_KEY"
- "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535> message-digest-key <1-255> md5 KEY"
- "area A.B.C.D virtual-link A.B.C.D message-digest-key <1-255> md5 KEY"
-
-** Clear cryptographic sequence number when neighbor status is changed
-to NSM down.
-
-** Make Summary LSA's origination and refreshment as same as other
-type of LSA.
-
-** New OSPF pakcet read method. Now maximum packet length may be 65535
-bytes (maximum IP packet length).
-
-** Checking the age of the found LSA and if the LSA is MAXAGE we
-should call refresh instead of originate.
-
-** Install multipath information to zebra.
-
-** Fix socket descriptor leak when system call failed.
-
-* Changes in ospf6d
-
-** Whole functionality has been rewritten as new code. new command
-"show ipv6 ospf6 spf node", "show ipv6 ospf6 spf tree", "show ipv6
-ospf6 spf table" has been added.
-
-** Change to do not send garbage route whose nexthop is not linklocal
-address.
-
-** "redistribute ospf6" was generated in "router ospf6" in config
-file. It is fixed.
-
-** LSDB sync bug is fixed.
-
-** Fix bug of using unavailable route.
-
-* Changes in vtysh
-
-** route-map and access-list configuration is merged into one
-configuration.
-
-** /usr/local/etc/Zebra.conf is integrated configuration file. "write
-memory" in vtysh will write whole configuration to this file.
-
-** When -b option is specified to vtysh, vtysh read
-/usr/local/etc/Zebra.conf file then pass the confuguration to proper
-protocol daemon. So make all protocol daemon's configuration file
-empty then invoke all daemon. After that vtysh -b will setup saved
-configuration.
-
-zebrastart.sh
-=============
-/usr/local/sbin/zebra -d
-/usr/local/sbin/ripd -d
-/usr/local/sbin/ospfd -d
-/usr/local/sbin/bgpd -d
-/usr/local/bin/vtysh -b
-
-* Changes in zebra-0.89
-
-* Changes in lib
-
-** distribute-list can set all interface's access-list and prefix-list
-configuration.
-
-* Changes in ripd
-
-** "show ip protocols" display proper distribute-list settings and
-distance settings.
-
-** When metric infinity route received withdraw the route from kernel
-immediately it used to be wait garbage collection.
-
-** key-chain can be used for simple password authentication.
-
-** RIPv2 MIB getnext interface bug is fixed.
-
-* Changes in vtysh
-
-** --with-libpam enable PAM authentication for vtysh.
-
-** Now vtysh read vtysh.conf. This file should be
-${SYSCONFDIR}/etc/vtysh.conf for security reason. Usually it is
-/usr/local/etc/vtysh.conf.
-
-** "username WORD nopassword" command is added to vtysh.
-
-* Chagees in ospfd
-
-** NBMA interface support is added.
-
-** OSPF area is sorted by area ID.
-
-** New implementation of OSPF refreesh.
-
-** OSPF-MIB read function is partly added.
-
-* Changes in bgpd
-
-** When the peering is done by ebgp-multihop, nexthop is looked up
-like IBGP routes.
-
-** "show ip mbgp" commands are changed to "show ip bgp ipv4
-multicast".
-
-** New terminal commands are added.
- "show ip bgp ipv4 (unicast|multicast) filter-list WORD"
- "show ip bgp ipv4 (unicast|multicast) community"
- "show ip bgp ipv4 (unicast|multicast) community-list WORD"
- "show ip bgp ipv4 (unicast|multicast) community-list WORD exact-match"
-
-** MBGP soft-reconfiguration command is added.
- "clear ip bgp x.x.x.x ipv4 (unicast|multicast) in"
- "clear ip bgp x.x.x.x ipv4 (unicast|multicast) out"
- "clear ip bgp x.x.x.x ipv4 (unicast|multicast) soft"
- "clear ip bgp <1-65535> ipv4 (unicast|multicast) in"
- "clear ip bgp <1-65535> ipv4 (unicast|multicast) out"
- "clear ip bgp <1-65535> ipv4 (unicast|multicast) soft"
- "clear ip bgp * ipv4 (unicast|multicast) in"
- "clear ip bgp * ipv4 (unicast|multicast) out"
- "clear ip bgp * ipv4 (unicast|multicast) soft"
-
-** MED related commands are added.
- "bgp deterministic-med"
- "bgp bestpath med confed"
- "bgp bestpath med missing-as-worst"
-
-** "bgp default local-preference" command is added.
-
-** BGP confederation peer's routes are passed to zebra like IBGP route.
-
-** Community match command is added.
- "show ip bgp community <val>"
- "show ip bgp community <val> exact-match"
-
-** EBGP multihop route treatment bug is fixed. Now nexthop is
-resolved by IGP routes.
-
-** Some commands are added to show routes by filter-list and community
-value.
- "show ip bgp ipv4 (unicast|multicast) filter-list WORD"
- "show ip bgp ipv4 (unicast|multicast) community"
- "show ip bgp ipv4 (unicast|multicast) community-list WORD"
- "show ip bgp ipv4 (unicast|multicast) community-list WORD exact-match"
-
-* Changes in zebra
-
-** zebra read interface's address information using getifaddrs() when
-it is available.
-
-** Reflect IPv6 interface's address change to protocol daemons.
-
-* Changes in zebra-0.88
-
-* Changes in lib
-
-** "exact-match" option is added to "access-list" and "ipv6
-access-list" command. If this option is specified, the prefix and
-prefix length is compared as exact match mode.
-
-* Changes in zebra
-
-** New Zebra message ZEBRA_REDISTRIBUTE_DEFAULT_ADD and
-ZEBRA_REDISTRIBUTE_DEFAULT_DELTE are added.
-
-** Default administrative distance value is changed.
-
- Old New
-------------------------------------------
-system 10 0
-kernel 20 0
-connected 30 0
-static 40 1
-rip 50 120
-ripng 50 120
-ospf 60 110
-ospf6 49 110
-bgp 70 200(iBGP) 20(eBGP)
-------------------------------------------
-
-** Distance value can be passed from protocol daemon to zebra.
-
-** "show ip route" shows [metric/distance] value pair.
-
-** Zebra Protocol is changed to support multi-path route and distance
-value.
-
-* Changes in ospfd
-
-** "default-information originate [always]" command is added.
-
-** "default-metric <0-16777214>" command is added.
-
-** "show ip ospf database" command is integrated. LS-ID and AdvRouter can
- be specifed. The commands are
-
- show ip ospf database TYPE LS-ID
- show ip ospf database TYPE LS-ID ADV-ROUTER
- show ip ospf database TYPE LS-ID self-originate
- show ip ospf database TYPE self-originate
-
-** route-map support for `redistribute' command are added.
- Supported `match' statements are
-
- match interface
- match ip address
- match next-hop
-
- Supported `set' statements are
-
- set metric
- set metric-type
-
-** Pass OSPF metric value to zebra daemon.
-
-* Changes in ripd
-
-** When specified route-map does not exist, it means all deny.
-
-** "default-metric <1-16>" command is added.
-
-** "offset-list ACCESS-LIST-NAME <0-16>" and "offset-list
-ACCESS-LIST-NAME <0-16> IFNAME" commands are added.
-
-** "redistribute ROUTE-TYPE metric <0-16>" command is added.
-
-** "default-information originate" command is added.
-
-** "ip split-horizon" and "no ip split-horizon" is added to interface
-configuration.
-
-** "no router rip" command is added.
-
-** "ip rip authentication mode (md5|text)" is added to interface
-configuration.
-
-** "ip rip authentication key-chain KEY-CHAIN" is added to interface
-configuration.
-
-** Pass RIP metric value to zebra daemon.
-
-** Distance manipulation functions are added.
-
-* Changes in bgpd
-
-** Fix bug of next hop treatment for MPLS-VPN route exchange.
-
-** BGP peer MIB is updated.
-
-** Aggregated route has origin IGP, atomic-aggregate and proper
-aggregator attribute.
-
-** Suppressed route now installed into BGP table. It is only
-suppressed from announcement.
-
-** BGP router-id is properly set after "no router bgp ASN" and "router
-bgp ASN".
-
-** Add check for nexthop is accessible or not for IBGP routes.
-
-** Add cehck for nexthop is on connected or not for EBGP routes.
-
-** "dump bgp route" command is changed to "dump bgp route-mrt" for
-generating MRT compatible dump output.
-
-** Soft reconfiguration inbound and outbound is supported.
-
-** Route refresh feature is supported.
-
-* Changes in vtysh
-
-** VTY shell is now included into the distribution.
-
-* Changes in zebra-0.87
-
-* Changes in lib
-
-** "show startup-config" command is added.
-
-** "show history" command is added.
-
-** Memory statistics command is changed. New command
-
- show memory all
- show memory lib
- show memory rip
- show memory ospf
- show memory bgp
-
-are added.
-
-** Filters can be removed only specify it's name. New command
-
- no access-list NAME
- no ip community-list NAME
- no ip as-path access-list NAME
- no route-map NAME
-
-are added.
-
-** At any node, user can view/save user configuration.
-
- write terminal
- write file
- wirte memory
-
-are added to every node in default.
-
-** LCD completion is added. For example both "ip" and "ipv6" command
-are exist, "i" then press TAB will be expanded to "ip".
-
-* Changes in bgpd
-
-** "show ip bgp" family shows total number of prefixes.
-
-** "no bgp default ipv4-unicast" command is added.
-
-** Extended Communities support is added.
-
-** "no neighbor PEER send-community extended" command is added.
-
-** MPLS-VPN PE-RR support is added.
-
- New address family vpnv4 unicast is introduced.
-
- !
- address-family vpnv4 unicast
- neighobr PEER activate
- network A.B.C.D rd RD tag TAG
- exit-address-family
- !
-
- To make it route-reflector, please configure it under normal router
-bgp ASN.
-
- !
- router bgp 7675
- no bgp default ipv4-unicast
- bgp router-id 10.0.0.100
- bgp cluster-id 10.0.0.100
- neighbor 10.0.0.1 remote-as 65535
- neighbor 10.0.0.1 route-reflector-client
- neighbor 10.0.0.2 remote-as 65535
- neighbor 10.0.0.2 route-reflector-client
- neighbor 10.0.0.3 remote-as 65535
- neighbor 10.0.0.3 route-reflector-client
- !
- address-family vpnv4 unicast
- neighbor 10.0.0.1 activate
- neighbor 10.0.0.2 activate
- neighbor 10.0.0.3 activate
- exit-address-family
- !
-
-* Changes in ospfd
-
-** Many many bugs are fixed.
-
-* Changes in ripd
-
-** Better interface up/down event handle.
-
-* Changes in zebra
-
-** Better interface up/down event handle.
-
-* Changes in zebra-0.86
-
-* Changes in lib
-
-** Fix bug of exec-timeout command which may cause crush.
-
-** Multiple same policy for "access-list", "ip prefix-list, "as-path
-access-list", "ip community-list" is not duplicated.
-
-** It used to be "ip prefix-list A.B.C.D/M" match routes which mask >=
-M. Now default behavior is exact match so it only match routes which
-mask == M.
-
-* Changes in bgpd
-
-** "match ip address prefix-list" is added to route-map.
-
-** A route without local preference is evaluated as 100 local preference.
-
-** Select smaller router-id route when other values are same.
-
-** Compare MED only both routes comes from same neighboring AS.
-
-** "bgp always-compare-med" command is added.
-
-** Now MED value is passed to IBGP peer.
-
-** When neighbor's filter is configured with non-existent access-list,
-as-path access-list, ip prefix-list, route-map. The behavior is
-changed from all permit to all deny.
-
-* Changes in ospfd
-
-** Fix bug of external route tag byte order.
-
-** OSPF Neighbor deletion bug which cause crush is fixed.
-
-** Some route calculation bug are fixed.
-
-** Add sanity check with router routing table.
-
-** Fix bug of memory leak about linklist.
-
-** Fix bug of 1-WayReceived in NSM.
-
-** Take care of BIGENDIAN architecture.
-
-** Fix bug of NSM state flapping between ExStart and Exchange.
-
-** Fix bug of Network-LSA originated in stub network.
-
-** Fix bug of MS flag unset.
-
-** Add to schedule router_lsa origination when the interface cost
-changes.
-
-** Increment LS age by configured interface transmit_delay.
-
-** distribute-list is reimplemented.
-
-** Fix bug of refresh never occurs.
-
-** Fix bug of summary-LSAs reorigination. Correctly copy
-OSPF_LSA_APPROVED flag to new LSA. when summary-LSA is reoriginatd.
-
-** Fix bug of re-origination when a neighbor disappears.
-
-** Fix bug of segmentation fault with DD retransmission.
-
-** Fix network-LSA re-origination problem.
-
-** Fix problem of remaining withdrawn routes on zebra.
-
-* Changes in ripd
-
-** Do not leave from multicast group when interface goes down bug is
-fixed.
-
-* Changes in zebra
-
-** Remove client structure when client dies.
-
-** Take care static route when interface goes up/down.
-
-* Changes in zebra-0.85
-
-* Changes in bgpd
-
-** "transparent-nexthop" and "transparenet-as" commands are added.
-
-** Route reflector's originator-id bug is fixed.
-
-* Changes in ospfd
-
-** Fix bug of OSPF LSA memory leak.
-
-** Fix bug of OSPF external route memory leak.
-
-** AS-external-LSA origination bug was fixed.
-
-** LS request treatment is completely rewritten. Now performance is
-drastically improved.
-
-* Changes in ripd
-
-** RIPv1 update is done by class-full manner.
-
-* Changes in zebra-0.84b
-
-* Changes in lib
-
-** Fix bug of inet_pton return value handling
-
-* Changes in bgpd
-
-** Fix bug of BGP-4+ link-local address nexthop check for IBGP peer.
-
-** Don't allocate whole buffer for displaying "show ip bgp". Now it
-consume only one screen size memory.
-
-* Changes in ripd
-
-** Fix debug output string.
-
-** Add RIP peer handling. RIP peer are shown by "show ip protocols".
-
-* Changes in zebra-0.84a
-
-* Changes in bgpd
-
-** Fix serious bug of BGP-4+ peering under IPv6 link-local address.
- Due to the bug BGP-4+ peering may not be established.
-
-* Changes in zebra-0.84
-
-* Changes in lib
-
-** IPv6 address and prefix parser is added to VTY by Toshiaki Takada
- <takada@zebra.org>. DEFUN string is "X:X::X:X" for IPv6 address,
- "X:X::X:X/M" for IPv6 prefix. You can use it like this.
-
- DEFUN (func, cmd, "neighbor (A.B.C.D|X:X::X:X) remote-as <1-65535>")
-
-** VTY configuration is locked during configuration. This is for
- avoiding unconditional crush from two terminals modify the
- configuration at the same time. "who" command shows which termnal
- lock the configuration. VTY which has '*' character at the head of
- line is locking the configuration.
-
-** Old logging functions are removed. Functions like
- log_open,log_close,openlog are deleted. Instead of that please use
- zlog_* functions. zvlog_* used in ospf6d are deleted also.
-
-** "terminal monitor" command is added. "no terminal monitor" is for
- disabling. This command simply display logging information to the
- VTY.
-
-** dropline.[ch] files are deleted.
-
-* Changes in bgpd
-
-** BGP neighbor configuration are sorted by it's IP address.
-
-** BGP peer configuration and actual peer is separated. This is
- preparation for Route Server support.
-
-** "no neighbor PEER" command is added. You can delete neighbor
- without specifying AS number.
-
-** "no neighbor ebgp-multihop" command is added.
-
-** "no neighbor port PORT" command is added.
-
-** To conform RFC1771, "neighbor PEER send-community" is default
- behavior. If you want to disable sending community attribute,
- please specify "no neighbor PEER send-community" to the peer.
-
-** "neighbor maximum-prefix NUMBER" command is added.
-
-** Multi-protocol extention NLRI is proceeded only when the peer is
- configured proper Address Family and Subsequent Address Family. If
- not, those NLRI are simply ignored.
-
-** Aggregate-address support is improved. Currently below commands
- works.
-
- "aggregate-address"
- "aggregate-address summary-only"
- "no aggregate-address"
- "no aggregate-address summary-only"
-
- "ipv6 bgp aggregate-address"
- "ipv6 bgp aggregate-address summary-only"
- "no ipv6 bgp aggregate-address"
- "no ipv6 bgp aggregate-address summary-only"
-
-** redistribute route-map bug is fixed.
-
-** MBGP support becomes default. "configure" option --enable-mbgp is
- removed.
-
-** New command "neighbor PEER timers connect <1-65535>" is added.
-
-** New command "neighbor PEER override-capability" is added.
-
-** New command "show ip bgp neighbor A.B.C.D advertised-route" is added.
-
-** New command "show ip bgp neighbor A.B.C.D routes" is added. To use
- this command, you have to configure neighbor with
- "neighbor A.B.C.D soft-reconfiguration inbound" beforehand.
-
-
-* Changes in zebra-0.83
-
-* bgpd
-
-** Serious bug fix about fetching global and link-local address at the
-same time. Due to this bug, corrupted IPv6 prefix is generated. If
-you uses bgpd for BGP-4+ please update to this version. The bug is
-introduced in zebra-0.82.
-
-** When bgpd send Notify message, don't use thread manager. It is now
-send to neighbor immediately.
-
-* Changes in zebra-0.82
-
-** Solaris 2.6 support is added by Michael Handler
-<handler@sub-rosa.com>.
-
-** MBGP support is added by Robert Olsson <Robert.Olsson@data.slu.se>.
-Please specify --enable-mbgp to configure script. This option will be
-removed in the future and MBGP support will be default.
-
-* Changes in zebra
-
-** When interface goes down, withdraw connected routes from routing
-table. When interface goes up, restore the routes to the routing
-table.
-
-** `show interface' show interface's statistics on Linux and BSD with
-routing socket.
-
-** Now zebra can get MTU value on BSDI/OS.
-
-* Changes in bgpd
-
-** Add capability option support based upon
-draft-ietf-idr-bgp4-cap-neg-04.txt.
-
-** Add `show ipv6 bgp prefix-list' command.
-
-** Check self AS appeared in received routes.
-
-** redistribute route-map support is added.
-
-** BGP packet dump feature compatible with MRT.
-
-* Changes in ripd
-
-** Fix bug of `timers basic' command's argument format.
-
-* Changes in ripngd
-
-** Calculate max RTE using interface's MTU value.
-
-* Changes in ospfd
-
-** Some correction to LSU processing.
-
-** Add check for lsa->refresh_list.
-
-* Changes in ospf6d
-
-** Many debug feature is added.
-
-* Changes in zebra-0.81
-
-** SNMP support is disabled in default.--enable-snmp option is added
-to configure script.
-
-* Changes in bgpd
-
-** Fix FSM bug which introduced in zebra-0.80.
-
-* Changes in zebra-0.80
-
-* access-list
-
- New access-list name space `ipv6 access-list' is added. At the same
- time, `access-list' statemant only accepts IPv4 prefix. Please be
- careful if you use IPv6 filtering. You will need to change your
- configuration. For IPv6 filtering please use `ipv6 access-list'.
-
- As of zebra-0.7x, user can use `access-list' for both IPv4 and IPv6
- filtering.
-
- ! zebra-0.7x
- access-list DML-net permit 203.181.89.0/24
- access-list DML-net permit 3ffe:506::0/32
- access-list DML-net deny any
- !
-
- Above configuration is not valid for zebra-08x. Please add `ipv6'
- before 'access-list' when you configure IPv6 filtering.
-
- ! zebra-0.8x
- access-list DML-net permit 203.181.89.0/24
- access-list DML-net deny any
- !
- ipv6 access-list DML-net permit 3ffe:506::0/32
- ipv6 access-list DML-net deny any
- !
-
-* prefix-list
-
- And also new prefix-list name space `ipv6 prefix-list' is added. It
- is the same as the change of `access-list'. `ip prefix-list' now only
- accept IPv4 prefix. It was source of confusion that `ip prefix-list'
- can be used both IPv4 and IPv6 filtering. Now name space is separated
- to clear the meaning of the filter.
-
- If you use `ip prefix-list' for IPv6 filtering, please change the
- stetement.
-
- ! zebra-0.7x
- ip prefix-list 6bone-filter seq 5 permit 3ffe::/17 le 24 ge 24
- ip prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 le 28 ge 28
- ip prefix-list 6bone-filter seq 12 deny 3ffe::/16
- ip prefix-list 6bone-filter seq 15 permit 2000::/3 le 16 ge 16
- ip prefix-list 6bone-filter seq 20 permit 2001::/16 le 35 ge 35
- ip prefix-list 6bone-filter seq 30 deny any
- !
-
- Now user can explicitly configure it as IPv6 prefix-list.
-
- ! zebra-0.8x
- ipv6 prefix-list 6bone-filter seq 5 permit 3ffe::/17 le 24 ge 24
- ipv6 prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 le 28 ge 28
- ipv6 prefix-list 6bone-filter seq 12 deny 3ffe::/16
- ipv6 prefix-list 6bone-filter seq 15 permit 2000::/3 le 16 ge 16
- ipv6 prefix-list 6bone-filter seq 20 permit 2001::/16 le 35 ge 35
- ipv6 prefix-list 6bone-filter seq 30 deny any
- !
-
-* RIP configuration
-
- If you want to filter only default route (0.0.0.0/0) and permit other
- routes, it was hard to do that. Now `ip prefix-list' can be used for
- RIP route filtering.
-
- New statement:
-
- `distribute-list prefix PLIST_NAME (in|out) IFNAME'
-
- is added to ripd. So you can configure on eth0 interface accept all
- routes other than default routes.
-
- !
- router rip
- distribute-list prefix filter-default in eth0
- !
- ip prefix-list filter-default deny 0.0.0.0/0 le 0
- ip prefix-list filter-default permit any
- !
-
-* RIPng configuration
-
- Same change is done for ripngd. You can use `ipv6 prefix-list' for
- filtering.
-
- !
- router ripng
- distribute-list prefix filter-default in eth0
- !
- ipv6 prefix-list filter-default deny ::/0 le 0
- ipv6 prefix-list filter-default permit any
- !
-
-* BGP configuration
-
- So far, Multiprotocol Extensions for BGP-4 (RFC2283) configuration is
- done with traditional IPv4 peering statement like blow.
-
- !
- router bgp 7675
- neighbor 3ffe:506::1 remote-as 2500
- neighbor 3ffe:506::1 prefix-list 6bone-filter out
- !
-
- For separating configuration IPv4 and IPv6, and for retaining Cisco
- configuration compatibility, now IPv6 configuration is done by IPv6
- specific statement. IPv6 BGP configuration is done by statement which
- start from `ipv6 bgp'.
-
- !
- router bgp 7675
- !
- ipv6 bgp neighbor 3ffe:506::1 remote-as 2500
- ipv6 bgp neighbor 3ffe:506::1 prefix-list 6bone-filter out
- !
-
- At the same time some IPv6 specific commands are deleted from IPv4
- configuration.
-
- o redistribute ripng
- o redistribute ospf6
- o neighbor PEER version BGP_VERSION
- o neighbor PEER interface IFNAME
-
- Those commands are only accepted as like below.
-
- o ipv6 bgp redistribute ripng
- o ipv6 bgp redistribute ospf6
- o ipv6 bgp neighbor PEER version BGP_VERSION
- o ipv6 bgp neighbor PEER interface IFNAME
-
- And below new commands are added.
-
- o ipv6 bgp network IPV6_PREFIX
- o ipv6 bgp redistribute static
- o ipv6 bgp redistribute connected
- o ipv6 bgp neighbor PEER remote-as <1-65535> [passive]
- o ipv6 bgp neighbor PEER ebgp-multihop [TTL]
- o ipv6 bgp neighbor PEER description DESCRIPTION
- o ipv6 bgp neighbor PEER shutdown
- o ipv6 bgp neighbor PEER route-reflector-client
- o ipv6 bgp neighbor PEER update-source IFNAME
- o ipv6 bgp neighbor PEER next-hop-self
- o ipv6 bgp neighbor PEER timers holdtime <0-65535>
- o ipv6 bgp neighbor PEER timers keepalive <0-65535>
- o ipv6 bgp neighbor PEER send-community
- o ipv6 bgp neighbor PEER weight <0-65535>
- o ipv6 bgp neighbor PEER default-originate
- o ipv6 bgp neighbor PEER filter-list FILTER_LIST_NAME (in|out)
- o ipv6 bgp neighbor PEER prefix-list PREFIX_LIST_NAME (in|out)
- o ipv6 bgp neighbor PEER distribute-list AS_LIST_NAME (in|out)
- o ipv6 bgp neighbor PEER route-map ROUTE_MAP_NAME (in|out)
-
- And some utility commands are introduced.
-
- o clear ipv6 bgp [PEER]
- o show ipv6 bgp neighbors [PEER]
- o show ipv6 bgp summary
-
- I hope these changes are easy to understand for current Zebra users...
-
-* To restrict connection to VTY interface.
-
- It used to be both IPv4 and IPv6 filter can be specified with one
- access-list. Then the access-list can be appried to VTY interface
- with `access-class' stetement in `line vty' node. Below is example in
- zebra-0.7x.
-
- !
- access-list local-only permit 127.0.0.1/32
- access-list local-only permit ::1/128
- access-list local-only deny any
- !
- line vty
- access-class local-only
- !
-
- Now IPv4 and IPv6 filter have each name space. It is not possible to
- specify IPv4 and IPv6 filter with one access-list. For setting IPv6
- access-list in `line vty', `ipv6 access-class' statement is
- introduced. Let me show the configuration in zebra-0.8x.
-
- !
- access-list local-only permit 127.0.0.1/32
- access-list local-only deny any
- !
- ipv6 access-list local-only permit ::1/128
- ipv6 access-list local-only dny any
- !
- line vty
- access-class local-only
- ipv6 access-class local-only
- !
-
-* route-map
-
- New IPv6 related route-map match commands are added.
-
- o match ipv6 address
- o match ipv6 next-hop
-
- Please change your configuration if you use IP match statement for
- IPv6 route.
-
- zebra-0.7x config
- =================
- !
- access-list all permit any
- !
- route-map set-nexthop permit 10
- match ip address all
- set ipv6 next-hop global 3ffe:506::1
- set ipv6 next-hop local fe80::cbb5:591a
- !
-
- zebra-0.8x config
- =================
- !
- ipv6 access-list all permit any
- !
- route-map set-nexthop permit 10
- match ipv6 address all
- set ipv6 next-hop global 3ffe:506::1
- set ipv6 next-hop local fe80::cbb5:591a
- !
-
-* zebra connection
-
- Protocol daemon such as ripd, bgpd, ospfd will reconnect zebra daemon
- when the connection fail. Those daemons try to connect zebra every 10
- seconds first three trial, then the interval changed to 60 seconds.
- After all, if ten connections are fail, protocol daemon give up the
- connection to the zebra daemon.
-
-* SNMP support (is not yet finished)
-
- Zebra uses SMUX protocol (RFC1227) for making communication with SNMP
- agent. Currently lib/smux.c can be compiled only with ucd-snmp-4.0.1
- and http://ucd-snmp.ucdavis.edu/patches/012.patch. It can not be
- compiled with ucd-snmp-3.6.2.
-
- After applying the patch to ucd-snmp-4.0.1, please configure it with
- SMUX module.
-
- % configure --with-mib-modules=smux
-
- After compile & install ucd-snmp-4.0.1, you will need to configure
- smuxpeer. I'm now using below configuration.
-
- /usr/local/share/snmp/snmpd.conf
- ================================
- smuxpeer 1.3.6.1.6.3.1 test
-
- Above 1.3.6.1.6.3.1 and test is temporary configuration which is hard
- coded in lib/smux.c. Yes, I know it is bad, I'll change it ASAP.
-
-* HUP signal treatment
-
- From zebra-0.80, ripd will reload it's configuration file when ripd
- receives HUP signal. Other daemon such as bgpd, ospfd will support
- HUP signal treatment soon.
-
-* Changes in zebra-0.79
-
-* Changes in zebra
-
-** Broadcast address setting on Linux box bug is fixed.
-
-** Protocol daemon can install connected IPv6 route into the kernel.
-
-** Now zebra can handle blackhole route.
-
-* Changes in ripd
-
-** Add route-map feature for RIP protocol.
-
-** In case of RIP version 2 routing table entry has IPv4 address and
-netmask pair which host part bit is on, ignore the entry.
-
-* Changes in ripngd
-
-** Change CMSG_DATA cast from (u_char *) to (int *). (u_char *) does
-not work for NetBSD-currnet on SparcStation 10.
-
-* Changes in ospfd
-
-** MaxAge LSA treatment is added.
-
-** ABR/ASBR functionality is added.
-
-** Virtual Link funtionality is added.
-
-** ABR behaviors IBM/Cisco/Shortcut is added.
-
-* Changes in ospf6d
-
-** Enclosed KAME specific part with #ifdef #endif
-
-* Changes in zebra-0.78
-
-* Changes in lib
-
-** SNMP support is started.
-
-** Now Zebra can work on BSD/OS 4.X.
-
-** Now Zebra can compiled on vanilla OpenBSD 2.5 but not yet working correcltly.
-
-* Changes in zebra
-
-** Interface index detection using ioctl() bug is fixed.
-
-** Interface information protocol is changed. Now interface
-addition/deletion and interface's address addition/deletion is
-separated.
-
-* Changes in bgpd
-
-** BGP hold timer bug is fixed.
-
-** BGP keepavlie timer becomes configurable.
-
-* Changes in ripd
-
-** When making reply to rip's REQUEST message, fill in
-RIP_METRIC_INFINITY with network byte order using htonl ().
-
-** Pass host byte order address to IN_CLASSC and IN_CLASSB macro.
-
-* Changes in ospfd
-
-** LSA flooding works.
-
-** Fix bug of DD processing.
-
-** Fix bug of originating router-LSA bug is fixed.
-
-** LSA structure is changed to support LSA aging.
-
-* Changes in ospf6d
-
-** `ip6' statement in configuration is changed to `ipv6'.
-
-* Changes in zebra-0.77
-
-* Changes in lib
-
-** SIGUSR1 reopen logging file.
-
-** route-map is extended to support multi-protocol routing
-information.
-
-** When compiling under GNU libc 2.1 environment don't use inet6-apps.
-
-* Changes in zebra
-
-** Basic IPv6 router advertisement codes added. It is not yet usable.
-
-** Fix IPv6 route addition/deletion bug is fixed.
-
-** `show ip route A.B.C.D' works
-
-* Changes in bgpd
-
-** When invalid unfeasible routes length comes, bgpd send notify then
-continue to process the packet. Now bgpd stop parsing invalid packet
-then return to main loop.
-
-** BGP-4+ withdrawn routes parse bug is fixed.
-
-** When BGP-4+ information passed to non shared network's peer, trim
-link-local next-hop information.
-
-** `no redistribute ROUTE_TYPE' withdraw installed routes from BGP
-routing information.
-
-** `show ipv6 route IPV6ADDR' command added.
-
-** BGP start timer has jitter.
-
-** Holdtimer configuration bug is fixed. Now configuration does not
-show unconfigured hold time value.
-
-* Changes in ripngd
-
-** Now update timer (default 30 seconds) has +/- 50% jitter value.
-
-** Add timers basic command.
-
-** `network' configuration is dynamically reflected.
-
-** `timers basic <update> <timeout> <garbage>' added.
-
-* Changes in ripd
-
-** Reconstruct almost codes.
-
-** `network' configuration is dynamically reflected.
-
-** RIP timers now conforms to RFC2453. So user can configure update,
-timeout, garbage timer.
-
-** `timers basic <update> <timeout> <garbage>' works.
-
-* Changes in ospfd
-
-** Bug of originating network LSA is fixed.
-
-** `no router ospf' core dump bug is fixed.
-
-* Changes in ospf6d
-
-** Redistribute route works.
-
-* Changes in zebra-0.76
-
-* Changes in lib
-
-** configure.in Linux IPv6 detection problem is fixed.
-
-** Include SERVICES file to the distribution
-
-** Update zebra.texi to zebra-0.76.
-
-* Changes in zebra-0.75
-
-* Changes in lib
-
-** `termnal length 0' bug is fixed.
-
-* Changes in zebra
-
-** When zebra starts up, sweep all zebra installed routes. If -k or
---keep_kernel option is specified to zebra dameon. This function is
-not performed.
-
-* Changes in ripngd
-
-** Aggreagte address command supported. In router ripngd,
-`aggregate-address IPV6PREFIX' works.
-
-* Changes in bgpd
-
-** Input route-map's bug which cause segmentation violation is fixed.
-
-** route-map method improved.
-
-** BGP-4+ nexthop detection improved.
-
-** BGP-4+ route re-selection bug is fixed.
-
-** BGP-4+ iBGP route's nexthop calculation works.
-
-** After connection Established `show ip bgp neighbor' display BGP TCP
-connection's source and destination address.
-
-** In case of BGP-4+ `show ip bgp neighbor' display BGP-4+ global and
-local nexthop which used for originated route. This address will be
-used when `next-hop-self'.
-
-* Changes in ospfd
-
-** Fix bug of DR election.
-
-** Set IP precedence field with IPTOS_PREC_INTERNET_CONTROL.
-
-** Schedule NeighborChange event if NSM status change.
-
-** Never include a neighbor in Hello packet, when the neighbor goes
-down.
-
-* Changes in zebra-0.74
-
-* Changes in lib
-
-** Now `terminal length 0' means no line output control.
-
-** `line LINES' command deleted. Instead of this please use `terminal
-length <0-512>'.
-
-** `terminal length <0-512>' is each vty specific configuration so it
-can not be configured in the configuration file. If you want to
-configure system wide line control, please use `service
-terminal-length <0-512>'. This configuration affects to the all vty
-interface.
-
-* Changes in zebra
-
-** Installation of IPv6 route bug is fixed.
-
-* Changes in bgpd
-
-** Very serious bug of bgp_stop () is fixed. When multiple route to
-the same destination exist, bgpd try to announce the information to
-stopped peer. Then add orphan write thread is added. This cause
-many strange behavior of bgpd.
-
-** Router-id parsing bug is fixed.
-
-** With BGP-4+ nexthop installation was done with global address but
-it should be link-local address. This bug is fixed now.
-
-** When incoming route-map prepend AS, old AS path remained. Now bgpd
-free old AS path.
-
-** `neighbor PEER weight <0-65535>' command added.
-
-* Changes in ripngd
-
-** Almost codes are rewritten to conform to RFC2080.
-
-* Changes in ospfd
-
-** SPF calculation timer is added. Currently it is set to 30 seconds.
-
-** SPF calculation works now.
-
-** OSPF routing table codes are added.
-
-** OSPF's internal routes installed into the kernel routing table.
-
-** Now `ospfd' works as non-area, non-external route support OSPF
-router.
-
-** Call of log_rotate() is removed.
-
-* Changes in ospf6d
-
-** LSA data structure is changed.
-
-** Call of log_rotate() is removed.
-
-* Changes in zebra-0.73
-
-* Changes in lib
-
-** `config terminal' is changed to `configure terminal'.
-
-** `terminal length <0-512>' command is added.
-
-** Variable length argument was specified by `...'. Now all strings
-started with character `.' is variable length argument.
-
-* Changes in zebra
-
-** Internal route (such as iBGP, internal OSPF route) handling works
-correctly.
-
-** In interface node, `ipv6 address' and `no ipv6 address' works.
-
-** Interface's address remain after `no ip address' bug is fixed.
-
-** Host route such as IPv4 with /32 mask and IPv6 with /128 mask
-didn't set RTF_GATEWAY even it has gateway. This bug if fixed now.
-
-* Changes in bgpd
-
-** `match as-path' argument is used to be specify AS PATH value itself
-directly (e.g. ^$). But it is changed to specify `ip as-apth
-access-list' name.
-
-** iBGP route handle works without getting error from the kernel.
-
-** `set aggregator as AS A.B.C.D' command is added to route-map.
-
-** `set atomic-aggregate' command is added to bgpd's routemap.
-
-** Announcement of atomic aggregate attribute and aggregator attribute
-works.
-
-** `update-source' bug is fixed.
-
-** When a route learned from eBGP is announced to iBGP, local
-preference was set to zero. But now it set to
-DEFAULT_LOCAL_PREF(100).
-
-* Changes in ripd
-
-** RIPv1 route filter bug is fixed.
-
-** Some memory leak is fixed.
-
-* Changes in ospfd
-
-** Fix bug of DR Election.
-
-** Fix bug of adjacency forming.
-
-* Changes in ospf6d
-
-** Clean up logging message.
-
-** Reflect routing information to zebra daemon.
-
-* Changes in zebra-0.72
-
-* Changes in lib
-
-** When getsockname return IPv4 mapped IPv6 address. Convert it to
-IPv4 address.
-
-* Changes in bgpd
-
-** Change route-map's next-hop related settings.
-
-set ip nexthop -> set ip next-hop
-set ipv6 nexthop global -> set ipv6 next-hop global
-set ipv6 nexthop local -> set ipv6 next-hop local
-
-** Add `next-hop-self' command.
-
-* Changes in ospfd
-
-** Fix bug of multiple `network area' directive crashes.
-
-* Changes in zebra-0.71
-
-* Changes in lib
-
-** `log syslog' command is added.
-
-** Use getaddrinfo function to bind IPv4/IPv6 server socket.
-
-** `no banner motd' will suppress motd output when user connect to VTY.
-
-** Bind `quit' command to major nodes.
-
-* Changes in zebra
-
-** Point-to-point link address handling bug is fixed.
-
-* Changes in bgpd
-
-** AS path validity check is added. If malformed AS path is received
-NOTIFY Malformed AS path is send to the peer.
-
-** Use getaddrinfo function to bind IPv4/IPv6 server socket.
-
-* Changes in ripd
-
-** Connected network announcement bug is fixed.
-
-** `broadcast' command is deleted.
-
-** `network' command is added.
-
-** `neighbor' command is added.
-
-** `redistribute' command is added.
-
-** `timers basic' command is added.
-
-** `route' command is added.
-
-* Changes in ripngd
-
-** Fix metric calculation bug.
-
-* Changes in ospfd
-
-** Check sum bug is fixed.
-
-* Chanegs in ospf6d
-
-** Routing table code is rewritten.
-
-* Changes in zebra-0.70
-
-* Changes in zebra
-
-** Critical routing information base calculation bug check is fixed.
-
-** zebra ipv4 message is extended to support external/internal route
-flavor.
-
-** Now if internal route doesn't has direct connected nexthop, then
-nexthop is calculated by looking up IGP routing table.
-
-* Changes in bgpd
-
-** `neighbor PEER update-source IFNAME' command added as ALIAS to
-`neighbor PEER interface IFNAME'.
-
-* Changes in ospfd
-
-** DD null pointer bug is fixed.
-
-* Changes in zebra-0.69
-
-* Changes in zebra
-
-** zebra redistirbution supports dynamic notification of the route
-change. If you add static route while running zebra, it will be
-reflected to other protocol daemon which set `redistribute static'.
-
-** If static route installation is failed due to the error. The
-static route is not added to the configuration and zebra routing
-table.
-
-** zebra sets forwarding flag to on when it starts up.
-
-** `no ip forwarding' turn off IPv4 forwarding.
-
-** `no ipv6 forwarding' turn off IPv6 forwarding.
-
-** Change `show ipforward' command to `show ip forwarding'.
-
-** Change `show ipv6forward' command to `show ipv6 forwarding'.
-
-** `ip route A.B.C.D/M INTERFACE' works. So you can set `ip route
-10.0.0.0/8 eth0'.
-
-* Changes in bgpd
-
-** `neighbor PEER send-community' command is added. If the option is
-set, bgpd will send community attribute to the peer.
-
-** When a BGP route has no-export community attribute and
-send-community is set to the peer, the route is not announced to the
-peer.
-
-* Changes in ripngd
-
-** When ripngd terminates, delete all installed route.
-
-** `redistribute static', `redistribute connected' works.
-
-** Change `debug ripng event' to `debug ripng events'.
-
-** Change `show debug ripng' to `show debugging ripng'.
-
-** Bug of static route deletion is fixed.
-
-* Changes in ospfd
-
-** LS request and LS update can be send and received.
-
-* Changes in zebra-0.68
-
-* Changes in lib
-
-** DEFUN() is extended to support (a|b|c) statement.
-
-** Input buffer overflow bug is fixed.
-
-* Changes in bgpd
-
-** `ip community-list' is added.
-
-** set community and match community is added to route-map statement.
-
-** aggregate-address A.B.C.D/M partly works. Now it works only
-summary-only mode.
-
-* Changes in zebra
-
-** IPv6 network address delete bug is fixed.
-
-* Changes in ospfd
-
-** DR election bug fixed.
-
-** Now Database Description can be send or received.
-
-** Neighbor State Machine goes to Full state.
-
-* Changes in ospf6d
-
-** router zebra related bug is fixed.
-
-* Changes in zebra-0.67
-
-* Changes in lib
-
-** `service password-encryption' is added for encrypted password.
-
-* Changes in bgpd
-
-** `set as-path prepend ASPATH' is added to route-map command.
-
-** `set weight WEIGHT' is added to route-map command.
-
-** `no set ipv6 nexthop global' and `no set ipv6 nexthop local'
-command is added to route-map.
-
-** `neighbor IP_ADDR version BGP_VERSION' command's BGP_VERSION
-argument changed.
-
-Old New
-=====================
-bgp4 4
-bgp4+ 4+
-bgp4+-draft-00 4-
-=====================
-
-If you want to peer with old draft version of BGP-4+, please configure
-like below:
-
-router bgp ASN
- neighbor PEER version 4-
-
-** Some AS path isn't correctly compared during route selection. Now
-it is fixed.
-
-* Changes in ospfd
-
-** `router zebra' is default behavior.
-
-* Changes in ospf6d
-
-** `router zebra' is default behavior.
-
-* Changes in zebra-0.66
-
-* Changes in zebra
-
-** When other daemon such as gated install routes into the kernel then
-zebra blocks. This is only occur with netlink socket. Now socket is
-set as NONBLOCKING and problem is fixed. Reported and fixed by
-Patrick Koppen <koppen@rhrk.uni-kl.de>
-
-* Changes in bgpd
-
-** Now `router zebra' is not needed to insert BGP routes into the
-kernel. It is default behavior. If you don't want to install the BGP
-routes to the kernel, please configure like below:
-
-!
-router zebra
- no redistribute bgp
-!
-
-** redistribute connected works.
-
-** redistribute static now filter local loopback routes and link local
-network.
-
-* Changes in ripd
-
-** Some network check is added. Patch is done by Carlos Alberto
-Barcenilla <barce@frlp.utn.edu.ar>
-
-* Changes in ripngd
-
-** Sometimes ripngd install wrong nexthop into the kernel. This bug
-is fixed now.
-
-** Now `router zebra' is not needed to insert RIPng routes into the
-kernel. It is default behavior. If you don't want to install the BGP
-routes to the kernel, please configure like below:
-
-!
-router zebra
- no redistribute ripng
-!
-
-* Changes in zebra-0.65
-
-* Changes in lib
-
-** `C-c' changes current node to ENABLE_NODE. Previously it doesn't.
-
-** In ENABLE_NODE, `exit' command close vty connection.
-
-** `service advanced-vty' enable advanced vty function. If this
-service is specified one can directly connect to ENABLE_NODE when
-enable password is not set.
-
-** `lines LINES' command is added by Stephen R. van den Berg
-<srb@cuci.nl>.
-
-* Changes in zebra
-
-** Basic Linux policy based routing table support is added by Stephen
-R. van den Berg <srb@cuci.nl>.
-
-* Changes in bgpd
-
-** route-map command is improved:
- `match ip next-hop': New command.
- `match metric': New command.
- `set metric': Doc fixed.
- `set local-preference': DEFUN added.
-
-* Changes in ripd
-
-** Check of announced network is added. Now multicast address is
-filtered. Reported by Carlos Alberto Barcenilla
-<barce@frlp.utn.edu.ar>
-
-** Check of network 127 is added. Reported by Carlos Alberto
-Barcenilla <barce@frlp.utn.edu.ar>
-
-* Changes in ripngd
-
-** Aging route bug is fixed.
-
-** `router zebra' semantics changed. ripngd automatically connect to
-zebra.
-
-* Changes in ospfd
-
-** `no router ospf' works.
-
-* Changes in ospf6d
-
-** Bug fix about network vertex.
-
-* Changes in zebra-0.64.1.
-
-This is bug fix release.
-
-* Changes in lib
-
-** Add check of sin6_scope_id in struct sockaddr_in6. For compilation
-on implementation which doesn't have sin6_scope_id. Reported by Wim
-Biemolt <Wim.Biemolt@ipv6.surfnet.nl>.
-
-* Changes in zebra
-
-** Fix bug of display BGP routes as "O" instead of "B". Reported by
-"William F. Maton" <wmaton@enterprise.ic.gc.ca> and Dave Hartzell
-<hartzell@greatplains.net>.
-
-* Changes in bgpd
-
-** `no network IPV6_NETWORK' statement and `no neighbor IP_ADDR timers
-holdtime [TIMER]' statement doesn't work. Reported by Georg Hitsch
-<georg@atnet.at>. Now both statement work.
-
-* Changes in ospfd
-
-** Last interface is not updated by ospf_if_update(). Reported by
-Dave Hartzell <hartzell@greatplains.net>.
-
-* Changes in ospf6d
-
-** Byte order of ifid is changed. Due to this change, this code will
-not work with previous version, sorry.
-
-** Fix `show ip route' route type mismatch.
-
-** Fix bug of no network IPV6_NETWORK.
-
-** Important bug fix about intra-area-prefix-lsa.
-
-* Changes in zebra-0.64.
-
-* Changes in lib
-
-** prefix-list based filtering routine is added. Currently used in
-bgpd but it will be in other daemons.
-
-* Changes in bgpd
-
-** `no router bgp' works. But network statement is not cleared. This
-should be fixed in next beta.
-
-** Route reflector related statement is added.
-
- router bgp ASN
- bgp cluster-id a.b.c.d
- neighbor a.b.c.d route-reflector-client
-
- is added.
-
-** Prefix list based filtering is added.
-
- router bgp ASN
- neighbor a.b.c.d prefix-list PREFIX_LIST_NAME
-
-** Prefix list based routing display works.
-
- show ip bgp prefix-list PREFIX_LIST_NAME
-
-* Changes in ripd
-
-** Fix route metric check bug. Reported from Mr. Carlos Alberto
-Barcenilla.
-
-* Changes in ospf6d
-
-** There are many changes. If you have interested in ospf6d please
-visit ospf6d/README file.
-
-* Changes in zebra-0.63 first beta package.
-
-* Changes in lib
-
-** `copy running-config stgartup-config' command is added.
-
-** prefix length check bug is fixed. Thanks Marlos Barcenilla
-<barce@frip.utn.edu.ar>.
-
-* Changes in ospfd
-
-** DR and BDR election works.
-
-** OSPF Hello simple authentication works.
-
-* Changes in ospf6d
-
-** Now ospf6d can be compiled on both Linux and *BSD system.
-
-* Changes in zebra-19990420 snapshot
-
-** `make dist' at top directory works now.
-
-* Changes in lib
-
-** VTY has now access-class to restrict remote connection.
-Implemented by Alex Bligh <amb@gxn.net>.
-
-!
-line vty
- access-class ACCESS-LIST-NAME
-!
-
-** `show version' command added. Implemented by Carlos Alberto
-Barcenilla <barce@frlp.utn.edu.ar>
-
-* Changes in zebra
-
-** `ip address' command on *BSD bug is fixed.
-
-** `no ip address' works now for IPv4 address.
-
-** Now `write terminal' display `ip address' configuration.
-
-* Changes in bgpd
-
-** Redistribute static works now. Please run both zebra and bgpd.
-bgpd.conf should be like this:
-
-!
-router zebra
-!
-router bgp ASN
- redisitribute static
-!
-
-* Changes in guile
-
-** configure --enable-guile turns on zebra-guile build.
-
-** (router-bgp ASN) allocates real bgp structre.
-
-* Changes in zebra-19990416 snapshot
-
-** Set version to 0.60 for preparation of beta release.
-
-** New directory guile is added for linking with guile interpreter.
-
-* Changes in zebra
-
-** On GNU/Linux Kernel 2.2.x (with netlink support), zebra detects
-asynchronous routing updates. *BSD support is not yet finished.
-
-* Changes in bgpd
-
-** `show ip bgp regexp ASPATH_REGEX' uses CISCO like regular expression
-instead of RPSL like regular expression. I'm planing to provide RPSL
-like regular expression with `show ip bgp rpsl' or something.
-
-* Changes in lib
-
-** Press '?' at variable mandatory argument, vty prints nothing. Now
-vty outputs description about the argument. Fixed by Alex Bligh
-<amb@gxn.net>
-
-** buffer.c has some ugly bugs. Due to the bug, vty interface hangs
-when large output date exists. This bug is fixed. Reported by Alex
-Bligh <amb@gxn.net>.
-
-* Changes in ospfd
-
-** DR and BDR information is shown by `show ip ospf interface' command.
-
-* Changes in zebra-19990408 snapshot
-
-* Changes in bgpd
-
-** Old BGP-4+ specification (described in old draft) treatment bug is
-fixed. It seems that mrtd uses this format as default. So if you
-have problem peering with mrtd and want to use old draft format please
-use version statement like this.
-
-neighbor PEER_ADDRESS remote-as ASN
-neighbor PEER_ADDRESS version bgp4+-draft-00
-
-** When AS path is epmty (routes generated by bgpd), SEGV is occur
-when announce the routes to eBGP peer. Reported by
-kad@gibson.skif.net.
-
-** ip as-path access-list command is added.
-
-** neighbor PEER_ADDRESS filter-list AS_LIST [in|out] command is added.
-
-** neighbor PEER_ADDRESS timers holdtimer TIMER command is added.
-
-* Changes in all daemons
-
-** With KAME stack, terminal interface is now bind AF_INET socket
-instead of AF_INET6 one.
-
-* Changes in zebra-19990403 snapshot
-
-* Changes in bgpd
-
-** When bgpd has 'router zebra', bgpd automatically select it's router
-ID as most highest interface's IP Address.
-
-** When AS path is empty (in case of iBGP), it doesn't include any AS
-segment. This change is for announcement to gated under iBGP.
-
-* Changes in ospfd
-
-** OSPF hello packet send/receive works.
-
-* Changes in ospf6d
-
-** Yasuhiro Ohara's ospf6d codes is imported. It is under development
-and can't be compiled on any platform.
-
-* Changes in zebra-19990327 snapshot
-
-* Changes in bgpd
-
-** When BGP-4+ connection is done by IPv6 link-local address. One
-have to specify interface index for the connection. So I've added
-interface statement to the neighbor commmand. Please specify
-interface name for getting interface index like below. This statement
-only works on GNU/Linux. I'll support BSD ASAP.
-
-router bgp 7675
- neighbor fe80::200:f8ff:fe01:5fd3 remote-as 2500
- neighbor fe80::200:f8ff:fe01:5fd3 interface sit3
-
-** For disable BGP peering `shutdown' command is added.
-
-router bgp 7675
- neighbor 10.0.0.1 shutdown
-
-** `description' command is added to neighbor statement.
-
-router bgp 7675
- neighbor 10.0.0.1 description peering with Norway.
-
-** `show ip bgp regexp AS-REGEXP' works again.
-
-show ip bgp regexp AS7675
-
-will show routes which include AS7675.
-
-** When a route which is made from `network' statement is send to
-neighbor. Set it's nexthop to self. So 10.0.0.0/8 is announced to
-the peer A with source address 192.168.1.1. The routes nexthop is set
-to 192.168.1.1.
-
-* Changes in zebra
-
-** In zebra/rtread_sysctl.c, function rtm_read() may overrun allocated
-buffer when the address family is not supported and the length is big
-(i.e link address). Reported Achim Patzner <ap@bnc.net>.
-
-* Changes in ospfd
-
-** Now ospfd receive OSPF packet.
-
-* Changes in zebra-19990319 snapshot
-
-* Changes in configuration and libraries
-
-** User can disable IPv6 feature and/or pthread feature by configure
- option.
-
- To disable IPv6: configure --disable-ipv6
- To disable pthread: configure --disable-pthread
-
-** User can disable specified daemon by configure option.
-
- Don't make zebra: configure --disable-zebra
- Don't make bgpd: configure --disable-bgpd
- Don't make ripd: configure --disable-ripd
- Don't make ripngd: configure --disable-ripngd
- Don't make ospfd: configure --disable-ospfd
- Don't make ospf6d: configure --disable-ospf6d
-
-** Sample configuration files are installed as 600 file flag.
- Suggested by Jeroen Ruigrok/Asmodai <asmodai@wxs.nl>.
-
-** syslog logging feature is added by Peter Galbavy
- <Peter.Galbavy@knowledge.com>
-
-** Inclusion of standard header files is reworked by Peter Galbavy
- <Peter.Galbavy@knowledge.com>
-
-** Change description from GNU/Linux 2.1.X to GNU/Linux 2.2.X
-
-** If daemon function exists in standard C library use it.
-
-** To generate configure script we upgrade autoconf to 2.13. To
-generate Makefile.in we upgrade automake to 1.4.
-
-** doc/texinfo.tex is added to distribution.
-
-** Update ports/pkg/DESCR description.
-
-** Update doc/zebra.texi.
-
-** logfile FILENAME statement deleted. Instead of that please use log
-file FILENAME.
-
-* Changes in zebra
-
-* Changes in bgpd
-
-** Communication between zebra and bgpd works now. So if there is
- `router zebra' line in bgpd.conf, selected route is installed
- into kernel routing table.
-
-** Delete all routes which inserted by bgpd when bgpd dies. If you
-want to retain routes even bgpd dies please specify [-r|--retain]
-option to bgpd.
-
-** BGP announcement code is reworked. Now bgpd announce selected
- routes to other peer.
-
-** All output bgp packet is buffered. It's written to the socket when
- it gets ready.
-
-** Output route-map works now. You can specify output route-map by:
-
- neighbor IP_ADDR route-map ROUTE_MAP_NAME out
-
-** New route-map command added.
-
- set ip nexthop IP_ADDR
- set ipv6 nexthop global IP_ADDR
-
-** Fix bug about unlock of the route_node structure.
-
-** BGP-4+ support is added. bgpd can listen and speak BGP-4+ packet
-specified in RFC2283. You can view IPv6 bgp table by: `show ipv6 bgp'.
-
-** Meny packet overflow check is added.
-
-* Changes in ripd
-
-* Changes in ripngd
-
-* Changes in ospfd
-
-** ospfd work is started by Toshiaki Takada <takada@zebra.org>. Now
-several files are included in ospfd directory.
-
-** ospf6d codes are merged from Yasuhiro Ohara <yasu@sfc.wide.ad.jp>'s
-ospfd work. Now codes are located in ospf6d directory.
-
-
-Local variables:
-mode: outline
-paragraph-separate: "[ ]*$"
-end:
diff --git a/README b/README
deleted file mode 100644
index 7600ec54c..000000000
--- a/README
+++ /dev/null
@@ -1,16 +0,0 @@
-FRRouting is free software that implements and manages various IPv4 and IPv6
-routing protocols.
-
-Currently FRRouting supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1, RIPv2, RIPng,
-IS-IS, PIM-SM/MSDP, LDP and Babel as well as very early support for EIGRP and
-NHRP.
-
-See doc/user/bugs.rst for information on how to report bugs.
-
-See doc/developer/workflow.rst for information on contributing.
-
-See the file COPYING for copying conditions.
-
-Public email discussion can be found at https://lists.frrouting.org/listinfo
-
-Our public slack channel is at https://frrouting.slack.com
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..48142f21b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,74 @@
+FRRouting
+=========
+
+FRR is free software that implements and manages various IPv4 and IPv6 routing
+protocols. It runs on nearly all distributions of Linux and BSD as well as
+Solaris and supports all modern CPU architectures.
+
+FRR currently supports the following protocols:
+
+* BGP
+* OSPFv2
+* OSPFv3
+* RIPv1
+* RIPv2
+* RIPng
+* IS-IS
+* PIM-SM/MSDP
+* LDP
+* BFD
+* Babel
+* EIGRP (alpha)
+* NHRP (alpha)
+
+Installation & Use
+------------------
+
+Packages are available for various distributions on our
+[releases page](https://github.com/FRRouting/frr/releases).
+
+Snaps are also available [here](https://snapcraft.io/frr).
+
+Instructions on building and installing from source for supported platforms may
+be found
+[here](http://docs.frrouting.org/projects/dev-guide/en/latest/building.html).
+
+Once installed, please refer to the [user guide](http://docs.frrouting.org/)
+for instructions on use.
+
+Community
+---------
+
+The FRRouting email list server is located
+[here](https://lists.frrouting.org/listinfo) and offers the following public
+lists:
+
+| Topic | List |
+|-------------------|------------------------------|
+| Development | dev@lists.frrouting.org |
+| Users & Operators | frog@lists.frrouting.org |
+| Announcements | announce@lists.frrouting.org |
+
+For chat, we currently use [Slack](https://frrouting.slack.com). Please email
+the mailing list to request an invite as we do not issue automatic invites.
+
+
+Contributing
+------------
+
+FRR maintains [developer's documentation](http://docs.frrouting.org/projects/dev-guide/en/latest/index.html)
+which contains the [project workflow](http://docs.frrouting.org/projects/dev-guide/en/latest/workflow.html)
+and expectations for contributors. Some technical documentation on project
+internals is also available.
+
+We welcome and appreciate all contributions, no matter how small!
+
+
+Security
+--------
+
+To report security issues, please use our security mailing list:
+
+```
+security [at] lists.frrouting.org
+```
diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c
index ff5cca42a..31778901a 100644
--- a/babeld/babel_filter.c
+++ b/babeld/babel_filter.c
@@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "babel_filter.h"
#include "vty.h"
#include "filter.h"
diff --git a/babeld/kernel.c b/babeld/kernel.c
index ba2b58131..d4c962af3 100644
--- a/babeld/kernel.c
+++ b/babeld/kernel.c
@@ -21,6 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/time.h>
#include <sys/param.h>
#include <time.h>
diff --git a/babeld/neighbour.c b/babeld/neighbour.c
index c1592fb18..512b60e29 100644
--- a/babeld/neighbour.c
+++ b/babeld/neighbour.c
@@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
diff --git a/babeld/net.c b/babeld/net.c
index ad9a6bad9..d1f6a4414 100644
--- a/babeld/net.c
+++ b/babeld/net.c
@@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
diff --git a/babeld/resend.c b/babeld/resend.c
index 1f2197744..8949075f6 100644
--- a/babeld/resend.c
+++ b/babeld/resend.c
@@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/time.h>
#include <time.h>
#include <string.h>
diff --git a/babeld/source.c b/babeld/source.c
index d6dd84895..75bca0620 100644
--- a/babeld/source.c
+++ b/babeld/source.c
@@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
diff --git a/babeld/subdir.am b/babeld/subdir.am
index 6f91f7393..e1f2cb0a0 100644
--- a/babeld/subdir.am
+++ b/babeld/subdir.am
@@ -6,6 +6,11 @@ if BABELD
noinst_LIBRARIES += babeld/libbabel.a
sbin_PROGRAMS += babeld/babeld
dist_examples_DATA += babeld/babeld.conf.sample
+vtysh_scan += \
+ $(top_srcdir)/babeld/babel_interface.c \
+ $(top_srcdir)/babeld/babel_zebra.c \
+ $(top_srcdir)/babeld/babeld.c \
+ # end
endif
babeld_libbabel_a_SOURCES = \
diff --git a/babeld/util.c b/babeld/util.c
index 4a3ecace0..880cda2fc 100644
--- a/babeld/util.c
+++ b/babeld/util.c
@@ -21,6 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
diff --git a/bfdd/.gitignore b/bfdd/.gitignore
index e554d1b33..2b020911f 100644
--- a/bfdd/.gitignore
+++ b/bfdd/.gitignore
@@ -1,3 +1,2 @@
# ignore binary files
-*.a
bfdd
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 4bdfb314e..8acb9438c 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -248,6 +248,8 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
struct iovec iov[1];
uint8_t cmsgbuf[255];
+ port[0] = '\0';
+
/* Prepare the recvmsg params. */
iov[0].iov_base = msgbuf;
iov[0].iov_len = msgbuflen;
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 428789162..a5fae3383 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -289,7 +289,7 @@ static int _ptm_msg_read(struct stream *msg, int command,
{
uint32_t pid;
uint8_t ttl __attribute__((unused));
- uint8_t ifnamelen;
+ size_t ifnamelen;
/*
* Register/Deregister/Update Message format:
diff --git a/bfdd/subdir.am b/bfdd/subdir.am
index 86923f5ce..334e974b0 100644
--- a/bfdd/subdir.am
+++ b/bfdd/subdir.am
@@ -6,6 +6,8 @@ if BFDD
noinst_LIBRARIES += bfdd/libbfd.a
sbin_PROGRAMS += bfdd/bfdd
dist_examples_DATA += bfdd/bfdd.conf.sample
+vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c
+man8 += $(MANBUILD)/bfdd.8
endif
bfdd_libbfd_a_SOURCES = \
diff --git a/bgpd/.gitignore b/bgpd/.gitignore
index 105be2299..2e77195b9 100644
--- a/bgpd/.gitignore
+++ b/bgpd/.gitignore
@@ -1,18 +1,3 @@
-Makefile
-Makefile.in
-*.o
bgpd
bgp_btoa
bgpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
diff --git a/bgpd/Makefile b/bgpd/Makefile
new file mode 100644
index 000000000..b8664a8e2
--- /dev/null
+++ b/bgpd/Makefile
@@ -0,0 +1,10 @@
+all: ALWAYS
+ @$(MAKE) -s -C .. bgpd/bgpd
+%: ALWAYS
+ @$(MAKE) -s -C .. bgpd/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
deleted file mode 100644
index b6b125f75..000000000
--- a/bgpd/Makefile.am
+++ /dev/null
@@ -1,140 +0,0 @@
-## Process this file with automake to produce Makefile.in.
-AUTOMAKE_OPTIONS = subdir-objects
-
-include ../common.am
-
-if ENABLE_BGP_VNC
-#o file to keep linker happy
-BGP_VNC_RFP_LIB=rfapi/rfapi_descriptor_rfp_utils.o @top_builddir@/$(LIBRFP)/librfp.a
-BGP_VNC_RFP_INC=-I@top_srcdir@/$(RFPINC)
-BGP_VNC_RFP_HD=\
- @top_srcdir@/$(RFPINC)/rfp.h
-BGP_VNC_RFP_LD_FLAGS_FILE=@top_srcdir@/$(LIBRFP)/rfp_ld_flags
-BGP_VNC_RFP_LD_FLAGS=`if [ -e "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ] ; then cat "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ; fi `
-
-#BGP_VNC_RFAPI_SRCDIR=rfapi
-BGP_VNC_RFAPI_SRCDIR=
-BGP_VNC_RFAPI_INC=-Irfapi
-BGP_VNC_RFAPI_SRC=rfapi/bgp_rfapi_cfg.c \
- rfapi/rfapi_import.c \
- rfapi/rfapi.c \
- rfapi/rfapi_ap.c \
- rfapi/rfapi_descriptor_rfp_utils.c \
- rfapi/rfapi_encap_tlv.c \
- rfapi/rfapi_nve_addr.c \
- rfapi/rfapi_monitor.c \
- rfapi/rfapi_rib.c \
- rfapi/rfapi_vty.c \
- rfapi/vnc_debug.c \
- rfapi/vnc_export_bgp.c \
- rfapi/vnc_export_table.c \
- rfapi/vnc_import_bgp.c \
- rfapi/vnc_zebra.c
-BGP_VNC_RFAPI_HD=rfapi/bgp_rfapi_cfg.h \
- rfapi/rfapi_import.h \
- rfapi/rfapi.h \
- rfapi/rfapi_ap.h \
- rfapi/rfapi_backend.h \
- rfapi/rfapi_descriptor_rfp_utils.h \
- rfapi/rfapi_encap_tlv.h \
- rfapi/rfapi_nve_addr.h \
- rfapi/rfapi_monitor.h \
- rfapi/rfapi_private.h \
- rfapi/rfapi_rib.h \
- rfapi/rfapi_vty.h \
- rfapi/vnc_debug.h \
- rfapi/vnc_export_bgp.h \
- rfapi/vnc_export_table.h \
- rfapi/vnc_import_bgp.h \
- rfapi/vnc_zebra.h \
- rfapi/vnc_export_bgp_p.h \
- rfapi/vnc_import_bgp_p.h \
- bgp_vnc_types.h $(BGP_VNC_RFP_HD)
-
-else
-BGP_VNC_RFAPI_INC=
-BGP_VNC_RFAPI_SRC=
-BGP_VNC_RFAPI_HD=
-BGP_VNC_RFP_LIB=
-BGP_VNC_RFP_INC=
-BGP_VNC_RFP_HD=
-BGP_VNC_RFP_LD_FLAGS=
-endif
-
-AM_CPPFLAGS += -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
- $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
-DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
-INSTALL_SDATA=@INSTALL@ -m 600
-
-noinst_LIBRARIES = libbgp.a
-module_LTLIBRARIES =
-sbin_PROGRAMS = bgpd
-bin_PROGRAMS = bgp_btoa
-
-BUILT_SOURCES =
-
-libbgp_a_SOURCES = \
- bgp_memory.c \
- bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
- bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
- bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
- bgp_dump.c bgp_ecommunity.c bgp_lcommunity.c \
- bgp_mplsvpn.c bgp_nexthop.c \
- bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \
- bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
- bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \
- bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c bgp_rd.c \
- bgp_keepalives.c bgp_io.c bgp_flowspec.c bgp_flowspec_util.c \
- bgp_flowspec_vty.c bgp_labelpool.c bgp_pbr.c bgp_errors.c
-
-noinst_HEADERS = \
- bgp_memory.h \
- bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
- bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
- bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
- bgp_ecommunity.h bgp_lcommunity.h \
- bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
- bgp_advertise.h bgp_vty.h bgp_mpath.h bgp_nht.h \
- bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h \
- $(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \
- bgp_vpn.h bgp_label.h bgp_rd.h bgp_evpn_private.h bgp_keepalives.h \
- bgp_io.h bgp_flowspec.h bgp_flowspec_private.h bgp_flowspec_util.h \
- bgp_labelpool.h bgp_pbr.h bgp_errors.h
-
-bgpd_SOURCES = bgp_main.c
-bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
-bgpd_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS)
-
-bgp_btoa_SOURCES = bgp_btoa.c
-bgp_btoa_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
-bgp_btoa_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS)
-
-if SNMP
-module_LTLIBRARIES += bgpd_snmp.la
-endif
-
-bgpd_snmp_la_SOURCES = bgp_snmp.c
-bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
-bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
-bgpd_snmp_la_LIBADD = ../lib/libfrrsnmp.la
-
-if RPKI
-module_LTLIBRARIES += bgpd_rpki.la
-BUILT_SOURCES += bgp_rpki_clippy.c
-endif
-
-bgpd_rpki_la_SOURCES = bgp_rpki.c
-bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS)
-bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
-bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS)
-
-examplesdir = $(exampledir)
-dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \
- bgpd.conf.vnc.sample
-
-bgp_vty.o: bgp_vty_clippy.c
-bgp_route.o: bgp_route_clippy.c
-bgp_debug.o: bgp_debug_clippy.c
-
-EXTRA_DIST = BGP4-MIB.txt
-
diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c
index e29508bf3..c604135bf 100644
--- a/bgpd/bgp_flowspec.c
+++ b/bgpd/bgp_flowspec.c
@@ -18,9 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "math.h"
-
#include <zebra.h>
+#include <math.h>
+
#include "prefix.h"
#include "lib_errors.h"
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 32506623c..2107d1f9f 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -5456,7 +5456,8 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
XFREE(MTYPE_BGP_AGGREGATE, aggregate);
}
-static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath,
+static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin,
+ struct aspath *aspath,
struct community *comm)
{
static struct aspath *ae = NULL;
@@ -5467,6 +5468,9 @@ static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath,
if (!ri)
return 0;
+ if (origin != ri->attr->origin)
+ return 0;
+
if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae))
return 0;
@@ -5501,7 +5505,8 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
* If the aggregate information has not changed
* no need to re-install it again.
*/
- if (bgp_aggregate_info_same(rn->info, aspath, community)) {
+ if (bgp_aggregate_info_same(rn->info, origin, aspath,
+ community)) {
bgp_unlock_node(rn);
if (aspath)
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index 82b268c31..2e0bb1ae6 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -49,6 +49,7 @@
#include "bgpd/bgp_route.h"
#include "lib/network.h"
#include "lib/thread.h"
+#ifndef VTYSH_EXTRACT_PL
#include "rtrlib/rtrlib.h"
#include "rtrlib/rtr_mgr.h"
#include "rtrlib/lib/ip.h"
@@ -56,6 +57,7 @@
#if defined(FOUND_SSH)
#include "rtrlib/transport/ssh/ssh_transport.h"
#endif
+#endif
#include "hook.h"
#include "libfrr.h"
#include "version.h"
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index a427608f6..51504bb0a 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -18,9 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c
index 691e1e4ec..c5fda15d3 100644
--- a/bgpd/rfapi/rfapi_ap.c
+++ b/bgpd/rfapi/rfapi_ap.c
@@ -18,8 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c
index 3217d34e7..ce5acf002 100644
--- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c
+++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c
@@ -18,9 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/table.h"
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index 4c506da68..4601718f1 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -23,8 +23,6 @@
* Purpose: Handle import of routes from BGP to RFAPI
*/
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c
index 59387240f..f18c6bfe1 100644
--- a/bgpd/rfapi/rfapi_monitor.c
+++ b/bgpd/rfapi/rfapi_monitor.c
@@ -24,8 +24,6 @@
/* TBD remove unneeded includes */
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index 3ac217ff8..008da3011 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -23,8 +23,6 @@
* Purpose: maintain per-nve ribs and generate change lists
*/
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index b2767da8b..cd751319e 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -18,9 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
diff --git a/bgpd/rfp-example/librfp/Makefile b/bgpd/rfp-example/librfp/Makefile
new file mode 100644
index 000000000..8deb93d74
--- /dev/null
+++ b/bgpd/rfp-example/librfp/Makefile
@@ -0,0 +1,10 @@
+all: ALWAYS
+ @$(MAKE) -s -C ../../.. bgpd/rfp-example/librfp/librfp.a
+%: ALWAYS
+ @$(MAKE) -s -C ../../.. bgpd/rfp-example/librfp/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/bgpd/rfp-example/librfp/Makefile.am b/bgpd/rfp-example/librfp/Makefile.am
deleted file mode 100644
index fc66a40f0..000000000
--- a/bgpd/rfp-example/librfp/Makefile.am
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# This file has been modified by LabN Consulting, L.L.C.
-#
-#
-## Process this file with automake to produce Makefile.in.
-
-if ENABLE_BGP_VNC
-BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi
-BGP_VNC_RFP_LIBDIR=.
-BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR)
-BGP_VNC_RFP_LIB=librfp.a
-BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR)
-
-librfp_a_SOURCES = \
- rfp_example.c
-
-librfp_a_INCLUDES = \
- rfp.h \
- rfp_internal.h
-
-else
-BGP_VNC_RFAPI_INC=
-BGP_VNC_RFAPI_SRC=
-BGP_VNC_RFP_LIB=
-BGP_VNC_RFP_INC=
-endif
-
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \
- -I$(top_builddir) -I$(top_builddir)/lib \
- $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
-DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
-INSTALL_SDATA=@INSTALL@ -m 600
-
-AM_CFLAGS = $(PICFLAGS)
-AM_LDFLAGS = $(PILDFLAGS)
-
-noinst_LIBRARIES = $(BGP_VNC_RFP_LIB)
-
-noinst_HEADERS = \
- $(librfp_a_INCLUDES)
diff --git a/bgpd/rfp-example/librfp/rfp_example.c b/bgpd/rfp-example/librfp/rfp_example.c
index 75e57a029..af3092232 100644
--- a/bgpd/rfp-example/librfp/rfp_example.c
+++ b/bgpd/rfp-example/librfp/rfp_example.c
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/* stub rfp */
#include "rfp_internal.h"
#include "bgpd/rfapi/rfapi.h"
diff --git a/bgpd/rfp-example/librfp/subdir.am b/bgpd/rfp-example/librfp/subdir.am
new file mode 100644
index 000000000..254ab716d
--- /dev/null
+++ b/bgpd/rfp-example/librfp/subdir.am
@@ -0,0 +1,17 @@
+#
+# librfp
+#
+
+if ENABLE_BGP_VNC
+noinst_LIBRARIES += bgpd/rfp-example/librfp/librfp.a
+RFPLDADD = bgpd/rfp-example/librfp/librfp.a
+endif
+
+bgpd_rfp_example_librfp_librfp_a_SOURCES = \
+ bgpd/rfp-example/librfp/rfp_example.c \
+ # end
+
+noinst_HEADERS += \
+ bgpd/rfp-example/librfp/rfp.h \
+ bgpd/rfp-example/librfp/rfp_internal.h \
+ # end
diff --git a/bgpd/rfp-example/rfptest/Makefile b/bgpd/rfp-example/rfptest/Makefile
new file mode 100644
index 000000000..659a9ceb1
--- /dev/null
+++ b/bgpd/rfp-example/rfptest/Makefile
@@ -0,0 +1,10 @@
+all: ALWAYS
+ @$(MAKE) -s -C ../../.. bgpd/rfp-example/rfptest/rfptest
+%: ALWAYS
+ @$(MAKE) -s -C ../../.. bgpd/rfp-example/rfptest/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/bgpd/rfp-example/rfptest/Makefile.am b/bgpd/rfp-example/rfptest/Makefile.am
deleted file mode 100644
index f5db852db..000000000
--- a/bgpd/rfp-example/rfptest/Makefile.am
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# This file has been modified by LabN Consulting, L.L.C.
-#
-#
-## Process this file with automake to produce Makefile.in.
-
-if ENABLE_BGP_VNC
-BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi
-BGP_VNC_RFP_LIBDIR=../librfp
-BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR)
-BGP_VNC_RFP_LIB=$(BGP_VNC_RFP_LIBDIR)/librfp.a
-BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR)
-
-rfptest_SOURCES = \
- rfptest.c
-
-rfptest_INCLUDES = \
- rfptest.h
-
-
-RFPTEST_BIN = rfptest
-
-else
-BGP_VNC_RFAPI_INC=
-BGP_VNC_RFAPI_SRC=
-BGP_VNC_RFP_LIB=
-BGP_VNC_RFP_INC=
-RFPTEST_BIN=
-endif
-
-AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \
- -I$(top_builddir) -I$(top_builddir)/lib \
- $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
-
-DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
-INSTALL_SDATA=@INSTALL@ -m 600
-
-
-AM_CFLAGS = $(PICFLAGS)
-AM_LDFLAGS = $(PILDFLAGS)
-
-
-noinst_HEADERS = \
- $(rfptest_INCLUDES)
-
-noinst_LIBRARIES =
-sbin_PROGRAMS = $(RFPTEST_BIN)
-
-examplesdir = $(exampledir)
-
-rfptest_LDADD = $(top_builddir)/lib/libfrr.la $(BGP_VNC_RFP_LIB)
-dist_examples_DATA =
diff --git a/bgpd/rfp-example/rfptest/rfptest.c b/bgpd/rfp-example/rfptest/rfptest.c
index 53e1c33cf..48df6c0cc 100644
--- a/bgpd/rfp-example/rfptest/rfptest.c
+++ b/bgpd/rfp-example/rfptest/rfptest.c
@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
/* dummy test program */
#include <stdio.h>
diff --git a/bgpd/rfp-example/rfptest/subdir.am b/bgpd/rfp-example/rfptest/subdir.am
new file mode 100644
index 000000000..fa7c66011
--- /dev/null
+++ b/bgpd/rfp-example/rfptest/subdir.am
@@ -0,0 +1,20 @@
+#
+# libtest
+#
+
+if ENABLE_BGP_VNC
+sbin_PROGRAMS += bgpd/rfp-example/rfptest/rfptest
+endif
+
+bgpd_rfp_example_rfptest_rfptest_CFLAGS = -I$(top_srcdir)/bgpd/rfapi
+bgpd_rfp_example_rfptest_rfptest_SOURCES = \
+ bgpd/rfp-example/rfptest/rfptest.c \
+ # end
+noinst_HEADERS += \
+ bgpd/rfp-example/rfptest/rfptest.h \
+ # end
+
+bgpd_rfp_example_rfptest_rfptest_LDADD = \
+ lib/libfrr.la \
+ $(RFPLDADD) \
+ # end
diff --git a/bgpd/subdir.am b/bgpd/subdir.am
new file mode 100644
index 000000000..429138856
--- /dev/null
+++ b/bgpd/subdir.am
@@ -0,0 +1,221 @@
+#
+# bgpd
+#
+
+if BGPD
+noinst_LIBRARIES += bgpd/libbgp.a
+sbin_PROGRAMS += bgpd/bgpd
+noinst_PROGRAMS += bgpd/bgp_btoa
+dist_examples_DATA += \
+ bgpd/bgpd.conf.sample \
+ bgpd/bgpd.conf.sample2 \
+ bgpd/bgpd.conf.vnc.sample \
+ # end
+vtysh_scan += \
+ $(top_srcdir)/bgpd/bgp_bfd.c \
+ $(top_srcdir)/bgpd/bgp_debug.c \
+ $(top_srcdir)/bgpd/bgp_dump.c \
+ $(top_srcdir)/bgpd/bgp_evpn_vty.c \
+ $(top_srcdir)/bgpd/bgp_filter.c \
+ $(top_srcdir)/bgpd/bgp_mplsvpn.c \
+ $(top_srcdir)/bgpd/bgp_nexthop.c \
+ $(top_srcdir)/bgpd/bgp_route.c \
+ $(top_srcdir)/bgpd/bgp_routemap.c \
+ $(top_srcdir)/bgpd/bgp_vty.c \
+ $(top_srcdir)/bgpd/bgp_flowspec_vty.c \
+ # end
+
+# can be loaded as DSO - always include for vtysh
+vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c
+
+if ENABLE_BGP_VNC
+vtysh_scan += \
+ $(top_srcdir)/bgpd/rfapi/bgp_rfapi_cfg.c \
+ $(top_srcdir)/bgpd/rfapi/rfapi.c \
+ $(top_srcdir)/bgpd/rfapi/rfapi_vty.c \
+ $(top_srcdir)/bgpd/rfapi/vnc_debug.c \
+ # end
+endif
+if SNMP
+module_LTLIBRARIES += bgpd/bgpd_snmp.la
+endif
+if RPKI
+module_LTLIBRARIES += bgpd/bgpd_rpki.la
+endif
+man8 += $(MANBUILD)/bgpd.8
+endif
+
+bgpd_libbgp_a_SOURCES = \
+ bgpd/bgp_advertise.c \
+ bgpd/bgp_aspath.c \
+ bgpd/bgp_attr.c \
+ bgpd/bgp_attr_evpn.c \
+ bgpd/bgp_bfd.c \
+ bgpd/bgp_clist.c \
+ bgpd/bgp_community.c \
+ bgpd/bgp_damp.c \
+ bgpd/bgp_debug.c \
+ bgpd/bgp_dump.c \
+ bgpd/bgp_ecommunity.c \
+ bgpd/bgp_encap_tlv.c \
+ bgpd/bgp_errors.c \
+ bgpd/bgp_evpn.c \
+ bgpd/bgp_evpn_vty.c \
+ bgpd/bgp_filter.c \
+ bgpd/bgp_flowspec.c \
+ bgpd/bgp_flowspec_util.c \
+ bgpd/bgp_flowspec_vty.c \
+ bgpd/bgp_fsm.c \
+ bgpd/bgp_io.c \
+ bgpd/bgp_keepalives.c \
+ bgpd/bgp_label.c \
+ bgpd/bgp_labelpool.c \
+ bgpd/bgp_lcommunity.c \
+ bgpd/bgp_memory.c \
+ bgpd/bgp_mpath.c \
+ bgpd/bgp_mplsvpn.c \
+ bgpd/bgp_network.c \
+ bgpd/bgp_nexthop.c \
+ bgpd/bgp_nht.c \
+ bgpd/bgp_open.c \
+ bgpd/bgp_packet.c \
+ bgpd/bgp_pbr.c \
+ bgpd/bgp_rd.c \
+ bgpd/bgp_regex.c \
+ bgpd/bgp_route.c \
+ bgpd/bgp_routemap.c \
+ bgpd/bgp_table.c \
+ bgpd/bgp_updgrp.c \
+ bgpd/bgp_updgrp_adv.c \
+ bgpd/bgp_updgrp_packet.c \
+ bgpd/bgp_vpn.c \
+ bgpd/bgp_vty.c \
+ bgpd/bgp_zebra.c \
+ bgpd/bgpd.c \
+ # end
+
+if ENABLE_BGP_VNC
+bgpd_libbgp_a_SOURCES += \
+ bgpd/rfapi/bgp_rfapi_cfg.c \
+ bgpd/rfapi/rfapi_import.c \
+ bgpd/rfapi/rfapi.c \
+ bgpd/rfapi/rfapi_ap.c \
+ bgpd/rfapi/rfapi_descriptor_rfp_utils.c \
+ bgpd/rfapi/rfapi_encap_tlv.c \
+ bgpd/rfapi/rfapi_nve_addr.c \
+ bgpd/rfapi/rfapi_monitor.c \
+ bgpd/rfapi/rfapi_rib.c \
+ bgpd/rfapi/rfapi_vty.c \
+ bgpd/rfapi/vnc_debug.c \
+ bgpd/rfapi/vnc_export_bgp.c \
+ bgpd/rfapi/vnc_export_table.c \
+ bgpd/rfapi/vnc_import_bgp.c \
+ bgpd/rfapi/vnc_zebra.c \
+ # end
+endif
+
+noinst_HEADERS += \
+ bgpd/bgp_advertise.h \
+ bgpd/bgp_aspath.h \
+ bgpd/bgp_attr.h \
+ bgpd/bgp_attr_evpn.h \
+ bgpd/bgp_bfd.h \
+ bgpd/bgp_clist.h \
+ bgpd/bgp_community.h \
+ bgpd/bgp_damp.h \
+ bgpd/bgp_debug.h \
+ bgpd/bgp_dump.h \
+ bgpd/bgp_ecommunity.h \
+ bgpd/bgp_encap_tlv.h \
+ bgpd/bgp_encap_types.h \
+ bgpd/bgp_errors.h \
+ bgpd/bgp_evpn.h \
+ bgpd/bgp_evpn_private.h \
+ bgpd/bgp_evpn_vty.h \
+ bgpd/bgp_filter.h \
+ bgpd/bgp_flowspec.h \
+ bgpd/bgp_flowspec_private.h \
+ bgpd/bgp_flowspec_util.h \
+ bgpd/bgp_fsm.h \
+ bgpd/bgp_io.h \
+ bgpd/bgp_keepalives.h \
+ bgpd/bgp_label.h \
+ bgpd/bgp_labelpool.h \
+ bgpd/bgp_lcommunity.h \
+ bgpd/bgp_memory.h \
+ bgpd/bgp_mpath.h \
+ bgpd/bgp_mplsvpn.h \
+ bgpd/bgp_network.h \
+ bgpd/bgp_nexthop.h \
+ bgpd/bgp_nht.h \
+ bgpd/bgp_open.h \
+ bgpd/bgp_packet.h \
+ bgpd/bgp_pbr.h \
+ bgpd/bgp_rd.h \
+ bgpd/bgp_regex.h \
+ bgpd/bgp_route.h \
+ bgpd/bgp_table.h \
+ bgpd/bgp_updgrp.h \
+ bgpd/bgp_vpn.h \
+ bgpd/bgp_vty.h \
+ bgpd/bgp_zebra.h \
+ bgpd/bgpd.h \
+ \
+ bgpd/rfapi/bgp_rfapi_cfg.h \
+ bgpd/rfapi/rfapi_import.h \
+ bgpd/rfapi/rfapi.h \
+ bgpd/rfapi/rfapi_ap.h \
+ bgpd/rfapi/rfapi_backend.h \
+ bgpd/rfapi/rfapi_descriptor_rfp_utils.h \
+ bgpd/rfapi/rfapi_encap_tlv.h \
+ bgpd/rfapi/rfapi_nve_addr.h \
+ bgpd/rfapi/rfapi_monitor.h \
+ bgpd/rfapi/rfapi_private.h \
+ bgpd/rfapi/rfapi_rib.h \
+ bgpd/rfapi/rfapi_vty.h \
+ bgpd/rfapi/vnc_debug.h \
+ bgpd/rfapi/vnc_export_bgp.h \
+ bgpd/rfapi/vnc_export_table.h \
+ bgpd/rfapi/vnc_import_bgp.h \
+ bgpd/rfapi/vnc_zebra.h \
+ bgpd/rfapi/vnc_export_bgp_p.h \
+ bgpd/rfapi/vnc_import_bgp_p.h \
+ bgpd/bgp_vnc_types.h \
+ # end
+
+bgpd_bgpd_SOURCES = bgpd/bgp_main.c
+bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c
+
+if ENABLE_BGP_VNC
+bgpd_bgpd_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c
+bgpd_bgpd_CFLAGS = -Irfapi -I@top_srcdir@/$(RFPINC)
+
+bgpd_bgp_btoa_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c
+bgpd_bgp_btoa_CFLAGS = -Irfapi -I@top_srcdir@/$(RFPINC)
+endif
+
+# RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am
+bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la @LIBCAP@ @LIBM@
+bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la @LIBCAP@ @LIBM@
+
+bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c
+bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
+bgpd_bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
+bgpd_bgpd_snmp_la_LIBADD = lib/libfrrsnmp.la
+
+bgpd_bgpd_rpki_la_SOURCES = bgpd/bgp_rpki.c
+bgpd_bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS)
+bgpd_bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
+bgpd_bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS)
+
+bgpd/bgp_vty_clippy.c: $(CLIPPY_DEPS)
+bgpd/bgp_vty.$(OBJEXT): bgpd/bgp_vty_clippy.c
+bgpd/bgp_route_clippy.c: $(CLIPPY_DEPS)
+bgpd/bgp_route.$(OBJEXT): bgpd/bgp_route_clippy.c
+bgpd/bgp_debug_clippy.c: $(CLIPPY_DEPS)
+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/common.am b/common.am
deleted file mode 100644
index 9c0c54781..000000000
--- a/common.am
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Automake fragment intended to be shared by Makefile.am files in the
-# tree. When used, should be included at the very top of the file.
-#
-AM_CPPFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@
-AM_CFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ $(WERROR)
-
-AM_V_CLIPPY = $(am__v_CLIPPY_$(V))
-am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY))
-am__v_CLIPPY_0 = @echo " CLIPPY " $@;
-am__v_CLIPPY_1 =
-
-CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py
-
-SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h
-.c_clippy.c:
- @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; }
- $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $<
-
-## automake's "ylwrap" is a great piece of GNU software... not.
-.l.c:
- $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $<
-.y.c:
- $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $<
-
-
-if HAVE_PROTOBUF
-
-# Uncomment to use an non-system version of libprotobuf-c.
-#
-# Q_PROTOBUF_C_CLIENT_INCLUDES = -I$(top_srcdir)/third-party/protobuf-c/src
-# Q_PROTOBUF_C_CLIENT_LDOPTS = $(top_builddir)/third-party/protobuf-c/src/libprotobuf-c.la
-
-Q_PROTOBUF_C_CLIENT_INCLUDES=
-Q_PROTOBUF_C_CLIENT_LDOPTS=-lprotobuf-c
-
-Q_PROTOC=protoc
-Q_PROTOC_C=protoc-c
-
-# Rules
-.proto.pb.h:
- $(Q_PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^
-
-AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V))
-am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY))
-am__v_PROTOC_C_0 = @echo " PROTOC_C" $@;
-am__v_PROTOC_C_1 =
-
-.proto.pb-c.c:
- $(AM_V_PROTOC_C)$(Q_PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^
-.pb-c.c.pb-c.h:
- @/bin/true
-
-#
-# Information about how to link to various libraries.
-#
-Q_FRR_PB_CLIENT_LDOPTS = $(top_srcdir)/qpb/libfrr_pb.la $(Q_PROTOBUF_C_CLIENT_LDOPTS)
-
-Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfrrfpm_pb.la $(Q_FRR_PB_CLIENT_LDOPTS)
-
-endif # HAVE_PROTOBUF
diff --git a/configure.ac b/configure.ac
index 09a6f364f..08f1c117e 100755
--- a/configure.ac
+++ b/configure.ac
@@ -57,7 +57,7 @@ AM_CONDITIONAL([BUILD_CLIPPY], [$build_clippy])
# Disable portability warnings -- our automake code (in particular
# common.am) uses some constructs specific to gmake.
-AM_INIT_AUTOMAKE([1.12 -Wno-portability])
+AM_INIT_AUTOMAKE([1.12 -Wno-portability foreign])
m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS(config.h)
@@ -189,46 +189,6 @@ CC="${CC% -std=c99}"
AC_C_FLAG([-std=gnu11], [CC="$ac_cc"], [CC="$CC -std=gnu11"])
-dnl AddressSanitizer support
-AC_ARG_ENABLE([address-sanitizer], AS_HELP_STRING([--enable-address-sanitizer], \
- [enabled AddressSanitizer support for detecting a wide variety of \
- memory allocation and deallocation errors]), \
- [AC_DEFINE(HAVE_ADDRESS_SANITIZER, 1, [enable AddressSanitizer])
- ASAN_FLAGS="-fsanitize=address"
- SAN_CLIPPY_FLAGS="-fno-sanitize=all"
- AC_SUBST([ASAN_FLAGS])
- AC_SUBST([SAN_CLIPPY_FLAGS])
- LIBS="-ldl $LIBS"
- AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Address Sanitizer Enabled])],
- [AC_MSG_ERROR([Address Sanitizer not available])])
- ])
-
-dnl ThreadSanitizer support
-AC_ARG_ENABLE([thread-sanitizer], AS_HELP_STRING([--enable-thread-sanitizer], \
- [enabled ThreadSanitizer support for detecting data races]), \
- [AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable ThreadSanitizer])
- TSAN_FLAGS="-fsanitize=thread"
- SAN_CLIPPY_FLAGS="-fno-sanitize=all"
- AC_SUBST([TSAN_FLAGS])
- AC_SUBST([SAN_CLIPPY_FLAGS])
- LIBS="-ldl $LIBS"
- AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Thread Sanitizer Enabled])],
- [AC_MSG_ERROR([Thread Sanitizer not available])])
- ])
-
-dnl MemorySanitizer support
-AC_ARG_ENABLE([memory-sanitizer], AS_HELP_STRING([--enable-memory-sanitizer], \
- [enabled MemorySanitizer support for detecting uninitialized memory reads]), \
- [AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable MemorySanitizer])
- MSAN_FLAGS="-fsanitize=memory -fPIE -pie"
- SAN_CLIPPY_FLAGS="-fno-sanitize=all"
- AC_SUBST([MSAN_FLAGS])
- AC_SUBST([SAN_CLIPPY_FLAGS])
- LIBS="-ldl $LIBS"
- AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Memory Sanitizer Enabled])],
- [AC_MSG_ERROR([Memory Sanitizer not available])])
- ])
-
dnl if the user has specified any CFLAGS, override our settings
if test "x${enable_gcov}" = "xyes"; then
if test "z$orig_cflags" = "z"; then
@@ -287,19 +247,29 @@ if test x"${enable_werror}" = x"yes" ; then
fi
AC_SUBST(WERROR)
-dnl need link on this one, not compile
-AC_LANG_PUSH(C)
-ac_ld_flag_save="$LDFLAGS"
-LDFLAGS="$LDFLAGS -rdynamic"
-AC_MSG_CHECKING([[whether linker supports -rdynamic]])
-AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([[]])],
- [AC_MSG_RESULT([yes])],
- [
- LDFLAGS="$ac_ld_flag_save"
- AC_MSG_RESULT([no])
- ])
-AC_LANG_POP(C)
+SAN_FLAGS=""
+if test "$enable_address_sanitizer" = "yes"; then
+ AC_C_FLAG([-fsanitize=address], [
+ AC_MSG_ERROR([$CC does not support Address Sanitizer.])
+ ], [
+ SAN_FLAGS="$SAN_FLAGS -fsanitize=address"
+ ])
+fi
+if test "$enable_thread_sanitizer" = "yes"; then
+ AC_C_FLAG([-fsanitize=thread], [
+ AC_MSG_ERROR([$CC does not support Thread Sanitizer.])
+ ], [
+ SAN_FLAGS="$SAN_FLAGS -fsanitize=thread"
+ ])
+fi
+if test "$enable_memory_sanitizer" = "yes"; then
+ AC_C_FLAG([-fsanitize=thread -fPIE -pie], [
+ AC_MSG_ERROR([$CC does not support Thread Sanitizer.])
+ ], [
+ SAN_FLAGS="-fsanitize=memory -fPIE -pie"
+ ])
+fi
+AC_SUBST([SAN_FLAGS])
dnl ----------
dnl Essentials
@@ -313,6 +283,13 @@ AX_PTHREAD([
AC_MSG_FAILURE([This FRR version needs pthreads])
])
+AC_SEARCH_LIBS([pthread_condattr_setclock], [],
+ [frr_cv_pthread_condattr_setclock=yes],
+ [frr_cv_pthread_condattr_setclock=no])
+if test "$frr_cv_pthread_condattr_setclock" = yes; then
+ AC_DEFINE(HAVE_PTHREAD_CONDATTR_SETCLOCK, 1, [Have pthread.h pthread_condattr_setclock])
+fi
+
dnl --------------
dnl Check programs
dnl --------------
@@ -321,11 +298,6 @@ AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_CHECK_TOOL(AR, ar)
-dnl -----------------
-dnl System extensions
-dnl -----------------
-AC_GNU_SOURCE
-
dnl -------
dnl libtool
dnl -------
@@ -381,12 +353,12 @@ AC_ARG_ENABLE(sharpd,
AS_HELP_STRING([--enable-sharpd], [build sharpd]))
AC_ARG_ENABLE(staticd,
AS_HELP_STRING([--disable-staticd], [do not build staticd]))
+AC_ARG_ENABLE(fabricd,
+ AS_HELP_STRING([--disable-fabricd], [do not build fabricd]))
AC_ARG_ENABLE(bgp-announce,
AS_HELP_STRING([--disable-bgp-announce,], [turn off BGP route announcement]))
AC_ARG_ENABLE(bgp-vnc,
AS_HELP_STRING([--disable-bgp-vnc],[turn off BGP VNC support]))
-AC_ARG_WITH(rfp-path,
- AS_HELP_STRING([--with-rfp-path[=DIR]],[path to replaced stub RFP used with BGP VNC]))
AC_ARG_ENABLE(snmp,
AS_HELP_STRING([--enable-snmp], [enable SNMP support for agentx]))
AC_ARG_ENABLE(zeromq,
@@ -460,6 +432,12 @@ AC_ARG_ENABLE([gcov],
AS_HELP_STRING([--enable-gcov], [Add code coverage information]))
AC_ARG_ENABLE(bfdd,
AS_HELP_STRING([--disable-bfdd], [do not build bfdd]))
+AC_ARG_ENABLE([address-sanitizer],
+ AS_HELP_STRING([--enable-address-sanitizer], [enable AddressSanitizer support for detecting a wide variety of memory allocation and deallocation errors]))
+AC_ARG_ENABLE([thread-sanitizer],
+ AS_HELP_STRING([--enable-thread-sanitizer], [enable ThreadSanitizer support for detecting data races]))
+AC_ARG_ENABLE([memory-sanitizer],
+ AS_HELP_STRING([--enable-memory-sanitizer], [enable MemorySanitizer support for detecting uninitialized memory reads]))
AS_IF([test "${enable_clippy_only}" != "yes"], [
AC_CHECK_HEADERS(json-c/json.h)
@@ -623,27 +601,26 @@ AC_SUBST(PYTHON_LIBS)
# Logic for protobuf support.
#
if test "$enable_protobuf" = "yes"; then
- have_protobuf=yes
-
- # Check for protoc-c
- AC_CHECK_PROG([PROTOC_C], [protoc-c], [protoc-c], [/bin/false])
- if test "x$PROTOC_C" = "x/bin/false"; then
- have_protobuf=no
- else
- found_protobuf_c=no
- PKG_CHECK_MODULES([PROTOBUF_C], libprotobuf-c >= 0.14,
- [found_protobuf_c=yes],
- [AC_MSG_RESULT([pkg-config did not find libprotobuf-c])])
-
- if test "x$found_protobuf_c" = "xyes"; then
- LDFLAGS="$LDFLAGS $PROTOBUF_C_LIBS"
- CFLAGS="$CFLAGS $PROTOBUF_C_CFLAGS"
- else
- AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [],
- [have_protobuf=no; AC_MSG_RESULT([Couldn't find google/protobuf-c.h])])
- fi
- fi
+ # Check for protoc & protoc-c
+
+ # protoc is not required, it's only for a "be nice" helper target
+ AC_CHECK_PROGS([PROTOC], [protoc], [/bin/false])
+
+ AC_CHECK_PROGS([PROTOC_C], [protoc-c], [/bin/false])
+ if test "$PROTOC_C" = "/bin/false"; then
+ AC_MSG_FAILURE([protobuf requested but protoc-c not found. Install protobuf-c.])
+ fi
+
+ PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c >= 0.14],, [
+ AC_MSG_FAILURE([protobuf requested but libprotobuf-c not found. Install protobuf-c.])
+ ])
+ AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [], [
+ AC_MSG_FAILURE([protobuf requested but protobuf-c.h not found. Install protobuf-c.])
+ ])
+
+ AC_DEFINE(HAVE_PROTOBUF,, protobuf)
fi
+AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$enable_protobuf" = "xyes"])
#
# Logic for old vpn commans support.
@@ -652,18 +629,6 @@ if test "$enable_oldvpn_commands" = "yes"; then
AC_DEFINE(KEEP_OLD_VPN_COMMANDS,, [Define for compiling with old vpn commands])
fi
-# Fail if the user explicity enabled protobuf support and we couldn't
-# find the compiler or libraries.
-if test "x$have_protobuf" = "xno" && test "x$enable_protobuf" = "xyes"; then
- AC_MSG_ERROR([Protobuf enabled explicitly but can't find libraries/tools])
-fi
-
-if test "x$have_protobuf" = "xyes"; then
- AC_DEFINE(HAVE_PROTOBUF,, protobuf)
-fi
-
-AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$have_protobuf" = "xyes"])
-
#
# End of logic for protobuf support.
#
@@ -850,10 +815,15 @@ int main(int argc, char **argv) {
])
])
+AC_CHECK_HEADERS([pthread_np.h],,, [
+#include <pthread.h>
+])
+AC_CHECK_FUNCS([pthread_setname_np pthread_set_name_np])
+
dnl Utility macro to avoid retyping includes all the time
m4_define([FRR_INCLUDES],
[#ifdef SUNOS_5
-#define _XPG4_2
+#define _POSIX_C_SOURCE 200809L
#define __EXTENSIONS__
#endif
#include <stdio.h>
@@ -946,6 +916,7 @@ case "$host_os" in
AC_DEFINE(SUNOS_5, 1, [SunOS 5])
AC_DEFINE(SOLARIS_IPV6, 1, Solaris IPv6)
+ AC_DEFINE(_POSIX_C_SOURCE, 200809L, [enable POSIX.1-2008 and XPG7/SUSv4])
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
@@ -1049,6 +1020,10 @@ dnl [TODO] on Linux, and in [TODO] on Solaris.
if test $ac_cv_lib_readline_rl_completion_matches = no; then
AC_DEFINE(rl_completion_matches,completion_matches,Old readline)
fi
+ AC_SEARCH_LIBS([append_history], [readline], [frr_cv_append_history=yes], [frr_cv_append_history=no])
+ if test "$frr_cv_append_history" = yes; then
+ AC_DEFINE(HAVE_APPEND_HISTORY, 1, [Have history.h append_history])
+ fi
;;
esac
AC_SUBST(LIBREADLINE)
@@ -1197,11 +1172,12 @@ case "$host_os" in
if test $ac_cv_header_net_bpf_h = no; then
if test $ac_cv_header_sys_dlpi_h = no; then
AC_MSG_RESULT(none)
- if test "${enable_isisd}" = yes; then
+ if test "${enable_isisd}" = yes -o "${enable_fabricd}" = yes; then
AC_MSG_FAILURE([IS-IS support requested but no packet backend found])
fi
AC_MSG_WARN([*** IS-IS support will not be built ***])
enable_isisd="no"
+ enable_fabricd="no"
else
AC_MSG_RESULT(DLPI)
fi
@@ -1339,8 +1315,13 @@ FRR_INCLUDES
])dnl
dnl disable doc check
-AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [no])
-AM_CONDITIONAL(DOC, test "${enable_doc}" != "no")
+AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [/bin/false])
+if test "$SPHINXBUILD" = "/bin/false"; then
+ if test "${enable_doc}" = "yes"; then
+ AC_MSG_ERROR([Documentation was explicitly requested with --enable-doc but sphinx-build is not available. Please disable docs or install sphinx.])
+ fi
+fi
+AM_CONDITIONAL(DOC, test "${enable_doc}" != "no" -a "$SPHINXBUILD" != "/bin/false")
AM_CONDITIONAL(DOC_HTML, test "${enable_doc_html}" = "yes")
dnl --------------------
@@ -1429,6 +1410,7 @@ AM_CONDITIONAL(PIMD, test "${enable_pimd}" != "no")
AM_CONDITIONAL(PBRD, test "${enable_pbrd}" != "no")
AM_CONDITIONAL(SHARPD, test "${enable_sharpd}" = "yes")
AM_CONDITIONAL(STATICD, test "${enable_staticd}" != "no")
+AM_CONDITIONAL(FABRICD, test "${enable_fabricd}" != "no")
if test "${enable_bgp_announce}" = "no";then
AC_DEFINE(DISABLE_BGP_ANNOUNCE,1,Disable BGP installation to zebra)
@@ -1436,33 +1418,12 @@ else
AC_DEFINE(DISABLE_BGP_ANNOUNCE,0,Disable BGP installation to zebra)
fi
-if test "${with_rfp_path}" = "yes" || test x"${with_rfp_path}" = x""; then
- with_rfp_path="bgpd/rfp-example"
-fi
-if test "${with_rfp_path}" != "no"; then
- VNC_RFP_PATH="${with_rfp_path}"
- AC_SUBST(VNC_RFP_PATH)
-fi
-
if test "${enable_bgp_vnc}" != "no";then
AC_DEFINE(ENABLE_BGP_VNC,1,Enable BGP VNC support)
- RFPTEST="${with_rfp_path}/rfptest"
- LIBRFP="${with_rfp_path}/librfp"
- RFPINC="${with_rfp_path}/librfp"
-else
- RFPTEST=
- LIBRFP=
- RFPINC="bgpd/rfp-example/librfp"
fi
-# set
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
-AC_SUBST(RFPTEST)
-AC_SUBST(LIBRFP)
-AC_SUBST(RFPINC)
-AC_SUBST(BGPD)
AC_SUBST(SOLARIS)
-AC_SUBST(VTYSH)
AC_SUBST(CURSES)
AC_CHECK_LIB(crypt, crypt, [],
[AC_CHECK_LIB(crypto, DES_crypt)])
@@ -1833,13 +1794,16 @@ dnl order to check no alternative allocator
dnl has been specified, which might not provide
dnl mallinfo, e.g. such as Umem on Solaris.
dnl -----------------------------------------
-AC_CHECK_HEADERS([malloc.h malloc/malloc.h],,, [FRR_INCLUDES])
+AC_CHECK_HEADERS([malloc.h malloc_np.h malloc/malloc.h],,, [FRR_INCLUDES])
AC_CACHE_CHECK([whether mallinfo is available], [frr_cv_mallinfo], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
+#ifdef HAVE_MALLOC_NP_H
+#include <malloc_np.h>
+#endif
#ifdef HAVE_MALLOC_MALLOC_H
#include <malloc/malloc.h>
#endif
@@ -1983,8 +1947,7 @@ dnl Enable RPKI and add librtr to libs
dnl ------------------------------------
if test "${enable_rpki}" = "yes"; then
PKG_CHECK_MODULES(RTRLIB,[rtrlib >= 0.5.0],
- [AC_DEFINE(HAVE_RPKI,1,Enable RPKI prefix validation for BGP)
- RPKI=true],
+ [RPKI=true],
[RPKI=false
AC_MSG_ERROR([rtrlib was not found on your system or is too old.])]
)
@@ -2016,11 +1979,6 @@ AC_MSG_RESULT($ac_cv_htonl_works)
AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile])
AC_CONFIG_FILES([
- bgpd/Makefile
- vtysh/Makefile
- tests/Makefile
- bgpd/rfp-example/rfptest/Makefile
- bgpd/rfp-example/librfp/Makefile
redhat/frr.spec
solaris/Makefile
debianpkg/changelog
@@ -2032,12 +1990,6 @@ AC_CONFIG_FILES([
pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
pkgsrc/eigrpd.sh])
-if test "${enable_bgp_vnc}" != "no"; then
- if test "${with_rfp_path}" != "bgpd/rfp-example" ; then
- AC_CONFIG_FILES([${with_rfp_path}/rfptest/Makefile ${with_rfp_path}/librfp/Makefile])
- fi
-fi
-
AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl])
AC_CONFIG_COMMANDS([lib/route_types.h], [
@@ -2079,9 +2031,9 @@ FRR version : ${PACKAGE_VERSION}
host operating system : ${host_os}
source code location : ${srcdir}
compiler : ${CC}
-compiler flags : ${CFLAGS}
+compiler flags : ${CFLAGS} ${SAN_FLAGS}
make : ${MAKE-make}
-linker flags : ${LDFLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM}
+linker flags : ${LDFLAGS} ${SAN_FLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM}
state file directory : ${frr_statedir}
config file directory : `eval echo \`echo ${sysconfdir}\``
example directory : `eval echo \`echo ${exampledir}\``
@@ -2091,12 +2043,12 @@ group to run as : ${enable_group}
group for vty sockets : ${enable_vty_group}
config file mask : ${enable_configfile_mask}
log file mask : ${enable_logfile_mask}
-zebra protobuf enabled : ${have_protobuf:-no}
+zebra protobuf enabled : ${enable_protobuf:-no}
The above user and group must have read/write access to the state file
directory and to the config files in the config file directory."
if test "${enable_doc}" != "no";then
- AS_IF([test "x$SPHINXBUILD" = xno],
+ AS_IF([test "$SPHINXBUILD" = /bin/false],
AC_MSG_WARN(sphinx-build is missing but required to build documentation))
fi
diff --git a/debianpkg/frr-doc.docs b/debianpkg/frr-doc.docs
index d2218d00f..605353289 100644
--- a/debianpkg/frr-doc.docs
+++ b/debianpkg/frr-doc.docs
@@ -1,5 +1,3 @@
-AUTHORS
-NEWS
-README
+README.md
doc/user/*.rst
doc/figures/*.png
diff --git a/doc/.gitignore b/doc/.gitignore
index d99a6a5b2..fa2b50832 100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -1,4 +1,3 @@
-!Makefile
mdate-sh
draft-zebra-00.txt
*.pdf
@@ -6,7 +5,6 @@ draft-zebra-00.txt
frr.ps
frr.dvi
stamp-vti
-.nfs*
*.aux
*.cp
*.cps
@@ -20,8 +18,4 @@ stamp-vti
*.toc
*.tp
*.vr
-.arch-inventory
-.arch-ids
-*~
-*.loT
refix
diff --git a/doc/developer/building-frr-for-centos6.rst b/doc/developer/building-frr-for-centos6.rst
index d4c2c3bfd..5f10f3715 100644
--- a/doc/developer/building-frr-for-centos6.rst
+++ b/doc/developer/building-frr-for-centos6.rst
@@ -128,8 +128,8 @@ Add frr groups and user
.. code-block:: shell
sudo groupadd -g 92 frr
- sudo groupadd -r -g 85 frrvt
- sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \
+ sudo groupadd -r -g 85 frrvty
+ sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \
-c "FRR FRRouting suite" -d /var/run/frr frr
Download Source, configure and compile it
@@ -158,7 +158,7 @@ an example.)
--enable-ospfapi=yes \
--enable-user=frr \
--enable-group=frr \
- --enable-vty-group=frrvt \
+ --enable-vty-group=frrvty \
--enable-rtadv \
--disable-exampledir \
--enable-watchfrr \
@@ -168,10 +168,11 @@ an example.)
--enable-eigrpd \
--enable-babeld \
--with-pkg-git-version \
- --with-pkg-extra-version=-MyOwnFRRVersion
- make SPHINXBUILD=sphinx-build2.7
- make check PYTHON=/usr/bin/python2.7 SPHINXBUILD=sphinx-build2.7
- sudo make SPHINXBUILD=sphinx-build2.7 install
+ --with-pkg-extra-version=-MyOwnFRRVersion \
+ SPHINXBUILD=sphinx-build2.7
+ make
+ make check PYTHON=/usr/bin/python2.7
+ sudo make install
Create empty FRR configuration files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst
index 31cd4dcc4..b157f540a 100644
--- a/doc/developer/building-frr-for-centos7.rst
+++ b/doc/developer/building-frr-for-centos7.rst
@@ -36,8 +36,8 @@ Add frr groups and user
::
sudo groupadd -g 92 frr
- sudo groupadd -r -g 85 frrvt
- sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \
+ sudo groupadd -r -g 85 frrvty
+ sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \
-c "FRR FRRouting suite" -d /var/run/frr frr
Download Source, configure and compile it
@@ -66,7 +66,7 @@ an example.)
--enable-ospfapi=yes \
--enable-user=frr \
--enable-group=frr \
- --enable-vty-group=frrvt \
+ --enable-vty-group=frrvty \
--enable-rtadv \
--enable-systemd=yes \
--disable-exampledir \
@@ -102,7 +102,7 @@ Create empty FRR configuration files
sudo touch /etc/frr/babeld.conf
sudo chown -R frr:frr /etc/frr/
sudo touch /etc/frr/vtysh.conf
- sudo chown frr:frrvt /etc/frr/vtysh.conf
+ sudo chown frr:frrvty /etc/frr/vtysh.conf
sudo chmod 640 /etc/frr/*.conf
Install daemon config file
diff --git a/doc/developer/building-frr-for-fedora24.rst b/doc/developer/building-frr-for-fedora24.rst
index 208c580b6..669cc4ae2 100644
--- a/doc/developer/building-frr-for-fedora24.rst
+++ b/doc/developer/building-frr-for-fedora24.rst
@@ -29,8 +29,8 @@ Add frr groups and user
::
sudo groupadd -g 92 frr
- sudo groupadd -r -g 85 frrvt
- sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \
+ sudo groupadd -r -g 85 frrvty
+ sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \
-c "FRR FRRouting suite" -d /var/run/frr frr
Download Source, configure and compile it
@@ -59,7 +59,7 @@ an example.)
--enable-ospfapi=yes \
--enable-user=frr \
--enable-group=frr \
- --enable-vty-group=frrvt \
+ --enable-vty-group=frrvty \
--enable-rtadv \
--disable-exampledir \
--enable-watchfrr \
@@ -95,7 +95,7 @@ Create empty FRR configuration files
sudo touch /etc/frr/babeld.conf
sudo chown -R frr:frr /etc/frr/
sudo touch /etc/frr/vtysh.conf
- sudo chown frr:frrvt /etc/frr/vtysh.conf
+ sudo chown frr:frrvty /etc/frr/vtysh.conf
sudo chmod 640 /etc/frr/*.conf
Install daemon config file
diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst
index 20391c47b..c0716a5c9 100644
--- a/doc/developer/cli.rst
+++ b/doc/developer/cli.rst
@@ -450,8 +450,6 @@ is no ordering requirement)
.. code-block:: make
- include ../common.am
-
# ...
# if linked into a LTLIBRARY (.la/.so):
diff --git a/doc/manpages/common-options.rst b/doc/manpages/common-options.rst
index 5fff6fca6..74d3eb7bb 100644
--- a/doc/manpages/common-options.rst
+++ b/doc/manpages/common-options.rst
@@ -125,6 +125,7 @@ These following options control the daemon's VTY (interactive command line) inte
pbrd 2615
staticd 2616
bfdd 2617
+ fabricd 2618
Port 2607 is used for ospfd's Opaque LSA API.
diff --git a/doc/manpages/conf.py b/doc/manpages/conf.py
index e540d236e..f57bc1d27 100644
--- a/doc/manpages/conf.py
+++ b/doc/manpages/conf.py
@@ -333,6 +333,7 @@ man_pages = [
('vtysh', 'vtysh', 'an integrated shell for FRRouting.', [], 1),
('frr', 'frr', 'a systemd interaction script', [], 1),
('bfdd', 'bfdd', fwfrr.format("a bfd"), [], 8),
+ ('fabricd', 'fabricd', fwfrr.format("an OpenFabric "), [], 8),
]
# -- Options for Texinfo output -------------------------------------------
diff --git a/doc/manpages/fabricd.rst b/doc/manpages/fabricd.rst
new file mode 100644
index 000000000..c14c07661
--- /dev/null
+++ b/doc/manpages/fabricd.rst
@@ -0,0 +1,38 @@
+*******
+FABRICD
+*******
+
+.. include:: defines.rst
+.. |DAEMON| replace:: fabricd
+
+SYNOPSIS
+========
+|DAEMON| |synopsis-options-hv|
+
+|DAEMON| |synopsis-options|
+
+DESCRIPTION
+===========
+|DAEMON| is a routing component that works with the FRRouting routing engine.
+
+OPTIONS
+=======
+OPTIONS available for the |DAEMON| command:
+
+.. include:: common-options.rst
+
+FILES
+=====
+
+|INSTALL_PREFIX_SBIN|/|DAEMON|
+ The default location of the |DAEMON| binary.
+
+|INSTALL_PREFIX_ETC|/|DAEMON|.conf
+ The default location of the |DAEMON| config file.
+
+$(PWD)/|DAEMON|.log
+ If the |DAEMON| process is configured to output logs to a file, then you
+ will find this file in the directory where you started |DAEMON|.
+
+.. include:: epilogue.rst
+
diff --git a/doc/manpages/index.rst b/doc/manpages/index.rst
index c62835c77..053555c4e 100644
--- a/doc/manpages/index.rst
+++ b/doc/manpages/index.rst
@@ -10,6 +10,7 @@
bgpd
eigrpd
isisd
+ fabricd
ldpd
nhrpd
ospf6d
diff --git a/doc/manpages/subdir.am b/doc/manpages/subdir.am
index 24f47fc7a..4a9aa4de4 100644
--- a/doc/manpages/subdir.am
+++ b/doc/manpages/subdir.am
@@ -9,6 +9,7 @@ man_RSTFILES = \
doc/manpages/defines.rst \
doc/manpages/eigrpd.rst \
doc/manpages/epilogue.rst \
+ doc/manpages/fabricd.rst \
doc/manpages/frr.rst \
doc/manpages/index.rst \
doc/manpages/isisd.rst \
@@ -46,83 +47,16 @@ rstman8dir = $(mandir)/man8
rstman1_DATA =
rstman8_DATA =
-rstman1_DATA += $(MANBUILD)/frr.1
+if DOC
+rstman1_DATA += $(man1)
+rstman8_DATA += $(man8)
+endif # DOC
-if PIMD
-rstman8_DATA += $(MANBUILD)/pimd.8
-rstman8_DATA += $(MANBUILD)/mtracebis.8
-endif
-
-if PBRD
-rstman8_DATA += $(MANBUILD)/pbrd.8
-endif
-
-if BGPD
-rstman8_DATA += $(MANBUILD)/bgpd.8
-endif
-
-if ISISD
-rstman8_DATA += $(MANBUILD)/isisd.8
-endif
-
-if OSPF6D
-rstman8_DATA += $(MANBUILD)/ospf6d.8
-endif
-
-if OSPFCLIENT
-rstman8_DATA += $(MANBUILD)/ospfclient.8
-endif
-
-if OSPFD
-rstman8_DATA += $(MANBUILD)/ospfd.8
-endif
-
-if LDPD
-rstman8_DATA += $(MANBUILD)/ldpd.8
-endif
-
-if RIPD
-rstman8_DATA += $(MANBUILD)/ripd.8
-endif
-
-if RIPNGD
-rstman8_DATA += $(MANBUILD)/ripngd.8
-endif
-
-if NHRPD
-rstman8_DATA += $(MANBUILD)/nhrpd.8
-endif
-
-if VTYSH
-rstman1_DATA += $(MANBUILD)/vtysh.1
-endif
-
-if WATCHFRR
-rstman8_DATA += $(MANBUILD)/watchfrr.8
-endif
-
-if ZEBRA
-rstman8_DATA += $(MANBUILD)/zebra.8
-endif
-
-if EIGRPD
-rstman8_DATA += $(MANBUILD)/eigrpd.8
-endif
-
-if SHARPD
-rstman8_DATA += $(MANBUILD)/sharpd.8
-endif
-
-if STATICD
-rstman8_DATA += $(MANBUILD)/staticd.8
-endif
-
-if BFDD
-rstman8_DATA += $(MANBUILD)/bfdd.8
-endif
+man1 = $(MANBUILD)/frr.1
+man8 =
# dependency
-$(rstman8_DATA) $(rstman1_DATA): $(MANBUILD)/man.stamp
+$(man8) $(man1): $(MANBUILD)/man.stamp
#
# hook-ins for clean / doc
diff --git a/doc/mpls/.gitignore b/doc/mpls/.gitignore
deleted file mode 100644
index b0a4a4619..000000000
--- a/doc/mpls/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.arch-ids
-.arch-inventory
-*~
-*.loT
-
diff --git a/doc/user/fabricd.rst b/doc/user/fabricd.rst
new file mode 100644
index 000000000..cf0f937c1
--- /dev/null
+++ b/doc/user/fabricd.rst
@@ -0,0 +1,404 @@
+.. _fabricd:
+
+**********
+OpenFabric
+**********
+
+OpenFabric, specified in :t:`draft-white-openfabric-06.txt`, is a routing
+protocol derived from IS-IS, providing link-state routing with efficient
+flooding for topologies like spine-leaf networks.
+
+FRR implements OpenFabric in a daemon called *fabricd*
+
+.. _configuring-fabricd:
+
+Configuring fabricd
+===================
+
+There are no *fabricd* specific options. Common options can be specified
+(:ref:`common-invocation-options`) to *fabricd*. *fabricd* needs to acquire
+interface information from *zebra* in order to function. Therefore *zebra* must
+be running before invoking *fabricd*. Also, if *zebra* is restarted then *fabricd*
+must be too.
+
+Like other daemons, *fabricd* configuration is done in an OpenFabric specific
+configuration file :file:`fabricd.conf`.
+
+.. _openfabric-router:
+
+OpenFabric router
+=================
+
+To enable the OpenFabric routing protocol, an OpenFabric router needs to be created
+in the configuration:
+
+.. index:: router openfabric WORD
+.. clicmd:: router openfabric WORD
+
+.. index:: no router openfabric WORD
+.. clicmd:: no router openfabric WORD
+
+ Enable or disable the OpenFabric process by specifying the OpenFabric domain with
+ 'WORD'.
+
+.. index:: net XX.XXXX. ... .XXX.XX
+.. clicmd:: net XX.XXXX. ... .XXX.XX
+
+.. index:: no net XX.XXXX. ... .XXX.XX
+.. clicmd:: no net XX.XXXX. ... .XXX.XX
+
+ Set/Unset network entity title (NET) provided in ISO format.
+
+.. index:: domain-password [clear | md5] <password>
+.. clicmd:: domain-password [clear | md5] <password>
+
+.. index:: no domain-password
+.. clicmd:: no domain-password
+
+ Configure the authentication password for a domain, as clear text or md5 one.
+
+.. index:: log-adjacency-changes
+.. clicmd:: log-adjacency-changes
+
+.. index:: no log-adjacency-changes
+.. clicmd:: no log-adjacency-changes
+
+ Log changes in adjacency state.
+
+.. index:: set-overload-bit
+.. clicmd:: set-overload-bit
+
+.. index:: no set-overload-bit
+.. clicmd:: no set-overload-bit
+
+ Set overload bit to avoid any transit traffic.
+
+.. index:: purge-originator
+.. clicmd:: purge-originator
+
+.. index:: no purge-originator
+.. clicmd:: no purge-originator
+
+ Enable or disable :rfc:`6232` purge originator identification.
+
+.. index:: fabric-tier (0-14)
+.. clicmd:: fabric-tier (0-14)
+
+.. index:: no fabric-tier
+.. clicmd:: no fabric-tier
+
+ Configure a static tier number to advertise as location in the fabric
+
+.. _openfabric-timer:
+
+OpenFabric Timer
+================
+
+.. index:: lsp-gen-interval (1-120)
+.. clicmd:: lsp-gen-interval (1-120)
+
+.. index:: no lsp-gen-interval
+.. clicmd:: no lsp-gen-interval
+
+ Set minimum interval in seconds between regenerating same LSP.
+
+.. index:: lsp-refresh-interval (1-65235)
+.. clicmd:: lsp-refresh-interval (1-65235)
+
+.. index:: no lsp-refresh-interval
+.. clicmd:: no lsp-refresh-interval
+
+ Set LSP refresh interval in seconds.
+
+.. index:: max-lsp-lifetime (360-65535)
+.. clicmd:: max-lsp-lifetime (360-65535)
+
+.. index:: no max-lsp-lifetime
+.. clicmd:: no max-lsp-lifetime
+
+ Set LSP maximum LSP lifetime in seconds.
+
+.. index:: spf-interval (1-120)
+.. clicmd:: spf-interval (1-120)
+
+.. index:: no spf-interval
+.. clicmd:: no spf-interval
+
+ Set minimum interval between consecutive SPF calculations in seconds.
+
+.. _openfabric-interface:
+
+OpenFabric interface
+====================
+
+.. index:: ip router openfabric WORD
+.. clicmd:: ip router openfabric WORD
+
+.. index:: no ip router openfabric WORD
+.. clicmd:: no ip router openfabric WORD
+
+.. _ip-router-openfabric-word:
+
+ Activate OpenFabric on this interface. Note that the name
+ of OpenFabric instance must be the same as the one used to configure the
+ routing process (see command :clicmd:`router openfabric WORD`).
+
+.. index:: openfabric csnp-interval (1-600)
+.. clicmd:: openfabric csnp-interval (1-600)
+
+.. index:: no openfabric csnp-interval
+.. clicmd:: no openfabric csnp-interval
+
+ Set CSNP interval in seconds.
+
+.. index:: openfabric hello-interval (1-600)
+.. clicmd:: openfabric hello-interval (1-600)
+
+.. index:: no openfabric hello-interval
+.. clicmd:: no openfabric hello-interval
+
+ Set Hello interval in seconds.
+
+.. index:: openfabric hello-multiplier (2-100)
+.. clicmd:: openfabric hello-multiplier (2-100)
+
+.. index:: no openfabric hello-multiplier
+.. clicmd:: no openfabric hello-multiplier
+
+ Set multiplier for Hello holding time.
+
+.. index:: openfabric metric (0-16777215)
+.. clicmd:: openfabric metric (0-16777215)
+
+.. index:: no openfabric metric
+.. clicmd:: no openfabric metric
+
+ Set interface metric value.
+
+.. index:: openfabric passive
+.. clicmd:: openfabric passive
+
+.. index:: no openfabric passive
+.. clicmd:: no openfabric passive
+
+ Configure the passive mode for this interface.
+
+.. index:: openfabric password [clear | md5] <password>
+.. clicmd:: openfabric password [clear | md5] <password>
+
+.. index:: no openfabric password
+.. clicmd:: no openfabric password
+
+ Configure the authentication password (clear or encoded text) for the
+ interface.
+
+.. index:: openfabric psnp-interval (1-120)
+.. clicmd:: openfabric psnp-interval (1-120)
+
+.. index:: no openfabric psnp-interval
+.. clicmd:: no openfabric psnp-interval
+
+ Set PSNP interval in seconds.
+
+.. _showing-openfabric-information:
+
+Showing OpenFabric information
+==============================
+
+.. index:: show openfabric summary
+.. clicmd:: show openfabric summary
+
+ Show summary information about OpenFabric.
+
+.. index:: show openfabric hostname
+.. clicmd:: show openfabric hostname
+
+ Show which hostnames are associated with which OpenFabric system ids.
+
+.. index:: show openfabric interface
+.. clicmd:: show openfabric interface
+
+.. index:: show openfabric interface detail
+.. clicmd:: show openfabric interface detail
+
+.. index:: show openfabric interface <interface name>
+.. clicmd:: show openfabric interface <interface name>
+
+ Show state and configuration of specified OpenFabric interface, or all interfaces
+ if no interface is given with or without details.
+
+.. index:: show openfabric neighbor
+.. clicmd:: show openfabric neighbor
+
+.. index:: show openfabric neighbor <System Id>
+.. clicmd:: show openfabric neighbor <System Id>
+
+.. index:: show openfabric neighbor detail
+.. clicmd:: show openfabric neighbor detail
+
+ Show state and information of specified OpenFabric neighbor, or all neighbors if
+ no system id is given with or without details.
+
+.. index:: show openfabric database
+.. clicmd:: show openfabric database
+
+.. index:: show openfabric database [detail]
+.. clicmd:: show openfabric database [detail]
+
+.. index:: show openfabric database <LSP id> [detail]
+.. clicmd:: show openfabric database <LSP id> [detail]
+
+.. index:: show openfabric database detail <LSP id>
+.. clicmd:: show openfabric database detail <LSP id>
+
+ Show the OpenFabric database globally, for a specific LSP id without or with
+ details.
+
+.. index:: show openfabric topology
+.. clicmd:: show openfabric topology
+
+ Show calculated OpenFabric paths and associated topology information.
+
+.. _debugging-openfabric:
+
+Debugging OpenFabric
+====================
+
+.. index:: debug openfabric adj-packets
+.. clicmd:: debug openfabric adj-packets
+
+.. index:: no debug openfabric adj-packets
+.. clicmd:: no debug openfabric adj-packets
+
+OpenFabric Adjacency related packets.
+
+.. index:: debug openfabric checksum-errors
+.. clicmd:: debug openfabric checksum-errors
+
+.. index:: no debug openfabric checksum-errors
+.. clicmd:: no debug openfabric checksum-errors
+
+OpenFabric LSP checksum errors.
+
+.. index:: debug openfabric events
+.. clicmd:: debug openfabric events
+
+.. index:: no debug openfabric events
+.. clicmd:: no debug openfabric events
+
+OpenFabric Events.
+
+.. index:: debug openfabric local-updates
+.. clicmd:: debug openfabric local-updates
+
+.. index:: no debug openfabric local-updates
+.. clicmd:: no debug openfabric local-updates
+
+OpenFabric local update packets.
+
+.. index:: debug openfabric lsp-gen
+.. clicmd:: debug openfabric lsp-gen
+
+.. index:: no debug openfabric lsp-gen
+.. clicmd:: no debug openfabric lsp-gen
+
+Generation of own LSPs.
+
+.. index:: debug openfabric lsp-sched
+.. clicmd:: debug openfabric lsp-sched
+
+.. index:: no debug openfabric lsp-sched
+.. clicmd:: no debug openfabric lsp-sched
+
+Debug scheduling of generation of own LSPs.
+
+.. index:: debug openfabric packet-dump
+.. clicmd:: debug openfabric packet-dump
+
+.. index:: no debug openfabric packet-dump
+.. clicmd:: no debug openfabric packet-dump
+
+OpenFabric packet dump.
+
+.. index:: debug openfabric protocol-errors
+.. clicmd:: debug openfabric protocol-errors
+
+.. index:: no debug openfabric protocol-errors
+.. clicmd:: no debug openfabric protocol-errors
+
+OpenFabric LSP protocol errors.
+
+.. index:: debug openfabric route-events
+.. clicmd:: debug openfabric route-events
+
+.. index:: no debug openfabric route-events
+.. clicmd:: no debug openfabric route-events
+
+OpenFabric Route related events.
+
+.. index:: debug openfabric snp-packets
+.. clicmd:: debug openfabric snp-packets
+
+.. index:: no debug openfabric snp-packets
+.. clicmd:: no debug openfabric snp-packets
+
+OpenFabric CSNP/PSNP packets.
+
+.. index:: debug openfabric spf-events
+.. clicmd:: debug openfabric spf-events
+
+.. index:: debug openfabric spf-statistics
+.. clicmd:: debug openfabric spf-statistics
+
+.. index:: debug openfabric spf-triggers
+.. clicmd:: debug openfabric spf-triggers
+
+.. index:: no debug openfabric spf-events
+.. clicmd:: no debug openfabric spf-events
+
+.. index:: no debug openfabric spf-statistics
+.. clicmd:: no debug openfabric spf-statistics
+
+.. index:: no debug openfabric spf-triggers
+.. clicmd:: no debug openfabric spf-triggers
+
+OpenFabric Shortest Path First Events, Timing and Statistic Data and triggering
+events.
+
+.. index:: debug openfabric update-packets
+.. clicmd:: debug openfabric update-packets
+
+.. index:: no debug openfabric update-packets
+.. clicmd:: no debug openfabric update-packets
+
+Update related packets.
+
+.. index:: show debugging openfabric
+.. clicmd:: show debugging openfabric
+
+ Print which OpenFabric debug levels are active.
+
+OpenFabric configuration example
+================================
+
+A simple example:
+
+.. code-block:: frr
+
+ !
+ interface lo
+ ip address 192.0.2.1/32
+ ip router openfabric 1
+ ipv6 address 2001:db8::1/128
+ ipv6 router openfabric 1
+ !
+ interface eth0
+ ip router openfabric 1
+ ipv6 router openfabric 1
+ !
+ interface eth1
+ ip router openfabric 1
+ ipv6 router openfabric 1
+ !
+ router openfabric 1
+ net 49.0000.0000.0001.00
diff --git a/doc/user/index.rst b/doc/user/index.rst
index 581855134..8190415bf 100644
--- a/doc/user/index.rst
+++ b/doc/user/index.rst
@@ -42,6 +42,7 @@ Protocols
bfd
bgp
babeld
+ fabricd
ldpd
eigrpd
isisd
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index 3da5a6cd3..da431916a 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -139,6 +139,10 @@ options from the list below.
Do not build isisd.
+.. option:: --disable-fabricd
+
+ Do not build fabricd.
+
.. option:: --enable-isis-topology
Enable IS-IS topology generator.
diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst
index 54f82f683..ee681858d 100644
--- a/doc/user/isisd.rst
+++ b/doc/user/isisd.rst
@@ -106,6 +106,14 @@ writing, *isisd* does not support multiple ISIS processes.
Set overload bit to avoid any transit traffic.
+.. index:: purge-originator
+.. clicmd:: purge-originator
+
+.. index:: no purge-originator
+.. clicmd:: no purge-originator
+
+ Enable or disable :rfc:`6232` purge originator identification.
+
.. _isis-timer:
ISIS Timer
diff --git a/doc/user/setup.rst b/doc/user/setup.rst
index 68ce14982..8a76a61e7 100644
--- a/doc/user/setup.rst
+++ b/doc/user/setup.rst
@@ -32,6 +32,7 @@ systemd. The file initially looks like this:
staticd=no
pbrd=no
bfdd=no
+ fabricd=no
To enable a particular daemon, simply change the corresponding 'no' to 'yes'.
Subsequent service restarts should start the daemon.
@@ -68,6 +69,7 @@ This file has several parts. Here is an example:
staticd_options=" --daemon -A 127.0.0.1"
pbrd_options=" --daemon -A 127.0.0.1"
bfdd_options=" --daemon -A 127.0.0.1"
+ fabricd_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
@@ -139,6 +141,7 @@ add the following entries to :file:`/etc/services`.
ldpd 2612/tcp # LDPd vty
eigprd 2613/tcp # EIGRPd vty
bfdd 2617/tcp # bfdd vty
+ fabricd 2618/tcp # fabricd vty
If you use a FreeBSD newer than 2.2.8, the above entries are already added to
diff --git a/doc/user/subdir.am b/doc/user/subdir.am
index 6e51eed9d..53d36052a 100644
--- a/doc/user/subdir.am
+++ b/doc/user/subdir.am
@@ -10,6 +10,7 @@ user_RSTFILES = \
doc/user/bugs.rst \
doc/user/conf.py \
doc/user/eigrpd.rst \
+ doc/user/fabricd.rst \
doc/user/filter.rst \
doc/user/glossary.rst \
doc/user/index.rst \
diff --git a/eigrpd/.gitignore b/eigrpd/.gitignore
index 5b72399e7..0303c6f0d 100644
--- a/eigrpd/.gitignore
+++ b/eigrpd/.gitignore
@@ -1,18 +1,2 @@
-!Makefile
-Makefile.in
-*.o
-*.a
eigrpd
eigrpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c
index eeefc5196..d291cab4c 100644
--- a/eigrpd/eigrp_fsm.c
+++ b/eigrpd/eigrp_fsm.c
@@ -67,8 +67,8 @@
* 7- state not changed, usually by receiving not last reply
*/
-#include <thread.h>
#include <zebra.h>
+#include <thread.h>
#include "prefix.h"
#include "table.h"
diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am
index 2635d555d..bc48173bb 100644
--- a/eigrpd/subdir.am
+++ b/eigrpd/subdir.am
@@ -6,6 +6,12 @@ if EIGRPD
noinst_LIBRARIES += eigrpd/libeigrp.a
sbin_PROGRAMS += eigrpd/eigrpd
dist_examples_DATA += eigrpd/eigrpd.conf.sample
+vtysh_scan += \
+ $(top_srcdir)/eigrpd/eigrp_dump.c \
+ $(top_srcdir)/eigrpd/eigrp_vty.c \
+ # end
+# $(top_srcdir)/eigrpd/eigrp_routemap.c
+man8 += $(MANBUILD)/eigrpd.8
endif
eigrpd_libeigrp_a_SOURCES = \
diff --git a/fpm/.gitignore b/fpm/.gitignore
deleted file mode 100644
index 17e90443e..000000000
--- a/fpm/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-!Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
diff --git a/fpm/subdir.am b/fpm/subdir.am
index 795535596..05cec5a52 100644
--- a/fpm/subdir.am
+++ b/fpm/subdir.am
@@ -3,8 +3,7 @@ lib_LTLIBRARIES += fpm/libfrrfpm_pb.la
endif
fpm_libfrrfpm_pb_la_LDFLAGS = -version-info 0:0:0
-fpm_libfrrfpm_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \
- $(Q_PROTOBUF_C_CLIENT_INCLUDES)
+fpm_libfrrfpm_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS)
fpm_libfrrfpm_pb_la_SOURCES = \
fpm/fpm.h \
fpm/fpm_pb.h \
@@ -12,11 +11,14 @@ fpm_libfrrfpm_pb_la_SOURCES = \
# end
if HAVE_PROTOBUF
-nodist_fpm_libfrrfpm_pb_la_SOURCES = fpm/fpm.pb-c.c
+nodist_fpm_libfrrfpm_pb_la_SOURCES = \
+ fpm/fpm.pb-c.c \
+ # end
+endif
+
CLEANFILES += \
fpm/fpm.pb-c.c \
fpm/fpm.pb-c.h \
# end
-endif
EXTRA_DIST += fpm/fpm.proto
diff --git a/init/.gitignore b/init/.gitignore
deleted file mode 100644
index 30b4bc99e..000000000
--- a/init/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-.nfs*
-*~
-*.loT
-
diff --git a/isisd/.gitignore b/isisd/.gitignore
index a882bbf67..b6184ca0f 100644
--- a/isisd/.gitignore
+++ b/isisd/.gitignore
@@ -1,15 +1,3 @@
-!Makefile
-Makefile.in
-*.o
isisd
-.deps
+fabricd
isisd.conf
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
diff --git a/isisd/fabricd.c b/isisd/fabricd.c
new file mode 100644
index 000000000..7951efe5a
--- /dev/null
+++ b/isisd/fabricd.c
@@ -0,0 +1,717 @@
+/*
+ * IS-IS Rout(e)ing protocol - OpenFabric extensions
+ *
+ * Copyright (C) 2018 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (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 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 "isisd/fabricd.h"
+#include "isisd/isisd.h"
+#include "isisd/isis_memory.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_misc.h"
+#include "isisd/isis_adjacency.h"
+#include "isisd/isis_spf.h"
+#include "isisd/isis_tlvs.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_spf_private.h"
+#include "isisd/isis_tx_queue.h"
+
+DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric")
+DEFINE_MTYPE_STATIC(ISISD, FABRICD_NEIGHBOR, "ISIS OpenFabric Neighbor Entry")
+
+/* Tracks initial synchronization as per section 2.4
+ *
+ * We declare the sync complete once we have seen at least one
+ * CSNP and there are no more LSPs with SSN or SRM set.
+ */
+enum fabricd_sync_state {
+ FABRICD_SYNC_PENDING,
+ FABRICD_SYNC_STARTED,
+ FABRICD_SYNC_COMPLETE
+};
+
+struct fabricd {
+ struct isis_area *area;
+
+ enum fabricd_sync_state initial_sync_state;
+ time_t initial_sync_start;
+ struct isis_circuit *initial_sync_circuit;
+ struct thread *initial_sync_timeout;
+
+ struct isis_spftree *spftree;
+ struct skiplist *neighbors;
+ struct hash *neighbors_neighbors;
+
+ uint8_t tier;
+ uint8_t tier_config;
+ uint8_t tier_pending;
+ struct thread *tier_calculation_timer;
+ struct thread *tier_set_timer;
+};
+
+/* Code related to maintaining the neighbor lists */
+
+struct neighbor_entry {
+ struct isis_vertex *vertex;
+ bool present;
+};
+
+static struct neighbor_entry *neighbor_entry_new(struct isis_vertex *vertex)
+{
+ struct neighbor_entry *rv = XMALLOC(MTYPE_FABRICD_NEIGHBOR, sizeof(*rv));
+
+ rv->vertex = vertex;
+ return rv;
+}
+
+static void neighbor_entry_del(struct neighbor_entry *neighbor)
+{
+ XFREE(MTYPE_FABRICD_NEIGHBOR, neighbor);
+}
+
+static void neighbor_entry_del_void(void *arg)
+{
+ neighbor_entry_del((struct neighbor_entry *)arg);
+}
+
+static void neighbor_lists_clear(struct fabricd *f)
+{
+ while (!skiplist_empty(f->neighbors))
+ skiplist_delete_first(f->neighbors);
+
+ hash_clean(f->neighbors_neighbors, neighbor_entry_del_void);
+}
+
+static unsigned neighbor_entry_hash_key(void *np)
+{
+ struct neighbor_entry *n = np;
+
+ return jhash(n->vertex->N.id, ISIS_SYS_ID_LEN, 0x55aa5a5a);
+}
+
+static int neighbor_entry_hash_cmp(const void *a, const void *b)
+{
+ const struct neighbor_entry *na = a, *nb = b;
+
+ return memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN) == 0;
+}
+
+static int neighbor_entry_list_cmp(void *a, void *b)
+{
+ struct neighbor_entry *na = a, *nb = b;
+
+ return -memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN);
+}
+
+static struct neighbor_entry *neighbor_entry_lookup_list(struct skiplist *list,
+ const uint8_t *id)
+{
+ struct isis_vertex querier;
+ isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS);
+
+ struct neighbor_entry n = {
+ .vertex = &querier
+ };
+
+ struct neighbor_entry *rv;
+
+ if (skiplist_search(list, &n, (void**)&rv))
+ return NULL;
+
+ if (!rv->present)
+ return NULL;
+
+ return rv;
+}
+
+static struct neighbor_entry *neighbor_entry_lookup_hash(struct hash *hash,
+ const uint8_t *id)
+{
+ struct isis_vertex querier;
+ isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS);
+
+ struct neighbor_entry n = {
+ .vertex = &querier
+ };
+
+ struct neighbor_entry *rv = hash_lookup(hash, &n);
+
+ if (!rv || !rv->present)
+ return NULL;
+
+ return rv;
+}
+
+static void neighbor_lists_update(struct fabricd *f)
+{
+ neighbor_lists_clear(f);
+
+ struct listnode *node;
+ struct isis_vertex *v;
+
+ for (ALL_QUEUE_ELEMENTS_RO(&f->spftree->paths, node, v)) {
+ if (!v->d_N || !VTYPE_IS(v->type))
+ continue;
+
+ if (v->d_N > 2)
+ break;
+
+ struct neighbor_entry *n = neighbor_entry_new(v);
+ if (v->d_N == 1) {
+ skiplist_insert(f->neighbors, n, n);
+ } else {
+ struct neighbor_entry *inserted;
+ inserted = hash_get(f->neighbors_neighbors, n, hash_alloc_intern);
+ assert(inserted == n);
+ }
+ }
+}
+
+struct fabricd *fabricd_new(struct isis_area *area)
+{
+ struct fabricd *rv = XCALLOC(MTYPE_FABRICD_STATE, sizeof(*rv));
+
+ rv->area = area;
+ rv->initial_sync_state = FABRICD_SYNC_PENDING;
+
+ rv->spftree = isis_spftree_new(area);
+ rv->neighbors = skiplist_new(0, neighbor_entry_list_cmp,
+ neighbor_entry_del_void);
+ rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key,
+ neighbor_entry_hash_cmp,
+ "Fabricd Neighbors");
+
+ rv->tier = rv->tier_config = ISIS_TIER_UNDEFINED;
+ return rv;
+};
+
+void fabricd_finish(struct fabricd *f)
+{
+ if (f->initial_sync_timeout)
+ thread_cancel(f->initial_sync_timeout);
+
+ if (f->tier_calculation_timer)
+ thread_cancel(f->tier_calculation_timer);
+
+ if (f->tier_set_timer)
+ thread_cancel(f->tier_set_timer);
+
+ isis_spftree_del(f->spftree);
+ neighbor_lists_clear(f);
+ skiplist_free(f->neighbors);
+ hash_free(f->neighbors_neighbors);
+}
+
+static int fabricd_initial_sync_timeout(struct thread *thread)
+{
+ struct fabricd *f = THREAD_ARG(thread);
+
+ zlog_info("OpenFabric: Initial synchronization on %s timed out!",
+ f->initial_sync_circuit->interface->name);
+ f->initial_sync_state = FABRICD_SYNC_PENDING;
+ f->initial_sync_circuit = NULL;
+ f->initial_sync_timeout = NULL;
+ return 0;
+}
+
+void fabricd_initial_sync_hello(struct isis_circuit *circuit)
+{
+ struct fabricd *f = circuit->area->fabricd;
+
+ if (!f)
+ return;
+
+ if (f->initial_sync_state > FABRICD_SYNC_PENDING)
+ return;
+
+ f->initial_sync_state = FABRICD_SYNC_STARTED;
+
+ long timeout = 2 * circuit->hello_interval[1] * circuit->hello_multiplier[1];
+
+ f->initial_sync_circuit = circuit;
+ if (f->initial_sync_timeout)
+ return;
+
+ thread_add_timer(master, fabricd_initial_sync_timeout, f,
+ timeout, &f->initial_sync_timeout);
+ f->initial_sync_start = monotime(NULL);
+
+ zlog_info("OpenFabric: Started initial synchronization with %s on %s",
+ sysid_print(circuit->u.p2p.neighbor->sysid),
+ circuit->interface->name);
+}
+
+bool fabricd_initial_sync_is_in_progress(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f)
+ return false;
+
+ if (f->initial_sync_state > FABRICD_SYNC_PENDING
+ && f->initial_sync_state < FABRICD_SYNC_COMPLETE)
+ return true;
+
+ return false;
+}
+
+bool fabricd_initial_sync_is_complete(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f)
+ return false;
+
+ return f->initial_sync_state == FABRICD_SYNC_COMPLETE;
+}
+
+struct isis_circuit *fabricd_initial_sync_circuit(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+ if (!f)
+ return NULL;
+
+ return f->initial_sync_circuit;
+}
+
+void fabricd_initial_sync_finish(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f)
+ return;
+
+ if (monotime(NULL) - f->initial_sync_start < 5)
+ return;
+
+ zlog_info("OpenFabric: Initial synchronization on %s complete.",
+ f->initial_sync_circuit->interface->name);
+ f->initial_sync_state = FABRICD_SYNC_COMPLETE;
+ f->initial_sync_circuit = NULL;
+ thread_cancel(f->initial_sync_timeout);
+ f->initial_sync_timeout = NULL;
+}
+
+static void fabricd_bump_tier_calculation_timer(struct fabricd *f);
+static void fabricd_set_tier(struct fabricd *f, uint8_t tier);
+
+static uint8_t fabricd_calculate_fabric_tier(struct isis_area *area)
+{
+ struct isis_spftree *local_tree = fabricd_spftree(area);
+ struct listnode *node;
+
+ struct isis_vertex *furthest_t0 = NULL,
+ *second_furthest_t0 = NULL;
+
+ struct isis_vertex *v;
+
+ for (ALL_QUEUE_ELEMENTS_RO(&local_tree->paths, node, v)) {
+ struct isis_lsp *lsp = lsp_for_vertex(local_tree, v);
+
+ if (!lsp || !lsp->tlvs
+ || !lsp->tlvs->spine_leaf
+ || !lsp->tlvs->spine_leaf->has_tier
+ || lsp->tlvs->spine_leaf->tier != 0)
+ continue;
+
+ second_furthest_t0 = furthest_t0;
+ furthest_t0 = v;
+ }
+
+ if (!second_furthest_t0) {
+ zlog_info("OpenFabric: Could not find two T0 routers");
+ return ISIS_TIER_UNDEFINED;
+ }
+
+ zlog_info("OpenFabric: Found %s as furthest t0 from local system, dist == %"
+ PRIu32, rawlspid_print(furthest_t0->N.id), furthest_t0->d_N);
+
+ struct isis_spftree *remote_tree =
+ isis_run_hopcount_spf(area, furthest_t0->N.id, NULL);
+
+ struct isis_vertex *furthest_from_remote =
+ isis_vertex_queue_last(&remote_tree->paths);
+
+ if (!furthest_from_remote) {
+ zlog_info("OpenFabric: Found no furthest node in remote spf");
+ isis_spftree_del(remote_tree);
+ return ISIS_TIER_UNDEFINED;
+ } else {
+ zlog_info("OpenFabric: Found %s as furthest from remote dist == %"
+ PRIu32, rawlspid_print(furthest_from_remote->N.id),
+ furthest_from_remote->d_N);
+ }
+
+ int64_t tier = furthest_from_remote->d_N - furthest_t0->d_N;
+ isis_spftree_del(remote_tree);
+
+ if (tier < 0 || tier >= ISIS_TIER_UNDEFINED) {
+ zlog_info("OpenFabric: Calculated tier %" PRId64 " seems implausible",
+ tier);
+ return ISIS_TIER_UNDEFINED;
+ }
+
+ zlog_info("OpenFabric: Calculated %" PRId64 " as tier", tier);
+ return tier;
+}
+
+static int fabricd_tier_set_timer(struct thread *thread)
+{
+ struct fabricd *f = THREAD_ARG(thread);
+ f->tier_set_timer = NULL;
+
+ fabricd_set_tier(f, f->tier_pending);
+ return 0;
+}
+
+static int fabricd_tier_calculation_cb(struct thread *thread)
+{
+ struct fabricd *f = THREAD_ARG(thread);
+ uint8_t tier = ISIS_TIER_UNDEFINED;
+ f->tier_calculation_timer = NULL;
+
+ tier = fabricd_calculate_fabric_tier(f->area);
+ if (tier == ISIS_TIER_UNDEFINED)
+ return 0;
+
+ zlog_info("OpenFabric: Got tier %" PRIu8 " from algorithm. Arming timer.",
+ tier);
+ f->tier_pending = tier;
+ thread_add_timer(master, fabricd_tier_set_timer, f,
+ f->area->lsp_gen_interval[ISIS_LEVEL2 - 1],
+ &f->tier_set_timer);
+
+ return 0;
+}
+
+static void fabricd_bump_tier_calculation_timer(struct fabricd *f)
+{
+ /* Cancel timer if we already know our tier */
+ if (f->tier != ISIS_TIER_UNDEFINED
+ || f->tier_set_timer) {
+ if (f->tier_calculation_timer) {
+ thread_cancel(f->tier_calculation_timer);
+ f->tier_calculation_timer = NULL;
+ }
+ return;
+ }
+
+ /* If we need to calculate the tier, wait some
+ * time for the topology to settle before running
+ * the calculation */
+ if (f->tier_calculation_timer) {
+ thread_cancel(f->tier_calculation_timer);
+ f->tier_calculation_timer = NULL;
+ }
+
+ thread_add_timer(master, fabricd_tier_calculation_cb, f,
+ 2 * f->area->lsp_gen_interval[ISIS_LEVEL2 - 1],
+ &f->tier_calculation_timer);
+}
+
+static void fabricd_set_tier(struct fabricd *f, uint8_t tier)
+{
+ if (f->tier == tier)
+ return;
+
+ zlog_info("OpenFabric: Set own tier to %" PRIu8, tier);
+ f->tier = tier;
+
+ fabricd_bump_tier_calculation_timer(f);
+ lsp_regenerate_schedule(f->area, ISIS_LEVEL2, 0);
+}
+
+void fabricd_run_spf(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f)
+ return;
+
+ isis_run_hopcount_spf(area, isis->sysid, f->spftree);
+ neighbor_lists_update(f);
+ fabricd_bump_tier_calculation_timer(f);
+}
+
+struct isis_spftree *fabricd_spftree(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f)
+ return NULL;
+
+ return f->spftree;
+}
+
+void fabricd_configure_tier(struct isis_area *area, uint8_t tier)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f || f->tier_config == tier)
+ return;
+
+ f->tier_config = tier;
+ fabricd_set_tier(f, tier);
+}
+
+uint8_t fabricd_tier(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f)
+ return ISIS_TIER_UNDEFINED;
+
+ return f->tier;
+}
+
+int fabricd_write_settings(struct isis_area *area, struct vty *vty)
+{
+ struct fabricd *f = area->fabricd;
+ int written = 0;
+
+ if (!f)
+ return written;
+
+ if (f->tier_config != ISIS_TIER_UNDEFINED) {
+ vty_out(vty, " fabric-tier %" PRIu8 "\n", f->tier_config);
+ written++;
+ }
+
+ return written;
+}
+
+static void move_to_dnr(struct isis_lsp *lsp, struct neighbor_entry *n)
+{
+ struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N);
+
+ n->present = false;
+
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ char buff[PREFIX2STR_BUFFER];
+ zlog_debug("OpenFabric: Adding %s to DNR",
+ vid2string(n->vertex, buff, sizeof(buff)));
+ }
+
+ if (adj) {
+ isis_tx_queue_add(adj->circuit->tx_queue, lsp,
+ TX_LSP_CIRCUIT_SCOPED);
+ }
+}
+
+static void move_to_rf(struct isis_lsp *lsp, struct neighbor_entry *n)
+{
+ struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N);
+
+ n->present = false;
+
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ char buff[PREFIX2STR_BUFFER];
+ zlog_debug("OpenFabric: Adding %s to RF",
+ vid2string(n->vertex, buff, sizeof(buff)));
+ }
+
+ if (adj) {
+ isis_tx_queue_add(adj->circuit->tx_queue, lsp,
+ TX_LSP_NORMAL);
+ }
+}
+
+static void mark_neighbor_as_present(struct hash_backet *backet, void *arg)
+{
+ struct neighbor_entry *n = backet->data;
+
+ n->present = true;
+}
+
+static void handle_firsthops(struct hash_backet *backet, void *arg)
+{
+ struct isis_lsp *lsp = arg;
+ struct fabricd *f = lsp->area->fabricd;
+ struct isis_vertex *vertex = backet->data;
+
+ struct neighbor_entry *n;
+
+ n = neighbor_entry_lookup_list(f->neighbors, vertex->N.id);
+ if (n) {
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ char buff[PREFIX2STR_BUFFER];
+ zlog_debug("Removing %s from NL as its in the reverse path",
+ vid2string(vertex, buff, sizeof(buff)));
+ }
+ n->present = false;
+ }
+
+ n = neighbor_entry_lookup_hash(f->neighbors_neighbors, vertex->N.id);
+ if (n) {
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ char buff[PREFIX2STR_BUFFER];
+ zlog_debug("Removing %s from NN as its in the reverse path",
+ vid2string(vertex, buff, sizeof(buff)));
+ }
+ n->present = false;
+ }
+}
+
+void fabricd_lsp_flood(struct isis_lsp *lsp)
+{
+ struct fabricd *f = lsp->area->fabricd;
+ assert(f);
+
+ void *cursor = NULL;
+ struct neighbor_entry *n;
+
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ zlog_debug("OpenFabric: Flooding LSP %s",
+ rawlspid_print(lsp->hdr.lsp_id));
+ }
+
+ /* Mark all elements in NL as present and move T0s into DNR */
+ while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) {
+ n->present = true;
+
+ struct isis_lsp *lsp = lsp_for_vertex(f->spftree, n->vertex);
+ if (!lsp || !lsp->tlvs || !lsp->tlvs->spine_leaf)
+ continue;
+
+ if (!lsp->tlvs->spine_leaf->has_tier
+ || lsp->tlvs->spine_leaf->tier != 0)
+ continue;
+
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ zlog_debug("Moving %s to DNR because it's T0",
+ rawlspid_print(lsp->hdr.lsp_id));
+ }
+
+ move_to_dnr(lsp, n);
+ }
+
+ /* Mark all elements in NN as present */
+ hash_iterate(f->neighbors_neighbors, mark_neighbor_as_present, NULL);
+
+ struct isis_vertex *originator = isis_find_vertex(&f->spftree->paths,
+ lsp->hdr.lsp_id,
+ VTYPE_NONPSEUDO_TE_IS);
+
+ /* Remove all IS from NL and NN in the shortest path
+ * to the IS that originated the LSP */
+ if (originator)
+ hash_iterate(originator->firsthops, handle_firsthops, lsp);
+
+ /* Iterate over all remaining IS in NL */
+ cursor = NULL;
+ while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) {
+ if (!n->present)
+ continue;
+
+ struct isis_lsp *nlsp = lsp_for_vertex(f->spftree, n->vertex);
+ if (!nlsp || !nlsp->tlvs) {
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ char buff[PREFIX2STR_BUFFER];
+ zlog_debug("Moving %s to DNR as it has no LSP",
+ vid2string(n->vertex, buff, sizeof(buff)));
+ }
+
+ move_to_dnr(lsp, n);
+ continue;
+ }
+
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ char buff[PREFIX2STR_BUFFER];
+ zlog_debug("Considering %s from NL...",
+ vid2string(n->vertex, buff, sizeof(buff)));
+ }
+
+ /* For all neighbors of the NL IS check whether they are present
+ * in NN. If yes, remove from NN and set need_reflood. */
+ bool need_reflood = false;
+ struct isis_extended_reach *er;
+ for (er = (struct isis_extended_reach *)nlsp->tlvs->extended_reach.head;
+ er; er = er->next) {
+ struct neighbor_entry *nn;
+
+ nn = neighbor_entry_lookup_hash(f->neighbors_neighbors,
+ er->id);
+
+ if (nn) {
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ char buff[PREFIX2STR_BUFFER];
+ zlog_debug("Found neighbor %s in NN, removing it from NN and setting reflood.",
+ vid2string(nn->vertex, buff, sizeof(buff)));
+ }
+
+ nn->present = false;
+ need_reflood = true;
+ }
+ }
+
+ if (need_reflood)
+ move_to_rf(lsp, n);
+ else
+ move_to_dnr(lsp, n);
+ }
+
+ if (isis->debugs & DEBUG_FABRICD_FLOODING) {
+ zlog_debug("OpenFabric: Flooding algorithm complete.");
+ }
+}
+
+void fabricd_trigger_csnp(struct isis_area *area)
+{
+ struct fabricd *f = area->fabricd;
+
+ if (!f)
+ return;
+
+ struct listnode *node;
+ struct isis_circuit *circuit;
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
+ if (!circuit->t_send_csnp[1])
+ continue;
+
+ thread_cancel(circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
+ thread_add_timer_msec(master, send_l2_csnp, circuit,
+ isis_jitter(500, CSNP_JITTER),
+ &circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
+ }
+}
+
+struct list *fabricd_ip_addrs(struct isis_circuit *circuit)
+{
+ if (circuit->ip_addrs && listcount(circuit->ip_addrs))
+ return circuit->ip_addrs;
+
+ if (!fabricd || !circuit->area || !circuit->area->circuit_list)
+ return NULL;
+
+ struct listnode *node;
+ struct isis_circuit *c;
+
+ for (ALL_LIST_ELEMENTS_RO(circuit->area->circuit_list, node, c)) {
+ if (c->circ_type != CIRCUIT_T_LOOPBACK)
+ continue;
+
+ if (!c->ip_addrs || !listcount(c->ip_addrs))
+ return NULL;
+
+ return c->ip_addrs;
+ }
+
+ return NULL;
+}
diff --git a/isisd/fabricd.conf.sample b/isisd/fabricd.conf.sample
new file mode 100644
index 000000000..be9e33ba6
--- /dev/null
+++ b/isisd/fabricd.conf.sample
@@ -0,0 +1,27 @@
+! -*- openfabric -*-
+!
+! fabricd sample configuration file
+!
+hostname fabricd
+password foo
+enable password foo
+log stdout
+!log file /tmp/fabricd.log
+!
+!
+router openfabric DEAD
+ net 47.0023.0000.0003.0300.0100.0102.0304.0506.00
+! lsp-lifetime 65535
+
+! hostname isisd-router
+! domain-password foobar
+
+interface eth0
+ ip router openfabric DEAD
+! openfabric hello-interval 5
+! openfabric lsp-interval 1000
+
+! -- optional
+! openfabric retransmit-interval 10
+! openfabric retransmit-throttle-interval
+!
diff --git a/isisd/fabricd.h b/isisd/fabricd.h
new file mode 100644
index 000000000..76c182f2d
--- /dev/null
+++ b/isisd/fabricd.h
@@ -0,0 +1,49 @@
+/*
+ * IS-IS Rout(e)ing protocol - OpenFabric extensions
+ *
+ * Copyright (C) 2018 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (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 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 FABRICD_H
+#define FABRICD_H
+
+struct fabricd;
+
+struct isis_circuit;
+struct isis_area;
+struct isis_spftree;
+struct isis_lsp;
+struct vty;
+
+struct fabricd *fabricd_new(struct isis_area *area);
+void fabricd_finish(struct fabricd *f);
+void fabricd_initial_sync_hello(struct isis_circuit *circuit);
+bool fabricd_initial_sync_is_complete(struct isis_area *area);
+bool fabricd_initial_sync_is_in_progress(struct isis_area *area);
+struct isis_circuit *fabricd_initial_sync_circuit(struct isis_area *area);
+void fabricd_initial_sync_finish(struct isis_area *area);
+void fabricd_run_spf(struct isis_area *area);
+struct isis_spftree *fabricd_spftree(struct isis_area *area);
+void fabricd_configure_tier(struct isis_area *area, uint8_t tier);
+uint8_t fabricd_tier(struct isis_area *area);
+int fabricd_write_settings(struct isis_area *area, struct vty *vty);
+void fabricd_lsp_flood(struct isis_lsp *lsp);
+void fabricd_trigger_csnp(struct isis_area *area);
+struct list *fabricd_ip_addrs(struct isis_circuit *circuit);
+
+#endif
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 4b3d78421..a41d6ff81 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -48,6 +48,7 @@
#include "isisd/isis_events.h"
#include "isisd/isis_mt.h"
#include "isisd/isis_tlvs.h"
+#include "isisd/fabricd.h"
extern struct isis *isis;
@@ -193,6 +194,9 @@ void isis_adj_process_threeway(struct isis_adjacency *adj,
}
}
+ if (next_tw_state != ISIS_THREEWAY_DOWN)
+ fabricd_initial_sync_hello(adj->circuit);
+
if (next_tw_state == ISIS_THREEWAY_DOWN) {
isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Neighbor restarted");
return;
@@ -264,7 +268,7 @@ void isis_adj_state_change(struct isis_adjacency *adj,
circuit->upadjcount[level - 1]--;
if (circuit->upadjcount[level - 1] == 0)
- isis_circuit_lsp_queue_clean(circuit);
+ isis_tx_queue_clean(circuit->tx_queue);
isis_event_adjacency_state_change(adj,
new_state);
@@ -306,16 +310,21 @@ void isis_adj_state_change(struct isis_adjacency *adj,
adj->last_flap = time(NULL);
adj->flaps++;
- /* 7.3.17 - going up on P2P -> send CSNP */
- /* FIXME: yup, I know its wrong... but i will do
- * it! (for now) */
- send_csnp(circuit, level);
+ if (level == IS_LEVEL_1) {
+ thread_add_timer(master, send_l1_csnp,
+ circuit, 0,
+ &circuit->t_send_csnp[0]);
+ } else {
+ thread_add_timer(master, send_l2_csnp,
+ circuit, 0,
+ &circuit->t_send_csnp[1]);
+ }
} else if (new_state == ISIS_ADJ_DOWN) {
if (adj->circuit->u.p2p.neighbor == adj)
adj->circuit->u.p2p.neighbor = NULL;
circuit->upadjcount[level - 1]--;
if (circuit->upadjcount[level - 1] == 0)
- isis_circuit_lsp_queue_clean(circuit);
+ isis_tx_queue_clean(circuit->tx_queue);
isis_event_adjacency_state_change(adj,
new_state);
diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c
index 7e8a4a4ed..28750278b 100644
--- a/isisd/isis_bpf.c
+++ b/isisd/isis_bpf.c
@@ -213,7 +213,7 @@ int isis_sock_init(struct isis_circuit *circuit)
int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa)
{
- int bytesread = 0, bytestoread, offset, one = 1, err = ISIS_OK;
+ int bytesread = 0, bytestoread, offset, one = 1;
uint8_t *buff_ptr;
struct bpf_hdr *bpf_hdr;
@@ -249,7 +249,7 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa)
memcpy(ssnpa, buff_ptr + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN,
ETHER_ADDR_LEN);
- err = isis_handle_pdu(circuit, ssnpa);
+ isis_handle_pdu(circuit, ssnpa);
stream_reset(circuit->rcv_stream);
buff_ptr += BPF_WORDALIGN(bpf_hdr->bh_hdrlen +
bpf_hdr->bh_datalen);
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index cd4b76139..817a44baf 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -45,7 +45,6 @@
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_lsp.h"
-#include "isisd/isis_lsp_hash.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
@@ -58,6 +57,7 @@
#include "isisd/isis_te.h"
#include "isisd/isis_mt.h"
#include "isisd/isis_errors.h"
+#include "isisd/isis_tx_queue.h"
DEFINE_QOBJ_TYPE(isis_circuit)
@@ -412,7 +412,7 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp)
isis_circuit_if_bind(circuit, ifp);
if (if_is_broadcast(ifp)) {
- if (circuit->circ_type_config == CIRCUIT_T_P2P)
+ if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P)
circuit->circ_type = CIRCUIT_T_P2P;
else
circuit->circ_type = CIRCUIT_T_BROADCAST;
@@ -495,29 +495,29 @@ static void isis_circuit_update_all_srmflags(struct isis_circuit *circuit,
{
struct isis_area *area;
struct isis_lsp *lsp;
- dnode_t *dnode, *dnode_next;
+ dnode_t *dnode;
int level;
assert(circuit);
area = circuit->area;
assert(area);
for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
- if (level & circuit->is_type) {
- if (area->lspdb[level - 1]
- && dict_count(area->lspdb[level - 1]) > 0) {
- for (dnode = dict_first(area->lspdb[level - 1]);
- dnode != NULL; dnode = dnode_next) {
- dnode_next = dict_next(
- area->lspdb[level - 1], dnode);
- lsp = dnode_get(dnode);
- if (is_set) {
- ISIS_SET_FLAG(lsp->SRMflags,
- circuit);
- } else {
- ISIS_CLEAR_FLAG(lsp->SRMflags,
- circuit);
- }
- }
+ if (!(level & circuit->is_type))
+ continue;
+
+ if (!area->lspdb[level - 1]
+ || !dict_count(area->lspdb[level - 1]))
+ continue;
+
+ for (dnode = dict_first(area->lspdb[level - 1]);
+ dnode != NULL;
+ dnode = dict_next(area->lspdb[level - 1], dnode)) {
+ lsp = dnode_get(dnode);
+ if (is_set) {
+ isis_tx_queue_add(circuit->tx_queue, lsp,
+ TX_LSP_NORMAL);
+ } else {
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
}
}
@@ -672,10 +672,7 @@ int isis_circuit_up(struct isis_circuit *circuit)
isis_circuit_prepare(circuit);
- circuit->lsp_queue = list_new();
- circuit->lsp_hash = isis_lsp_hash_new();
- circuit->lsp_queue_last_push[0] = circuit->lsp_queue_last_push[1] =
- monotime(NULL);
+ circuit->tx_queue = isis_tx_queue_new(circuit, send_lsp);
return ISIS_OK;
}
@@ -743,13 +740,9 @@ void isis_circuit_down(struct isis_circuit *circuit)
THREAD_OFF(circuit->t_send_lsp);
THREAD_OFF(circuit->t_read);
- if (circuit->lsp_queue) {
- list_delete_and_null(&circuit->lsp_queue);
- }
-
- if (circuit->lsp_hash) {
- isis_lsp_hash_free(circuit->lsp_hash);
- circuit->lsp_hash = NULL;
+ if (circuit->tx_queue) {
+ isis_tx_queue_free(circuit->tx_queue);
+ circuit->tx_queue = NULL;
}
/* send one gratuitous hello to spead up convergence */
@@ -957,33 +950,35 @@ int isis_interface_config_write(struct vty *vty)
if (circuit == NULL)
continue;
if (circuit->ip_router) {
- vty_out(vty, " ip router isis %s\n",
+ vty_out(vty, " ip router " PROTO_NAME " %s\n",
area->area_tag);
write++;
}
if (circuit->is_passive) {
- vty_out(vty, " isis passive\n");
+ vty_out(vty, " " PROTO_NAME " passive\n");
write++;
}
if (circuit->circ_type_config == CIRCUIT_T_P2P) {
- vty_out(vty, " isis network point-to-point\n");
+ vty_out(vty, " " PROTO_NAME " network point-to-point\n");
write++;
}
if (circuit->ipv6_router) {
- vty_out(vty, " ipv6 router isis %s\n",
+ vty_out(vty, " ipv6 router " PROTO_NAME " %s\n",
area->area_tag);
write++;
}
/* ISIS - circuit type */
- if (circuit->is_type == IS_LEVEL_1) {
- vty_out(vty, " isis circuit-type level-1\n");
- write++;
- } else {
- if (circuit->is_type == IS_LEVEL_2) {
- vty_out(vty,
- " isis circuit-type level-2-only\n");
+ if (!fabricd) {
+ if (circuit->is_type == IS_LEVEL_1) {
+ vty_out(vty, " " PROTO_NAME " circuit-type level-1\n");
write++;
+ } else {
+ if (circuit->is_type == IS_LEVEL_2) {
+ vty_out(vty,
+ " " PROTO_NAME " circuit-type level-2-only\n");
+ write++;
+ }
}
}
@@ -992,7 +987,7 @@ int isis_interface_config_write(struct vty *vty)
== circuit->csnp_interval[1]) {
if (circuit->csnp_interval[0]
!= DEFAULT_CSNP_INTERVAL) {
- vty_out(vty, " isis csnp-interval %d\n",
+ vty_out(vty, " " PROTO_NAME " csnp-interval %d\n",
circuit->csnp_interval[0]);
write++;
}
@@ -1001,7 +996,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->csnp_interval[i]
!= DEFAULT_CSNP_INTERVAL) {
vty_out(vty,
- " isis csnp-interval %d level-%d\n",
+ " " PROTO_NAME " csnp-interval %d level-%d\n",
circuit->csnp_interval
[i],
i + 1);
@@ -1015,7 +1010,7 @@ int isis_interface_config_write(struct vty *vty)
== circuit->psnp_interval[1]) {
if (circuit->psnp_interval[0]
!= DEFAULT_PSNP_INTERVAL) {
- vty_out(vty, " isis psnp-interval %d\n",
+ vty_out(vty, " " PROTO_NAME " psnp-interval %d\n",
circuit->psnp_interval[0]);
write++;
}
@@ -1024,7 +1019,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->psnp_interval[i]
!= DEFAULT_PSNP_INTERVAL) {
vty_out(vty,
- " isis psnp-interval %d level-%d\n",
+ " " PROTO_NAME " psnp-interval %d level-%d\n",
circuit->psnp_interval
[i],
i + 1);
@@ -1036,7 +1031,7 @@ int isis_interface_config_write(struct vty *vty)
/* ISIS - Hello padding - Defaults to true so only
* display if false */
if (circuit->pad_hellos == 0) {
- vty_out(vty, " no isis hello padding\n");
+ vty_out(vty, " no " PROTO_NAME " hello padding\n");
write++;
}
@@ -1051,7 +1046,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->hello_interval[0]
!= DEFAULT_HELLO_INTERVAL) {
vty_out(vty,
- " isis hello-interval %d\n",
+ " " PROTO_NAME " hello-interval %d\n",
circuit->hello_interval[0]);
write++;
}
@@ -1060,7 +1055,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->hello_interval[i]
!= DEFAULT_HELLO_INTERVAL) {
vty_out(vty,
- " isis hello-interval %d level-%d\n",
+ " " PROTO_NAME " hello-interval %d level-%d\n",
circuit->hello_interval
[i],
i + 1);
@@ -1075,7 +1070,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->hello_multiplier[0]
!= DEFAULT_HELLO_MULTIPLIER) {
vty_out(vty,
- " isis hello-multiplier %d\n",
+ " " PROTO_NAME " hello-multiplier %d\n",
circuit->hello_multiplier[0]);
write++;
}
@@ -1084,7 +1079,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->hello_multiplier[i]
!= DEFAULT_HELLO_MULTIPLIER) {
vty_out(vty,
- " isis hello-multiplier %d level-%d\n",
+ " " PROTO_NAME " hello-multiplier %d level-%d\n",
circuit->hello_multiplier
[i],
i + 1);
@@ -1096,7 +1091,7 @@ int isis_interface_config_write(struct vty *vty)
/* ISIS - Priority */
if (circuit->priority[0] == circuit->priority[1]) {
if (circuit->priority[0] != DEFAULT_PRIORITY) {
- vty_out(vty, " isis priority %d\n",
+ vty_out(vty, " " PROTO_NAME " priority %d\n",
circuit->priority[0]);
write++;
}
@@ -1105,7 +1100,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->priority[i]
!= DEFAULT_PRIORITY) {
vty_out(vty,
- " isis priority %d level-%d\n",
+ " " PROTO_NAME " priority %d level-%d\n",
circuit->priority[i],
i + 1);
write++;
@@ -1117,7 +1112,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->te_metric[0] == circuit->te_metric[1]) {
if (circuit->te_metric[0]
!= DEFAULT_CIRCUIT_METRIC) {
- vty_out(vty, " isis metric %d\n",
+ vty_out(vty, " " PROTO_NAME " metric %d\n",
circuit->te_metric[0]);
write++;
}
@@ -1126,7 +1121,7 @@ int isis_interface_config_write(struct vty *vty)
if (circuit->te_metric[i]
!= DEFAULT_CIRCUIT_METRIC) {
vty_out(vty,
- " isis metric %d level-%d\n",
+ " " PROTO_NAME " metric %d level-%d\n",
circuit->te_metric[i],
i + 1);
write++;
@@ -1134,12 +1129,12 @@ int isis_interface_config_write(struct vty *vty)
}
}
if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) {
- vty_out(vty, " isis password md5 %s\n",
+ vty_out(vty, " " PROTO_NAME " password md5 %s\n",
circuit->passwd.passwd);
write++;
} else if (circuit->passwd.type
== ISIS_PASSWD_TYPE_CLEARTXT) {
- vty_out(vty, " isis password clear %s\n",
+ vty_out(vty, " " PROTO_NAME " password clear %s\n",
circuit->passwd.passwd);
write++;
}
@@ -1343,60 +1338,4 @@ void isis_circuit_init()
/* Install interface node */
install_node(&interface_node, isis_interface_config_write);
if_cmd_init();
-
- isis_vty_init();
-}
-
-void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit)
-{
- if (circuit->t_send_lsp)
- return;
- circuit->t_send_lsp =
- thread_add_event(master, send_lsp, circuit, 0, NULL);
-}
-
-void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp)
-{
- if (isis_lsp_hash_lookup(circuit->lsp_hash, lsp))
- return;
-
- listnode_add(circuit->lsp_queue, lsp);
- isis_lsp_hash_add(circuit->lsp_hash, lsp);
- isis_circuit_schedule_lsp_send(circuit);
-}
-
-void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit)
-{
- if (!circuit->lsp_queue)
- return;
-
- list_delete_all_node(circuit->lsp_queue);
- isis_lsp_hash_clean(circuit->lsp_hash);
-}
-
-void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
- struct isis_lsp *lsp)
-{
- if (!circuit->lsp_queue)
- return;
-
- listnode_delete(circuit->lsp_queue, lsp);
- isis_lsp_hash_release(circuit->lsp_hash, lsp);
-}
-
-struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit)
-{
- if (!circuit->lsp_queue)
- return NULL;
-
- struct listnode *node = listhead(circuit->lsp_queue);
- if (!node)
- return NULL;
-
- struct isis_lsp *rv = listgetdata(node);
-
- list_delete_node(circuit->lsp_queue, node);
- isis_lsp_hash_release(circuit->lsp_hash, rv);
-
- return rv;
}
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index 8dbd7ac49..ea68767fe 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -80,14 +80,8 @@ struct isis_circuit {
struct thread *t_send_csnp[2];
struct thread *t_send_psnp[2];
struct thread *t_send_lsp;
- struct list *lsp_queue; /* LSPs to be txed (both levels) */
- struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */
- time_t lsp_queue_last_push[2]; /* timestamp used to enforce transmit
- * interval;
- * for scalability, use one timestamp per
- * circuit, instead of one per lsp per
- * circuit
- */
+ struct isis_tx_queue *tx_queue;
+
/* there is no real point in two streams, just for programming kicker */
int (*rx)(struct isis_circuit *circuit, uint8_t *ssnpa);
struct stream *rcv_stream; /* Stream for receiving */
@@ -114,10 +108,10 @@ struct isis_circuit {
struct isis_passwd passwd; /* Circuit rx/tx password */
int is_type; /* circuit is type == level of circuit
* differentiated from circuit type (media) */
- uint32_t hello_interval[2]; /* l1HelloInterval in msecs */
- uint16_t hello_multiplier[2]; /* l1HelloMultiplier */
- uint16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */
- uint16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */
+ uint32_t hello_interval[2]; /* hello-interval in seconds */
+ uint16_t hello_multiplier[2]; /* hello-multiplier */
+ uint16_t csnp_interval[2]; /* csnp-interval in seconds */
+ uint16_t psnp_interval[2]; /* psnp-interval in seconds */
uint8_t metric[2];
uint32_t te_metric[2];
struct mpls_te_circuit
@@ -196,10 +190,4 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit,
int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid,
bool enabled);
-void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit);
-void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp);
-void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit);
-void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
- struct isis_lsp *lsp);
-struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit);
#endif /* _ZEBRA_ISIS_CIRCUIT_H */
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 66c97ae89..e8777e9b5 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -56,6 +56,8 @@
#include "isisd/isis_te.h"
#include "isisd/isis_mt.h"
#include "isisd/isis_tlvs.h"
+#include "isisd/fabricd.h"
+#include "isisd/isis_tx_queue.h"
static int lsp_l1_refresh(struct thread *thread);
static int lsp_l2_refresh(struct thread *thread);
@@ -117,10 +119,9 @@ static void lsp_destroy(struct isis_lsp *lsp)
return;
for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, circuit))
- isis_circuit_cancel_queued_lsp(circuit, lsp);
+ isis_tx_queue_del(circuit->tx_queue, lsp);
ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags);
- ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);
lsp_clear_data(lsp);
@@ -352,7 +353,21 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno)
isis_spf_schedule(lsp->area, lsp->level);
}
-static void lsp_purge(struct isis_lsp *lsp, int level)
+static void lsp_purge_add_poi(struct isis_lsp *lsp,
+ const uint8_t *sender)
+{
+ if (!lsp->area->purge_originator)
+ return;
+
+ /* add purge originator identification */
+ if (!lsp->tlvs)
+ lsp->tlvs = isis_alloc_tlvs();
+ isis_tlvs_set_purge_originator(lsp->tlvs, isis->sysid, sender);
+ isis_tlvs_set_dynamic_hostname(lsp->tlvs, cmd_hostname_get());
+}
+
+static void lsp_purge(struct isis_lsp *lsp, int level,
+ const uint8_t *sender)
{
/* reset stream */
lsp_clear_data(lsp);
@@ -364,8 +379,10 @@ static void lsp_purge(struct isis_lsp *lsp, int level)
lsp->level = level;
lsp->age_out = lsp->area->max_lsp_lifetime[level - 1];
+ lsp_purge_add_poi(lsp, sender);
+
lsp_pack_pdu(lsp);
- lsp_set_all_srmflags(lsp);
+ lsp_flood(lsp, NULL);
}
/*
@@ -385,7 +402,7 @@ static void lsp_seqno_update(struct isis_lsp *lsp0)
if (lsp->tlvs)
lsp_inc_seqno(lsp, 0);
else
- lsp_purge(lsp, lsp0->level);
+ lsp_purge(lsp, lsp0->level, NULL);
}
return;
@@ -425,7 +442,8 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
lsp->tlvs = tlvs;
- if (area->dynhostname && lsp->tlvs->hostname) {
+ if (area->dynhostname && lsp->tlvs->hostname
+ && lsp->hdr.rem_lifetime) {
isis_dynhn_insert(lsp->hdr.lsp_id, lsp->tlvs->hostname,
(lsp->hdr.lsp_bits & LSPBIT_IST)
== IS_LEVEL_1_AND_2
@@ -462,10 +480,10 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
lsp->own_lsp = 0;
}
- lsp_update_data(lsp, hdr, tlvs, stream, area, level);
if (confusion) {
- lsp->hdr.rem_lifetime = hdr->rem_lifetime = 0;
- put_lsp_hdr(lsp, NULL, true);
+ lsp_purge(lsp, level, NULL);
+ } else {
+ lsp_update_data(lsp, hdr, tlvs, stream, area, level);
}
if (LSP_FRAGMENT(lsp->hdr.lsp_id) && !lsp->lspu.zero_lsp) {
@@ -928,6 +946,14 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
lsp_debug("ISIS (%s): Adding circuit specific information.",
area->area_tag);
+ if (fabricd) {
+ lsp_debug(
+ "ISIS (%s): Adding tier %" PRIu8 " spine-leaf-extension tlv.",
+ area->area_tag, fabricd_tier(area));
+ isis_tlvs_add_spine_leaf(lsp->tlvs, fabricd_tier(area), true,
+ false, false, false);
+ }
+
struct isis_circuit *circuit;
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
if (!circuit->interface)
@@ -1091,9 +1117,16 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
*/
subtlv_len = 0;
+ uint32_t neighbor_metric;
+ if (fabricd_tier(area) == 0) {
+ neighbor_metric = 0xffe;
+ } else {
+ neighbor_metric = metric;
+ }
+
tlvs_add_mt_p2p(lsp->tlvs, circuit,
- ne_id, metric, subtlvs,
- subtlv_len);
+ ne_id, neighbor_metric,
+ subtlvs, subtlv_len);
}
} else {
lsp_debug(
@@ -1192,7 +1225,7 @@ int lsp_generate(struct isis_area *area, int level)
/* time to calculate our checksum */
lsp_seqno_update(newlsp);
newlsp->last_generated = time(NULL);
- lsp_set_all_srmflags(newlsp);
+ lsp_flood(newlsp, NULL);
refresh_time = lsp_refresh_time(newlsp, rem_lifetime);
@@ -1223,7 +1256,7 @@ int lsp_generate(struct isis_area *area, int level)
}
/*
- * Search own LSPs, update holding time and set SRM
+ * Search own LSPs, update holding time and flood
*/
static int lsp_regenerate(struct isis_area *area, int level)
{
@@ -1255,7 +1288,7 @@ static int lsp_regenerate(struct isis_area *area, int level)
rem_lifetime = lsp_rem_lifetime(area, level);
lsp->hdr.rem_lifetime = rem_lifetime;
lsp->last_generated = time(NULL);
- lsp_set_all_srmflags(lsp);
+ lsp_flood(lsp, NULL);
for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
frag->hdr.lsp_bits = lsp_bits_generate(
level, area->overload_bit, area->attached_bit);
@@ -1265,7 +1298,7 @@ static int lsp_regenerate(struct isis_area *area, int level)
*/
frag->hdr.rem_lifetime = rem_lifetime;
frag->age_out = ZERO_AGE_LIFETIME;
- lsp_set_all_srmflags(frag);
+ lsp_flood(frag, NULL);
}
lsp_seqno_update(lsp);
@@ -1565,7 +1598,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
lsp_pack_pdu(lsp);
lsp->own_lsp = 1;
lsp_insert(lsp, lspdb);
- lsp_set_all_srmflags(lsp);
+ lsp_flood(lsp, NULL);
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
@@ -1624,7 +1657,7 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
lsp_build_pseudo(lsp, circuit, level);
lsp_inc_seqno(lsp, 0);
lsp->last_generated = time(NULL);
- lsp_set_all_srmflags(lsp);
+ lsp_flood(lsp, NULL);
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
if (level == IS_LEVEL_1)
@@ -1800,30 +1833,25 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level)
/*
* Walk through LSPs for an area
* - set remaining lifetime
- * - set LSPs with SRMflag set for sending
*/
int lsp_tick(struct thread *thread)
{
struct isis_area *area;
- struct isis_circuit *circuit;
struct isis_lsp *lsp;
- struct list *lsp_list;
- struct listnode *lspnode, *cnode;
dnode_t *dnode, *dnode_next;
int level;
uint16_t rem_lifetime;
- time_t now = monotime(NULL);
-
- lsp_list = list_new();
+ bool fabricd_sync_incomplete = false;
area = THREAD_ARG(thread);
assert(area);
area->t_tick = NULL;
thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
+ struct isis_circuit *fabricd_init_c = fabricd_initial_sync_circuit(area);
+
/*
- * Build a list of LSPs with (any) SRMflag set
- * and removed the ones that have aged out
+ * Remove LSPs which have aged out
*/
for (level = 0; level < ISIS_LEVELS; level++) {
if (area->lspdb[level] && dict_count(area->lspdb[level]) > 0) {
@@ -1854,17 +1882,14 @@ int lsp_tick(struct thread *thread)
*/
if (rem_lifetime == 1 && lsp->hdr.seqno != 0) {
/* 7.3.16.4 a) set SRM flags on all */
- lsp_set_all_srmflags(lsp);
- /* 7.3.16.4 b) retain only the header
- * FIXME */
+ /* 7.3.16.4 b) retain only the header */
+ if (lsp->area->purge_originator)
+ lsp_purge(lsp, lsp->level, NULL);
+ else
+ lsp_flood(lsp, NULL);
/* 7.3.16.4 c) record the time to purge
* FIXME */
- /* run/schedule spf */
- /* isis_spf_schedule is called inside
- * lsp_destroy() below;
- * so it is not needed here. */
- /* isis_spf_schedule (lsp->area,
- * lsp->level); */
+ isis_spf_schedule(lsp->area, lsp->level);
}
if (lsp->age_out == 0) {
@@ -1878,44 +1903,22 @@ int lsp_tick(struct thread *thread)
lsp = NULL;
dict_delete_free(area->lspdb[level],
dnode);
- } else if (flags_any_set(lsp->SRMflags))
- listnode_add(lsp_list, lsp);
- }
-
- /*
- * Send LSPs on circuits indicated by the SRMflags
- */
- if (listcount(lsp_list) > 0) {
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
- cnode, circuit)) {
- if (!circuit->lsp_queue)
- continue;
-
- if (now - circuit->lsp_queue_last_push[level]
- < MIN_LSP_RETRANS_INTERVAL) {
- continue;
- }
+ }
- circuit->lsp_queue_last_push[level] = now;
-
- for (ALL_LIST_ELEMENTS_RO(
- lsp_list, lspnode, lsp)) {
- if (circuit->upadjcount
- [lsp->level - 1]
- && ISIS_CHECK_FLAG(
- lsp->SRMflags,
- circuit)) {
- isis_circuit_queue_lsp(
- circuit, lsp);
- }
- }
+ if (fabricd_init_c) {
+ fabricd_sync_incomplete |=
+ ISIS_CHECK_FLAG(lsp->SSNflags,
+ fabricd_init_c);
}
- list_delete_all_node(lsp_list);
}
}
}
- list_delete_and_null(&lsp_list);
+ if (fabricd_init_c
+ && !fabricd_sync_incomplete
+ && !isis_tx_queue_len(fabricd_init_c->tx_queue)) {
+ fabricd_initial_sync_finish(area);
+ }
return ISIS_OK;
}
@@ -1928,7 +1931,7 @@ void lsp_purge_pseudo(uint8_t *id, struct isis_circuit *circuit, int level)
if (!lsp)
return;
- lsp_purge(lsp, level);
+ lsp_purge(lsp, level, NULL);
}
/*
@@ -1952,27 +1955,44 @@ void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr));
lsp->hdr.rem_lifetime = 0;
+ lsp_purge_add_poi(lsp, NULL);
+
lsp_pack_pdu(lsp);
lsp_insert(lsp, area->lspdb[lsp->level - 1]);
- lsp_set_all_srmflags(lsp);
+ lsp_flood(lsp, NULL);
return;
}
-void lsp_set_all_srmflags(struct isis_lsp *lsp)
+void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set)
{
struct listnode *node;
struct isis_circuit *circuit;
assert(lsp);
- ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);
+ if (!lsp->area)
+ return;
- if (lsp->area) {
- struct list *circuit_list = lsp->area->circuit_list;
- for (ALL_LIST_ELEMENTS_RO(circuit_list, node, circuit)) {
- ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ struct list *circuit_list = lsp->area->circuit_list;
+ for (ALL_LIST_ELEMENTS_RO(circuit_list, node, circuit)) {
+ if (set) {
+ isis_tx_queue_add(circuit->tx_queue, lsp,
+ TX_LSP_NORMAL);
+ } else {
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
}
}
+
+void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
+{
+ if (!fabricd) {
+ lsp_set_all_srmflags(lsp, true);
+ if (circuit)
+ isis_tx_queue_del(circuit->tx_queue, lsp);
+ } else {
+ fabricd_lsp_flood(lsp);
+ }
+}
diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h
index d531cb157..4e6379447 100644
--- a/isisd/isis_lsp.h
+++ b/isisd/isis_lsp.h
@@ -37,7 +37,6 @@ struct isis_lsp {
struct list *frags;
struct isis_lsp *zero_lsp;
} lspu;
- uint32_t SRMflags[ISIS_MAX_CIRCUITS];
uint32_t SSNflags[ISIS_MAX_CIRCUITS];
int level; /* L1 or L2? */
int scheduled; /* scheduled for sending */
@@ -100,6 +99,7 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost);
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost);
int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost);
/* sets SRMflags for all active circuits of an lsp */
-void lsp_set_all_srmflags(struct isis_lsp *lsp);
+void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);
+void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit);
#endif /* ISIS_LSP */
diff --git a/isisd/isis_lsp_hash.c b/isisd/isis_lsp_hash.c
deleted file mode 100644
index c521f42b3..000000000
--- a/isisd/isis_lsp_hash.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * IS-IS Rout(e)ing protocol - LSP Hash
- *
- * Copyright (C) 2017 Christian Franke
- *
- * This file is part of FreeRangeRouting (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 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 "hash.h"
-#include "jhash.h"
-
-#include "isisd/isis_memory.h"
-#include "isisd/isis_flags.h"
-#include "dict.h"
-#include "isisd/isis_circuit.h"
-#include "isisd/isis_lsp.h"
-#include "isisd/isis_lsp_hash.h"
-
-DEFINE_MTYPE_STATIC(ISISD, LSP_HASH, "ISIS LSP Hash")
-
-struct isis_lsp_hash {
- struct hash *h;
-};
-
-static unsigned lsp_hash_key(void *lp)
-{
- struct isis_lsp *lsp = lp;
-
- return jhash(lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 2, 0x55aa5a5a);
-}
-
-static int lsp_hash_cmp(const void *a, const void *b)
-{
- const struct isis_lsp *la = a, *lb = b;
-
- return 0 == memcmp(la->hdr.lsp_id, lb->hdr.lsp_id, ISIS_SYS_ID_LEN + 2);
-}
-
-struct isis_lsp_hash *isis_lsp_hash_new(void)
-{
- struct isis_lsp_hash *rv = XCALLOC(MTYPE_LSP_HASH, sizeof(*rv));
-
- rv->h = hash_create(lsp_hash_key, lsp_hash_cmp, NULL);
- return rv;
-}
-
-void isis_lsp_hash_clean(struct isis_lsp_hash *ih)
-{
- hash_clean(ih->h, NULL);
-}
-
-void isis_lsp_hash_free(struct isis_lsp_hash *ih)
-{
- isis_lsp_hash_clean(ih);
- hash_free(ih->h);
-}
-
-struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
- struct isis_lsp *lsp)
-{
- return hash_lookup(ih->h, lsp);
-}
-
-void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
-{
- struct isis_lsp *inserted;
- inserted = hash_get(ih->h, lsp, hash_alloc_intern);
- assert(inserted == lsp);
-}
-
-void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
-{
- hash_release(ih->h, lsp);
-}
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 3b4168adb..4d6a6da5d 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -54,11 +54,13 @@
#include "isisd/isis_zebra.h"
#include "isisd/isis_te.h"
#include "isisd/isis_errors.h"
+#include "isisd/isis_vty_common.h"
/* Default configuration file name */
#define ISISD_DEFAULT_CONFIG "isisd.conf"
/* Default vty port */
#define ISISD_VTY_PORT 2608
+#define FABRICD_VTY_PORT 2618
/* isisd privileges */
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND};
@@ -145,9 +147,15 @@ struct quagga_signal_t isisd_signals[] = {
},
};
+#ifdef FABRICD
+FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT,
+
+ .proghelp = "Implementation of the OpenFabric routing protocol.",
+#else
FRR_DAEMON_INFO(isisd, ISIS, .vty_port = ISISD_VTY_PORT,
.proghelp = "Implementation of the IS-IS routing protocol.",
+#endif
.copyright =
"Copyright (c) 2001-2002 Sampo Saaristo,"
" Ofer Wald and Hannes Gredler",
@@ -164,7 +172,11 @@ int main(int argc, char **argv, char **envp)
{
int opt;
+#ifdef FABRICD
+ frr_preinit(&fabricd_di, argc, argv);
+#else
frr_preinit(&isisd_di, argc, argv);
+#endif
frr_opt_add("", longopts, "");
/* Command line argument treatment. */
@@ -196,6 +208,7 @@ int main(int argc, char **argv, char **envp)
prefix_list_init();
isis_init();
isis_circuit_init();
+ isis_vty_init();
isis_spf_cmds_init();
isis_redist_init();
isis_route_map_init();
diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c
index 2155bf584..2dfccf983 100644
--- a/isisd/isis_mt.c
+++ b/isisd/isis_mt.c
@@ -311,7 +311,7 @@ int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty)
for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, setting)) {
const char *name = isis_mtid2str(setting->mtid);
if (name && !setting->enabled) {
- vty_out(vty, " no isis topology %s\n", name);
+ vty_out(vty, " no " PROTO_NAME " topology %s\n", name);
written++;
}
}
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 5c4e3a35b..88575f531 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -56,6 +56,8 @@
#include "isisd/isis_mt.h"
#include "isisd/isis_tlvs.h"
#include "isisd/isis_errors.h"
+#include "isisd/fabricd.h"
+#include "isisd/isis_tx_queue.h"
static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
int level)
@@ -207,6 +209,12 @@ static int process_p2p_hello(struct iih_info *iih)
thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
&adj->t_expire);
+ /* While fabricds initial sync is in progress, ignore hellos from other
+ * interfaces than the one we are performing the initial sync on. */
+ if (fabricd_initial_sync_is_in_progress(iih->circuit->area)
+ && fabricd_initial_sync_circuit(iih->circuit->area) != iih->circuit)
+ return ISIS_OK;
+
/* 8.2.5.2 a) a match was detected */
if (isis_tlvs_area_addresses_match(iih->tlvs,
iih->circuit->area->area_addrs)) {
@@ -671,7 +679,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
goto out;
}
- iih.v4_usable = (circuit->ip_addrs && listcount(circuit->ip_addrs)
+ iih.v4_usable = (fabricd_ip_addrs(circuit)
&& iih.tlvs->ipv4_address.count);
iih.v6_usable = (circuit->ipv6_link && listcount(circuit->ipv6_link)
@@ -700,14 +708,37 @@ out:
* Section 7.3.15.1 - Action on receipt of a link state PDU
*/
static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
- const uint8_t *ssnpa)
+ const uint8_t *ssnpa, uint8_t max_area_addrs)
{
- int level = (pdu_type == L1_LINK_STATE) ? ISIS_LEVEL1 : ISIS_LEVEL2;
+ int level;
+ bool circuit_scoped;
+
+ if (pdu_type == FS_LINK_STATE) {
+ if (!fabricd)
+ return ISIS_ERROR;
+ if (max_area_addrs != L2_CIRCUIT_FLOODING_SCOPE)
+ return ISIS_ERROR;
+ level = ISIS_LEVEL2;
+ circuit_scoped = true;
+
+ /* The stream is used verbatim for sending out new LSPDUs.
+ * So make sure we store it as an L2 LSPDU internally.
+ * (compare for the reverse in `send_lsp`) */
+ stream_putc_at(circuit->rcv_stream, 4, L2_LINK_STATE);
+ stream_putc_at(circuit->rcv_stream, 7, 0);
+ } else {
+ if (pdu_type == L1_LINK_STATE)
+ level = ISIS_LEVEL1;
+ else
+ level = ISIS_LEVEL2;
+ circuit_scoped = false;
+ }
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u",
- circuit->area->area_tag, level,
+ "ISIS-Upd (%s): Rcvd %sL%d LSP on %s, cirType %s, cirID %u",
+ circuit->area->area_tag,
+ circuit_scoped ? "Circuit scoped " : "", level,
circuit->interface->name,
circuit_t2string(circuit->is_type),
circuit->circuit_id);
@@ -869,7 +900,8 @@ dontcheckadj:
* but
* wrong checksum, initiate a purge. */
if (lsp && (lsp->hdr.seqno == hdr.seqno)
- && (lsp->hdr.checksum != hdr.checksum)) {
+ && (lsp->hdr.checksum != hdr.checksum)
+ && hdr.rem_lifetime) {
zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08" PRIx32
" with confused checksum received.",
circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
@@ -899,7 +931,8 @@ dontcheckadj:
lsp_confusion);
tlvs = NULL;
/* ii */
- lsp_set_all_srmflags(lsp);
+ if (!circuit_scoped)
+ lsp_flood(lsp, NULL);
/* v */
ISIS_FLAGS_CLEAR_ALL(
lsp->SSNflags); /* FIXME:
@@ -913,9 +946,10 @@ dontcheckadj:
* Otherwise, don't reflood
* through incoming circuit as usual */
if (!lsp_confusion) {
- /* iii */
- ISIS_CLEAR_FLAG(lsp->SRMflags,
- circuit);
+ isis_tx_queue_del(
+ circuit->tx_queue,
+ lsp);
+
/* iv */
if (circuit->circ_type
!= CIRCUIT_T_BROADCAST)
@@ -926,7 +960,8 @@ dontcheckadj:
} /* 7.3.16.4 b) 2) */
else if (comp == LSP_EQUAL) {
/* i */
- ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_del(circuit->tx_queue,
+ lsp);
/* ii */
if (circuit->circ_type
!= CIRCUIT_T_BROADCAST)
@@ -934,16 +969,19 @@ dontcheckadj:
circuit);
} /* 7.3.16.4 b) 3) */
else {
- ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_add(circuit->tx_queue,
+ lsp, TX_LSP_NORMAL);
ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
}
} else if (lsp->hdr.rem_lifetime != 0) {
/* our own LSP -> 7.3.16.4 c) */
if (comp == LSP_NEWER) {
lsp_inc_seqno(lsp, hdr.seqno);
- lsp_set_all_srmflags(lsp);
+ if (!circuit_scoped)
+ lsp_flood(lsp, NULL);
} else {
- ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_add(circuit->tx_queue,
+ lsp, TX_LSP_NORMAL);
ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
}
if (isis->debugs & DEBUG_UPDATE_PACKETS)
@@ -985,7 +1023,7 @@ dontcheckadj:
}
/* If the received LSP is older or equal,
* resend the LSP which will act as ACK */
- lsp_set_all_srmflags(lsp);
+ lsp_flood(lsp, NULL);
} else {
/* 7.3.15.1 e) - This lsp originated on another system */
@@ -1006,7 +1044,7 @@ dontcheckadj:
if (!lsp0) {
zlog_debug(
"Got lsp frag, while zero lsp not in database");
- return ISIS_OK;
+ goto out;
}
}
/* i */
@@ -1023,10 +1061,8 @@ dontcheckadj:
circuit->area, level, false);
tlvs = NULL;
}
- /* ii */
- lsp_set_all_srmflags(lsp);
- /* iii */
- ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ if (!circuit_scoped)
+ lsp_flood(lsp, circuit);
/* iv */
if (circuit->circ_type != CIRCUIT_T_BROADCAST)
@@ -1035,7 +1071,7 @@ dontcheckadj:
}
/* 7.3.15.1 e) 2) LSP equal to the one in db */
else if (comp == LSP_EQUAL) {
- ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_del(circuit->tx_queue, lsp);
lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream,
circuit->area, level, false);
tlvs = NULL;
@@ -1044,7 +1080,8 @@ dontcheckadj:
}
/* 7.3.15.1 e) 3) LSP older than the one in db */
else {
- ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_add(circuit->tx_queue, lsp,
+ TX_LSP_NORMAL);
ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
}
}
@@ -1052,6 +1089,10 @@ dontcheckadj:
retval = ISIS_OK;
out:
+ if (circuit_scoped) {
+ fabricd_trigger_csnp(circuit->area);
+ }
+
isis_free_tlvs(tlvs);
return retval;
}
@@ -1157,7 +1198,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
circuit->u.bc.adjdb[level - 1]))
return ISIS_OK; /* Silently discard */
} else {
- if (!circuit->u.p2p.neighbor) {
+ if (!fabricd && !circuit->u.p2p.neighbor) {
zlog_warn("no p2p neighbor on circuit %s",
circuit->interface->name);
return ISIS_OK; /* Silently discard */
@@ -1206,6 +1247,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
}
}
+ bool resync_needed = false;
+
/* 7.3.15.2 b) Actions on LSP_ENTRIES reported */
for (struct isis_lsp_entry *entry = entry_head; entry;
entry = entry->next) {
@@ -1221,25 +1264,28 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
if (cmp == LSP_EQUAL) {
/* if (circuit->circ_type !=
* CIRCUIT_T_BROADCAST) */
- ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
/* 7.3.15.2 b) 3) if it is older, clear SSN and set SRM
*/
else if (cmp == LSP_OLDER) {
ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
- ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_add(circuit->tx_queue, lsp,
+ TX_LSP_NORMAL);
}
/* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM
on p2p */
else {
if (own_lsp) {
lsp_inc_seqno(lsp, entry->seqno);
- ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_add(circuit->tx_queue, lsp,
+ TX_LSP_NORMAL);
} else {
ISIS_SET_FLAG(lsp->SSNflags, circuit);
/* if (circuit->circ_type !=
* CIRCUIT_T_BROADCAST) */
- ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_del(circuit->tx_queue, lsp);
+ resync_needed = true;
}
}
} else {
@@ -1271,8 +1317,10 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
entry->checksum, lsp0, level);
lsp_insert(lsp,
circuit->area->lspdb[level - 1]);
- ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);
+
+ lsp_set_all_srmflags(lsp, false);
ISIS_SET_FLAG(lsp->SSNflags, circuit);
+ resync_needed = true;
}
}
}
@@ -1303,12 +1351,18 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
}
/* on remaining LSPs we set SRM (neighbor knew not of) */
- for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp))
- ISIS_SET_FLAG(lsp->SRMflags, circuit);
+ for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) {
+ isis_tx_queue_add(circuit->tx_queue, lsp, TX_LSP_NORMAL);
+ resync_needed = true;
+ }
+
/* lets free it */
list_delete_and_null(&lsp_list);
}
+ if (fabricd_initial_sync_is_complete(circuit->area) && resync_needed)
+ zlog_warn("OpenFabric: Needed to resync LSPDB using CSNP!\n");
+
retval = ISIS_OK;
out:
isis_free_tlvs(tlvs);
@@ -1327,6 +1381,7 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size)
break;
case L1_LINK_STATE:
case L2_LINK_STATE:
+ case FS_LINK_STATE:
*size = ISIS_LSP_HDR_LEN;
break;
case L1_COMPLETE_SEQ_NUM:
@@ -1427,7 +1482,9 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
}
/* either 3 or 0 */
- if (max_area_addrs != 0 && max_area_addrs != isis->max_area_addrs) {
+ if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr field */
+ && max_area_addrs != 0
+ && max_area_addrs != isis->max_area_addrs) {
flog_err(
ISIS_ERR_PACKET,
"maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8
@@ -1440,11 +1497,18 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
case L1_LAN_HELLO:
case L2_LAN_HELLO:
case P2P_HELLO:
+ if (fabricd && pdu_type != P2P_HELLO)
+ return ISIS_ERROR;
retval = process_hello(pdu_type, circuit, ssnpa);
break;
case L1_LINK_STATE:
case L2_LINK_STATE:
- retval = process_lsp(pdu_type, circuit, ssnpa);
+ case FS_LINK_STATE:
+ if (fabricd
+ && pdu_type != L2_LINK_STATE
+ && pdu_type != FS_LINK_STATE)
+ return ISIS_ERROR;
+ retval = process_lsp(pdu_type, circuit, ssnpa, max_area_addrs);
break;
case L1_COMPLETE_SEQ_NUM:
case L2_COMPLETE_SEQ_NUM:
@@ -1582,8 +1646,15 @@ int send_hello(struct isis_circuit *circuit, int level)
&& !circuit->disable_threeway_adj) {
uint32_t ext_circuit_id = circuit->idx;
if (circuit->u.p2p.neighbor) {
+ uint8_t threeway_state;
+
+ if (fabricd_initial_sync_is_in_progress(circuit->area)
+ && fabricd_initial_sync_circuit(circuit->area) != circuit)
+ threeway_state = ISIS_THREEWAY_DOWN;
+ else
+ threeway_state = circuit->u.p2p.neighbor->threeway_state;
isis_tlvs_add_threeway_adj(tlvs,
- circuit->u.p2p.neighbor->threeway_state,
+ threeway_state,
ext_circuit_id,
circuit->u.p2p.neighbor->sysid,
circuit->u.p2p.neighbor->ext_circuit_id);
@@ -1618,8 +1689,12 @@ int send_hello(struct isis_circuit *circuit, int level)
false, false);
}
- if (circuit->ip_router && circuit->ip_addrs)
- isis_tlvs_add_ipv4_addresses(tlvs, circuit->ip_addrs);
+ if (circuit->ip_router) {
+ struct list *circuit_ip_addrs = fabricd_ip_addrs(circuit);
+
+ if (circuit_ip_addrs)
+ isis_tlvs_add_ipv4_addresses(tlvs, circuit_ip_addrs);
+ }
if (circuit->ipv6_router && circuit->ipv6_link)
isis_tlvs_add_ipv6_addresses(tlvs, circuit->ipv6_link);
@@ -1889,8 +1964,9 @@ int send_l1_csnp(struct thread *thread)
circuit->t_send_csnp[0] = NULL;
- if (circuit->circ_type == CIRCUIT_T_BROADCAST
- && circuit->u.bc.is_dr[0]) {
+ if ((circuit->circ_type == CIRCUIT_T_BROADCAST
+ && circuit->u.bc.is_dr[0])
+ || circuit->circ_type == CIRCUIT_T_P2P) {
send_csnp(circuit, 1);
}
/* set next timer thread */
@@ -1911,8 +1987,9 @@ int send_l2_csnp(struct thread *thread)
circuit->t_send_csnp[1] = NULL;
- if (circuit->circ_type == CIRCUIT_T_BROADCAST
- && circuit->u.bc.is_dr[1]) {
+ if ((circuit->circ_type == CIRCUIT_T_BROADCAST
+ && circuit->u.bc.is_dr[1])
+ || circuit->circ_type == CIRCUIT_T_P2P) {
send_csnp(circuit, 2);
}
/* set next timer thread */
@@ -2086,25 +2163,12 @@ int send_l2_psnp(struct thread *thread)
/*
* ISO 10589 - 7.3.14.3
*/
-int send_lsp(struct thread *thread)
+void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type)
{
- struct isis_circuit *circuit;
- struct isis_lsp *lsp;
+ struct isis_circuit *circuit = arg;
int clear_srm = 1;
int retval = ISIS_OK;
- circuit = THREAD_ARG(thread);
- assert(circuit);
- circuit->t_send_lsp = NULL;
-
- lsp = isis_circuit_lsp_queue_pop(circuit);
- if (!lsp)
- return ISIS_OK;
-
- if (!list_isempty(circuit->lsp_queue)) {
- isis_circuit_schedule_lsp_send(circuit);
- }
-
if (circuit->state != C_STATE_UP || circuit->is_passive == 1)
goto out;
@@ -2144,6 +2208,11 @@ int send_lsp(struct thread *thread)
/* copy our lsp to the send buffer */
stream_copy(circuit->snd_stream, lsp->pdu);
+ if (tx_type == TX_LSP_CIRCUIT_SCOPED) {
+ stream_putc_at(circuit->snd_stream, 4, FS_LINK_STATE);
+ stream_putc_at(circuit->snd_stream, 7, L2_CIRCUIT_FLOODING_SCOPE);
+ }
+
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08" PRIx32
", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
@@ -2181,8 +2250,6 @@ out:
* to clear
* the fag.
*/
- ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
-
- return retval;
}
diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h
index c69bfedea..3d2420eb0 100644
--- a/isisd/isis_pdu.h
+++ b/isisd/isis_pdu.h
@@ -24,6 +24,8 @@
#ifndef _ZEBRA_ISIS_PDU_H
#define _ZEBRA_ISIS_PDU_H
+#include "isisd/isis_tx_queue.h"
+
#ifdef __SUNPRO_C
#pragma pack(1)
#endif
@@ -125,6 +127,8 @@ struct isis_p2p_hello_hdr {
#define L1_LINK_STATE 18
#define L2_LINK_STATE 20
+#define FS_LINK_STATE 10
+#define L2_CIRCUIT_FLOODING_SCOPE 2
struct isis_lsp_hdr {
uint16_t pdu_len;
uint16_t rem_lifetime;
@@ -212,7 +216,7 @@ int send_l1_csnp(struct thread *thread);
int send_l2_csnp(struct thread *thread);
int send_l1_psnp(struct thread *thread);
int send_l2_psnp(struct thread *thread);
-int send_lsp(struct thread *thread);
+void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type);
void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
int send_hello(struct isis_circuit *circuit, int level);
int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa);
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index cd3ca4437..ab7584ed3 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -377,7 +377,7 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis)
* routes to Zebra and has nothing to do with
* redistribution,
* so skip it. */
- if (type == ZEBRA_ROUTE_ISIS)
+ if (type == PROTO_TYPE)
continue;
afi_t afi = afi_for_redist_protocol(protocol);
@@ -515,13 +515,19 @@ void isis_redist_area_finish(struct isis_area *area)
DEFUN (isis_redistribute,
isis_redistribute_cmd,
- "redistribute <ipv4|ipv6> " FRR_REDIST_STR_ISISD " <level-1|level-2> [<metric (0-16777215)|route-map WORD>]",
+ "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"
- FRR_REDIST_HELP_STR_ISISD
+ 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"
@@ -530,7 +536,7 @@ DEFUN (isis_redistribute,
int idx_afi = 1;
int idx_protocol = 2;
int idx_level = 3;
- int idx_metric_rmap = 4;
+ int idx_metric_rmap = fabricd ? 3 : 4;
VTY_DECLVAR_CONTEXT(isis_area, area);
int family;
int afi;
@@ -551,7 +557,9 @@ DEFUN (isis_redistribute,
if (type < 0)
return CMD_WARNING_CONFIG_FAILED;
- if (!strcmp("level-1", argv[idx_level]->arg))
+ 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;
@@ -585,14 +593,20 @@ DEFUN (isis_redistribute,
DEFUN (no_isis_redistribute,
no_isis_redistribute_cmd,
- "no redistribute <ipv4|ipv6> " FRR_REDIST_STR_ISISD " <level-1|level-2>",
- NO_STR
+ "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR
+#ifndef FABRICD
+ " <level-1|level-2>"
+#endif
+ , NO_STR
REDIST_STR
"Redistribute IPv4 routes\n"
"Redistribute IPv6 routes\n"
- FRR_REDIST_HELP_STR_ISISD
+ PROTO_REDIST_HELP
+#ifndef FABRICD
"Redistribute into level-1\n"
- "Redistribute into level-2\n")
+ "Redistribute into level-2\n"
+#endif
+ )
{
int idx_afi = 2;
int idx_protocol = 3;
@@ -615,7 +629,10 @@ DEFUN (no_isis_redistribute,
if (type < 0)
return CMD_WARNING_CONFIG_FAILED;
- level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
+ if (fabricd)
+ level = 2;
+ else
+ level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
isis_redist_unset(area, level, family, type);
return 0;
@@ -623,13 +640,19 @@ DEFUN (no_isis_redistribute,
DEFUN (isis_default_originate,
isis_default_originate_cmd,
- "default-information originate <ipv4|ipv6> <level-1|level-2> [always] [<metric (0-16777215)|route-map WORD>]",
+ "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"
@@ -638,8 +661,8 @@ DEFUN (isis_default_originate,
{
int idx_afi = 2;
int idx_level = 3;
- int idx_always = 4;
- int idx_metric_rmap = 4;
+ int idx_always = fabricd ? 3 : 4;
+ int idx_metric_rmap = fabricd ? 3 : 4;
VTY_DECLVAR_CONTEXT(isis_area, area);
int family;
int originate_type = DEFAULT_ORIGINATE;
@@ -651,7 +674,10 @@ DEFUN (isis_default_originate,
if (family < 0)
return CMD_WARNING_CONFIG_FAILED;
- level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
+ if (fabricd)
+ level = 2;
+ else
+ level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
if ((area->is_type & level) != level) {
vty_out(vty, "Node is not a level-%d IS\n", level);
@@ -685,14 +711,20 @@ DEFUN (isis_default_originate,
DEFUN (no_isis_default_originate,
no_isis_default_originate_cmd,
- "no default-information originate <ipv4|ipv6> <level-1|level-2>",
- NO_STR
+ "no default-information originate <ipv4|ipv6>"
+#ifndef FABRICD
+ " <level-1|level-2>"
+#endif
+ , 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")
+ "Distribute default route into level-2\n"
+#endif
+ )
{
int idx_afi = 3;
int idx_level = 4;
@@ -704,7 +736,9 @@ DEFUN (no_isis_default_originate,
if (family < 0)
return CMD_WARNING_CONFIG_FAILED;
- if (strmatch("level-1", argv[idx_level]->text))
+ 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;
@@ -732,15 +766,17 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
return 0;
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
- if (type == ZEBRA_ROUTE_ISIS)
+ if (type == PROTO_TYPE)
continue;
for (level = 1; level <= ISIS_LEVELS; level++) {
redist = get_redist_settings(area, family, type, level);
if (!redist->redist)
continue;
- vty_out(vty, " redistribute %s %s level-%d", family_str,
- zebra_route_string(type), level);
+ vty_out(vty, " redistribute %s %s", family_str,
+ zebra_route_string(type));
+ if (!fabricd)
+ vty_out(vty, " level-%d", level);
if (redist->metric)
vty_out(vty, " metric %u", redist->metric);
if (redist->map_name)
@@ -755,8 +791,10 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
get_redist_settings(area, family, DEFAULT_ROUTE, level);
if (!redist->redist)
continue;
- vty_out(vty, " default-information originate %s level-%d",
- family_str, level);
+ vty_out(vty, " default-information originate %s",
+ family_str);
+ if (!fabricd)
+ vty_out(vty, " level-%d", level);
if (redist->redist == DEFAULT_ORIGINATE_ALWAYS)
vty_out(vty, " always");
if (redist->metric)
@@ -772,8 +810,8 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
void isis_redist_init(void)
{
- install_element(ISIS_NODE, &isis_redistribute_cmd);
- install_element(ISIS_NODE, &no_isis_redistribute_cmd);
- install_element(ISIS_NODE, &isis_default_originate_cmd);
- install_element(ISIS_NODE, &no_isis_default_originate_cmd);
+ 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);
}
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 341921146..6a7528623 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -31,14 +31,10 @@
#include "command.h"
#include "memory.h"
#include "prefix.h"
-#include "hash.h"
#include "if.h"
#include "table.h"
#include "spf_backoff.h"
-#include "jhash.h"
-#include "skiplist.h"
#include "srcdest_table.h"
-#include "lib_errors.h"
#include "isis_constants.h"
#include "isis_common.h"
@@ -56,256 +52,11 @@
#include "isis_csm.h"
#include "isis_mt.h"
#include "isis_tlvs.h"
+#include "fabricd.h"
+#include "isis_spf_private.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info");
-enum vertextype {
- VTYPE_PSEUDO_IS = 1,
- VTYPE_PSEUDO_TE_IS,
- VTYPE_NONPSEUDO_IS,
- VTYPE_NONPSEUDO_TE_IS,
- VTYPE_ES,
- VTYPE_IPREACH_INTERNAL,
- VTYPE_IPREACH_EXTERNAL,
- VTYPE_IPREACH_TE,
- VTYPE_IP6REACH_INTERNAL,
- VTYPE_IP6REACH_EXTERNAL
-};
-
-#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS)
-#define VTYPE_ES(t) ((t) == VTYPE_ES)
-#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL)
-
-struct prefix_pair {
- struct prefix dest;
- struct prefix_ipv6 src;
-};
-
-/*
- * Triple <N, d(N), {Adj(N)}>
- */
-union isis_N {
- uint8_t id[ISIS_SYS_ID_LEN + 1];
- struct prefix_pair ip;
-};
-struct isis_vertex {
- enum vertextype type;
- union isis_N N;
- uint32_t d_N; /* d(N) Distance from this IS */
- uint16_t depth; /* The depth in the imaginary tree */
- struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */
- struct list *parents; /* list of parents for ECMP */
- uint64_t insert_counter;
-};
-
-/* Vertex Queue and associated functions */
-
-struct isis_vertex_queue {
- union {
- struct skiplist *slist;
- struct list *list;
- } l;
- struct hash *hash;
- uint64_t insert_counter;
-};
-
-static unsigned isis_vertex_queue_hash_key(void *vp)
-{
- struct isis_vertex *vertex = vp;
-
- if (VTYPE_IP(vertex->type)) {
- uint32_t key;
-
- key = prefix_hash_key(&vertex->N.ip.dest);
- key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key);
- return key;
- }
-
- return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a);
-}
-
-static int isis_vertex_queue_hash_cmp(const void *a, const void *b)
-{
- const struct isis_vertex *va = a, *vb = b;
-
- if (va->type != vb->type)
- return 0;
-
- if (VTYPE_IP(va->type)) {
- if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest))
- return 0;
-
- return prefix_cmp((struct prefix *)&va->N.ip.src,
- (struct prefix *)&vb->N.ip.src) == 0;
- }
-
- return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0;
-}
-
-/*
- * Compares vertizes for sorting in the TENT list. Returns true
- * if candidate should be considered before current, false otherwise.
- */
-static int isis_vertex_queue_tent_cmp(void *a, void *b)
-{
- struct isis_vertex *va = a;
- struct isis_vertex *vb = b;
-
- if (va->d_N < vb->d_N)
- return -1;
-
- if (va->d_N > vb->d_N)
- return 1;
-
- if (va->type < vb->type)
- return -1;
-
- if (va->type > vb->type)
- return 1;
-
- if (va->insert_counter < vb->insert_counter)
- return -1;
-
- if (va->insert_counter > vb->insert_counter)
- return 1;
-
- return 0;
-}
-
-static struct skiplist *isis_vertex_queue_skiplist(void)
-{
- return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL);
-}
-
-static void isis_vertex_queue_init(struct isis_vertex_queue *queue,
- const char *name, bool ordered)
-{
- if (ordered) {
- queue->insert_counter = 1;
- queue->l.slist = isis_vertex_queue_skiplist();
- } else {
- queue->insert_counter = 0;
- queue->l.list = list_new();
- }
- queue->hash = hash_create(isis_vertex_queue_hash_key,
- isis_vertex_queue_hash_cmp, name);
-}
-
-static void isis_vertex_del(struct isis_vertex *vertex);
-
-static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
-{
- hash_clean(queue->hash, NULL);
-
- if (queue->insert_counter) {
- struct isis_vertex *vertex;
- while (0 == skiplist_first(queue->l.slist, NULL,
- (void **)&vertex)) {
- isis_vertex_del(vertex);
- skiplist_delete_first(queue->l.slist);
- }
- queue->insert_counter = 1;
- } else {
- queue->l.list->del = (void (*)(void *))isis_vertex_del;
- list_delete_all_node(queue->l.list);
- queue->l.list->del = NULL;
- }
-}
-
-static void isis_vertex_queue_free(struct isis_vertex_queue *queue)
-{
- isis_vertex_queue_clear(queue);
-
- hash_free(queue->hash);
- queue->hash = NULL;
-
- if (queue->insert_counter) {
- skiplist_free(queue->l.slist);
- queue->l.slist = NULL;
- } else
- list_delete_and_null(&queue->l.list);
-}
-
-static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue)
-{
- return hashcount(queue->hash);
-}
-
-static void isis_vertex_queue_append(struct isis_vertex_queue *queue,
- struct isis_vertex *vertex)
-{
- assert(!queue->insert_counter);
-
- listnode_add(queue->l.list, vertex);
-
- struct isis_vertex *inserted;
-
- inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
- assert(inserted == vertex);
-}
-
-static void isis_vertex_queue_insert(struct isis_vertex_queue *queue,
- struct isis_vertex *vertex)
-{
- assert(queue->insert_counter);
- vertex->insert_counter = queue->insert_counter++;
- assert(queue->insert_counter != (uint64_t)-1);
-
- skiplist_insert(queue->l.slist, vertex, vertex);
-
- struct isis_vertex *inserted;
- inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
- assert(inserted == vertex);
-}
-
-static struct isis_vertex *
-isis_vertex_queue_pop(struct isis_vertex_queue *queue)
-{
- assert(queue->insert_counter);
-
- struct isis_vertex *rv;
-
- if (skiplist_first(queue->l.slist, NULL, (void **)&rv))
- return NULL;
-
- skiplist_delete_first(queue->l.slist);
- hash_release(queue->hash, rv);
-
- return rv;
-}
-
-static void isis_vertex_queue_delete(struct isis_vertex_queue *queue,
- struct isis_vertex *vertex)
-{
- assert(queue->insert_counter);
-
- skiplist_delete(queue->l.slist, vertex, vertex);
- hash_release(queue->hash, vertex);
-}
-
-#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \
- ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data)
-
-
-/* End of vertex queue definitions */
-
-struct isis_spftree {
- struct isis_vertex_queue paths; /* the SPT */
- struct isis_vertex_queue tents; /* TENT */
- struct route_table *route_table;
- struct isis_area *area; /* back pointer to area */
- unsigned int runcount; /* number of runs since uptime */
- time_t last_run_timestamp; /* last run timestamp as wall time for display */
- time_t last_run_monotime; /* last run as monotime for scheduling */
- time_t last_run_duration; /* last run duration in msec */
-
- uint16_t mtid;
- int family;
- int level;
- enum spf_tree_id tree_id;
-};
-
-
/*
* supports the given af ?
*/
@@ -411,8 +162,7 @@ static const char *vtype2string(enum vertextype vtype)
return NULL; /* Not reached */
}
-#define VID2STR_BUFFER SRCDEST2STR_BUFFER
-static const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
+const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
{
if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) {
return print_sys_hostname(vertex->N.id);
@@ -428,44 +178,26 @@ static const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
return "UNKNOWN";
}
-static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n,
- enum vertextype vtype)
-{
- vertex->type = vtype;
-
- if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
- memcpy(vertex->N.id, n->id, ISIS_SYS_ID_LEN + 1);
- } else if (VTYPE_IP(vtype)) {
- memcpy(&vertex->N.ip, &n->ip, sizeof(n->ip));
- } else {
- flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type");
- }
-}
-
-static struct isis_vertex *isis_vertex_new(union isis_N *n,
+static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree,
+ void *id,
enum vertextype vtype)
{
struct isis_vertex *vertex;
vertex = XCALLOC(MTYPE_ISIS_VERTEX, sizeof(struct isis_vertex));
- isis_vertex_id_init(vertex, n, vtype);
+ isis_vertex_id_init(vertex, id, vtype);
vertex->Adj_N = list_new();
vertex->parents = list_new();
- return vertex;
-}
-
-static void isis_vertex_del(struct isis_vertex *vertex)
-{
- list_delete_and_null(&vertex->Adj_N);
- list_delete_and_null(&vertex->parents);
-
- memset(vertex, 0, sizeof(struct isis_vertex));
- XFREE(MTYPE_ISIS_VERTEX, vertex);
+ if (spftree->hopcount_metric) {
+ vertex->firsthops = hash_create(isis_vertex_queue_hash_key,
+ isis_vertex_queue_hash_cmp,
+ NULL);
+ }
- return;
+ return vertex;
}
static void isis_vertex_adj_del(struct isis_vertex *vertex,
@@ -563,6 +295,9 @@ void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj)
adj);
}
}
+
+ if (fabricd_spftree(area) != NULL)
+ isis_spftree_adj_del(fabricd_spftree(area), adj);
}
/*
@@ -595,17 +330,13 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
#ifdef EXTREME_DEBUG
char buff[VID2STR_BUFFER];
#endif /* EXTREME_DEBUG */
- union isis_N n;
-
- memcpy(n.id, sysid, ISIS_SYS_ID_LEN);
- LSP_PSEUDO_ID(n.id) = 0;
lsp = isis_root_system_lsp(spftree->area, spftree->level, sysid);
if (lsp == NULL)
zlog_warn("ISIS-Spf: could not find own l%d LSP!",
spftree->level);
- vertex = isis_vertex_new(&n,
+ vertex = isis_vertex_new(spftree, sysid,
spftree->area->oldmetric
? VTYPE_NONPSEUDO_IS
: VTYPE_NONPSEUDO_TE_IS);
@@ -621,14 +352,24 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
return vertex;
}
-static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue,
- union isis_N *n,
- enum vertextype vtype)
+static void vertex_add_parent_firsthop(struct hash_backet *backet, void *arg)
{
- struct isis_vertex querier;
+ struct isis_vertex *vertex = arg;
+ struct isis_vertex *hop = backet->data;
- isis_vertex_id_init(&querier, n, vtype);
- return hash_lookup(queue->hash, &querier);
+ hash_get(vertex->firsthops, hop, hash_alloc_intern);
+}
+
+static void vertex_update_firsthops(struct isis_vertex *vertex,
+ struct isis_vertex *parent)
+{
+ if (vertex->d_N <= 2)
+ hash_get(vertex->firsthops, vertex, hash_alloc_intern);
+
+ if (vertex->d_N < 2 || !parent)
+ return;
+
+ hash_iterate(parent->firsthops, vertex_add_parent_firsthop, vertex);
}
/*
@@ -649,7 +390,7 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
assert(isis_find_vertex(&spftree->paths, id, vtype) == NULL);
assert(isis_find_vertex(&spftree->tents, id, vtype) == NULL);
- vertex = isis_vertex_new(id, vtype);
+ vertex = isis_vertex_new(spftree, id, vtype);
vertex->d_N = cost;
vertex->depth = depth;
@@ -657,6 +398,9 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
listnode_add(vertex->parents, parent);
}
+ if (spftree->hopcount_metric)
+ vertex_update_firsthops(vertex, parent);
+
if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) {
for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_adj))
listnode_add(vertex->Adj_N, parent_adj);
@@ -722,6 +466,10 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
assert(spftree && parent);
+ if (spftree->hopcount_metric
+ && !VTYPE_IS(vtype))
+ return;
+
struct prefix_pair p;
if (vtype >= VTYPE_IPREACH_INTERNAL) {
memcpy(&p, id, sizeof(p));
@@ -774,6 +522,8 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
if (listnode_lookup(vertex->Adj_N, parent_adj)
== NULL)
listnode_add(vertex->Adj_N, parent_adj);
+ if (spftree->hopcount_metric)
+ vertex_update_firsthops(vertex, parent);
/* 2) */
if (listcount(vertex->Adj_N) > ISIS_MAX_PATH_SPLITS)
remove_excess_adjs(vertex->Adj_N);
@@ -853,6 +603,9 @@ lspfragloop:
for (r = (struct isis_oldstyle_reach *)
lsp->tlvs->oldstyle_reach.head;
r; r = r->next) {
+ if (fabricd)
+ continue;
+
/* C.2.6 a) */
/* Two way connectivity */
if (!memcmp(r->id, root_sysid, ISIS_SYS_ID_LEN))
@@ -889,7 +642,7 @@ lspfragloop:
if (!pseudo_lsp
&& !memcmp(er->id, null_sysid, ISIS_SYS_ID_LEN))
continue;
- dist = cost + er->metric;
+ dist = cost + (spftree->hopcount_metric ? 1 : er->metric);
process_N(spftree,
LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
: VTYPE_NONPSEUDO_TE_IS,
@@ -897,7 +650,7 @@ lspfragloop:
}
}
- if (!pseudo_lsp && spftree->family == AF_INET
+ if (!fabricd && !pseudo_lsp && spftree->family == AF_INET
&& spftree->mtid == ISIS_MT_IPV4_UNICAST) {
struct isis_item_list *reachs[] = {
&lsp->tlvs->oldstyle_ip_reach,
@@ -1037,7 +790,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
/*
* Add IP(v6) addresses of this circuit
*/
- if (spftree->family == AF_INET) {
+ if (spftree->family == AF_INET && !spftree->hopcount_metric) {
memset(&ip_info, 0, sizeof(ip_info));
ip_info.dest.family = AF_INET;
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, ipnode,
@@ -1050,7 +803,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
&ip_info, NULL, 0, parent);
}
}
- if (spftree->family == AF_INET6) {
+ if (spftree->family == AF_INET6 && !spftree->hopcount_metric) {
memset(&ip_info, 0, sizeof(ip_info));
ip_info.dest.family = AF_INET6;
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link,
@@ -1094,6 +847,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
LSP_PSEUDO_ID(lsp_id) = 0;
isis_spf_add_local(
spftree, VTYPE_ES, lsp_id, adj,
+ spftree->hopcount_metric ? 1 :
circuit->te_metric
[spftree->level - 1],
parent);
@@ -1111,6 +865,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
? VTYPE_NONPSEUDO_IS
: VTYPE_NONPSEUDO_TE_IS,
lsp_id, adj,
+ spftree->hopcount_metric ? 1 :
circuit->te_metric
[spftree->level - 1],
parent);
@@ -1180,10 +935,10 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
circuit->circuit_id);
continue;
}
- isis_spf_process_lsp(
- spftree, lsp,
- circuit->te_metric[spftree->level - 1], 0,
- root_sysid, parent);
+ isis_spf_process_lsp(spftree, lsp,
+ spftree->hopcount_metric ?
+ 1 : circuit->te_metric[spftree->level - 1],
+ 0, root_sysid, parent);
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
adj = circuit->u.p2p.neighbor;
if (!adj || adj->adj_state != ISIS_ADJ_UP)
@@ -1196,6 +951,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
LSP_PSEUDO_ID(lsp_id) = 0;
isis_spf_add_local(
spftree, VTYPE_ES, lsp_id, adj,
+ spftree->hopcount_metric ? 1 :
circuit->te_metric[spftree->level - 1],
parent);
break;
@@ -1215,6 +971,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
? VTYPE_NONPSEUDO_IS
: VTYPE_NONPSEUDO_TE_IS,
lsp_id, adj,
+ spftree->hopcount_metric ? 1 :
circuit->te_metric
[spftree->level - 1],
parent);
@@ -1275,7 +1032,8 @@ static void add_to_paths(struct isis_spftree *spftree,
}
static void init_spt(struct isis_spftree *spftree, int mtid, int level,
- int family, enum spf_tree_id tree_id)
+ int family, enum spf_tree_id tree_id,
+ bool hopcount_metric)
{
isis_vertex_queue_clear(&spftree->tents);
isis_vertex_queue_clear(&spftree->paths);
@@ -1284,7 +1042,63 @@ static void init_spt(struct isis_spftree *spftree, int mtid, int level,
spftree->level = level;
spftree->family = family;
spftree->tree_id = tree_id;
- return;
+ spftree->hopcount_metric = hopcount_metric;
+}
+
+static void isis_spf_loop(struct isis_spftree *spftree,
+ uint8_t *root_sysid)
+{
+ struct isis_vertex *vertex;
+ struct isis_lsp *lsp;
+
+ while (isis_vertex_queue_count(&spftree->tents)) {
+ vertex = isis_vertex_queue_pop(&spftree->tents);
+
+#ifdef EXTREME_DEBUG
+ zlog_debug(
+ "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS",
+ print_sys_hostname(vertex->N.id),
+ vtype2string(vertex->type), vertex->depth, vertex->d_N);
+#endif /* EXTREME_DEBUG */
+
+ add_to_paths(spftree, vertex);
+ if (!VTYPE_IS(vertex->type))
+ continue;
+
+ lsp = lsp_for_vertex(spftree, vertex);
+ if (!lsp) {
+ zlog_warn("ISIS-Spf: No LSP found for %s",
+ rawlspid_print(vertex->N.id)); /* FIXME */
+ continue;
+ }
+
+ isis_spf_process_lsp(spftree, lsp, vertex->d_N, vertex->depth,
+ root_sysid, vertex);
+ }
+}
+
+struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
+ uint8_t *sysid,
+ struct isis_spftree *spftree)
+{
+ if (!spftree)
+ spftree = isis_spftree_new(area);
+
+ init_spt(spftree, ISIS_MT_IPV4_UNICAST, ISIS_LEVEL2,
+ AF_INET, SPFTREE_IPV4, true);
+ if (!memcmp(sysid, isis->sysid, ISIS_SYS_ID_LEN)) {
+ /* If we are running locally, initialize with information from adjacencies */
+ struct isis_vertex *root = isis_spf_add_root(spftree, sysid);
+ isis_spf_preload_tent(spftree, sysid, root);
+ } else {
+ isis_vertex_queue_insert(&spftree->tents, isis_vertex_new(
+ spftree, sysid,
+ VTYPE_NONPSEUDO_TE_IS));
+ }
+
+ isis_spf_loop(spftree, sysid);
+
+ return spftree;
}
static int isis_run_spf(struct isis_area *area, int level,
@@ -1292,11 +1106,8 @@ static int isis_run_spf(struct isis_area *area, int level,
uint8_t *sysid, struct timeval *nowtv)
{
int retval = ISIS_OK;
- struct isis_vertex *vertex;
struct isis_vertex *root_vertex;
struct isis_spftree *spftree = area->spftree[tree_id][level - 1];
- uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
- struct isis_lsp *lsp;
struct timeval time_now;
unsigned long long start_time, end_time;
uint16_t mtid = 0;
@@ -1330,7 +1141,7 @@ static int isis_run_spf(struct isis_area *area, int level,
/*
* C.2.5 Step 0
*/
- init_spt(spftree, mtid, level, family, tree_id);
+ init_spt(spftree, mtid, level, family, tree_id, false);
/* a) */
root_vertex = isis_spf_add_root(spftree, sysid);
/* b) */
@@ -1350,32 +1161,7 @@ static int isis_run_spf(struct isis_area *area, int level,
print_sys_hostname(sysid));
}
- while (isis_vertex_queue_count(&spftree->tents)) {
- vertex = isis_vertex_queue_pop(&spftree->tents);
-
-#ifdef EXTREME_DEBUG
- zlog_debug(
- "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS",
- print_sys_hostname(vertex->N.id),
- vtype2string(vertex->type), vertex->depth, vertex->d_N);
-#endif /* EXTREME_DEBUG */
-
- add_to_paths(spftree, vertex);
- if (VTYPE_IS(vertex->type)) {
- memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
- LSP_FRAGMENT(lsp_id) = 0;
- lsp = lsp_search(lsp_id, area->lspdb[level - 1]);
- if (lsp && lsp->hdr.rem_lifetime != 0) {
- isis_spf_process_lsp(spftree, lsp, vertex->d_N,
- vertex->depth, sysid,
- vertex);
- } else {
- zlog_warn("ISIS-Spf: No LSP found for %s",
- rawlspid_print(lsp_id));
- }
- }
- }
-
+ isis_spf_loop(spftree, sysid);
out:
spftree->runcount++;
spftree->last_run_timestamp = time(NULL);
@@ -1446,6 +1232,8 @@ static int isis_run_spf_cb(struct thread *thread)
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
+ fabricd_run_spf(area);
+
return retval;
}
@@ -1617,12 +1405,18 @@ static void isis_print_spftree(struct vty *vty, int level,
DEFUN (show_isis_topology,
show_isis_topology_cmd,
- "show isis topology [<level-1|level-2>]",
- SHOW_STR
- "IS-IS information\n"
+ "show " PROTO_NAME " topology"
+#ifndef FABRICD
+ " [<level-1|level-2>]"
+#endif
+ , SHOW_STR
+ PROTO_HELP
"IS-IS paths to Intermediate Systems\n"
+#ifndef FABRICD
"Paths to all level-1 routers in the area\n"
- "Paths to all level-2 routers in the domain\n")
+ "Paths to all level-2 routers in the domain\n"
+#endif
+ )
{
int levels;
struct listnode *node;
@@ -1660,6 +1454,13 @@ DEFUN (show_isis_topology,
}
}
+ if (fabricd_spftree(area)) {
+ vty_out(vty,
+ "IS-IS paths to level-2 routers with hop-by-hop metric\n");
+ isis_print_paths(vty, &fabricd_spftree(area)->paths, isis->sysid);
+ vty_out(vty, "\n");
+ }
+
vty_out(vty, "\n");
}
diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h
index 9a73ca878..f4db98cfe 100644
--- a/isisd/isis_spf.h
+++ b/isisd/isis_spf.h
@@ -37,4 +37,7 @@ void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj);
int isis_spf_schedule(struct isis_area *area, int level);
void isis_spf_cmds_init(void);
void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
+struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
+ uint8_t *sysid,
+ struct isis_spftree *spftree);
#endif /* _ZEBRA_ISIS_SPF_H */
diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h
new file mode 100644
index 000000000..af552e0ed
--- /dev/null
+++ b/isisd/isis_spf_private.h
@@ -0,0 +1,362 @@
+/*
+ * IS-IS Rout(e)ing protocol - isis_spf_private.h
+ *
+ * Copyright (C) 2001,2002 Sampo Saaristo
+ * Tampere University of Technology
+ * Institute of Communications Engineering
+ * Copyright (C) 2017 Christian Franke <chris@opensourcerouting.org>
+ *
+ * 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
+ */
+#ifndef ISIS_SPF_PRIVATE_H
+#define ISIS_SPF_PRIVATE_H
+
+#include "hash.h"
+#include "jhash.h"
+#include "skiplist.h"
+#include "lib_errors.h"
+
+enum vertextype {
+ VTYPE_PSEUDO_IS = 1,
+ VTYPE_PSEUDO_TE_IS,
+ VTYPE_NONPSEUDO_IS,
+ VTYPE_NONPSEUDO_TE_IS,
+ VTYPE_ES,
+ VTYPE_IPREACH_INTERNAL,
+ VTYPE_IPREACH_EXTERNAL,
+ VTYPE_IPREACH_TE,
+ VTYPE_IP6REACH_INTERNAL,
+ VTYPE_IP6REACH_EXTERNAL
+};
+
+#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS)
+#define VTYPE_ES(t) ((t) == VTYPE_ES)
+#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL)
+
+struct prefix_pair {
+ struct prefix dest;
+ struct prefix_ipv6 src;
+};
+
+/*
+ * Triple <N, d(N), {Adj(N)}>
+ */
+struct isis_vertex {
+ enum vertextype type;
+ union {
+ uint8_t id[ISIS_SYS_ID_LEN + 1];
+ struct prefix_pair ip;
+ } N;
+ uint32_t d_N; /* d(N) Distance from this IS */
+ uint16_t depth; /* The depth in the imaginary tree */
+ struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */
+ struct list *parents; /* list of parents for ECMP */
+ struct hash *firsthops; /* first two hops to neighbor */
+ uint64_t insert_counter;
+};
+
+/* Vertex Queue and associated functions */
+
+struct isis_vertex_queue {
+ union {
+ struct skiplist *slist;
+ struct list *list;
+ } l;
+ struct hash *hash;
+ uint64_t insert_counter;
+};
+
+__attribute__((__unused__))
+static unsigned isis_vertex_queue_hash_key(void *vp)
+{
+ struct isis_vertex *vertex = vp;
+
+ if (VTYPE_IP(vertex->type)) {
+ uint32_t key;
+
+ key = prefix_hash_key(&vertex->N.ip.dest);
+ key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key);
+ return key;
+ }
+
+ return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a);
+}
+
+__attribute__((__unused__))
+static int isis_vertex_queue_hash_cmp(const void *a, const void *b)
+{
+ const struct isis_vertex *va = a, *vb = b;
+
+ if (va->type != vb->type)
+ return 0;
+
+ if (VTYPE_IP(va->type)) {
+ if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest))
+ return 0;
+
+ return prefix_cmp((struct prefix *)&va->N.ip.src,
+ (struct prefix *)&vb->N.ip.src) == 0;
+ }
+
+ return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0;
+}
+
+/*
+ * Compares vertizes for sorting in the TENT list. Returns true
+ * if candidate should be considered before current, false otherwise.
+ */
+__attribute__((__unused__))
+static int isis_vertex_queue_tent_cmp(void *a, void *b)
+{
+ struct isis_vertex *va = a;
+ struct isis_vertex *vb = b;
+
+ if (va->d_N < vb->d_N)
+ return -1;
+
+ if (va->d_N > vb->d_N)
+ return 1;
+
+ if (va->type < vb->type)
+ return -1;
+
+ if (va->type > vb->type)
+ return 1;
+
+ if (va->insert_counter < vb->insert_counter)
+ return -1;
+
+ if (va->insert_counter > vb->insert_counter)
+ return 1;
+
+ return 0;
+}
+
+__attribute__((__unused__))
+static struct skiplist *isis_vertex_queue_skiplist(void)
+{
+ return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_init(struct isis_vertex_queue *queue,
+ const char *name, bool ordered)
+{
+ if (ordered) {
+ queue->insert_counter = 1;
+ queue->l.slist = isis_vertex_queue_skiplist();
+ } else {
+ queue->insert_counter = 0;
+ queue->l.list = list_new();
+ }
+ queue->hash = hash_create(isis_vertex_queue_hash_key,
+ isis_vertex_queue_hash_cmp, name);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_del(struct isis_vertex *vertex)
+{
+ list_delete_and_null(&vertex->Adj_N);
+ list_delete_and_null(&vertex->parents);
+ if (vertex->firsthops) {
+ hash_clean(vertex->firsthops, NULL);
+ hash_free(vertex->firsthops);
+ vertex->firsthops = NULL;
+ }
+
+ memset(vertex, 0, sizeof(struct isis_vertex));
+ XFREE(MTYPE_ISIS_VERTEX, vertex);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
+{
+ hash_clean(queue->hash, NULL);
+
+ if (queue->insert_counter) {
+ struct isis_vertex *vertex;
+ while (0 == skiplist_first(queue->l.slist, NULL,
+ (void **)&vertex)) {
+ isis_vertex_del(vertex);
+ skiplist_delete_first(queue->l.slist);
+ }
+ queue->insert_counter = 1;
+ } else {
+ queue->l.list->del = (void (*)(void *))isis_vertex_del;
+ list_delete_all_node(queue->l.list);
+ queue->l.list->del = NULL;
+ }
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_free(struct isis_vertex_queue *queue)
+{
+ isis_vertex_queue_clear(queue);
+
+ hash_free(queue->hash);
+ queue->hash = NULL;
+
+ if (queue->insert_counter) {
+ skiplist_free(queue->l.slist);
+ queue->l.slist = NULL;
+ } else
+ list_delete_and_null(&queue->l.list);
+}
+
+__attribute__((__unused__))
+static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue)
+{
+ return hashcount(queue->hash);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_append(struct isis_vertex_queue *queue,
+ struct isis_vertex *vertex)
+{
+ assert(!queue->insert_counter);
+
+ listnode_add(queue->l.list, vertex);
+
+ struct isis_vertex *inserted;
+
+ inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
+ assert(inserted == vertex);
+}
+
+__attribute__((__unused__))
+static struct isis_vertex *isis_vertex_queue_last(struct isis_vertex_queue *queue)
+{
+ struct listnode *tail;
+
+ assert(!queue->insert_counter);
+ tail = listtail(queue->l.list);
+ assert(tail);
+ return listgetdata(tail);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_insert(struct isis_vertex_queue *queue,
+ struct isis_vertex *vertex)
+{
+ assert(queue->insert_counter);
+ vertex->insert_counter = queue->insert_counter++;
+ assert(queue->insert_counter != (uint64_t)-1);
+
+ skiplist_insert(queue->l.slist, vertex, vertex);
+
+ struct isis_vertex *inserted;
+ inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
+ assert(inserted == vertex);
+}
+
+__attribute__((__unused__))
+static struct isis_vertex *
+isis_vertex_queue_pop(struct isis_vertex_queue *queue)
+{
+ assert(queue->insert_counter);
+
+ struct isis_vertex *rv;
+
+ if (skiplist_first(queue->l.slist, NULL, (void **)&rv))
+ return NULL;
+
+ skiplist_delete_first(queue->l.slist);
+ hash_release(queue->hash, rv);
+
+ return rv;
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_delete(struct isis_vertex_queue *queue,
+ struct isis_vertex *vertex)
+{
+ assert(queue->insert_counter);
+
+ skiplist_delete(queue->l.slist, vertex, vertex);
+ hash_release(queue->hash, vertex);
+}
+
+#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \
+ ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data)
+
+/* End of vertex queue definitions */
+
+struct isis_spftree {
+ struct isis_vertex_queue paths; /* the SPT */
+ struct isis_vertex_queue tents; /* TENT */
+ struct route_table *route_table;
+ struct isis_area *area; /* back pointer to area */
+ unsigned int runcount; /* number of runs since uptime */
+ time_t last_run_timestamp; /* last run timestamp as wall time for display */
+ time_t last_run_monotime; /* last run as monotime for scheduling */
+ time_t last_run_duration; /* last run duration in msec */
+
+ uint16_t mtid;
+ int family;
+ int level;
+ enum spf_tree_id tree_id;
+ bool hopcount_metric;
+};
+
+__attribute__((__unused__))
+static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id,
+ enum vertextype vtype)
+{
+ vertex->type = vtype;
+
+ if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
+ memcpy(vertex->N.id, id, ISIS_SYS_ID_LEN + 1);
+ } else if (VTYPE_IP(vtype)) {
+ memcpy(&vertex->N.ip, id, sizeof(vertex->N.ip));
+ } else {
+ flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type");
+ }
+}
+
+__attribute__((__unused__))
+static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue,
+ const void *id,
+ enum vertextype vtype)
+{
+ struct isis_vertex querier;
+
+ isis_vertex_id_init(&querier, id, vtype);
+ return hash_lookup(queue->hash, &querier);
+}
+
+__attribute__((__unused__))
+static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree,
+ struct isis_vertex *vertex)
+{
+ uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
+
+ assert(VTYPE_IS(vertex->type));
+
+ memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
+ LSP_FRAGMENT(lsp_id) = 0;
+
+ dict_t *lspdb = spftree->area->lspdb[spftree->level - 1];
+ struct isis_lsp *lsp = lsp_search(lsp_id, lspdb);
+
+ if (lsp && lsp->hdr.rem_lifetime != 0)
+ return lsp;
+
+ return NULL;
+}
+
+#define VID2STR_BUFFER SRCDEST2STR_BUFFER
+const char *vid2string(struct isis_vertex *vertex, char *buff, int size);
+
+#endif
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 44ba64ce2..08b905c65 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -67,17 +67,6 @@ const char *mode2text[] = {"Disable", "Area", "AS", "Emulate"};
* Followings are control functions for MPLS-TE parameters management.
*------------------------------------------------------------------------*/
-/* Search MPLS TE Circuit context from Interface */
-static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp)
-{
- struct isis_circuit *circuit;
-
- if ((circuit = circuit_scan_by_ifp(ifp)) == NULL)
- return NULL;
-
- return circuit->mtc;
-}
-
/* Create new MPLS TE Circuit context */
struct mpls_te_circuit *mpls_te_circuit_new()
{
@@ -1085,6 +1074,18 @@ void isis_mpls_te_config_write_router(struct vty *vty)
/*------------------------------------------------------------------------*
* Followings are vty command functions.
*------------------------------------------------------------------------*/
+#ifndef FABRICD
+
+/* Search MPLS TE Circuit context from Interface */
+static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp)
+{
+ struct isis_circuit *circuit;
+
+ if ((circuit = circuit_scan_by_ifp(ifp)) == NULL)
+ return NULL;
+
+ return circuit->mtc;
+}
DEFUN (isis_mpls_te_on,
isis_mpls_te_on_cmd,
@@ -1223,9 +1224,9 @@ DEFUN (no_isis_mpls_te_inter_as,
DEFUN (show_isis_mpls_te_router,
show_isis_mpls_te_router_cmd,
- "show isis mpls-te router",
+ "show " PROTO_NAME " mpls-te router",
SHOW_STR
- ISIS_STR
+ PROTO_HELP
MPLS_TE_STR
"Router information\n")
{
@@ -1314,9 +1315,9 @@ static void show_mpls_te_sub(struct vty *vty, struct interface *ifp)
DEFUN (show_isis_mpls_te_interface,
show_isis_mpls_te_interface_cmd,
- "show isis mpls-te interface [INTERFACE]",
+ "show " PROTO_NAME " mpls-te interface [INTERFACE]",
SHOW_STR
- ISIS_STR
+ PROTO_HELP
MPLS_TE_STR
"Interface information\n"
"Interface name\n")
@@ -1342,6 +1343,7 @@ DEFUN (show_isis_mpls_te_interface,
return CMD_SUCCESS;
}
+#endif
/* Initialize MPLS_TE */
void isis_mpls_te_init(void)
@@ -1357,15 +1359,17 @@ void isis_mpls_te_init(void)
isisMplsTE.cir_list = list_new();
isisMplsTE.router_id.s_addr = 0;
+#ifndef FABRICD
/* 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(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, &no_isis_mpls_te_inter_as_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 a433fcdb4..b22460a0b 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -107,6 +107,111 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX];
/* Prototypes */
static void append_item(struct isis_item_list *dest, struct isis_item *item);
+/* Functions for Sub-TLV 3 SR Prefix-SID */
+
+static struct isis_item *copy_item_prefix_sid(struct isis_item *i)
+{
+ struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i;
+ struct isis_prefix_sid *rv = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*rv));
+
+ rv->flags = sid->flags;
+ rv->algorithm = sid->algorithm;
+ rv->value = sid->value;
+ return (struct isis_item *)rv;
+}
+
+static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i,
+ struct sbuf *buf, int indent)
+{
+ struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i;
+
+ sbuf_push(buf, indent, "SR Prefix-SID:\n");
+ sbuf_push(buf, indent, " Flags:%s%s%s%s%s%s\n",
+ sid->flags & ISIS_PREFIX_SID_READVERTISED ? " READVERTISED" : "",
+ sid->flags & ISIS_PREFIX_SID_NODE ? " NODE" : "",
+ sid->flags & ISIS_PREFIX_SID_NO_PHP ? " NO_PHP" : "",
+ sid->flags & ISIS_PREFIX_SID_EXPLICIT_NULL ? " EXPLICIT-NULL" : "",
+ sid->flags & ISIS_PREFIX_SID_VALUE ? " VALUE" : "",
+ sid->flags & ISIS_PREFIX_SID_LOCAL ? " LOCAL" : "");
+ sbuf_push(buf, indent, " Algorithm: %" PRIu8 "\n", sid->algorithm);
+ if (sid->flags & ISIS_PREFIX_SID_VALUE) {
+ sbuf_push(buf, indent, "Label: %" PRIu32 "\n", sid->value);
+ } else {
+ sbuf_push(buf, indent, "Index: %" PRIu32 "\n", sid->value);
+ }
+}
+
+static void free_item_prefix_sid(struct isis_item *i)
+{
+ XFREE(MTYPE_ISIS_SUBTLV, i);
+}
+
+static int pack_item_prefix_sid(struct isis_item *i, struct stream *s)
+{
+ struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i;
+
+ uint8_t size = (sid->flags & ISIS_PREFIX_SID_VALUE) ? 5 : 6;
+
+ if (STREAM_WRITEABLE(s) < size)
+ return 1;
+
+ stream_putc(s, sid->flags);
+ stream_putc(s, sid->algorithm);
+
+ if (sid->flags & ISIS_PREFIX_SID_VALUE) {
+ stream_put3(s, sid->value);
+ } else {
+ stream_putl(s, sid->value);
+ }
+
+ return 0;
+}
+
+static int unpack_item_prefix_sid(uint16_t mtid, uint8_t len, struct stream *s,
+ struct sbuf *log, void *dest, int indent)
+{
+ struct isis_subtlvs *subtlvs = dest;
+ struct isis_prefix_sid sid = {
+ };
+
+ sbuf_push(log, indent, "Unpacking SR Prefix-SID...\n");
+
+ if (len < 5) {
+ sbuf_push(log, indent,
+ "Not enough data left. (expected 5 or more bytes, got %" PRIu8 ")\n",
+ len);
+ return 1;
+ }
+
+ sid.flags = stream_getc(s);
+ if ((sid.flags & ISIS_PREFIX_SID_VALUE)
+ != (sid.flags & ISIS_PREFIX_SID_LOCAL)) {
+ sbuf_push(log, indent, "Flags inplausible: Local Flag needs to match Value Flag\n");
+ return 0;
+ }
+
+ sid.algorithm = stream_getc(s);
+
+ uint8_t expected_size = (sid.flags & ISIS_PREFIX_SID_VALUE) ? 5 : 6;
+ if (len != expected_size) {
+ sbuf_push(log, indent,
+ "TLV size differs from expected size. "
+ "(expected %u but got %" PRIu8 ")\n",
+ expected_size, len);
+ return 1;
+ }
+
+ if (sid.flags & ISIS_PREFIX_SID_VALUE) {
+ sid.value = stream_get3(s);
+ } else {
+ sid.value = stream_getl(s);
+ }
+
+ format_item_prefix_sid(mtid, (struct isis_item *)&sid, log, indent + 2);
+ append_item(&subtlvs->prefix_sids, copy_item_prefix_sid((struct isis_item *)&sid));
+ return 0;
+}
+
/* Functions for Sub-TVL ??? IPv6 Source Prefix */
static struct prefix_ipv6 *copy_subtlv_ipv6_source_prefix(struct prefix_ipv6 *p)
@@ -198,14 +303,36 @@ static int unpack_subtlv_ipv6_source_prefix(enum isis_tlv_context context,
memcpy(subtlvs->source_prefix, &p, sizeof(p));
return 0;
}
+static void init_item_list(struct isis_item_list *items);
+static struct isis_item *copy_item(enum isis_tlv_context context,
+ enum isis_tlv_type type,
+ struct isis_item *item);
+static void copy_items(enum isis_tlv_context context, enum isis_tlv_type type,
+ struct isis_item_list *src, struct isis_item_list *dest);
+static void format_items_(uint16_t mtid, enum isis_tlv_context context,
+ enum isis_tlv_type type, struct isis_item_list *items,
+ struct sbuf *buf, int indent);
+#define format_items(...) format_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__)
+static void free_items(enum isis_tlv_context context, enum isis_tlv_type type,
+ struct isis_item_list *items);
+static int pack_items_(uint16_t mtid, enum isis_tlv_context context,
+ enum isis_tlv_type type, struct isis_item_list *items,
+ struct stream *s, struct isis_tlvs **fragment_tlvs,
+ struct pack_order_entry *pe,
+ struct isis_tlvs *(*new_fragment)(struct list *l),
+ struct list *new_fragment_arg);
+#define pack_items(...) pack_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__)
/* Functions related to subtlvs */
-static struct isis_subtlvs *isis_alloc_subtlvs(void)
+static struct isis_subtlvs *isis_alloc_subtlvs(enum isis_tlv_context context)
{
struct isis_subtlvs *result;
result = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*result));
+ result->context = context;
+
+ init_item_list(&result->prefix_sids);
return result;
}
@@ -217,6 +344,11 @@ static struct isis_subtlvs *copy_subtlvs(struct isis_subtlvs *subtlvs)
struct isis_subtlvs *rv = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*rv));
+ rv->context = subtlvs->context;
+
+ copy_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID,
+ &subtlvs->prefix_sids, &rv->prefix_sids);
+
rv->source_prefix =
copy_subtlv_ipv6_source_prefix(subtlvs->source_prefix);
return rv;
@@ -225,6 +357,9 @@ static struct isis_subtlvs *copy_subtlvs(struct isis_subtlvs *subtlvs)
static void format_subtlvs(struct isis_subtlvs *subtlvs, struct sbuf *buf,
int indent)
{
+ format_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID,
+ &subtlvs->prefix_sids, buf, indent);
+
format_subtlv_ipv6_source_prefix(subtlvs->source_prefix, buf, indent);
}
@@ -233,6 +368,9 @@ static void isis_free_subtlvs(struct isis_subtlvs *subtlvs)
if (!subtlvs)
return;
+ free_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID,
+ &subtlvs->prefix_sids);
+
XFREE(MTYPE_ISIS_SUBTLV, subtlvs->source_prefix);
XFREE(MTYPE_ISIS_SUBTLV, subtlvs);
@@ -248,6 +386,11 @@ static int pack_subtlvs(struct isis_subtlvs *subtlvs, struct stream *s)
stream_putc(s, 0); /* Put 0 as subtlvs length, filled in later */
+ rv = pack_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID,
+ &subtlvs->prefix_sids, s, NULL, NULL, NULL, NULL);
+ if (rv)
+ return rv;
+
rv = pack_subtlv_ipv6_source_prefix(subtlvs->source_prefix, s);
if (rv)
return rv;
@@ -1135,6 +1278,7 @@ static void free_item_extended_ip_reach(struct isis_item *i)
{
struct isis_extended_ip_reach *item =
(struct isis_extended_ip_reach *)i;
+ isis_free_subtlvs(item->subtlvs);
XFREE(MTYPE_ISIS_TLV, item);
}
@@ -1149,11 +1293,16 @@ static int pack_item_extended_ip_reach(struct isis_item *i, struct stream *s)
control = r->down ? ISIS_EXTENDED_IP_REACH_DOWN : 0;
control |= r->prefix.prefixlen;
+ control |= r->subtlvs ? ISIS_EXTENDED_IP_REACH_SUBTLV : 0;
+
stream_putc(s, control);
if (STREAM_WRITEABLE(s) < (unsigned)PSIZE(r->prefix.prefixlen))
return 1;
stream_put(s, &r->prefix.prefix.s_addr, PSIZE(r->prefix.prefixlen));
+
+ if (r->subtlvs)
+ return pack_subtlvs(r->subtlvs, s);
return 0;
}
@@ -1235,9 +1384,12 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len,
len - 6 - PSIZE(rv->prefix.prefixlen));
goto out;
}
- sbuf_push(log, indent, "Skipping %" PRIu8 " bytes of subvls",
- subtlv_len);
- stream_forward_getp(s, subtlv_len);
+
+ rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH);
+ if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IP_REACH, subtlv_len, s,
+ log, rv->subtlvs, indent + 4)) {
+ goto out;
+ }
}
append_item(items, (struct isis_item *)rv);
@@ -1329,6 +1481,126 @@ static int unpack_tlv_dynamic_hostname(enum isis_tlv_context context,
return 0;
}
+/* Functions related to TLV 150 Spine-Leaf-Extension */
+
+static struct isis_spine_leaf *copy_tlv_spine_leaf(
+ const struct isis_spine_leaf *spine_leaf)
+{
+ if (!spine_leaf)
+ return NULL;
+
+ struct isis_spine_leaf *rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv));
+ memcpy(rv, spine_leaf, sizeof(*rv));
+
+ return rv;
+}
+
+static void format_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf,
+ struct sbuf *buf, int indent)
+{
+ if (!spine_leaf)
+ return;
+
+ sbuf_push(buf, indent, "Spine-Leaf-Extension:\n");
+ if (spine_leaf->has_tier) {
+ if (spine_leaf->tier == ISIS_TIER_UNDEFINED) {
+ sbuf_push(buf, indent, " Tier: undefined\n");
+ } else {
+ sbuf_push(buf, indent, " Tier: %" PRIu8 "\n",
+ spine_leaf->tier);
+ }
+ }
+
+ sbuf_push(buf, indent, " Flags:%s%s%s\n",
+ spine_leaf->is_leaf ? " LEAF" : "",
+ spine_leaf->is_spine ? " SPINE" : "",
+ spine_leaf->is_backup ? " BACKUP" : "");
+
+}
+
+static void free_tlv_spine_leaf(struct isis_spine_leaf *spine_leaf)
+{
+ XFREE(MTYPE_ISIS_TLV, spine_leaf);
+}
+
+#define ISIS_SPINE_LEAF_FLAG_TIER 0x08
+#define ISIS_SPINE_LEAF_FLAG_BACKUP 0x04
+#define ISIS_SPINE_LEAF_FLAG_SPINE 0x02
+#define ISIS_SPINE_LEAF_FLAG_LEAF 0x01
+
+static int pack_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf,
+ struct stream *s)
+{
+ if (!spine_leaf)
+ return 0;
+
+ uint8_t tlv_len = 2;
+
+ if (STREAM_WRITEABLE(s) < (unsigned)(2 + tlv_len))
+ return 1;
+
+ stream_putc(s, ISIS_TLV_SPINE_LEAF_EXT);
+ stream_putc(s, tlv_len);
+
+ uint16_t spine_leaf_flags = 0;
+
+ if (spine_leaf->has_tier) {
+ spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_TIER;
+ spine_leaf_flags |= spine_leaf->tier << 12;
+ }
+
+ if (spine_leaf->is_leaf)
+ spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_LEAF;
+
+ if (spine_leaf->is_spine)
+ spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_SPINE;
+
+ if (spine_leaf->is_backup)
+ spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_BACKUP;
+
+ stream_putw(s, spine_leaf_flags);
+
+ return 0;
+}
+
+static int unpack_tlv_spine_leaf(enum isis_tlv_context context,
+ uint8_t tlv_type, uint8_t tlv_len,
+ struct stream *s, struct sbuf *log,
+ void *dest, int indent)
+{
+ struct isis_tlvs *tlvs = dest;
+
+ sbuf_push(log, indent, "Unpacking Spine Leaf Extension TLV...\n");
+ if (tlv_len < 2) {
+ sbuf_push(log, indent, "WARNING: Unexepected TLV size\n");
+ stream_forward_getp(s, tlv_len);
+ return 0;
+ }
+
+ if (tlvs->spine_leaf) {
+ sbuf_push(log, indent,
+ "WARNING: Spine Leaf Extension TLV present multiple times.\n");
+ stream_forward_getp(s, tlv_len);
+ return 0;
+ }
+
+ tlvs->spine_leaf = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->spine_leaf));
+
+ uint16_t spine_leaf_flags = stream_getw(s);
+
+ if (spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_TIER) {
+ tlvs->spine_leaf->has_tier = true;
+ tlvs->spine_leaf->tier = spine_leaf_flags >> 12;
+ }
+
+ tlvs->spine_leaf->is_leaf = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_LEAF;
+ tlvs->spine_leaf->is_spine = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_SPINE;
+ tlvs->spine_leaf->is_backup = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_BACKUP;
+
+ stream_forward_getp(s, tlv_len - 2);
+ return 0;
+}
+
/* Functions related to TLV 240 P2P Three-Way Adjacency */
const char *isis_threeway_state_name(enum isis_threeway_state state)
@@ -1592,7 +1864,7 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s,
goto out;
}
- rv->subtlvs = isis_alloc_subtlvs();
+ rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH);
if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH, subtlv_len, s,
log, rv->subtlvs, indent + 4)) {
goto out;
@@ -1713,6 +1985,114 @@ static int unpack_item_auth(uint16_t mtid, uint8_t len, struct stream *s,
return 0;
}
+/* Functions related to TLV 13 Purge Originator */
+
+static struct isis_purge_originator *copy_tlv_purge_originator(
+ struct isis_purge_originator *poi)
+{
+ if (!poi)
+ return NULL;
+
+ struct isis_purge_originator *rv;
+
+ rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv));
+ rv->sender_set = poi->sender_set;
+ memcpy(rv->generator, poi->generator, sizeof(rv->generator));
+ if (poi->sender_set)
+ memcpy(rv->sender, poi->sender, sizeof(rv->sender));
+ return rv;
+}
+
+static void format_tlv_purge_originator(struct isis_purge_originator *poi,
+ struct sbuf *buf, int indent)
+{
+ if (!poi)
+ return;
+
+ sbuf_push(buf, indent, "Purge Originator Identification:\n");
+ sbuf_push(buf, indent, " Generator: %s\n",
+ isis_format_id(poi->generator, sizeof(poi->generator)));
+ if (poi->sender_set) {
+ sbuf_push(buf, indent, " Received-From: %s\n",
+ isis_format_id(poi->sender, sizeof(poi->sender)));
+ }
+}
+
+static void free_tlv_purge_originator(struct isis_purge_originator *poi)
+{
+ XFREE(MTYPE_ISIS_TLV, poi);
+}
+
+static int pack_tlv_purge_originator(struct isis_purge_originator *poi,
+ struct stream *s)
+{
+ if (!poi)
+ return 0;
+
+ uint8_t data_len = 1 + sizeof(poi->generator);
+
+ if (poi->sender_set)
+ data_len += sizeof(poi->sender);
+
+ if (STREAM_WRITEABLE(s) < (unsigned)(2 + data_len))
+ return 1;
+
+ stream_putc(s, ISIS_TLV_PURGE_ORIGINATOR);
+ stream_putc(s, data_len);
+ stream_putc(s, poi->sender_set ? 2 : 1);
+ stream_put(s, poi->generator, sizeof(poi->generator));
+ if (poi->sender_set)
+ stream_put(s, poi->sender, sizeof(poi->sender));
+ return 0;
+}
+
+static int unpack_tlv_purge_originator(enum isis_tlv_context context,
+ uint8_t tlv_type, uint8_t tlv_len,
+ struct stream *s, struct sbuf *log,
+ void *dest, int indent)
+{
+ struct isis_tlvs *tlvs = dest;
+ struct isis_purge_originator poi = {};
+
+ sbuf_push(log, indent, "Unpacking Purge Originator Identification TLV...\n");
+ if (tlv_len < 7) {
+ sbuf_push(log, indent, "Not enough data left. (Expected at least 7 bytes, got %"
+ PRIu8 ")\n", tlv_len);
+ return 1;
+ }
+
+ uint8_t number_of_ids = stream_getc(s);
+
+ if (number_of_ids == 1) {
+ poi.sender_set = false;
+ } else if (number_of_ids == 2) {
+ poi.sender_set = true;
+ } else {
+ sbuf_push(log, indent, "Got invalid value for number of system IDs: %"
+ PRIu8 ")\n", number_of_ids);
+ return 1;
+ }
+
+ if (tlv_len != 1 + 6 * number_of_ids) {
+ sbuf_push(log, indent, "Incorrect tlv len for number of IDs.\n");
+ return 1;
+ }
+
+ stream_get(poi.generator, s, sizeof(poi.generator));
+ if (poi.sender_set)
+ stream_get(poi.sender, s, sizeof(poi.sender));
+
+ if (tlvs->purge_originator) {
+ sbuf_push(log, indent,
+ "WARNING: Purge originator present multiple times, ignoring.\n");
+ return 0;
+ }
+
+ tlvs->purge_originator = copy_tlv_purge_originator(&poi);
+ return 0;
+}
+
+
/* Functions relating to item TLVs */
static void init_item_list(struct isis_item_list *items)
@@ -1770,7 +2150,6 @@ static void format_items_(uint16_t mtid, enum isis_tlv_context context,
for (i = items->head; i; i = i->next)
format_item(mtid, context, type, i, buf, indent);
}
-#define format_items(...) format_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__)
static void free_item(enum isis_tlv_context tlv_context,
enum isis_tlv_type tlv_type, struct isis_item *item)
@@ -1876,6 +2255,14 @@ top:
break;
}
+ /* Multiple prefix-sids don't go into one TLV, so always break */
+ if (type == ISIS_SUBTLV_PREFIX_SID
+ && (context == ISIS_CONTEXT_SUBTLV_IP_REACH
+ || context == ISIS_CONTEXT_SUBTLV_IPV6_REACH)) {
+ item = item->next;
+ break;
+ }
+
if (len > 255) {
if (!last_len) /* strange, not a single item fit */
return 1;
@@ -2131,6 +2518,9 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs)
copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth,
&rv->isis_auth);
+ rv->purge_originator =
+ copy_tlv_purge_originator(tlvs->purge_originator);
+
copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES,
&tlvs->area_addresses, &rv->area_addresses);
@@ -2187,6 +2577,8 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs)
rv->threeway_adj = copy_tlv_threeway_adj(tlvs->threeway_adj);
+ rv->spine_leaf = copy_tlv_spine_leaf(tlvs->spine_leaf);
+
return rv;
}
@@ -2197,6 +2589,8 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent)
format_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth, buf,
indent);
+ format_tlv_purge_originator(tlvs->purge_originator, buf, indent);
+
format_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES,
&tlvs->area_addresses, buf, indent);
@@ -2250,6 +2644,8 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent)
&tlvs->mt_ipv6_reach, buf, indent);
format_tlv_threeway_adj(tlvs->threeway_adj, buf, indent);
+
+ format_tlv_spine_leaf(tlvs->spine_leaf, buf, indent);
}
const char *isis_format_tlvs(struct isis_tlvs *tlvs)
@@ -2270,6 +2666,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs)
return;
free_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth);
+ free_tlv_purge_originator(tlvs->purge_originator);
free_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES,
&tlvs->area_addresses);
free_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_ROUTER_INFO,
@@ -2301,6 +2698,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs)
free_mt_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_IPV6_REACH,
&tlvs->mt_ipv6_reach);
free_tlv_threeway_adj(tlvs->threeway_adj);
+ free_tlv_spine_leaf(tlvs->spine_leaf);
XFREE(MTYPE_ISIS_TLV, tlvs);
}
@@ -2417,6 +2815,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream,
return rv;
}
+ rv = pack_tlv_purge_originator(tlvs->purge_originator, stream);
+ if (rv)
+ return rv;
+ if (fragment_tlvs) {
+ fragment_tlvs->purge_originator =
+ copy_tlv_purge_originator(tlvs->purge_originator);
+ }
+
rv = pack_tlv_protocols_supported(&tlvs->protocols_supported, stream);
if (rv)
return rv;
@@ -2480,6 +2886,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream,
copy_tlv_threeway_adj(tlvs->threeway_adj);
}
+ rv = pack_tlv_spine_leaf(tlvs->spine_leaf, stream);
+ if (rv)
+ return rv;
+ if (fragment_tlvs) {
+ fragment_tlvs->spine_leaf =
+ copy_tlv_spine_leaf(tlvs->spine_leaf);
+ }
+
for (size_t pack_idx = 0; pack_idx < array_size(pack_order);
pack_idx++) {
rv = handle_pack_entry(&pack_order[pack_idx], tlvs, stream,
@@ -2667,11 +3081,15 @@ int isis_unpack_tlvs(size_t avail_len, struct stream *stream,
.name = _desc_, .unpack = unpack_subtlv_##_name_, \
}
+#define ITEM_SUBTLV_OPS(_name_, _desc_) \
+ ITEM_TLV_OPS(_name_, _desc_)
+
ITEM_TLV_OPS(area_address, "TLV 1 Area Addresses");
ITEM_TLV_OPS(oldstyle_reach, "TLV 2 IS Reachability");
ITEM_TLV_OPS(lan_neighbor, "TLV 6 LAN Neighbors");
ITEM_TLV_OPS(lsp_entry, "TLV 9 LSP Entries");
ITEM_TLV_OPS(auth, "TLV 10 IS-IS Auth");
+TLV_OPS(purge_originator, "TLV 13 Purge Originator Identification");
ITEM_TLV_OPS(extended_reach, "TLV 22 Extended Reachability");
ITEM_TLV_OPS(oldstyle_ip_reach, "TLV 128/130 IP Reachability");
TLV_OPS(protocols_supported, "TLV 129 Protocols Supported");
@@ -2679,11 +3097,13 @@ ITEM_TLV_OPS(ipv4_address, "TLV 132 IPv4 Interface Address");
TLV_OPS(te_router_id, "TLV 134 TE Router ID");
ITEM_TLV_OPS(extended_ip_reach, "TLV 135 Extended IP Reachability");
TLV_OPS(dynamic_hostname, "TLV 137 Dynamic Hostname");
+TLV_OPS(spine_leaf, "TLV 150 Spine Leaf Extensions");
ITEM_TLV_OPS(mt_router_info, "TLV 229 MT Router Information");
TLV_OPS(threeway_adj, "TLV 240 P2P Three-Way Adjacency");
ITEM_TLV_OPS(ipv6_address, "TLV 232 IPv6 Interface Address");
ITEM_TLV_OPS(ipv6_reach, "TLV 236 IPv6 Reachability");
+ITEM_SUBTLV_OPS(prefix_sid, "Sub-TLV 3 SR Prefix-SID");
SUBTLV_OPS(ipv6_source_prefix, "Sub-TLV 22 IPv6 Source Prefix");
static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
@@ -2693,6 +3113,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
[ISIS_TLV_LAN_NEIGHBORS] = &tlv_lan_neighbor_ops,
[ISIS_TLV_LSP_ENTRY] = &tlv_lsp_entry_ops,
[ISIS_TLV_AUTH] = &tlv_auth_ops,
+ [ISIS_TLV_PURGE_ORIGINATOR] = &tlv_purge_originator_ops,
[ISIS_TLV_EXTENDED_REACH] = &tlv_extended_reach_ops,
[ISIS_TLV_MT_REACH] = &tlv_extended_reach_ops,
[ISIS_TLV_OLDSTYLE_IP_REACH] = &tlv_oldstyle_ip_reach_ops,
@@ -2703,6 +3124,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
[ISIS_TLV_EXTENDED_IP_REACH] = &tlv_extended_ip_reach_ops,
[ISIS_TLV_MT_IP_REACH] = &tlv_extended_ip_reach_ops,
[ISIS_TLV_DYNAMIC_HOSTNAME] = &tlv_dynamic_hostname_ops,
+ [ISIS_TLV_SPINE_LEAF_EXT] = &tlv_spine_leaf_ops,
[ISIS_TLV_MT_ROUTER_INFO] = &tlv_mt_router_info_ops,
[ISIS_TLV_THREE_WAY_ADJ] = &tlv_threeway_adj_ops,
[ISIS_TLV_IPV6_ADDRESS] = &tlv_ipv6_address_ops,
@@ -2710,8 +3132,11 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
[ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops,
},
[ISIS_CONTEXT_SUBTLV_NE_REACH] = {},
- [ISIS_CONTEXT_SUBTLV_IP_REACH] = {},
+ [ISIS_CONTEXT_SUBTLV_IP_REACH] = {
+ [ISIS_SUBTLV_PREFIX_SID] = &tlv_prefix_sid_ops,
+ },
[ISIS_CONTEXT_SUBTLV_IPV6_REACH] = {
+ [ISIS_SUBTLV_PREFIX_SID] = &tlv_prefix_sid_ops,
[ISIS_SUBTLV_IPV6_SOURCE_PREFIX] = &subtlv_ipv6_source_prefix_ops,
}
};
@@ -3183,7 +3608,7 @@ void isis_tlvs_add_ipv6_dstsrc_reach(struct isis_tlvs *tlvs, uint16_t mtid,
mtid);
struct isis_ipv6_reach *r = (struct isis_ipv6_reach*)last_item(l);
- r->subtlvs = isis_alloc_subtlvs();
+ r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH);
r->subtlvs->source_prefix = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*src));
memcpy(r->subtlvs->source_prefix, src, sizeof(*src));
}
@@ -3239,6 +3664,24 @@ void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs,
}
}
+void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier,
+ bool has_tier, bool is_leaf, bool is_spine,
+ bool is_backup)
+{
+ assert(!tlvs->spine_leaf);
+
+ tlvs->spine_leaf = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->spine_leaf));
+
+ if (has_tier) {
+ tlvs->spine_leaf->tier = tier;
+ }
+
+ tlvs->spine_leaf->has_tier = has_tier;
+ tlvs->spine_leaf->is_leaf = is_leaf;
+ tlvs->spine_leaf->is_spine = is_spine;
+ tlvs->spine_leaf->is_backup = is_backup;
+}
+
struct isis_mt_router_info *
isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid)
{
@@ -3254,3 +3697,20 @@ isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid)
return NULL;
}
+
+void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs,
+ const uint8_t *generator,
+ const uint8_t *sender)
+{
+ assert(!tlvs->purge_originator);
+
+ tlvs->purge_originator = XCALLOC(MTYPE_ISIS_TLV,
+ sizeof(*tlvs->purge_originator));
+ memcpy(tlvs->purge_originator->generator, generator,
+ sizeof(tlvs->purge_originator->generator));
+ if (sender) {
+ tlvs->purge_originator->sender_set = true;
+ memcpy(tlvs->purge_originator->sender, sender,
+ sizeof(tlvs->purge_originator->sender));
+ }
+}
diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h
index bd1fa3e67..4144809fa 100644
--- a/isisd/isis_tlvs.h
+++ b/isisd/isis_tlvs.h
@@ -83,6 +83,8 @@ struct isis_extended_ip_reach {
uint32_t metric;
bool down;
struct prefix_ipv4 prefix;
+
+ struct isis_subtlvs *subtlvs;
};
struct isis_ipv6_reach;
@@ -103,6 +105,17 @@ struct isis_protocols_supported {
uint8_t *protocols;
};
+#define ISIS_TIER_UNDEFINED 15
+
+struct isis_spine_leaf {
+ uint8_t tier;
+
+ bool has_tier;
+ bool is_leaf;
+ bool is_spine;
+ bool is_backup;
+};
+
enum isis_threeway_state {
ISIS_THREEWAY_DOWN = 2,
ISIS_THREEWAY_INITIALIZING = 1,
@@ -176,6 +189,13 @@ struct isis_item_list {
unsigned int count;
};
+struct isis_purge_originator {
+ bool sender_set;
+
+ uint8_t generator[6];
+ uint8_t sender[6];
+};
+
RB_HEAD(isis_mt_item_list, isis_item_list);
struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m,
@@ -185,6 +205,7 @@ struct isis_item_list *isis_lookup_mt_items(struct isis_mt_item_list *m,
struct isis_tlvs {
struct isis_item_list isis_auth;
+ struct isis_purge_originator *purge_originator;
struct isis_item_list area_addresses;
struct isis_item_list oldstyle_reach;
struct isis_item_list lan_neighbor;
@@ -205,11 +226,24 @@ struct isis_tlvs {
struct isis_item_list ipv6_reach;
struct isis_mt_item_list mt_ipv6_reach;
struct isis_threeway_adj *threeway_adj;
+ struct isis_spine_leaf *spine_leaf;
};
-struct isis_subtlvs {
- /* draft-baker-ipv6-isis-dst-src-routing-06 */
- struct prefix_ipv6 *source_prefix;
+#define ISIS_PREFIX_SID_READVERTISED 0x80
+#define ISIS_PREFIX_SID_NODE 0x40
+#define ISIS_PREFIX_SID_NO_PHP 0x20
+#define ISIS_PREFIX_SID_EXPLICIT_NULL 0x10
+#define ISIS_PREFIX_SID_VALUE 0x08
+#define ISIS_PREFIX_SID_LOCAL 0x04
+
+struct isis_prefix_sid;
+struct isis_prefix_sid {
+ struct isis_prefix_sid *next;
+
+ uint8_t flags;
+ uint8_t algorithm;
+
+ uint32_t value;
};
enum isis_tlv_context {
@@ -220,6 +254,15 @@ enum isis_tlv_context {
ISIS_CONTEXT_MAX
};
+struct isis_subtlvs {
+ enum isis_tlv_context context;
+
+ /* draft-baker-ipv6-isis-dst-src-routing-06 */
+ struct prefix_ipv6 *source_prefix;
+ /* draft-ietf-isis-segment-routing-extensions-16 */
+ struct isis_item_list prefix_sids;
+};
+
enum isis_tlv_type {
ISIS_TLV_AREA_ADDRESSES = 1,
ISIS_TLV_OLDSTYLE_REACH = 2,
@@ -227,6 +270,7 @@ enum isis_tlv_type {
ISIS_TLV_PADDING = 8,
ISIS_TLV_LSP_ENTRY = 9,
ISIS_TLV_AUTH = 10,
+ ISIS_TLV_PURGE_ORIGINATOR = 13,
ISIS_TLV_EXTENDED_REACH = 22,
ISIS_TLV_OLDSTYLE_IP_REACH = 128,
@@ -236,6 +280,7 @@ enum isis_tlv_type {
ISIS_TLV_TE_ROUTER_ID = 134,
ISIS_TLV_EXTENDED_IP_REACH = 135,
ISIS_TLV_DYNAMIC_HOSTNAME = 137,
+ ISIS_TLV_SPINE_LEAF_EXT = 150,
ISIS_TLV_MT_REACH = 222,
ISIS_TLV_MT_ROUTER_INFO = 229,
ISIS_TLV_IPV6_ADDRESS = 232,
@@ -245,6 +290,7 @@ enum isis_tlv_type {
ISIS_TLV_THREE_WAY_ADJ = 240,
ISIS_TLV_MAX = 256,
+ ISIS_SUBTLV_PREFIX_SID = 3,
ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22
};
@@ -331,6 +377,14 @@ void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs,
const uint8_t *neighbor_id,
uint32_t neighbor_circuit_id);
+void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier,
+ bool has_tier, bool is_leaf, bool is_spine,
+ bool is_backup);
+
struct isis_mt_router_info *
isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid);
+
+void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs,
+ const uint8_t *generator,
+ const uint8_t *sender);
#endif
diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c
new file mode 100644
index 000000000..32427628a
--- /dev/null
+++ b/isisd/isis_tx_queue.c
@@ -0,0 +1,182 @@
+/*
+ * IS-IS Rout(e)ing protocol - LSP TX Queuing logic
+ *
+ * Copyright (C) 2018 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (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 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 "hash.h"
+#include "jhash.h"
+
+#include "isisd/isisd.h"
+#include "isisd/isis_memory.h"
+#include "isisd/isis_flags.h"
+#include "dict.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_tx_queue.h"
+
+DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE, "ISIS TX Queue")
+DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE_ENTRY, "ISIS TX Queue Entry")
+
+struct isis_tx_queue {
+ void *arg;
+ void (*send_event)(void *arg, struct isis_lsp *, enum isis_tx_type);
+ struct hash *hash;
+};
+
+struct isis_tx_queue_entry {
+ struct isis_lsp *lsp;
+ enum isis_tx_type type;
+ struct thread *retry;
+ struct isis_tx_queue *queue;
+};
+
+static unsigned tx_queue_hash_key(void *p)
+{
+ struct isis_tx_queue_entry *e = p;
+
+ uint32_t id_key = jhash(e->lsp->hdr.lsp_id,
+ ISIS_SYS_ID_LEN + 2, 0x55aa5a5a);
+
+ return jhash_1word(e->lsp->level, id_key);
+}
+
+static int tx_queue_hash_cmp(const void *a, const void *b)
+{
+ const struct isis_tx_queue_entry *ea = a, *eb = b;
+
+ if (ea->lsp->level != eb->lsp->level)
+ return 0;
+
+ if (memcmp(ea->lsp->hdr.lsp_id, eb->lsp->hdr.lsp_id,
+ ISIS_SYS_ID_LEN + 2))
+ return 0;
+
+ return 1;
+}
+
+struct isis_tx_queue *isis_tx_queue_new(void *arg,
+ void(*send_event)(void *arg,
+ struct isis_lsp *,
+ enum isis_tx_type))
+{
+ struct isis_tx_queue *rv = XCALLOC(MTYPE_TX_QUEUE, sizeof(*rv));
+
+ rv->arg = arg;
+ rv->send_event = send_event;
+
+ rv->hash = hash_create(tx_queue_hash_key, tx_queue_hash_cmp, NULL);
+ return rv;
+}
+
+static void tx_queue_element_free(void *element)
+{
+ struct isis_tx_queue_entry *e = element;
+
+ if (e->retry)
+ thread_cancel(e->retry);
+
+ XFREE(MTYPE_TX_QUEUE_ENTRY, e);
+}
+
+void isis_tx_queue_free(struct isis_tx_queue *queue)
+{
+ hash_clean(queue->hash, tx_queue_element_free);
+ hash_free(queue->hash);
+ XFREE(MTYPE_TX_QUEUE, queue);
+}
+
+static struct isis_tx_queue_entry *tx_queue_find(struct isis_tx_queue *queue,
+ struct isis_lsp *lsp)
+{
+ struct isis_tx_queue_entry e = {
+ .lsp = lsp
+ };
+
+ return hash_lookup(queue->hash, &e);
+}
+
+static int tx_queue_send_event(struct thread *thread)
+{
+ struct isis_tx_queue_entry *e = THREAD_ARG(thread);
+ struct isis_tx_queue *queue = e->queue;
+
+ e->retry = NULL;
+ thread_add_timer(master, tx_queue_send_event, e, 5, &e->retry);
+
+ queue->send_event(queue->arg, e->lsp, e->type);
+ /* Don't access e here anymore, send_event might have destroyed it */
+
+ return 0;
+}
+
+void isis_tx_queue_add(struct isis_tx_queue *queue,
+ struct isis_lsp *lsp,
+ enum isis_tx_type type)
+{
+ if (!queue)
+ return;
+
+ struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp);
+ if (!e) {
+ e = XCALLOC(MTYPE_TX_QUEUE_ENTRY, sizeof(*e));
+ e->lsp = lsp;
+ e->queue = queue;
+
+ struct isis_tx_queue_entry *inserted;
+ inserted = hash_get(queue->hash, e, hash_alloc_intern);
+ assert(inserted == e);
+ }
+
+ e->type = type;
+
+ if (e->retry)
+ thread_cancel(e->retry);
+ thread_add_event(master, tx_queue_send_event, e, 0, &e->retry);
+}
+
+void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp)
+{
+ if (!queue)
+ return;
+
+ struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp);
+ if (!e)
+ return;
+
+ if (e->retry)
+ thread_cancel(e->retry);
+
+ hash_release(queue->hash, e);
+ XFREE(MTYPE_TX_QUEUE_ENTRY, e);
+}
+
+unsigned long isis_tx_queue_len(struct isis_tx_queue *queue)
+{
+ if (!queue)
+ return 0;
+
+ return hashcount(queue->hash);
+}
+
+void isis_tx_queue_clean(struct isis_tx_queue *queue)
+{
+ hash_clean(queue->hash, tx_queue_element_free);
+}
diff --git a/isisd/isis_lsp_hash.h b/isisd/isis_tx_queue.h
index b50aa09dc..ddecdf1e4 100644
--- a/isisd/isis_lsp_hash.h
+++ b/isisd/isis_tx_queue.h
@@ -1,7 +1,7 @@
/*
- * IS-IS Rout(e)ing protocol - LSP Hash
+ * IS-IS Rout(e)ing protocol - LSP TX Queuing logic
*
- * Copyright (C) 2017 Christian Franke
+ * Copyright (C) 2018 Christian Franke
*
* This file is part of FreeRangeRouting (FRR)
*
@@ -19,16 +19,31 @@
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef ISIS_LSP_HASH_H
-#define ISIS_LSP_HASH_H
-
-struct isis_lsp_hash;
-
-struct isis_lsp_hash *isis_lsp_hash_new(void);
-void isis_lsp_hash_clean(struct isis_lsp_hash *ih);
-void isis_lsp_hash_free(struct isis_lsp_hash *ih);
-struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
- struct isis_lsp *lsp);
-void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
-void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
+#ifndef ISIS_TX_QUEUE_H
+#define ISIS_TX_QUEUE_H
+
+enum isis_tx_type {
+ TX_LSP_NORMAL = 0,
+ TX_LSP_CIRCUIT_SCOPED
+};
+
+struct isis_tx_queue;
+
+struct isis_tx_queue *isis_tx_queue_new(void *arg,
+ void(*send_event)(void *arg,
+ struct isis_lsp *,
+ enum isis_tx_type));
+
+void isis_tx_queue_free(struct isis_tx_queue *queue);
+
+void isis_tx_queue_add(struct isis_tx_queue *queue,
+ struct isis_lsp *lsp,
+ enum isis_tx_type type);
+
+void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp);
+
+unsigned long isis_tx_queue_len(struct isis_tx_queue *queue);
+
+void isis_tx_queue_clean(struct isis_tx_queue *queue);
+
#endif
diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c
deleted file mode 100644
index ce2952c13..000000000
--- a/isisd/isis_vty.c
+++ /dev/null
@@ -1,2165 +0,0 @@
-/*
- * IS-IS Rout(e)ing protocol - isis_circuit.h
- *
- * Copyright (C) 2001,2002 Sampo Saaristo
- * Tampere University of Technology
- * Institute of Communications Engineering
- * Copyright (C) 2016 David Lamparter, 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 "spf_backoff.h"
-
-#include "isis_circuit.h"
-#include "isis_csm.h"
-#include "isis_misc.h"
-#include "isis_mt.h"
-#include "isisd.h"
-
-static struct isis_circuit *isis_circuit_lookup(struct vty *vty)
-{
- struct interface *ifp = VTY_GET_CONTEXT(interface);
- struct isis_circuit *circuit;
-
- if (!ifp) {
- vty_out(vty, "Invalid interface \n");
- return NULL;
- }
-
- circuit = circuit_scan_by_ifp(ifp);
- if (!circuit) {
- vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
- return NULL;
- }
-
- return circuit;
-}
-
-DEFUN (ip_router_isis,
- ip_router_isis_cmd,
- "ip router isis WORD",
- "Interface Internet Protocol config commands\n"
- "IP router interface commands\n"
- "IS-IS Routing for IP\n"
- "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 isis WORD",
- "Interface Internet Protocol config commands\n"
- "IP router interface commands\n"
- "IS-IS Routing for IP\n"
- "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 isis WORD",
- NO_STR
- "Interface Internet Protocol config commands\n"
- "IP router interface commands\n"
- "IP router interface commands\n"
- "IS-IS Routing for IP\n"
- "Routing process tag\n")
-{
- int idx_afi = 1;
- int idx_word = 4;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct isis_area *area;
- struct isis_circuit *circuit;
- const char *af = argv[idx_afi]->arg;
- const char *area_tag = argv[idx_word]->arg;
-
- area = isis_area_lookup(area_tag);
- if (!area) {
- vty_out(vty, "Can't find ISIS instance %s\n",
- argv[idx_afi]->arg);
- 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,
- "isis passive",
- "IS-IS commands\n"
- "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 isis passive",
- NO_STR
- "IS-IS commands\n"
- "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_circuit_type,
- isis_circuit_type_cmd,
- "isis circuit-type <level-1|level-1-2|level-2-only>",
- "IS-IS commands\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 commands\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 commands\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 commands\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_passwd,
- isis_passwd_cmd,
- "isis password <md5|clear> WORD",
- "IS-IS commands\n"
- "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 isis password [<md5|clear> WORD]",
- NO_STR
- "IS-IS commands\n"
- "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_priority,
- isis_priority_cmd,
- "isis priority (0-127)",
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n")
-{
- int idx_number = 2;
- int prio;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- prio = atoi(argv[idx_number]->arg);
- if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) {
- vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- 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 commands\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_l1,
- isis_priority_l1_cmd,
- "isis priority (0-127) level-1",
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n"
- "Specify priority for level-1 routing\n")
-{
- int idx_number = 2;
- int prio;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- prio = atoi(argv[idx_number]->arg);
- if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) {
- vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->priority[0] = prio;
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_priority_l1,
- no_isis_priority_l1_cmd,
- "no isis priority [(0-127)] level-1",
- NO_STR
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n"
- "Specify priority for level-1 routing\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->priority[0] = DEFAULT_PRIORITY;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (isis_priority_l2,
- isis_priority_l2_cmd,
- "isis priority (0-127) level-2",
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n"
- "Specify priority for level-2 routing\n")
-{
- int idx_number = 2;
- int prio;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- prio = atoi(argv[idx_number]->arg);
- if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) {
- vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->priority[1] = prio;
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_isis_priority_l2,
- no_isis_priority_l2_cmd,
- "no isis priority [(0-127)] level-2",
- NO_STR
- "IS-IS commands\n"
- "Set priority for Designated Router election\n"
- "Priority value\n"
- "Specify priority for level-2 routing\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->priority[1] = DEFAULT_PRIORITY;
-
- return CMD_SUCCESS;
-}
-
-
-/* Metric command */
-DEFUN (isis_metric,
- isis_metric_cmd,
- "isis metric (0-16777215)",
- "IS-IS commands\n"
- "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 isis metric [(0-16777215)]",
- NO_STR
- "IS-IS commands\n"
- "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_metric_l1,
- isis_metric_l1_cmd,
- "isis metric (0-16777215) level-1",
- "IS-IS commands\n"
- "Set default metric for circuit\n"
- "Default metric value\n"
- "Specify metric for level-1 routing\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);
- CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met),
- "Failed to set L1 metric: $ERR");
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_isis_metric_l1,
- no_isis_metric_l1_cmd,
- "no isis metric [(0-16777215)] level-1",
- NO_STR
- "IS-IS commands\n"
- "Set default metric for circuit\n"
- "Default metric value\n"
- "Specify metric for level-1 routing\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");
- return CMD_SUCCESS;
-}
-
-
-DEFUN (isis_metric_l2,
- isis_metric_l2_cmd,
- "isis metric (0-16777215) level-2",
- "IS-IS commands\n"
- "Set default metric for circuit\n"
- "Default metric value\n"
- "Specify metric for level-2 routing\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);
- 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_l2,
- no_isis_metric_l2_cmd,
- "no isis metric [(0-16777215)] level-2",
- NO_STR
- "IS-IS commands\n"
- "Set default metric for circuit\n"
- "Default metric value\n"
- "Specify metric for level-2 routing\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_2,
- DEFAULT_CIRCUIT_METRIC),
- "Failed to set L2 metric: $ERR");
- return CMD_SUCCESS;
-}
-
-/* end of metrics */
-
-DEFUN (isis_hello_interval,
- isis_hello_interval_cmd,
- "isis hello-interval (1-600)",
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Holdtime 1 seconds, interval depends on multiplier\n")
-{
- int idx_number = 2;
- int interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atoi(argv[idx_number]->arg);
- if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) {
- vty_out(vty, "Invalid hello-interval %d - should be <1-600>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->hello_interval[0] = (uint16_t)interval;
- circuit->hello_interval[1] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_isis_hello_interval,
- no_isis_hello_interval_cmd,
- "no isis hello-interval [(1-600)]",
- NO_STR
- "IS-IS commands\n"
- "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_interval_l1,
- isis_hello_interval_l1_cmd,
- "isis hello-interval (1-600) level-1",
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Holdtime 1 second, interval depends on multiplier\n"
- "Specify hello-interval for level-1 IIHs\n")
-{
- int idx_number = 2;
- long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atoi(argv[idx_number]->arg);
- if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) {
- vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->hello_interval[0] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_isis_hello_interval_l1,
- no_isis_hello_interval_l1_cmd,
- "no isis hello-interval [(1-600)] level-1",
- NO_STR
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Holdtime 1 second, interval depends on multiplier\n"
- "Specify hello-interval for level-1 IIHs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (isis_hello_interval_l2,
- isis_hello_interval_l2_cmd,
- "isis hello-interval (1-600) level-2",
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Holdtime 1 second, interval depends on multiplier\n"
- "Specify hello-interval for level-2 IIHs\n")
-{
- int idx_number = 2;
- long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atoi(argv[idx_number]->arg);
- if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) {
- vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->hello_interval[1] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_isis_hello_interval_l2,
- no_isis_hello_interval_l2_cmd,
- "no isis hello-interval [(1-600)] level-2",
- NO_STR
- "IS-IS commands\n"
- "Set Hello interval\n"
- "Holdtime 1 second, interval depends on multiplier\n"
- "Specify hello-interval for level-2 IIHs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (isis_hello_multiplier,
- isis_hello_multiplier_cmd,
- "isis hello-multiplier (2-100)",
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n")
-{
- int idx_number = 2;
- int mult;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- mult = atoi(argv[idx_number]->arg);
- if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) {
- vty_out(vty,
- "Invalid hello-multiplier %d - should be <2-100>\n",
- mult);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->hello_multiplier[0] = (uint16_t)mult;
- circuit->hello_multiplier[1] = (uint16_t)mult;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_isis_hello_multiplier,
- no_isis_hello_multiplier_cmd,
- "no isis hello-multiplier [(2-100)]",
- NO_STR
- "IS-IS commands\n"
- "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 (isis_hello_multiplier_l1,
- isis_hello_multiplier_l1_cmd,
- "isis hello-multiplier (2-100) level-1",
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n"
- "Specify hello multiplier for level-1 IIHs\n")
-{
- int idx_number = 2;
- int mult;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- mult = atoi(argv[idx_number]->arg);
- if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) {
- vty_out(vty,
- "Invalid hello-multiplier %d - should be <2-100>\n",
- mult);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->hello_multiplier[0] = (uint16_t)mult;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_isis_hello_multiplier_l1,
- no_isis_hello_multiplier_l1_cmd,
- "no isis hello-multiplier [(2-100)] level-1",
- NO_STR
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n"
- "Specify hello multiplier for level-1 IIHs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (isis_hello_multiplier_l2,
- isis_hello_multiplier_l2_cmd,
- "isis hello-multiplier (2-100) level-2",
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n"
- "Specify hello multiplier for level-2 IIHs\n")
-{
- int idx_number = 2;
- int mult;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- mult = atoi(argv[idx_number]->arg);
- if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) {
- vty_out(vty,
- "Invalid hello-multiplier %d - should be <2-100>\n",
- mult);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->hello_multiplier[1] = (uint16_t)mult;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_isis_hello_multiplier_l2,
- no_isis_hello_multiplier_l2_cmd,
- "no isis hello-multiplier [(2-100)] level-2",
- NO_STR
- "IS-IS commands\n"
- "Set multiplier for Hello holding time\n"
- "Hello multiplier value\n"
- "Specify hello multiplier for level-2 IIHs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (isis_hello_padding,
- isis_hello_padding_cmd,
- "isis hello padding",
- "IS-IS commands\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 commands\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 (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 (csnp_interval,
- csnp_interval_cmd,
- "isis csnp-interval (1-600)",
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n")
-{
- int idx_number = 2;
- unsigned long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atol(argv[idx_number]->arg);
- if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) {
- vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->csnp_interval[0] = (uint16_t)interval;
- circuit->csnp_interval[1] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_csnp_interval,
- no_csnp_interval_cmd,
- "no isis csnp-interval [(1-600)]",
- NO_STR
- "IS-IS commands\n"
- "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 (csnp_interval_l1,
- csnp_interval_l1_cmd,
- "isis csnp-interval (1-600) level-1",
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n"
- "Specify interval for level-1 CSNPs\n")
-{
- int idx_number = 2;
- unsigned long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atol(argv[idx_number]->arg);
- if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) {
- vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->csnp_interval[0] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_csnp_interval_l1,
- no_csnp_interval_l1_cmd,
- "no isis csnp-interval [(1-600)] level-1",
- NO_STR
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n"
- "Specify interval for level-1 CSNPs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (csnp_interval_l2,
- csnp_interval_l2_cmd,
- "isis csnp-interval (1-600) level-2",
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n"
- "Specify interval for level-2 CSNPs\n")
-{
- int idx_number = 2;
- unsigned long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atol(argv[idx_number]->arg);
- if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) {
- vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->csnp_interval[1] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_csnp_interval_l2,
- no_csnp_interval_l2_cmd,
- "no isis csnp-interval [(1-600)] level-2",
- NO_STR
- "IS-IS commands\n"
- "Set CSNP interval in seconds\n"
- "CSNP interval value\n"
- "Specify interval for level-2 CSNPs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (psnp_interval,
- psnp_interval_cmd,
- "isis psnp-interval (1-120)",
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n")
-{
- int idx_number = 2;
- unsigned long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atol(argv[idx_number]->arg);
- if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) {
- vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->psnp_interval[0] = (uint16_t)interval;
- circuit->psnp_interval[1] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_psnp_interval,
- no_psnp_interval_cmd,
- "no isis psnp-interval [(1-120)]",
- NO_STR
- "IS-IS commands\n"
- "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 (psnp_interval_l1,
- psnp_interval_l1_cmd,
- "isis psnp-interval (1-120) level-1",
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n"
- "Specify interval for level-1 PSNPs\n")
-{
- int idx_number = 2;
- unsigned long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atol(argv[idx_number]->arg);
- if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) {
- vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->psnp_interval[0] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_psnp_interval_l1,
- no_psnp_interval_l1_cmd,
- "no isis psnp-interval [(1-120)] level-1",
- NO_STR
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n"
- "Specify interval for level-1 PSNPs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (psnp_interval_l2,
- psnp_interval_l2_cmd,
- "isis psnp-interval (1-120) level-2",
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n"
- "Specify interval for level-2 PSNPs\n")
-{
- int idx_number = 2;
- unsigned long interval;
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- interval = atol(argv[idx_number]->arg);
- if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) {
- vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n",
- interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- circuit->psnp_interval[1] = (uint16_t)interval;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_psnp_interval_l2,
- no_psnp_interval_l2_cmd,
- "no isis psnp-interval [(1-120)] level-2",
- NO_STR
- "IS-IS commands\n"
- "Set PSNP interval in seconds\n"
- "PSNP interval value\n"
- "Specify interval for level-2 PSNPs\n")
-{
- struct isis_circuit *circuit = isis_circuit_lookup(vty);
- if (!circuit)
- return CMD_ERR_NO_MATCH;
-
- circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-DEFUN (circuit_topology,
- circuit_topology_cmd,
- "isis topology " ISIS_MT_NAMES,
- "IS-IS commands\n"
- "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 isis topology " ISIS_MT_NAMES,
- NO_STR
- "IS-IS commands\n"
- "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);
-}
-
-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_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;
-}
-
-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;
-}
-
-static int area_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 area_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 area_lsp_mtu_set(vty, DEFAULT_LSP_MTU);
-}
-
-
-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;
-}
-
-static int set_lsp_gen_interval(struct vty *vty, struct isis_area *area,
- uint16_t interval, int level)
-{
- 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 [<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")
-{
- int idx = 0;
- VTY_DECLVAR_CONTEXT(isis_area, area);
- uint16_t interval;
- int level;
-
- level = 0;
- level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0;
- level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0;
- if (!level)
- level = IS_LEVEL_1 | IS_LEVEL_2;
-
- argv_find(argv, argc, "(1-120)", &idx);
-
- interval = atoi(argv[idx]->arg);
- return set_lsp_gen_interval(vty, area, interval, level);
-}
-
-DEFUN (no_lsp_gen_interval,
- no_lsp_gen_interval_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")
-{
- int idx = 0;
- VTY_DECLVAR_CONTEXT(isis_area, area);
- uint16_t interval;
- int level;
-
- level = 0;
- level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0;
- level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0;
- if (!level)
- level = IS_LEVEL_1 | IS_LEVEL_2;
-
- interval = DEFAULT_MIN_LSP_GEN_INTERVAL;
- return set_lsp_gen_interval(vty, area, interval, level);
-}
-
-DEFUN (spf_interval,
- spf_interval_cmd,
- "spf-interval (1-120)",
- "Minimum interval between SPF calculations\n"
- "Minimum interval between consecutive SPFs in seconds\n")
-{
- int idx_number = 1;
- VTY_DECLVAR_CONTEXT(isis_area, area);
- uint16_t interval;
-
- interval = atoi(argv[idx_number]->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 [[<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);
-
- area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
- area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (spf_interval_l1,
- spf_interval_l1_cmd,
- "spf-interval level-1 (1-120)",
- "Minimum interval between SPF calculations\n"
- "Set interval for level 1 only\n"
- "Minimum interval between consecutive SPFs in seconds\n")
-{
- int idx_number = 2;
- VTY_DECLVAR_CONTEXT(isis_area, area);
- uint16_t interval;
-
- interval = atoi(argv[idx_number]->arg);
- area->min_spf_interval[0] = interval;
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_spf_interval_l1,
- no_spf_interval_l1_cmd,
- "no spf-interval level-1",
- NO_STR
- "Minimum interval between SPF calculations\n"
- "Set interval for level 1 only\n")
-{
- VTY_DECLVAR_CONTEXT(isis_area, area);
-
- area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (spf_interval_l2,
- spf_interval_l2_cmd,
- "spf-interval level-2 (1-120)",
- "Minimum interval between SPF calculations\n"
- "Set interval for level 2 only\n"
- "Minimum interval between consecutive SPFs in seconds\n")
-{
- int idx_number = 2;
- VTY_DECLVAR_CONTEXT(isis_area, area);
- uint16_t interval;
-
- interval = atoi(argv[idx_number]->arg);
- area->min_spf_interval[1] = interval;
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_spf_interval_l2,
- no_spf_interval_l2_cmd,
- "no spf-interval level-2",
- NO_STR
- "Minimum interval between SPF calculations\n"
- "Set interval for level 2 only\n")
-{
- VTY_DECLVAR_CONTEXT(isis_area, area);
-
- 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;
-}
-
-static int area_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 [<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")
-{
- int idx = 0;
- unsigned int level = IS_LEVEL_1_AND_2;
-
- if (argv_find(argv, argc, "level-1", &idx))
- level = IS_LEVEL_1;
- else if (argv_find(argv, argc, "level-2", &idx))
- level = IS_LEVEL_2;
-
- argv_find(argv, argc, "(350-65535)", &idx);
- int lifetime = atoi(argv[idx]->arg);
-
- return area_max_lsp_lifetime_set(vty, level, lifetime);
-}
-
-
-DEFUN (no_max_lsp_lifetime,
- no_max_lsp_lifetime_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")
-{
- int idx = 0;
- unsigned int level = IS_LEVEL_1_AND_2;
-
- if (argv_find(argv, argc, "level-1", &idx))
- level = IS_LEVEL_1;
- else if (argv_find(argv, argc, "level-2", &idx))
- level = IS_LEVEL_2;
-
- return area_max_lsp_lifetime_set(vty, level, DEFAULT_LSP_LIFETIME);
-}
-
-static int area_lsp_refresh_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_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 [<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")
-{
- int idx = 0;
- unsigned int level = IS_LEVEL_1_AND_2;
- unsigned int interval = 0;
-
- if (argv_find(argv, argc, "level-1", &idx))
- level = IS_LEVEL_1;
- else if (argv_find(argv, argc, "level-2", &idx))
- level = IS_LEVEL_2;
-
- interval = atoi(argv[argc - 1]->arg);
- return area_lsp_refresh_interval_set(vty, level, interval);
-}
-
-DEFUN (no_lsp_refresh_interval,
- no_lsp_refresh_interval_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")
-{
- int idx = 0;
- unsigned int level = IS_LEVEL_1_AND_2;
-
- if (argv_find(argv, argc, "level-1", &idx))
- level = IS_LEVEL_1;
- else if (argv_find(argv, argc, "level-2", &idx))
- level = IS_LEVEL_2;
-
- return area_lsp_refresh_interval_set(vty, level,
- DEFAULT_MAX_LSP_GEN_INTERVAL);
-}
-
-static int area_passwd_set(struct vty *vty, int level,
- int (*type_set)(struct isis_area *area, int level,
- const char *passwd,
- uint8_t snp_auth),
- const char *passwd, uint8_t snp_auth)
-{
- VTY_DECLVAR_CONTEXT(isis_area, area);
-
- if (passwd && strlen(passwd) > 254) {
- vty_out(vty, "Too long area password (>254)\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- type_set(area, level, passwd, snp_auth);
- return CMD_SUCCESS;
-}
-
-
-DEFUN (area_passwd_md5,
- area_passwd_md5_cmd,
- "area-password md5 WORD [authenticate snp <send-only|validate>]",
- "Configure the authentication password for an area\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")
-{
- int idx_password = 0;
- int idx_word = 2;
- int idx_type = 5;
- uint8_t snp_auth = 0;
- int level = strmatch(argv[idx_password]->text, "domain-password")
- ? IS_LEVEL_2
- : IS_LEVEL_1;
-
- if (argc > 3) {
- snp_auth = SNP_AUTH_SEND;
- if (strmatch(argv[idx_type]->text, "validate"))
- snp_auth |= SNP_AUTH_RECV;
- }
-
- return area_passwd_set(vty, level, isis_area_passwd_hmac_md5_set,
- argv[idx_word]->arg, snp_auth);
-}
-
-DEFUN (domain_passwd_md5,
- domain_passwd_md5_cmd,
- "domain-password md5 WORD [authenticate snp <send-only|validate>]",
- "Set the authentication password for a routing domain\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 area_passwd_md5(self, vty, argc, argv);
-}
-
-DEFUN (area_passwd_clear,
- area_passwd_clear_cmd,
- "area-password clear WORD [authenticate snp <send-only|validate>]",
- "Configure the authentication password for an area\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")
-{
- int idx_password = 0;
- int idx_word = 2;
- int idx_type = 5;
- uint8_t snp_auth = 0;
- int level = strmatch(argv[idx_password]->text, "domain-password")
- ? IS_LEVEL_2
- : IS_LEVEL_1;
-
- if (argc > 3) {
- snp_auth = SNP_AUTH_SEND;
- if (strmatch(argv[idx_type]->text, "validate"))
- snp_auth |= SNP_AUTH_RECV;
- }
-
- return area_passwd_set(vty, level, isis_area_passwd_cleartext_set,
- argv[idx_word]->arg, snp_auth);
-}
-
-DEFUN (domain_passwd_clear,
- domain_passwd_clear_cmd,
- "domain-password clear WORD [authenticate snp <send-only|validate>]",
- "Set the authentication password for a routing domain\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 area_passwd_clear(self, vty, argc, argv);
-}
-
-DEFUN (no_area_passwd,
- no_area_passwd_cmd,
- "no <area-password|domain-password>",
- NO_STR
- "Configure the authentication password for an area\n"
- "Set the authentication password for a routing domain\n")
-{
- int idx_password = 1;
- int level = strmatch(argv[idx_password]->text, "domain-password")
- ? IS_LEVEL_2
- : IS_LEVEL_1;
- VTY_DECLVAR_CONTEXT(isis_area, area);
-
- return isis_area_passwd_unset(area, level);
-}
-
-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_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_passwd_cmd);
- install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
-
- install_element(INTERFACE_NODE, &isis_priority_cmd);
- install_element(INTERFACE_NODE, &no_isis_priority_cmd);
- install_element(INTERFACE_NODE, &isis_priority_l1_cmd);
- install_element(INTERFACE_NODE, &no_isis_priority_l1_cmd);
- install_element(INTERFACE_NODE, &isis_priority_l2_cmd);
- install_element(INTERFACE_NODE, &no_isis_priority_l2_cmd);
-
- install_element(INTERFACE_NODE, &isis_metric_cmd);
- install_element(INTERFACE_NODE, &no_isis_metric_cmd);
- install_element(INTERFACE_NODE, &isis_metric_l1_cmd);
- install_element(INTERFACE_NODE, &no_isis_metric_l1_cmd);
- install_element(INTERFACE_NODE, &isis_metric_l2_cmd);
- install_element(INTERFACE_NODE, &no_isis_metric_l2_cmd);
-
- install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
- install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
- install_element(INTERFACE_NODE, &isis_hello_interval_l1_cmd);
- install_element(INTERFACE_NODE, &no_isis_hello_interval_l1_cmd);
- install_element(INTERFACE_NODE, &isis_hello_interval_l2_cmd);
- install_element(INTERFACE_NODE, &no_isis_hello_interval_l2_cmd);
-
- install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
- install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
- install_element(INTERFACE_NODE, &isis_hello_multiplier_l1_cmd);
- install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd);
- install_element(INTERFACE_NODE, &isis_hello_multiplier_l2_cmd);
- install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd);
-
- install_element(INTERFACE_NODE, &isis_hello_padding_cmd);
- install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd);
-
- install_element(INTERFACE_NODE, &isis_threeway_adj_cmd);
-
- install_element(INTERFACE_NODE, &csnp_interval_cmd);
- install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
- install_element(INTERFACE_NODE, &csnp_interval_l1_cmd);
- install_element(INTERFACE_NODE, &no_csnp_interval_l1_cmd);
- install_element(INTERFACE_NODE, &csnp_interval_l2_cmd);
- install_element(INTERFACE_NODE, &no_csnp_interval_l2_cmd);
-
- install_element(INTERFACE_NODE, &psnp_interval_cmd);
- install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
- install_element(INTERFACE_NODE, &psnp_interval_l1_cmd);
- install_element(INTERFACE_NODE, &no_psnp_interval_l1_cmd);
- install_element(INTERFACE_NODE, &psnp_interval_l2_cmd);
- install_element(INTERFACE_NODE, &no_psnp_interval_l2_cmd);
-
- install_element(INTERFACE_NODE, &circuit_topology_cmd);
- install_element(INTERFACE_NODE, &no_circuit_topology_cmd);
-
- install_element(ISIS_NODE, &metric_style_cmd);
- install_element(ISIS_NODE, &no_metric_style_cmd);
-
- install_element(ISIS_NODE, &set_overload_bit_cmd);
- install_element(ISIS_NODE, &no_set_overload_bit_cmd);
-
- install_element(ISIS_NODE, &set_attached_bit_cmd);
- install_element(ISIS_NODE, &no_set_attached_bit_cmd);
-
- install_element(ISIS_NODE, &dynamic_hostname_cmd);
- install_element(ISIS_NODE, &no_dynamic_hostname_cmd);
-
- install_element(ISIS_NODE, &area_lsp_mtu_cmd);
- install_element(ISIS_NODE, &no_area_lsp_mtu_cmd);
-
- install_element(ISIS_NODE, &is_type_cmd);
- install_element(ISIS_NODE, &no_is_type_cmd);
-
- install_element(ISIS_NODE, &lsp_gen_interval_cmd);
- install_element(ISIS_NODE, &no_lsp_gen_interval_cmd);
-
- install_element(ISIS_NODE, &spf_interval_cmd);
- install_element(ISIS_NODE, &no_spf_interval_cmd);
- install_element(ISIS_NODE, &spf_interval_l1_cmd);
- install_element(ISIS_NODE, &no_spf_interval_l1_cmd);
- install_element(ISIS_NODE, &spf_interval_l2_cmd);
- install_element(ISIS_NODE, &no_spf_interval_l2_cmd);
-
- install_element(ISIS_NODE, &max_lsp_lifetime_cmd);
- install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd);
-
- install_element(ISIS_NODE, &lsp_refresh_interval_cmd);
- install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd);
-
- install_element(ISIS_NODE, &area_passwd_md5_cmd);
- install_element(ISIS_NODE, &area_passwd_clear_cmd);
- install_element(ISIS_NODE, &domain_passwd_md5_cmd);
- install_element(ISIS_NODE, &domain_passwd_clear_cmd);
- install_element(ISIS_NODE, &no_area_passwd_cmd);
-
- install_element(ISIS_NODE, &spf_delay_ietf_cmd);
- install_element(ISIS_NODE, &no_spf_delay_ietf_cmd);
-}
diff --git a/isisd/isis_vty_common.c b/isisd/isis_vty_common.c
new file mode 100644
index 000000000..2b98a88b3
--- /dev/null
+++ b/isisd/isis_vty_common.c
@@ -0,0 +1,960 @@
+/*
+ * IS-IS Rout(e)ing protocol - isis_vty_common.c
+ *
+ * This file contains the CLI that is shared between OpenFabric and 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 "spf_backoff.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"
+
+struct isis_circuit *isis_circuit_lookup(struct vty *vty)
+{
+ struct interface *ifp = VTY_GET_CONTEXT(interface);
+ struct isis_circuit *circuit;
+
+ if (!ifp) {
+ vty_out(vty, "Invalid interface \n");
+ return NULL;
+ }
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit) {
+ vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
+ return NULL;
+ }
+
+ 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 (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(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);
+
+ isis_vty_daemon_init();
+}
diff --git a/isisd/isis_vty_common.h b/isisd/isis_vty_common.h
new file mode 100644
index 000000000..b726b4ee8
--- /dev/null
+++ b/isisd/isis_vty_common.h
@@ -0,0 +1,38 @@
+/*
+ * IS-IS Rout(e)ing protocol - isis_vty_common.h
+ *
+ * Copyright (C) 2001,2002 Sampo Saaristo
+ * Tampere University of Technology
+ * Institute of Communications Engineering
+ * Copyright (C) 2016 David Lamparter, 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
+ */
+
+#ifndef ISIS_VTY_COMMON_H
+#define ISIS_VTY_COMMON_H
+
+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);
+
+#endif
diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c
new file mode 100644
index 000000000..95ebe0de8
--- /dev/null
+++ b/isisd/isis_vty_fabricd.c
@@ -0,0 +1,94 @@
+/*
+ * IS-IS Rout(e)ing protocol - isis_vty_fabricd.c
+ *
+ * This file contains the CLI that is specific to OpenFabric
+ *
+ * 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 "isisd.h"
+#include "isis_vty_common.h"
+#include "fabricd.h"
+#include "isis_tlvs.h"
+
+DEFUN (fabric_tier,
+ fabric_tier_cmd,
+ "fabric-tier (0-14)",
+ "Statically configure the tier to advertise\n"
+ "Tier to advertise\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ uint8_t tier = atoi(argv[1]->arg);
+
+ fabricd_configure_tier(area, tier);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_fabric_tier,
+ no_fabric_tier_cmd,
+ "no fabric-tier [(0-14)]",
+ NO_STR
+ "Statically configure the tier to advertise\n"
+ "Tier to advertise\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ fabricd_configure_tier(area, ISIS_TIER_UNDEFINED);
+ return CMD_SUCCESS;
+}
+
+DEFUN (debug_fabric_flooding,
+ debug_fabric_flooding_cmd,
+ "debug openfabric flooding",
+ DEBUG_STR
+ PROTO_HELP
+ "Flooding optimization algorithm\n")
+{
+ isis->debugs |= DEBUG_FABRICD_FLOODING;
+ print_debug(vty, DEBUG_FABRICD_FLOODING, 1);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_fabric_flooding,
+ no_debug_fabric_flooding_cmd,
+ "no debug openfabric flooding",
+ NO_STR
+ UNDEBUG_STR
+ PROTO_HELP
+ "Flooding optimization algorithm\n")
+{
+ isis->debugs &= ~DEBUG_FABRICD_FLOODING;
+ print_debug(vty, DEBUG_FABRICD_FLOODING, 0);
+
+ return CMD_SUCCESS;
+}
+
+
+void isis_vty_daemon_init(void)
+{
+ install_element(ROUTER_NODE, &fabric_tier_cmd);
+ install_element(ROUTER_NODE, &no_fabric_tier_cmd);
+ install_element(ENABLE_NODE, &debug_fabric_flooding_cmd);
+ install_element(ENABLE_NODE, &no_debug_fabric_flooding_cmd);
+ install_element(CONFIG_NODE, &debug_fabric_flooding_cmd);
+ install_element(CONFIG_NODE, &no_debug_fabric_flooding_cmd);
+}
diff --git a/isisd/isis_vty_isisd.c b/isisd/isis_vty_isisd.c
new file mode 100644
index 000000000..95aaeae81
--- /dev/null
+++ b/isisd/isis_vty_isisd.c
@@ -0,0 +1,858 @@
+/*
+ * 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/isis_zebra.c b/isisd/isis_zebra.c
index 9bc0f2ef3..33d8a0f77 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -261,8 +261,10 @@ static void isis_zebra_route_add_route(struct prefix *prefix,
return;
memset(&api, 0, sizeof(api));
+ if (fabricd)
+ api.flags |= ZEBRA_FLAG_ONLINK;
api.vrf_id = VRF_DEFAULT;
- api.type = ZEBRA_ROUTE_ISIS;
+ api.type = PROTO_TYPE;
api.safi = SAFI_UNICAST;
api.prefix = *prefix;
if (src_p && src_p->prefixlen) {
@@ -337,7 +339,7 @@ static void isis_zebra_route_del_route(struct prefix *prefix,
memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
- api.type = ZEBRA_ROUTE_ISIS;
+ api.type = PROTO_TYPE;
api.safi = SAFI_UNICAST;
api.prefix = *prefix;
if (src_p && src_p->prefixlen) {
@@ -378,7 +380,7 @@ static int isis_zebra_read(int command, struct zclient *zclient,
*/
if (api.prefix.prefixlen == 0
&& api.src_prefix.prefixlen == 0
- && api.type == ZEBRA_ROUTE_ISIS) {
+ && api.type == PROTO_TYPE) {
command = ZEBRA_REDISTRIBUTE_ROUTE_DEL;
}
@@ -424,7 +426,7 @@ static void isis_zebra_connected(struct zclient *zclient)
void isis_zebra_init(struct thread_master *master)
{
zclient = zclient_new_notify(master, &zclient_options_default);
- zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0, &isisd_privs);
+ zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
zclient->zebra_connected = isis_zebra_connected;
zclient->router_id_update = isis_router_id_update_zebra;
zclient->interface_add = isis_zebra_if_add;
diff --git a/isisd/isisd.c b/isisd/isisd.c
index a19f28745..e3ff3b8d9 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -56,6 +56,7 @@
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
#include "isisd/isis_mt.h"
+#include "isisd/fabricd.h"
struct isis *isis = NULL;
@@ -95,6 +96,7 @@ void isis_new(unsigned long process_id)
*/
/* isis->debugs = 0xFFFF; */
isisMplsTE.status = disable; /* Only support TE metric */
+
QOBJ_REG(isis, isis);
}
@@ -105,10 +107,13 @@ struct isis_area *isis_area_create(const char *area_tag)
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
/*
- * The first instance is level-1-2 rest are level-1, unless otherwise
- * configured
+ * Fabricd runs only as level-2.
+ * For IS-IS, the first instance is level-1-2 rest are level-1,
+ * unless otherwise configured
*/
- if (listcount(isis->area_list) > 0)
+ if (fabricd) {
+ area->is_type = IS_LEVEL_2;
+ } else if (listcount(isis->area_list) > 0)
area->is_type = IS_LEVEL_1;
else
area->is_type = IS_LEVEL_1_AND_2;
@@ -153,6 +158,8 @@ struct isis_area *isis_area_create(const char *area_tag)
listnode_add(isis->area_list, area);
area->isis = isis;
+ if (fabricd)
+ area->fabricd = fabricd_new(area);
QOBJ_REG(area, isis_area);
return area;
@@ -179,7 +186,7 @@ int isis_area_get(struct vty *vty, const char *area_tag)
area = isis_area_lookup(area_tag);
if (area) {
- VTY_PUSH_CONTEXT(ISIS_NODE, area);
+ VTY_PUSH_CONTEXT(ROUTER_NODE, area);
return CMD_SUCCESS;
}
@@ -188,7 +195,7 @@ int isis_area_get(struct vty *vty, const char *area_tag)
if (isis->debugs & DEBUG_EVENTS)
zlog_debug("New IS-IS area instance %s", area->area_tag);
- VTY_PUSH_CONTEXT(ISIS_NODE, area);
+ VTY_PUSH_CONTEXT(ROUTER_NODE, area);
return CMD_SUCCESS;
}
@@ -209,6 +216,9 @@ int isis_area_destroy(struct vty *vty, const char *area_tag)
QOBJ_UNREG(area);
+ if (fabricd)
+ fabricd_finish(area->fabricd);
+
if (area->circuit_list) {
for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
circuit)) {
@@ -463,9 +473,9 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail)
DEFUN (show_isis_interface,
show_isis_interface_cmd,
- "show isis interface",
+ "show " PROTO_NAME " interface",
SHOW_STR
- "ISIS network information\n"
+ PROTO_HELP
"ISIS interface\n")
{
return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
@@ -473,9 +483,9 @@ DEFUN (show_isis_interface,
DEFUN (show_isis_interface_detail,
show_isis_interface_detail_cmd,
- "show isis interface detail",
+ "show " PROTO_NAME " interface detail",
SHOW_STR
- "ISIS network information\n"
+ PROTO_HELP
"ISIS interface\n"
"show detailed information\n")
{
@@ -484,9 +494,9 @@ DEFUN (show_isis_interface_detail,
DEFUN (show_isis_interface_arg,
show_isis_interface_arg_cmd,
- "show isis interface WORD",
+ "show " PROTO_NAME " interface WORD",
SHOW_STR
- "ISIS network information\n"
+ PROTO_HELP
"ISIS interface\n"
"ISIS interface name\n")
{
@@ -634,9 +644,9 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id)
DEFUN (show_isis_neighbor,
show_isis_neighbor_cmd,
- "show isis neighbor",
+ "show " PROTO_NAME " neighbor",
SHOW_STR
- "ISIS network information\n"
+ PROTO_HELP
"ISIS neighbor adjacencies\n")
{
return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
@@ -644,9 +654,9 @@ DEFUN (show_isis_neighbor,
DEFUN (show_isis_neighbor_detail,
show_isis_neighbor_detail_cmd,
- "show isis neighbor detail",
+ "show " PROTO_NAME " neighbor detail",
SHOW_STR
- "ISIS network information\n"
+ PROTO_HELP
"ISIS neighbor adjacencies\n"
"show detailed information\n")
{
@@ -655,9 +665,9 @@ DEFUN (show_isis_neighbor_detail,
DEFUN (show_isis_neighbor_arg,
show_isis_neighbor_arg_cmd,
- "show isis neighbor WORD",
+ "show " PROTO_NAME " neighbor WORD",
SHOW_STR
- "ISIS network information\n"
+ PROTO_HELP
"ISIS neighbor adjacencies\n"
"System id\n")
{
@@ -668,19 +678,19 @@ DEFUN (show_isis_neighbor_arg,
DEFUN (clear_isis_neighbor,
clear_isis_neighbor_cmd,
- "clear isis neighbor",
+ "clear " PROTO_NAME " neighbor",
CLEAR_STR
- "Reset ISIS network information\n"
- "Reset ISIS neighbor adjacencies\n")
+ PROTO_HELP
+ "ISIS neighbor adjacencies\n")
{
return clear_isis_neighbor_common(vty, NULL);
}
DEFUN (clear_isis_neighbor_arg,
clear_isis_neighbor_arg_cmd,
- "clear isis neighbor WORD",
+ "clear " PROTO_NAME " neighbor WORD",
CLEAR_STR
- "ISIS network information\n"
+ PROTO_HELP
"ISIS neighbor adjacencies\n"
"System id\n")
{
@@ -734,16 +744,18 @@ void print_debug(struct vty *vty, int flags, int onoff)
vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs);
if (flags & DEBUG_LSP_SCHED)
vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs);
+ if (flags & DEBUG_FABRICD_FLOODING)
+ vty_out(vty, "OpenFabric Flooding debugging is %s\n", onoffs);
}
DEFUN_NOSH (show_debugging,
show_debugging_isis_cmd,
- "show debugging [isis]",
+ "show debugging [" PROTO_NAME "]",
SHOW_STR
"State of each debugging option\n"
- ISIS_STR)
+ PROTO_HELP)
{
- vty_out(vty, "IS-IS debugging status:\n");
+ vty_out(vty, PROTO_NAME " debugging status:\n");
if (isis->debugs)
print_debug(vty, isis->debugs, 1);
@@ -760,59 +772,63 @@ static int config_write_debug(struct vty *vty)
int flags = isis->debugs;
if (flags & DEBUG_ADJ_PACKETS) {
- vty_out(vty, "debug isis adj-packets\n");
+ vty_out(vty, "debug " PROTO_NAME " adj-packets\n");
write++;
}
if (flags & DEBUG_CHECKSUM_ERRORS) {
- vty_out(vty, "debug isis checksum-errors\n");
+ vty_out(vty, "debug " PROTO_NAME " checksum-errors\n");
write++;
}
if (flags & DEBUG_LOCAL_UPDATES) {
- vty_out(vty, "debug isis local-updates\n");
+ vty_out(vty, "debug " PROTO_NAME " local-updates\n");
write++;
}
if (flags & DEBUG_PROTOCOL_ERRORS) {
- vty_out(vty, "debug isis protocol-errors\n");
+ vty_out(vty, "debug " PROTO_NAME " protocol-errors\n");
write++;
}
if (flags & DEBUG_SNP_PACKETS) {
- vty_out(vty, "debug isis snp-packets\n");
+ vty_out(vty, "debug " PROTO_NAME " snp-packets\n");
write++;
}
if (flags & DEBUG_SPF_EVENTS) {
- vty_out(vty, "debug isis spf-events\n");
+ vty_out(vty, "debug " PROTO_NAME " spf-events\n");
write++;
}
if (flags & DEBUG_SPF_STATS) {
- vty_out(vty, "debug isis spf-statistics\n");
+ vty_out(vty, "debug " PROTO_NAME " spf-statistics\n");
write++;
}
if (flags & DEBUG_SPF_TRIGGERS) {
- vty_out(vty, "debug isis spf-triggers\n");
+ vty_out(vty, "debug " PROTO_NAME " spf-triggers\n");
write++;
}
if (flags & DEBUG_UPDATE_PACKETS) {
- vty_out(vty, "debug isis update-packets\n");
+ vty_out(vty, "debug " PROTO_NAME " update-packets\n");
write++;
}
if (flags & DEBUG_RTE_EVENTS) {
- vty_out(vty, "debug isis route-events\n");
+ vty_out(vty, "debug " PROTO_NAME " route-events\n");
write++;
}
if (flags & DEBUG_EVENTS) {
- vty_out(vty, "debug isis events\n");
+ vty_out(vty, "debug " PROTO_NAME " events\n");
write++;
}
if (flags & DEBUG_PACKET_DUMP) {
- vty_out(vty, "debug isis packet-dump\n");
+ vty_out(vty, "debug " PROTO_NAME " packet-dump\n");
write++;
}
if (flags & DEBUG_LSP_GEN) {
- vty_out(vty, "debug isis lsp-gen\n");
+ vty_out(vty, "debug " PROTO_NAME " lsp-gen\n");
write++;
}
if (flags & DEBUG_LSP_SCHED) {
- vty_out(vty, "debug isis lsp-sched\n");
+ vty_out(vty, "debug " PROTO_NAME " lsp-sched\n");
+ write++;
+ }
+ if (flags & DEBUG_FABRICD_FLOODING) {
+ vty_out(vty, "debug " PROTO_NAME " flooding\n");
write++;
}
write += spf_backoff_write_config(vty);
@@ -822,9 +838,9 @@ static int config_write_debug(struct vty *vty)
DEFUN (debug_isis_adj,
debug_isis_adj_cmd,
- "debug isis adj-packets",
+ "debug " PROTO_NAME " adj-packets",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Adjacency related packets\n")
{
isis->debugs |= DEBUG_ADJ_PACKETS;
@@ -835,10 +851,10 @@ DEFUN (debug_isis_adj,
DEFUN (no_debug_isis_adj,
no_debug_isis_adj_cmd,
- "no debug isis adj-packets",
+ "no debug " PROTO_NAME " adj-packets",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Adjacency related packets\n")
{
isis->debugs &= ~DEBUG_ADJ_PACKETS;
@@ -849,9 +865,9 @@ DEFUN (no_debug_isis_adj,
DEFUN (debug_isis_csum,
debug_isis_csum_cmd,
- "debug isis checksum-errors",
+ "debug " PROTO_NAME " checksum-errors",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS LSP checksum errors\n")
{
isis->debugs |= DEBUG_CHECKSUM_ERRORS;
@@ -862,10 +878,10 @@ DEFUN (debug_isis_csum,
DEFUN (no_debug_isis_csum,
no_debug_isis_csum_cmd,
- "no debug isis checksum-errors",
+ "no debug " PROTO_NAME " checksum-errors",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS LSP checksum errors\n")
{
isis->debugs &= ~DEBUG_CHECKSUM_ERRORS;
@@ -876,9 +892,9 @@ DEFUN (no_debug_isis_csum,
DEFUN (debug_isis_lupd,
debug_isis_lupd_cmd,
- "debug isis local-updates",
+ "debug " PROTO_NAME " local-updates",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS local update packets\n")
{
isis->debugs |= DEBUG_LOCAL_UPDATES;
@@ -889,10 +905,10 @@ DEFUN (debug_isis_lupd,
DEFUN (no_debug_isis_lupd,
no_debug_isis_lupd_cmd,
- "no debug isis local-updates",
+ "no debug " PROTO_NAME " local-updates",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS local update packets\n")
{
isis->debugs &= ~DEBUG_LOCAL_UPDATES;
@@ -903,9 +919,9 @@ DEFUN (no_debug_isis_lupd,
DEFUN (debug_isis_err,
debug_isis_err_cmd,
- "debug isis protocol-errors",
+ "debug " PROTO_NAME " protocol-errors",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS LSP protocol errors\n")
{
isis->debugs |= DEBUG_PROTOCOL_ERRORS;
@@ -916,10 +932,10 @@ DEFUN (debug_isis_err,
DEFUN (no_debug_isis_err,
no_debug_isis_err_cmd,
- "no debug isis protocol-errors",
+ "no debug " PROTO_NAME " protocol-errors",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS LSP protocol errors\n")
{
isis->debugs &= ~DEBUG_PROTOCOL_ERRORS;
@@ -930,9 +946,9 @@ DEFUN (no_debug_isis_err,
DEFUN (debug_isis_snp,
debug_isis_snp_cmd,
- "debug isis snp-packets",
+ "debug " PROTO_NAME " snp-packets",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS CSNP/PSNP packets\n")
{
isis->debugs |= DEBUG_SNP_PACKETS;
@@ -943,10 +959,10 @@ DEFUN (debug_isis_snp,
DEFUN (no_debug_isis_snp,
no_debug_isis_snp_cmd,
- "no debug isis snp-packets",
+ "no debug " PROTO_NAME " snp-packets",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS CSNP/PSNP packets\n")
{
isis->debugs &= ~DEBUG_SNP_PACKETS;
@@ -957,9 +973,9 @@ DEFUN (no_debug_isis_snp,
DEFUN (debug_isis_upd,
debug_isis_upd_cmd,
- "debug isis update-packets",
+ "debug " PROTO_NAME " update-packets",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Update related packets\n")
{
isis->debugs |= DEBUG_UPDATE_PACKETS;
@@ -970,10 +986,10 @@ DEFUN (debug_isis_upd,
DEFUN (no_debug_isis_upd,
no_debug_isis_upd_cmd,
- "no debug isis update-packets",
+ "no debug " PROTO_NAME " update-packets",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Update related packets\n")
{
isis->debugs &= ~DEBUG_UPDATE_PACKETS;
@@ -984,9 +1000,9 @@ DEFUN (no_debug_isis_upd,
DEFUN (debug_isis_spfevents,
debug_isis_spfevents_cmd,
- "debug isis spf-events",
+ "debug " PROTO_NAME " spf-events",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Shortest Path First Events\n")
{
isis->debugs |= DEBUG_SPF_EVENTS;
@@ -997,10 +1013,10 @@ DEFUN (debug_isis_spfevents,
DEFUN (no_debug_isis_spfevents,
no_debug_isis_spfevents_cmd,
- "no debug isis spf-events",
+ "no debug " PROTO_NAME " spf-events",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Shortest Path First Events\n")
{
isis->debugs &= ~DEBUG_SPF_EVENTS;
@@ -1011,9 +1027,9 @@ DEFUN (no_debug_isis_spfevents,
DEFUN (debug_isis_spfstats,
debug_isis_spfstats_cmd,
- "debug isis spf-statistics ",
+ "debug " PROTO_NAME " spf-statistics ",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS SPF Timing and Statistic Data\n")
{
isis->debugs |= DEBUG_SPF_STATS;
@@ -1024,10 +1040,10 @@ DEFUN (debug_isis_spfstats,
DEFUN (no_debug_isis_spfstats,
no_debug_isis_spfstats_cmd,
- "no debug isis spf-statistics",
+ "no debug " PROTO_NAME " spf-statistics",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS SPF Timing and Statistic Data\n")
{
isis->debugs &= ~DEBUG_SPF_STATS;
@@ -1038,9 +1054,9 @@ DEFUN (no_debug_isis_spfstats,
DEFUN (debug_isis_spftrigg,
debug_isis_spftrigg_cmd,
- "debug isis spf-triggers",
+ "debug " PROTO_NAME " spf-triggers",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS SPF triggering events\n")
{
isis->debugs |= DEBUG_SPF_TRIGGERS;
@@ -1051,10 +1067,10 @@ DEFUN (debug_isis_spftrigg,
DEFUN (no_debug_isis_spftrigg,
no_debug_isis_spftrigg_cmd,
- "no debug isis spf-triggers",
+ "no debug " PROTO_NAME " spf-triggers",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS SPF triggering events\n")
{
isis->debugs &= ~DEBUG_SPF_TRIGGERS;
@@ -1065,9 +1081,9 @@ DEFUN (no_debug_isis_spftrigg,
DEFUN (debug_isis_rtevents,
debug_isis_rtevents_cmd,
- "debug isis route-events",
+ "debug " PROTO_NAME " route-events",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Route related events\n")
{
isis->debugs |= DEBUG_RTE_EVENTS;
@@ -1078,10 +1094,10 @@ DEFUN (debug_isis_rtevents,
DEFUN (no_debug_isis_rtevents,
no_debug_isis_rtevents_cmd,
- "no debug isis route-events",
+ "no debug " PROTO_NAME " route-events",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Route related events\n")
{
isis->debugs &= ~DEBUG_RTE_EVENTS;
@@ -1092,9 +1108,9 @@ DEFUN (no_debug_isis_rtevents,
DEFUN (debug_isis_events,
debug_isis_events_cmd,
- "debug isis events",
+ "debug " PROTO_NAME " events",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Events\n")
{
isis->debugs |= DEBUG_EVENTS;
@@ -1105,10 +1121,10 @@ DEFUN (debug_isis_events,
DEFUN (no_debug_isis_events,
no_debug_isis_events_cmd,
- "no debug isis events",
+ "no debug " PROTO_NAME " events",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Events\n")
{
isis->debugs &= ~DEBUG_EVENTS;
@@ -1119,9 +1135,9 @@ DEFUN (no_debug_isis_events,
DEFUN (debug_isis_packet_dump,
debug_isis_packet_dump_cmd,
- "debug isis packet-dump",
+ "debug " PROTO_NAME " packet-dump",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS packet dump\n")
{
isis->debugs |= DEBUG_PACKET_DUMP;
@@ -1132,10 +1148,10 @@ DEFUN (debug_isis_packet_dump,
DEFUN (no_debug_isis_packet_dump,
no_debug_isis_packet_dump_cmd,
- "no debug isis packet-dump",
+ "no debug " PROTO_NAME " packet-dump",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS packet dump\n")
{
isis->debugs &= ~DEBUG_PACKET_DUMP;
@@ -1146,9 +1162,9 @@ DEFUN (no_debug_isis_packet_dump,
DEFUN (debug_isis_lsp_gen,
debug_isis_lsp_gen_cmd,
- "debug isis lsp-gen",
+ "debug " PROTO_NAME " lsp-gen",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS generation of own LSPs\n")
{
isis->debugs |= DEBUG_LSP_GEN;
@@ -1159,10 +1175,10 @@ DEFUN (debug_isis_lsp_gen,
DEFUN (no_debug_isis_lsp_gen,
no_debug_isis_lsp_gen_cmd,
- "no debug isis lsp-gen",
+ "no debug " PROTO_NAME " lsp-gen",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS generation of own LSPs\n")
{
isis->debugs &= ~DEBUG_LSP_GEN;
@@ -1173,9 +1189,9 @@ DEFUN (no_debug_isis_lsp_gen,
DEFUN (debug_isis_lsp_sched,
debug_isis_lsp_sched_cmd,
- "debug isis lsp-sched",
+ "debug " PROTO_NAME " lsp-sched",
DEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS scheduling of LSP generation\n")
{
isis->debugs |= DEBUG_LSP_SCHED;
@@ -1186,10 +1202,10 @@ DEFUN (debug_isis_lsp_sched,
DEFUN (no_debug_isis_lsp_sched,
no_debug_isis_lsp_sched_cmd,
- "no debug isis lsp-sched",
+ "no debug " PROTO_NAME " lsp-sched",
NO_STR
UNDEBUG_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS scheduling of LSP generation\n")
{
isis->debugs &= ~DEBUG_LSP_SCHED;
@@ -1200,9 +1216,9 @@ DEFUN (no_debug_isis_lsp_sched,
DEFUN (show_hostname,
show_hostname_cmd,
- "show isis hostname",
+ "show " PROTO_NAME " hostname",
SHOW_STR
- "IS-IS information\n"
+ PROTO_HELP
"IS-IS Dynamic hostname mapping\n")
{
dynhn_print_all(vty);
@@ -1212,10 +1228,10 @@ DEFUN (show_hostname,
DEFUN (show_isis_spf_ietf,
show_isis_spf_ietf_cmd,
- "show isis spf-delay-ietf",
+ "show " PROTO_NAME " spf-delay-ietf",
SHOW_STR
- "IS-IS information\n"
- "IS-IS SPF delay IETF information\n")
+ PROTO_HELP
+ "SPF delay IETF information\n")
{
if (!isis) {
vty_out(vty, "ISIS is not running\n");
@@ -1261,15 +1277,15 @@ DEFUN (show_isis_spf_ietf,
DEFUN (show_isis_summary,
show_isis_summary_cmd,
- "show isis summary",
- SHOW_STR "IS-IS information\n" "IS-IS summary\n")
+ "show " PROTO_NAME " summary",
+ SHOW_STR PROTO_HELP "summary\n")
{
struct listnode *node, *node2;
struct isis_area *area;
int level;
if (isis == NULL) {
- vty_out(vty, "ISIS is not running\n");
+ vty_out(vty, PROTO_NAME " is not running\n");
return CMD_SUCCESS;
}
@@ -1289,6 +1305,14 @@ DEFUN (show_isis_summary,
vty_out(vty, "Area %s:\n",
area->area_tag ? area->area_tag : "null");
+ if (fabricd) {
+ uint8_t tier = fabricd_tier(area);
+ if (tier == ISIS_TIER_UNDEFINED)
+ vty_out(vty, " Tier: undefined\n");
+ else
+ vty_out(vty, " Tier: %" PRIu8 "\n", tier);
+ }
+
if (listcount(area->area_addrs) > 0) {
struct area_addr *area_addr;
for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2,
@@ -1471,10 +1495,10 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
DEFUN (show_database,
show_database_cmd,
- "show isis database [detail] [WORD]",
+ "show " PROTO_NAME " database [detail] [WORD]",
SHOW_STR
- "IS-IS information\n"
- "IS-IS link state database\n"
+ PROTO_HELP
+ "Link state database\n"
"Detailed information\n"
"LSP ID\n")
{
@@ -1491,9 +1515,9 @@ DEFUN (show_database,
*/
DEFUN_NOSH (router_isis,
router_isis_cmd,
- "router isis WORD",
+ "router " PROTO_NAME " WORD",
ROUTER_STR
- "ISO IS-IS\n"
+ PROTO_HELP
"ISO Routing area tag\n")
{
int idx_word = 2;
@@ -1505,8 +1529,11 @@ DEFUN_NOSH (router_isis,
*/
DEFUN (no_router_isis,
no_router_isis_cmd,
- "no router isis WORD",
- "no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag\n")
+ "no router " PROTO_NAME " 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);
@@ -1869,7 +1896,7 @@ int isis_config_write(struct vty *vty)
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
/* ISIS - Area name */
- vty_out(vty, "router isis %s\n", area->area_tag);
+ vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);
write++;
/* ISIS - Net */
if (listcount(area->area_addrs) > 0) {
@@ -1893,16 +1920,18 @@ int isis_config_write(struct vty *vty)
write++;
}
/* ISIS - Metric-Style - when true displays wide */
- if (area->newmetric) {
- if (!area->oldmetric)
- vty_out(vty, " metric-style wide\n");
- else
- vty_out(vty,
- " metric-style transition\n");
- write++;
- } else {
- vty_out(vty, " metric-style narrow\n");
- write++;
+ if (!fabricd) {
+ if (area->newmetric) {
+ if (!area->oldmetric)
+ vty_out(vty, " metric-style wide\n");
+ else
+ vty_out(vty,
+ " metric-style transition\n");
+ write++;
+ } else {
+ vty_out(vty, " metric-style narrow\n");
+ write++;
+ }
}
/* ISIS - overload-bit */
if (area->overload_bit) {
@@ -1910,12 +1939,14 @@ int isis_config_write(struct vty *vty)
write++;
}
/* ISIS - Area is-type (level-1-2 is default) */
- if (area->is_type == IS_LEVEL_1) {
- vty_out(vty, " is-type level-1\n");
- write++;
- } else if (area->is_type == IS_LEVEL_2) {
- vty_out(vty, " is-type level-2-only\n");
- write++;
+ if (!fabricd) {
+ if (area->is_type == IS_LEVEL_1) {
+ vty_out(vty, " is-type level-1\n");
+ write++;
+ } else if (area->is_type == IS_LEVEL_2) {
+ vty_out(vty, " is-type level-2-only\n");
+ write++;
+ }
}
write += isis_redist_config_write(vty, area, AF_INET);
write += isis_redist_config_write(vty, area, AF_INET6);
@@ -1998,6 +2029,10 @@ int isis_config_write(struct vty *vty)
vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu);
write++;
}
+ if (area->purge_originator) {
+ vty_out(vty, " purge-originator\n");
+ write++;
+ }
/* Minimum SPF interval. */
if (area->min_spf_interval[0]
@@ -2116,6 +2151,7 @@ int isis_config_write(struct vty *vty)
}
write += area_write_mt_settings(area, vty);
+ write += fabricd_write_settings(area, vty);
}
isis_mpls_te_config_write_router(vty);
}
@@ -2123,12 +2159,12 @@ int isis_config_write(struct vty *vty)
return write;
}
-struct cmd_node isis_node = {ISIS_NODE, "%s(config-router)# ", 1};
+struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1};
void isis_init()
{
/* Install IS-IS top node */
- install_node(&isis_node, isis_config_write);
+ install_node(&router_node, isis_config_write);
install_element(VIEW_NODE, &show_isis_summary_cmd);
@@ -2212,16 +2248,16 @@ void isis_init()
install_element(CONFIG_NODE, &router_isis_cmd);
install_element(CONFIG_NODE, &no_router_isis_cmd);
- install_default(ISIS_NODE);
+ install_default(ROUTER_NODE);
- install_element(ISIS_NODE, &net_cmd);
- install_element(ISIS_NODE, &no_net_cmd);
+ install_element(ROUTER_NODE, &net_cmd);
+ install_element(ROUTER_NODE, &no_net_cmd);
- install_element(ISIS_NODE, &isis_topology_cmd);
- install_element(ISIS_NODE, &no_isis_topology_cmd);
+ install_element(ROUTER_NODE, &isis_topology_cmd);
+ install_element(ROUTER_NODE, &no_isis_topology_cmd);
- install_element(ISIS_NODE, &log_adj_changes_cmd);
- install_element(ISIS_NODE, &no_log_adj_changes_cmd);
+ install_element(ROUTER_NODE, &log_adj_changes_cmd);
+ install_element(ROUTER_NODE, &no_log_adj_changes_cmd);
spf_backoff_cmd_init();
}
diff --git a/isisd/isisd.h b/isisd/isisd.h
index ce602e440..864021428 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -33,12 +33,32 @@
#include "isis_memory.h"
#include "qobj.h"
+#ifdef FABRICD
+static const bool fabricd = true;
+#define PROTO_TYPE ZEBRA_ROUTE_OPENFABRIC
+#define PROTO_NAME "openfabric"
+#define PROTO_HELP "OpenFabric routing protocol\n"
+#define PROTO_REDIST_STR FRR_REDIST_STR_FABRICD
+#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_FABRICD
+#define ROUTER_NODE OPENFABRIC_NODE
+#else
+static const bool fabricd = false;
+#define PROTO_TYPE ZEBRA_ROUTE_ISIS
+#define PROTO_NAME "isis"
+#define PROTO_HELP "IS-IS routing protocol\n"
+#define PROTO_REDIST_STR FRR_REDIST_STR_ISISD
+#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_ISISD
+#define ROUTER_NODE ISIS_NODE
+#endif
+
extern struct zebra_privs_t isisd_privs;
/* uncomment if you are a developer in bug hunt */
/* #define EXTREME_DEBUG */
/* #define EXTREME_DICT_DEBUG */
+struct fabricd;
+
struct isis {
unsigned long process_id;
int sysid_set;
@@ -93,6 +113,8 @@ struct isis_area {
*/
int lsp_regenerate_pending[ISIS_LEVELS];
+ struct fabricd *fabricd;
+
/*
* Configurables
*/
@@ -126,6 +148,7 @@ struct isis_area {
/* multi topology settings */
struct list *mt_settings;
int ipv6_circuits;
+ bool purge_originator;
/* Counters */
uint32_t circuit_state_changes;
struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT]
@@ -168,7 +191,6 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth);
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth);
-void isis_vty_init(void);
/* Master of threads. */
extern struct thread_master *master;
@@ -188,6 +210,7 @@ extern struct thread_master *master;
#define DEBUG_PACKET_DUMP (1<<12)
#define DEBUG_LSP_GEN (1<<13)
#define DEBUG_LSP_SCHED (1<<14)
+#define DEBUG_FABRICD_FLOODING (1<<15)
#define lsp_debug(...) \
do { \
diff --git a/isisd/subdir.am b/isisd/subdir.am
index 7b8be4616..7571255e5 100644
--- a/isisd/subdir.am
+++ b/isisd/subdir.am
@@ -6,35 +6,23 @@ if ISISD
noinst_LIBRARIES += isisd/libisis.a
sbin_PROGRAMS += isisd/isisd
dist_examples_DATA += isisd/isisd.conf.sample
+vtysh_scan += \
+ $(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
endif
-isisd_libisis_a_SOURCES = \
- isisd/dict.c \
- isisd/isis_adjacency.c \
- isisd/isis_circuit.c \
- isisd/isis_csm.c \
- isisd/isis_dr.c \
- isisd/isis_dynhn.c \
- isisd/isis_errors.c \
- isisd/isis_events.c \
- isisd/isis_flags.c \
- isisd/isis_lsp.c \
- isisd/isis_lsp_hash.c \
- isisd/isis_memory.c \
- isisd/isis_misc.c \
- isisd/isis_mt.c \
- isisd/isis_pdu.c \
- isisd/isis_redist.c \
- isisd/isis_route.c \
- isisd/isis_routemap.c \
- isisd/isis_spf.c \
- isisd/isis_te.c \
- isisd/isis_tlvs.c \
- isisd/isis_vty.c \
- isisd/isis_zebra.c \
- isisd/isisd.c \
- isisd/iso_checksum.c \
- # end
+if FABRICD
+noinst_LIBRARIES += isisd/libfabric.a
+sbin_PROGRAMS += isisd/fabricd
+dist_examples_DATA += isisd/fabricd.conf.sample
+endif
noinst_HEADERS += \
isisd/dict.h \
@@ -49,7 +37,6 @@ noinst_HEADERS += \
isisd/isis_events.h \
isisd/isis_flags.h \
isisd/isis_lsp.h \
- isisd/isis_lsp_hash.h \
isisd/isis_memory.h \
isisd/isis_misc.h \
isisd/isis_mt.h \
@@ -59,17 +46,73 @@ noinst_HEADERS += \
isisd/isis_route.h \
isisd/isis_routemap.h \
isisd/isis_spf.h \
+ isisd/isis_spf_private.h \
isisd/isis_te.h \
isisd/isis_tlvs.h \
+ isisd/isis_tx_queue.h \
+ isisd/isis_vty_common.h \
isisd/isis_zebra.h \
isisd/isisd.h \
isisd/iso_checksum.h \
+ isisd/fabricd.h \
# end
-isisd_isisd_LDADD = isisd/libisis.a lib/libfrr.la @LIBCAP@
-isisd_isisd_SOURCES = \
+LIBISIS_SOURCES = \
+ isisd/dict.c \
+ isisd/isis_adjacency.c \
+ isisd/isis_circuit.c \
+ isisd/isis_csm.c \
+ isisd/isis_dr.c \
+ isisd/isis_dynhn.c \
+ isisd/isis_errors.c \
+ isisd/isis_events.c \
+ isisd/isis_flags.c \
+ isisd/isis_lsp.c \
+ isisd/isis_memory.c \
+ isisd/isis_misc.c \
+ isisd/isis_mt.c \
+ isisd/isis_pdu.c \
+ isisd/isis_redist.c \
+ isisd/isis_route.c \
+ isisd/isis_routemap.c \
+ isisd/isis_spf.c \
+ isisd/isis_te.c \
+ isisd/isis_tlvs.c \
+ isisd/isis_tx_queue.c \
+ isisd/isis_vty_common.c \
+ isisd/isis_zebra.c \
+ isisd/isisd.c \
+ isisd/iso_checksum.c \
+ isisd/fabricd.c \
+ # end
+
+ISIS_SOURCES = \
isisd/isis_bpf.c \
isisd/isis_dlpi.c \
isisd/isis_main.c \
isisd/isis_pfpacket.c \
# end
+
+ISIS_LDADD_COMMON = lib/libfrr.la @LIBCAP@
+
+# Building isisd
+
+isisd_libisis_a_SOURCES = \
+ $(LIBISIS_SOURCES) \
+ isisd/isis_vty_isisd.c \
+ #end
+isisd_isisd_LDADD = isisd/libisis.a $(ISIS_LDADD_COMMON)
+isisd_isisd_SOURCES = $(ISIS_SOURCES)
+
+# Building fabricd
+
+FABRICD_CPPFLAGS = -DFABRICD=1 $(AM_CPPFLAGS)
+
+isisd_libfabric_a_SOURCES = \
+ $(LIBISIS_SOURCES) \
+ isisd/isis_vty_fabricd.c \
+ #end
+isisd_libfabric_a_CPPFLAGS = $(FABRICD_CPPFLAGS)
+isisd_fabricd_LDADD = isisd/libfabric.a $(ISIS_LDADD_COMMON)
+isisd_fabricd_SOURCES = $(ISIS_SOURCES)
+isisd_fabricd_CPPFLAGS = $(FABRICD_CPPFLAGS)
diff --git a/ldpd/.gitignore b/ldpd/.gitignore
index a2f4b5169..ec8a5c408 100644
--- a/ldpd/.gitignore
+++ b/ldpd/.gitignore
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
ldpd
ldpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 03b62b482..810439888 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -1620,10 +1620,8 @@ lde_address_list_free(struct lde_nbr *ln)
{
struct lde_addr *lde_addr;
- while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) {
- TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
+ while ((lde_addr = TAILQ_POP_FIRST(&ln->addr_list, entry)) != NULL)
free(lde_addr);
- }
}
static void zclient_sync_init(unsigned short instance)
diff --git a/ldpd/pfkey.c b/ldpd/pfkey.c
index 906737217..a719d0cbb 100644
--- a/ldpd/pfkey.c
+++ b/ldpd/pfkey.c
@@ -17,6 +17,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef __OpenBSD__
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/ldpd/subdir.am b/ldpd/subdir.am
index 2d87be0cd..24e738d62 100644
--- a/ldpd/subdir.am
+++ b/ldpd/subdir.am
@@ -6,6 +6,8 @@ if LDPD
noinst_LIBRARIES += ldpd/libldp.a
sbin_PROGRAMS += ldpd/ldpd
dist_examples_DATA += ldpd/ldpd.conf.sample
+vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c
+man8 += $(MANBUILD)/ldpd.8
endif
ldpd_libldp_a_SOURCES = \
diff --git a/lib/.gitignore b/lib/.gitignore
index 072146dbd..6176b30f8 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -1,26 +1,13 @@
-!Makefile
-Makefile.in
-*.o
-*.lo
-*.la
-version.c
-version.h
-gitversion.h
-gitversion.h.tmp
-.deps
-.nfs*
-.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-route_types.h
-memtypes.h
-command_lex.c
-command_lex.h
-command_parse.c
-command_parse.h
-refix
-grammar_sandbox
-clippy
-defun_lex.c
+/version.c
+/version.h
+/gitversion.h
+/gitversion.h.tmp
+/route_types.h
+/memtypes.h
+/command_lex.c
+/command_lex.h
+/command_parse.c
+/command_parse.h
+/grammar_sandbox
+/clippy
+/defun_lex.c
diff --git a/lib/command.c b/lib/command.c
index 1df644210..26afc762f 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -146,6 +146,7 @@ const char *node_names[] = {
*/
"bfd", /* BFD_NODE */
"bfd peer", /* BFD_PEER_NODE */
+ "openfabric", // OPENFABRIC_NODE
};
/* clang-format on */
@@ -1197,6 +1198,7 @@ static int handle_pipe_action(struct vty *vty, const char *cmd_in,
/* retrieve action */
token = strsep(&working, " ");
+ assert(token);
/* match result to known actions */
if (strmatch(token, "include")) {
@@ -1435,6 +1437,7 @@ void cmd_exit(struct vty *vty)
case LDP_NODE:
case LDP_L2VPN_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
@@ -1550,6 +1553,7 @@ DEFUN (config_end,
case LDP_L2VPN_NODE:
case LDP_PSEUDOWIRE_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case KEYCHAIN_KEY_NODE:
case VTY_NODE:
diff --git a/lib/command.h b/lib/command.h
index 75b69507e..8e51641b8 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -141,6 +141,7 @@ enum node_type {
BGP_FLOWSPECV6_NODE, /* BGP IPv6 FLOWSPEC Address-Family */
BFD_NODE, /* BFD protocol mode. */
BFD_PEER_NODE, /* BFD peer configuration mode. */
+ OPENFABRIC_NODE, /* OpenFabric router configuration node */
NODE_TYPE_MAX, /* maximum */
};
@@ -364,7 +365,6 @@ struct cmd_node {
#define PREFIX_LIST_STR "Build a prefix list\n"
#define OSPF6_DUMP_TYPE_LIST \
"<neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr>"
-#define ISIS_STR "IS-IS information\n"
#define AREA_TAG_STR "[area tag]\n"
#define COMMUNITY_AANN_STR "Community number where AA and NN are (0-65535)\n"
#define COMMUNITY_VAL_STR "Community number in AA:NN format (where AA and NN are (0-65535)) or local-AS|no-advertise|no-export|internet or additive\n"
diff --git a/lib/command_lex.l b/lib/command_lex.l
index 0d6e6ee7e..3b18b58a2 100644
--- a/lib/command_lex.l
+++ b/lib/command_lex.l
@@ -22,6 +22,11 @@
* 02111-1307, USA.
*/
+%top{
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+}
%{
/* ignore flex generated code in static analyzer */
#ifndef __clang_analyzer__
diff --git a/lib/csv.c b/lib/csv.c
index ce84783aa..582106ebd 100644
--- a/lib/csv.c
+++ b/lib/csv.c
@@ -17,6 +17,11 @@
* 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
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -563,6 +568,8 @@ void csv_decode(csv_t *csv, char *inbuf)
csv_record_t *rec;
buf = (inbuf) ? inbuf : csv->buf;
+ assert(buf);
+
pos = strpbrk(buf, "\n");
while (pos != NULL) {
rec = calloc(1, sizeof(csv_record_t));
diff --git a/lib/defun_lex.l b/lib/defun_lex.l
index d901c26a2..6c0805a4f 100644
--- a/lib/defun_lex.l
+++ b/lib/defun_lex.l
@@ -1,4 +1,3 @@
-%{
/*
* clippy (CLI preparator in python) C pseudo-lexer
* Copyright (C) 2016-2017 David Lamparter for NetDEF, Inc.
@@ -34,6 +33,12 @@
* code documentation in it.
*/
+%top{
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+}
+%{
/* ignore harmless bugs in old versions of flex */
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wunused-value"
diff --git a/lib/ferr.c b/lib/ferr.c
index 35d0fe4ff..afef196ce 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -14,6 +14,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
@@ -148,7 +152,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json)
snprintf(pbuf, sizeof(pbuf), "\nError %"PRIu32" - %s",
ref->code, ref->title);
memset(ubuf, '=', strlen(pbuf));
- ubuf[strlen(pbuf) - 1] = '\0';
+ ubuf[strlen(pbuf)] = '\0';
vty_out(vty, "%s\n%s\n", pbuf, ubuf);
vty_out(vty, "Description:\n%s\n\n", ref->description);
diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c
index c0aae5e52..d48b23f38 100644
--- a/lib/frr_pthread.c
+++ b/lib/frr_pthread.c
@@ -19,6 +19,9 @@
#include <zebra.h>
#include <pthread.h>
+#ifdef HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
#include <sched.h>
#include "frr_pthread.h"
@@ -163,10 +166,14 @@ int frr_pthread_set_name(struct frr_pthread *fpt, const char *name,
pthread_mutex_lock(&fpt->mtx);
snprintf(fpt->os_name, OS_THREAD_NAMELEN, "%s", os_name);
pthread_mutex_unlock(&fpt->mtx);
-#ifdef GNU_LINUX
+#ifdef HAVE_PTHREAD_SETNAME_NP
+# ifdef GNU_LINUX
ret = pthread_setname_np(fpt->thread, fpt->os_name);
-#elif defined(OPEN_BSD)
- ret = pthread_set_name_np(fpt->thread, fpt->os_name);
+# else /* NetBSD */
+ ret = pthread_setname_np(fpt->thread, fpt->os_name, NULL);
+# endif
+#elif defined(HAVE_PTHREAD_SET_NAME_NP)
+ pthread_set_name_np(fpt->thread, fpt->os_name);
#endif
}
diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h
index cc4fc7433..732e2925f 100644
--- a/lib/frr_pthread.h
+++ b/lib/frr_pthread.h
@@ -234,4 +234,8 @@ void frr_pthread_yield(void);
*/
uint32_t frr_pthread_get_id(void);
+#ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK
+#define pthread_condattr_setclock(A, B)
+#endif
+
#endif /* _FRR_PTHREAD_H */
diff --git a/lib/frrstr.c b/lib/frrstr.c
index 715e67b86..85d968182 100644
--- a/lib/frrstr.c
+++ b/lib/frrstr.c
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
index 51e7a3987..ef03e8521 100644
--- a/lib/grammar_sandbox.c
+++ b/lib/grammar_sandbox.c
@@ -23,6 +23,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "command.h"
#include "memory_vty.h"
#include "graph.h"
diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c
index 264c7c48f..c9c942f9b 100644
--- a/lib/grammar_sandbox_main.c
+++ b/lib/grammar_sandbox_main.c
@@ -23,6 +23,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "command.h"
#include "memory_vty.h"
diff --git a/lib/hook.c b/lib/hook.c
index 935064f4d..4fe305f28 100644
--- a/lib/hook.c
+++ b/lib/hook.c
@@ -20,6 +20,10 @@
* DEALINGS IN THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "memory.h"
#include "hook.h"
diff --git a/lib/if.c b/lib/if.c
index 2bf0c6e6b..2f2073c0a 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -371,37 +371,47 @@ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id)
one. */
struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty)
{
- struct interface *ifp;
+ struct interface *ifp = NULL;
- ifp = if_lookup_by_name(name, vrf_id);
- if (ifp)
- return ifp;
- /* Not Found on same VRF. If the interface command
- * was entered in vty without a VRF (passed as VRF_DEFAULT),
- * accept the ifp we found. If a vrf was entered and there is
- * a mismatch, reject it if from vty.
- */
- ifp = if_lookup_by_name_all_vrf(name);
- if (!ifp)
+ if (vrf_is_mapped_on_netns(vrf_lookup_by_id(vrf_id))) {
+ ifp = if_lookup_by_name(name, vrf_id);
+ if (ifp)
+ return ifp;
+ if (vty) {
+ /* If the interface command was entered in vty without a
+ * VRF (passed as VRF_DEFAULT), search an interface with
+ * this name in all VRs
+ */
+ if (vrf_id == VRF_DEFAULT)
+ return if_lookup_by_name_all_vrf(name);
+ return NULL;
+ }
return if_create(name, vrf_id);
- if (vty) {
- if (vrf_id == VRF_DEFAULT)
+ }
+ /* vrf is based on vrf-lite */
+ ifp = if_lookup_by_name_all_vrf(name);
+ if (ifp) {
+ if (ifp->vrf_id == vrf_id)
return ifp;
- return NULL;
+ /* Found a match on a different VRF. If the interface command
+ * was entered in vty without a VRF (passed as VRF_DEFAULT),
+ * accept the ifp we found. If a vrf was entered and there is a
+ * mismatch, reject it if from vty. If it came from the kernel
+ * or by way of zclient, believe it and update the ifp
+ * accordingly.
+ */
+ if (vty) {
+ if (vrf_id == VRF_DEFAULT)
+ return ifp;
+ return NULL;
+ }
+ /* If it came from the kernel or by way of zclient, believe it
+ * and update the ifp accordingly.
+ */
+ if_update_to_new_vrf(ifp, vrf_id);
+ return ifp;
}
- /* if vrf backend uses NETNS, then
- * this should not be considered as an update
- * then create the new interface
- */
- if (ifp->vrf_id != vrf_id && vrf_is_mapped_on_netns(
- vrf_lookup_by_id(vrf_id)))
- return if_create(name, vrf_id);
- /* If it came from the kernel
- * or by way of zclient, believe it and update
- * the ifp accordingly.
- */
- if_update_to_new_vrf(ifp, vrf_id);
- return ifp;
+ return if_create(name, vrf_id);
}
void if_set_index(struct interface *ifp, ifindex_t ifindex)
@@ -619,7 +629,7 @@ DEFUN (no_interface_desc,
* if not:
* - no idea, just get the name in its entirety.
*/
-static struct interface *if_sunwzebra_get(char *name, vrf_id_t vrf_id)
+static struct interface *if_sunwzebra_get(const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
char *cp;
diff --git a/lib/imsg-buffer.c b/lib/imsg-buffer.c
index b83f1f76f..c2f4052b8 100644
--- a/lib/imsg-buffer.c
+++ b/lib/imsg-buffer.c
@@ -21,9 +21,9 @@
#include "queue.h"
#include "imsg.h"
-int ibuf_realloc(struct ibuf *, size_t);
-void ibuf_enqueue(struct msgbuf *, struct ibuf *);
-void ibuf_dequeue(struct msgbuf *, struct ibuf *);
+static int ibuf_realloc(struct ibuf *, size_t);
+static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
+static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
struct ibuf *ibuf_open(size_t len)
{
@@ -57,7 +57,7 @@ struct ibuf *ibuf_dynamic(size_t len, size_t max)
return (buf);
}
-int ibuf_realloc(struct ibuf *buf, size_t len)
+static int ibuf_realloc(struct ibuf *buf, size_t len)
{
uint8_t *b;
@@ -183,6 +183,8 @@ void msgbuf_drain(struct msgbuf *msgbuf, size_t n)
next = TAILQ_NEXT(buf, entry);
if (buf->rpos + n >= buf->wpos) {
n -= buf->wpos - buf->rpos;
+
+ TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
ibuf_dequeue(msgbuf, buf);
} else {
buf->rpos += n;
@@ -195,7 +197,7 @@ void msgbuf_clear(struct msgbuf *msgbuf)
{
struct ibuf *buf;
- while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
+ while ((buf = TAILQ_POP_FIRST(&msgbuf->bufs, entry)) != NULL)
ibuf_dequeue(msgbuf, buf);
}
@@ -266,16 +268,15 @@ again:
return (1);
}
-void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
+static void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
{
TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
msgbuf->queued++;
}
-void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
+static void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
{
- TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
-
+ /* TAILQ_REMOVE done by caller */
if (buf->fd != -1)
close(buf->fd);
diff --git a/lib/imsg.c b/lib/imsg.c
index 542414072..935d13772 100644
--- a/lib/imsg.c
+++ b/lib/imsg.c
@@ -299,11 +299,10 @@ int imsg_get_fd(struct imsgbuf *ibuf)
int fd;
struct imsg_fd *ifd;
- if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
+ if ((ifd = TAILQ_POP_FIRST(&ibuf->fds, entry)) == NULL)
return (-1);
fd = ifd->fd;
- TAILQ_REMOVE(&ibuf->fds, ifd, entry);
free(ifd);
return (fd);
diff --git a/lib/lib_errors.c b/lib/lib_errors.c
index b27f9391a..a608aa9e6 100644
--- a/lib/lib_errors.c
+++ b/lib/lib_errors.c
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "lib_errors.h"
/* clang-format off */
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 18e263656..ecdc27757 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -262,6 +262,32 @@ bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len,
static struct frr_daemon_info *di = NULL;
+static void frr_guard_daemon(void)
+{
+ int fd;
+ struct flock lock;
+ const char *path = di->pid_file;
+
+ fd = open(path, O_RDWR);
+ if (fd != -1) {
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ if (fcntl(fd, F_GETLK, &lock) < 0) {
+ flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ "Could not do F_GETLK pid_file %s (%s), exiting",
+ path, safe_strerror(errno));
+ exit(1);
+ } else if (lock.l_type == F_WRLCK) {
+ flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ "Process %d has a write lock on file %s already! Error: (%s)",
+ lock.l_pid, path, safe_strerror(errno));
+ exit(1);
+ }
+ close(fd);
+ }
+}
+
void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
{
di = daemon;
@@ -591,6 +617,9 @@ struct thread_master *frr_init(void)
zprivs_init(di->privs);
+ /* Guard to prevent a second instance of this daemon */
+ frr_guard_daemon();
+
master = thread_master_create(NULL);
signal_init(master, di->n_signals, di->signals);
diff --git a/lib/log.c b/lib/log.c
index 010b98478..521783e4b 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -1074,6 +1074,8 @@ int proto_redistnum(int afi, const char *s)
return ZEBRA_ROUTE_BABEL;
else if (strmatch(s, "sharp"))
return ZEBRA_ROUTE_SHARP;
+ else if (strmatch(s, "openfabric"))
+ return ZEBRA_ROUTE_OPENFABRIC;
}
if (afi == AFI_IP6) {
if (strmatch(s, "kernel"))
@@ -1102,6 +1104,8 @@ int proto_redistnum(int afi, const char *s)
return ZEBRA_ROUTE_BABEL;
else if (strmatch(s, "sharp"))
return ZEBRA_ROUTE_SHARP;
+ else if (strmatch(s, "openfabric"))
+ return ZEBRA_ROUTE_OPENFABRIC;
}
return -1;
}
diff --git a/lib/memory.c b/lib/memory.c
index 695bbfe11..fee23a75a 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -20,6 +20,9 @@
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
+#ifdef HAVE_MALLOC_NP_H
+#include <malloc_np.h>
+#endif
#ifdef HAVE_MALLOC_MALLOC_H
#include <malloc/malloc.h>
#endif
diff --git a/lib/memory_vty.c b/lib/memory_vty.c
index 73a18529a..5fd9c3b90 100644
--- a/lib/memory_vty.c
+++ b/lib/memory_vty.c
@@ -28,7 +28,9 @@
#include <malloc/malloc.h>
#endif
#include <dlfcn.h>
+#ifdef HAVE_LINK_H
#include <link.h>
+#endif
#include "log.h"
#include "memory.h"
diff --git a/lib/openbsd-tree.c b/lib/openbsd-tree.c
index 35bfce3a8..e8d13339b 100644
--- a/lib/openbsd-tree.c
+++ b/lib/openbsd-tree.c
@@ -41,6 +41,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <lib/openbsd-tree.h>
diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c
index 69fd61e2a..7f868beda 100644
--- a/lib/ptm_lib.c
+++ b/lib/ptm_lib.c
@@ -17,6 +17,11 @@
* 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
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
diff --git a/lib/queue.h b/lib/queue.h
index 04fbeee70..11e28b4c9 100644
--- a/lib/queue.h
+++ b/lib/queue.h
@@ -72,4 +72,17 @@
#include "freebsd-queue.h"
#endif /* defined(__OpenBSD__) && !defined(STAILQ_HEAD) */
+#ifndef TAILQ_POP_FIRST
+#define TAILQ_POP_FIRST(head, field) \
+ ({ typeof((head)->tqh_first) _elm = TAILQ_FIRST(head); \
+ if (_elm) { \
+ if ((TAILQ_NEXT((_elm), field)) != NULL) \
+ TAILQ_NEXT((_elm), field)->field.tqe_prev = \
+ &TAILQ_FIRST(head); \
+ else \
+ (head)->tqh_last = &TAILQ_FIRST(head); \
+ TAILQ_FIRST(head) = TAILQ_NEXT((_elm), field); \
+ }; _elm; })
+#endif
+
#endif /* _FRR_QUEUE_H */
diff --git a/lib/route_types.txt b/lib/route_types.txt
index 72f59a1b7..c5eff44ca 100644
--- a/lib/route_types.txt
+++ b/lib/route_types.txt
@@ -82,6 +82,7 @@ ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, 1, "Babel"
ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, 1, "SHARP"
ZEBRA_ROUTE_PBR, pbr, pbrd, 'F', 1, 1, 0, "PBR"
ZEBRA_ROUTE_BFD, bfd, bfdd, '-', 0, 0, 0, "BFD"
+ZEBRA_ROUTE_OPENFABRIC, openfabric, fabricd, 'f', 1, 1, 1, "OpenFabric"
ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, 0, "-"
@@ -109,3 +110,4 @@ ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)"
ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)"
ZEBRA_ROUTE_PBR, "Policy Based Routing (PBR)"
ZEBRA_ROUTE_BFD, "Bidirectional Fowarding Detection (BFD)"
+ZEBRA_ROUTE_OPENFABRIC, "OpenFabric Routing Protocol"
diff --git a/lib/skiplist.c b/lib/skiplist.c
index a36bf4713..585cf859e 100644
--- a/lib/skiplist.c
+++ b/lib/skiplist.c
@@ -202,6 +202,7 @@ int skiplist_insert(register struct skiplist *l, register void *key,
}
k = randomLevel();
+ assert(k >= 0);
if (k > l->level) {
k = ++l->level;
update[k] = l->header;
diff --git a/lib/stream.c b/lib/stream.c
index 2a34ec233..8424a941d 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -272,7 +272,7 @@ void stream_forward_endp(struct stream *s, size_t size)
}
/* Copy from stream to destination. */
-inline bool stream_get2(void *dst, struct stream *s, size_t size)
+bool stream_get2(void *dst, struct stream *s, size_t size)
{
STREAM_VERIFY_SANE(s);
@@ -301,7 +301,7 @@ void stream_get(void *dst, struct stream *s, size_t size)
}
/* Get next character from the stream. */
-inline bool stream_getc2(struct stream *s, uint8_t *byte)
+bool stream_getc2(struct stream *s, uint8_t *byte)
{
STREAM_VERIFY_SANE(s);
@@ -346,7 +346,7 @@ uint8_t stream_getc_from(struct stream *s, size_t from)
return c;
}
-inline bool stream_getw2(struct stream *s, uint16_t *word)
+bool stream_getw2(struct stream *s, uint16_t *word)
{
STREAM_VERIFY_SANE(s);
@@ -467,7 +467,7 @@ void stream_get_from(void *dst, struct stream *s, size_t from, size_t size)
memcpy(dst, s->data + from, size);
}
-inline bool stream_getl2(struct stream *s, uint32_t *l)
+bool stream_getl2(struct stream *s, uint32_t *l)
{
STREAM_VERIFY_SANE(s);
diff --git a/lib/strlcat.c b/lib/strlcat.c
index be211f82a..39773d9ac 100644
--- a/lib/strlcat.c
+++ b/lib/strlcat.c
@@ -20,11 +20,13 @@
/* adapted for Quagga from glibc patch submission originally from
* Florian Weimer <fweimer@redhat.com>, 2016-05-18 */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdint.h>
#include <string.h>
-#include "config.h"
-
#ifndef HAVE_STRLCAT
#undef strlcat
diff --git a/lib/strlcpy.c b/lib/strlcpy.c
index b0c33ca7f..71ee9f1a5 100644
--- a/lib/strlcpy.c
+++ b/lib/strlcpy.c
@@ -20,9 +20,11 @@
/* adapted for Quagga from glibc patch submission originally from
* Florian Weimer <fweimer@redhat.com>, 2016-05-18 */
-#include <string.h>
-
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
+#include <string.h>
#ifndef HAVE_STRLCPY
#undef strlcpy
diff --git a/lib/subdir.am b/lib/subdir.am
index ef6c8f8e5..499bb9492 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -84,6 +84,22 @@ lib_libfrr_la_SOURCES = \
lib/logicalrouter.c \
# end
+vtysh_scan += \
+ $(top_srcdir)/lib/distribute.c \
+ $(top_srcdir)/lib/filter.c \
+ $(top_srcdir)/lib/if.c \
+ $(top_srcdir)/lib/if_rmap.c \
+ $(top_srcdir)/lib/keychain.c \
+ $(top_srcdir)/lib/logicalrouter.c \
+ $(top_srcdir)/lib/nexthop_group.c \
+ $(top_srcdir)/lib/plist.c \
+ $(top_srcdir)/lib/routemap.c \
+ $(top_srcdir)/lib/vrf.c \
+ $(top_srcdir)/lib/vty.c \
+ # end
+# can be loaded as DSO - always include for vtysh
+vtysh_scan += $(top_srcdir)/lib/agentx.c
+
lib/plist_clippy.c: $(CLIPPY_DEPS)
lib/plist.lo: lib/plist_clippy.c
lib/nexthop_group_clippy.c: $(CLIPPY_DEPS)
@@ -152,6 +168,7 @@ pkginclude_HEADERS += \
lib/sha256.h \
lib/sigevent.h \
lib/skiplist.h \
+ lib/smux.h \
lib/sockopt.h \
lib/sockunion.h \
lib/spf_backoff.h \
@@ -237,9 +254,10 @@ lib_grammar_sandbox_SOURCES = \
lib_grammar_sandbox_LDADD = \
lib/libfrr.la
-lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY @SAN_CLIPPY_FLAGS@
-lib_clippy_CFLAGS = $(PYTHON_CFLAGS) @SAN_CLIPPY_FLAGS@
+lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY
+lib_clippy_CFLAGS = $(PYTHON_CFLAGS)
lib_clippy_LDADD = $(PYTHON_LIBS)
+lib_clippy_LDFLAGS = -export-dynamic
lib_clippy_SOURCES = \
lib/clippy.c \
lib/command_graph.c \
@@ -252,6 +270,26 @@ lib_clippy_SOURCES = \
lib/vector.c \
# end
+# (global) clippy rules for all directories
+
+AM_V_CLIPPY = $(am__v_CLIPPY_$(V))
+am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY))
+am__v_CLIPPY_0 = @echo " CLIPPY " $@;
+am__v_CLIPPY_1 =
+
+CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py
+
+SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h
+.c_clippy.c:
+ @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || \
+ $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; }
+ $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $<
+
+## automake's "ylwrap" is a great piece of GNU software... not.
+.l.c:
+ $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $<
+.y.c:
+ $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $<
#
# generated sources & extra foo
diff --git a/lib/vrf.c b/lib/vrf.c
index 1e538a8c5..4b7e84275 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -493,9 +493,15 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
"vrf_init: failed to create the default VRF!");
exit(1);
}
- if (vrf_is_backend_netns())
+ if (vrf_is_backend_netns()) {
+ struct ns *ns;
+
strlcpy(default_vrf->data.l.netns_name,
VRF_DEFAULT_NAME, NS_NAMSIZ);
+ ns = ns_lookup(ns_get_default_id());
+ ns->vrf_ctxt = default_vrf;
+ default_vrf->ns_ctxt = ns;
+ }
/* Enable the default VRF. */
if (!vrf_enable(default_vrf)) {
@@ -712,8 +718,6 @@ int vrf_is_mapped_on_netns(struct vrf *vrf)
{
if (!vrf || vrf->data.l.netns_name[0] == '\0')
return 0;
- if (vrf->vrf_id == VRF_DEFAULT)
- return 0;
return 1;
}
diff --git a/lib/vty.c b/lib/vty.c
index afcb4edaa..921f92df1 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -813,6 +813,7 @@ static void vty_end_config(struct vty *vty)
case LDP_L2VPN_NODE:
case LDP_PSEUDOWIRE_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case KEYCHAIN_KEY_NODE:
case VTY_NODE:
@@ -1212,6 +1213,7 @@ static void vty_stop_input(struct vty *vty)
case LDP_L2VPN_NODE:
case LDP_PSEUDOWIRE_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case KEYCHAIN_KEY_NODE:
case VTY_NODE:
diff --git a/lib/zebra.h b/lib/zebra.h
index b12f6616b..d80aa0693 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -28,7 +28,6 @@
#include "compiler.h"
#ifdef SUNOS_5
-#define _XPG4_2
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
@@ -414,6 +413,7 @@ extern const char *zserv_command_string(unsigned int command);
#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 */
diff --git a/m4/.gitignore b/m4/.gitignore
index 798188b0b..357e65588 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -1,8 +1,8 @@
-Makefile
-Makefile.in
-.arch-inventory
-.arch-ids
-*~
-*.loT
+*.m4
+
+!ax_compare_version.m4
+!ax_prog_perl_modules.m4
!ax_pthread.m4
!ax_sys_weak_alias.m4
+!ax_sys_weak_alias.m4
+!pkg.m4
diff --git a/m4/pkg.m4 b/m4/pkg.m4
index c5b26b52e..a8dcd17c4 100644
--- a/m4/pkg.m4
+++ b/m4/pkg.m4
@@ -109,7 +109,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
-AC_MSG_CHECKING([for $1])
+AC_MSG_CHECKING([for $1 ($2)])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
diff --git a/nhrpd/.gitignore b/nhrpd/.gitignore
index 3f4738127..3d4d56d58 100644
--- a/nhrpd/.gitignore
+++ b/nhrpd/.gitignore
@@ -1,2 +1 @@
-!Makefile
nhrpd
diff --git a/nhrpd/linux.c b/nhrpd/linux.c
index 46a327b59..85e941e7b 100644
--- a/nhrpd/linux.c
+++ b/nhrpd/linux.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c
index af78b3d9e..4c6827cb3 100644
--- a/nhrpd/netlink_arp.c
+++ b/nhrpd/netlink_arp.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <fcntl.h>
#include <net/if.h>
#include <netinet/if_ether.h>
diff --git a/nhrpd/netlink_gre.c b/nhrpd/netlink_gre.c
index 75ecaa70c..3fdfa9c31 100644
--- a/nhrpd/netlink_gre.c
+++ b/nhrpd/netlink_gre.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
diff --git a/nhrpd/nhrp_event.c b/nhrpd/nhrp_event.c
index 7ca973176..9301c2d51 100644
--- a/nhrpd/nhrp_event.c
+++ b/nhrpd/nhrp_event.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c
index 3a4271274..ccca100db 100644
--- a/nhrpd/nhrp_interface.c
+++ b/nhrpd/nhrp_interface.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <net/if_arp.h>
#include "zebra.h"
#include "linklist.h"
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index 737e70103..f99e56639 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include "zebra.h"
diff --git a/nhrpd/nhrp_packet.c b/nhrpd/nhrp_packet.c
index e62ee1ef7..a983aa71b 100644
--- a/nhrpd/nhrp_packet.c
+++ b/nhrpd/nhrp_packet.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <netinet/if_ether.h>
#include "nhrpd.h"
#include "zbuf.h"
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 44271d68a..e051830f8 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <netinet/if_ether.h>
#include "zebra.h"
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index 044529a5c..e7b187f3b 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "nhrpd.h"
#include "table.h"
#include "memory.h"
diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c
index 9ed251706..84053b4b5 100644
--- a/nhrpd/nhrp_shortcut.c
+++ b/nhrpd/nhrp_shortcut.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "nhrpd.h"
#include "table.h"
#include "memory.h"
diff --git a/nhrpd/resolver.c b/nhrpd/resolver.c
index dfa5dc3df..f017d974d 100644
--- a/nhrpd/resolver.c
+++ b/nhrpd/resolver.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <ares.h>
#include <ares_version.h>
diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am
index d66e96822..758c22e2b 100644
--- a/nhrpd/subdir.am
+++ b/nhrpd/subdir.am
@@ -4,6 +4,8 @@
if NHRPD
sbin_PROGRAMS += nhrpd/nhrpd
+vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c
+man8 += $(MANBUILD)/nhrpd.8
endif
nhrpd_nhrpd_LDADD = lib/libfrr.la @LIBCAP@ @CARES_LIBS@
diff --git a/nhrpd/vici.c b/nhrpd/vici.c
index 7cd703414..c1a99685f 100644
--- a/nhrpd/vici.c
+++ b/nhrpd/vici.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
diff --git a/nhrpd/zbuf.c b/nhrpd/zbuf.c
index 6e7cad8ae..c66229508 100644
--- a/nhrpd/zbuf.c
+++ b/nhrpd/zbuf.c
@@ -7,7 +7,10 @@
* (at your option) any later version.
*/
-#define _GNU_SOURCE
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <string.h>
#include <unistd.h>
#include <errno.h>
diff --git a/nhrpd/znl.c b/nhrpd/znl.c
index 01b2f433a..6030987a1 100644
--- a/nhrpd/znl.c
+++ b/nhrpd/znl.c
@@ -7,6 +7,10 @@
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <fcntl.h>
#include <errno.h>
#include <string.h>
diff --git a/ospf6d/.gitignore b/ospf6d/.gitignore
index 744af2d5c..e398b1ca5 100644
--- a/ospf6d/.gitignore
+++ b/ospf6d/.gitignore
@@ -1,18 +1,2 @@
-!Makefile
-Makefile.in
-*.o
-*.patch
ospf6d
ospf6d.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 5af88defe..dc7a3f6d4 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -732,7 +732,8 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
? 1
: 2,
buf, listcount(route->paths),
- listcount(route->nh_list));
+ route->nh_list ?
+ listcount(route->nh_list) : 0);
}
if (listcount(route->paths)) {
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index 8b720b6d8..40b3522c3 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -130,7 +130,7 @@ uint8_t ospf6_lstype_debug(uint16_t type)
{
const struct ospf6_lsa_handler *handler;
handler = ospf6_get_lsa_handler(type);
- return handler->debug;
+ return handler->lh_debug;
}
/* RFC2328: Section 13.2 */
@@ -844,13 +844,13 @@ DEFUN (debug_ospf6_lsa_type,
if (argc == 5) {
if (strmatch(argv[idx_type]->text, "originate"))
- SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
+ SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_ORIGINATE);
else if (strmatch(argv[idx_type]->text, "examine"))
- SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
+ SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN);
else if (strmatch(argv[idx_type]->text, "flooding"))
- SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD);
+ SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD);
} else
- SET_FLAG(handler->debug, OSPF6_LSA_DEBUG);
+ SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG);
return CMD_SUCCESS;
}
@@ -896,13 +896,14 @@ DEFUN (no_debug_ospf6_lsa_type,
if (argc == 6) {
if (strmatch(argv[idx_type]->text, "originate"))
- UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
+ UNSET_FLAG(handler->lh_debug,
+ OSPF6_LSA_DEBUG_ORIGINATE);
if (strmatch(argv[idx_type]->text, "examine"))
- UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
+ UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN);
if (strmatch(argv[idx_type]->text, "flooding"))
- UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD);
+ UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD);
} else
- UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG);
+ UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG);
return CMD_SUCCESS;
}
@@ -924,16 +925,16 @@ int config_write_ospf6_debug_lsa(struct vty *vty)
handler = vector_slot(ospf6_lsa_handler_vector, i);
if (handler == NULL)
continue;
- if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG))
+ if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG))
vty_out(vty, "debug ospf6 lsa %s\n",
ospf6_lsa_handler_name(handler));
- if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE))
+ if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_ORIGINATE))
vty_out(vty, "debug ospf6 lsa %s originate\n",
ospf6_lsa_handler_name(handler));
- if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN))
+ if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN))
vty_out(vty, "debug ospf6 lsa %s examine\n",
ospf6_lsa_handler_name(handler));
- if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD))
+ if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD))
vty_out(vty, "debug ospf6 lsa %s flooding\n",
ospf6_lsa_handler_name(handler));
}
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index e88d10ad7..d871a8842 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -137,21 +137,14 @@ struct ospf6_lsa {
#define OSPF6_LSA_SEQWRAPPED 0x20
struct ospf6_lsa_handler {
- const struct {
- uint16_t type; /* host byte order */
- const char *name;
- const char *short_name;
- int (*show)(struct vty *, struct ospf6_lsa *);
- char *(*get_prefix_str)(struct ospf6_lsa *, char *buf,
- int buflen, int pos);
- } s;
-#define lh_type s.type
-#define lh_name s.name
-#define lh_short_name s.short_name
-#define lh_show s.show
-#define lh_get_prefix_str s.get_prefix_str
- uint8_t debug;
-#define lh_debug debug
+ uint16_t lh_type; /* host byte order */
+ const char *lh_name;
+ const char *lh_short_name;
+ int (*lh_show)(struct vty *, struct ospf6_lsa *);
+ char *(*lh_get_prefix_str)(struct ospf6_lsa *, char *buf,
+ int buflen, int pos);
+
+ uint8_t lh_debug;
};
#define OSPF6_LSA_IS_KNOWN(t) \
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index 0cc7294d6..4c24f4713 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -921,7 +921,7 @@ DEFUN (no_debug_ospf6,
handler = vector_slot(ospf6_lsa_handler_vector, i);
if (handler != NULL) {
- UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG);
+ UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG);
}
}
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index a099eead4..021e825ae 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -732,7 +732,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
route->next = next;
if (node->info == next) {
- assert(next->rnode == node);
+ assert(next && next->rnode == node);
node->info = route;
UNSET_FLAG(next->flag, OSPF6_ROUTE_BEST);
SET_FLAG(route->flag, OSPF6_ROUTE_BEST);
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index fde47c74f..ca1a65ff0 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -425,19 +425,6 @@ DEFUN(no_ospf6_router_id,
return CMD_SUCCESS;
}
-#if CONFDATE > 20180828
-CPP_NOTICE("ospf6: `router-id A.B.C.D` deprecated 2017/08/28")
-#endif
-ALIAS_HIDDEN(ospf6_router_id, ospf6_router_id_hdn_cmd, "router-id A.B.C.D",
- "Configure OSPF6 Router-ID\n" V4NOTATION_STR)
-
-#if CONFDATE > 20180828
-CPP_NOTICE("ospf6: `no router-id A.B.C.D` deprecated 2017/08/28")
-#endif
-ALIAS_HIDDEN(no_ospf6_router_id, no_ospf6_router_id_hdn_cmd,
- "no router-id [A.B.C.D]",
- NO_STR "Configure OSPF6 Router-ID\n" V4NOTATION_STR)
-
DEFUN (ospf6_log_adjacency_changes,
ospf6_log_adjacency_changes_cmd,
"log-adjacency-changes",
@@ -1144,8 +1131,6 @@ void ospf6_top_init(void)
install_default(OSPF6_NODE);
install_element(OSPF6_NODE, &ospf6_router_id_cmd);
install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
- install_element(OSPF6_NODE, &ospf6_router_id_hdn_cmd);
- install_element(OSPF6_NODE, &no_ospf6_router_id_hdn_cmd);
install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am
index 8a6c4a5cc..d9c29f265 100644
--- a/ospf6d/subdir.am
+++ b/ospf6d/subdir.am
@@ -6,9 +6,27 @@ if OSPF6D
noinst_LIBRARIES += ospf6d/libospf6.a
sbin_PROGRAMS += ospf6d/ospf6d
dist_examples_DATA += ospf6d/ospf6d.conf.sample
+vtysh_scan += \
+ $(top_srcdir)/ospf6d/ospf6_abr.c \
+ $(top_srcdir)/ospf6d/ospf6_asbr.c \
+ $(top_srcdir)/ospf6d/ospf6_area.c \
+ $(top_srcdir)/ospf6d/ospf6_bfd.c \
+ $(top_srcdir)/ospf6d/ospf6_flood.c \
+ $(top_srcdir)/ospf6d/ospf6_interface.c \
+ $(top_srcdir)/ospf6d/ospf6_intra.c \
+ $(top_srcdir)/ospf6d/ospf6_lsa.c \
+ $(top_srcdir)/ospf6d/ospf6_message.c \
+ $(top_srcdir)/ospf6d/ospf6_neighbor.c \
+ $(top_srcdir)/ospf6d/ospf6_route.c \
+ $(top_srcdir)/ospf6d/ospf6_spf.c \
+ $(top_srcdir)/ospf6d/ospf6_top.c \
+ $(top_srcdir)/ospf6d/ospf6_zebra.c \
+ $(top_srcdir)/ospf6d/ospf6d.c \
+ # end
if SNMP
module_LTLIBRARIES += ospf6d/ospf6d_snmp.la
endif
+man8 += $(MANBUILD)/ospf6d.8
endif
ospf6d_libospf6_a_SOURCES = \
diff --git a/ospfclient/.gitignore b/ospfclient/.gitignore
index 1740b04fb..9be70451f 100644
--- a/ospfclient/.gitignore
+++ b/ospfclient/.gitignore
@@ -1,16 +1 @@
-!Makefile
-Makefile.in
-*.o
ospfclient
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-refix
diff --git a/ospfclient/subdir.am b/ospfclient/subdir.am
index 834d4aaba..df7d85a1f 100644
--- a/ospfclient/subdir.am
+++ b/ospfclient/subdir.am
@@ -5,6 +5,7 @@
if OSPFCLIENT
lib_LTLIBRARIES += ospfclient/libfrrospfapiclient.la
sbin_PROGRAMS += ospfclient/ospfclient
+man8 += $(MANBUILD)/ospfclient.8
endif
ospfclient_libfrrospfapiclient_la_LDFLAGS = -version-info 0:0:0
diff --git a/ospfd/.gitignore b/ospfd/.gitignore
index 752c875a6..fc65db33e 100644
--- a/ospfd/.gitignore
+++ b/ospfd/.gitignore
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
ospfd
ospfd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 19d2e6a95..755634a2f 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -995,7 +995,6 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name,
if (len <= 0)
type_next = 1;
else {
- len = 1;
type_next = 0;
*type = *offset;
}
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index 2f8ff9909..17aa10ba0 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -24,6 +24,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/ospfd/subdir.am b/ospfd/subdir.am
index cd659a9bc..83074b5ac 100644
--- a/ospfd/subdir.am
+++ b/ospfd/subdir.am
@@ -6,9 +6,20 @@ if OSPFD
noinst_LIBRARIES += ospfd/libfrrospf.a
sbin_PROGRAMS += ospfd/ospfd
dist_examples_DATA += ospfd/ospfd.conf.sample
+vtysh_scan += \
+ $(top_srcdir)/ospfd/ospf_bfd.c \
+ $(top_srcdir)/ospfd/ospf_dump.c \
+ $(top_srcdir)/ospfd/ospf_opaque.c \
+ $(top_srcdir)/ospfd/ospf_ri.c \
+ $(top_srcdir)/ospfd/ospf_routemap.c \
+ $(top_srcdir)/ospfd/ospf_te.c \
+ $(top_srcdir)/ospfd/ospf_sr.c \
+ $(top_srcdir)/ospfd/ospf_vty.c \
+ # end
if SNMP
module_LTLIBRARIES += ospfd/ospfd_snmp.la
endif
+man8 += $(MANBUILD)/ospfd.8
endif
ospfd_libfrrospf_a_SOURCES = \
diff --git a/pbrd/.gitignore b/pbrd/.gitignore
index ff95d8852..86622ea17 100644
--- a/pbrd/.gitignore
+++ b/pbrd/.gitignore
@@ -1,15 +1 @@
-!Makefile
-Makefile.in
-libpbr.a
pbrd
-tags
-TAGS
-.deps
-*.o
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
diff --git a/pbrd/subdir.am b/pbrd/subdir.am
index 42ab39321..794755903 100644
--- a/pbrd/subdir.am
+++ b/pbrd/subdir.am
@@ -6,6 +6,11 @@ if PBRD
noinst_LIBRARIES += pbrd/libpbr.a
sbin_PROGRAMS += pbrd/pbrd
dist_examples_DATA += pbrd/pbrd.conf.sample
+vtysh_scan += \
+ $(top_srcdir)/pbrd/pbr_vty.c \
+ $(top_srcdir)/pbrd/pbr_debug.c \
+ # end
+man8 += $(MANBUILD)/pbrd.8
endif
pbrd_libpbr_a_SOURCES = \
diff --git a/pimd/.gitignore b/pimd/.gitignore
index 1f56cfaec..b1780df75 100644
--- a/pimd/.gitignore
+++ b/pimd/.gitignore
@@ -1,17 +1,3 @@
-!Makefile
-Makefile.in
-libpim.a
pimd
mtracebis
test_igmpv3_join
-tags
-TAGS
-.deps
-*.o
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
diff --git a/pimd/mtracebis.c b/pimd/mtracebis.c
index c0d95aeed..65c495eff 100644
--- a/pimd/mtracebis.c
+++ b/pimd/mtracebis.c
@@ -17,6 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef __linux__
#include "pim_igmp_mtrace.h"
diff --git a/pimd/mtracebis_netlink.c b/pimd/mtracebis_netlink.c
index b4bf6bada..30ee8f24a 100644
--- a/pimd/mtracebis_netlink.c
+++ b/pimd/mtracebis_netlink.c
@@ -10,6 +10,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef __linux__
#include <stdio.h>
diff --git a/pimd/mtracebis_routeget.c b/pimd/mtracebis_routeget.c
index 8c1cd8d96..8d974403a 100644
--- a/pimd/mtracebis_routeget.c
+++ b/pimd/mtracebis_routeget.c
@@ -17,6 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef __linux__
#include <asm/types.h>
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 5dc86417c..968fc378f 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -5640,27 +5640,6 @@ DEFUN (show_ip_pim_group_type,
return CMD_SUCCESS;
}
-DEFUN_HIDDEN (ip_multicast_routing,
- ip_multicast_routing_cmd,
- "ip multicast-routing",
- IP_STR
- "Enable IP multicast forwarding\n")
-{
- return CMD_SUCCESS;
-}
-
-DEFUN_HIDDEN (no_ip_multicast_routing,
- no_ip_multicast_routing_cmd,
- "no ip multicast-routing",
- NO_STR
- IP_STR
- "Enable IP multicast forwarding\n")
-{
- vty_out(vty,
- "Command is Disabled and will be removed in a future version\n");
- return CMD_SUCCESS;
-}
-
DEFUN (ip_ssmpingd,
ip_ssmpingd_cmd,
"ip ssmpingd [A.B.C.D]",
@@ -6431,16 +6410,12 @@ DEFUN_HIDDEN (interface_ip_pim_ssm,
return CMD_SUCCESS;
}
-DEFUN (interface_ip_pim_sm,
- interface_ip_pim_sm_cmd,
- "ip pim sm",
- IP_STR
- PIM_STR
- IFACE_PIM_SM_STR)
+static int interface_ip_pim_helper(struct vty *vty)
{
struct pim_interface *pim_ifp;
VTY_DECLVAR_CONTEXT(interface, ifp);
+
if (!pim_cmd_interface_add(ifp)) {
vty_out(vty, "Could not enable PIM SM on interface\n");
return CMD_WARNING_CONFIG_FAILED;
@@ -6453,6 +6428,25 @@ DEFUN (interface_ip_pim_sm,
return CMD_SUCCESS;
}
+DEFUN_HIDDEN (interface_ip_pim_sm,
+ interface_ip_pim_sm_cmd,
+ "ip pim sm",
+ IP_STR
+ PIM_STR
+ IFACE_PIM_SM_STR)
+{
+ return interface_ip_pim_helper(vty);
+}
+
+DEFUN (interface_ip_pim,
+ interface_ip_pim_cmd,
+ "ip pim",
+ IP_STR
+ PIM_STR)
+{
+ return interface_ip_pim_helper(vty);
+}
+
static int pim_cmd_interface_delete(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
@@ -6478,13 +6472,7 @@ static int pim_cmd_interface_delete(struct interface *ifp)
return 1;
}
-DEFUN_HIDDEN (interface_no_ip_pim_ssm,
- interface_no_ip_pim_ssm_cmd,
- "no ip pim ssm",
- NO_STR
- IP_STR
- PIM_STR
- IFACE_PIM_STR)
+static int interface_no_ip_pim_helper(struct vty *vty)
{
VTY_DECLVAR_CONTEXT(interface, ifp);
if (!pim_cmd_interface_delete(ifp)) {
@@ -6495,7 +6483,18 @@ DEFUN_HIDDEN (interface_no_ip_pim_ssm,
return CMD_SUCCESS;
}
-DEFUN (interface_no_ip_pim_sm,
+DEFUN_HIDDEN (interface_no_ip_pim_ssm,
+ interface_no_ip_pim_ssm_cmd,
+ "no ip pim ssm",
+ NO_STR
+ IP_STR
+ PIM_STR
+ IFACE_PIM_STR)
+{
+ return interface_no_ip_pim_helper(vty);
+}
+
+DEFUN_HIDDEN (interface_no_ip_pim_sm,
interface_no_ip_pim_sm_cmd,
"no ip pim sm",
NO_STR
@@ -6503,13 +6502,17 @@ DEFUN (interface_no_ip_pim_sm,
PIM_STR
IFACE_PIM_SM_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- if (!pim_cmd_interface_delete(ifp)) {
- vty_out(vty, "Unable to delete interface information\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ return interface_no_ip_pim_helper(vty);
+}
- return CMD_SUCCESS;
+DEFUN (interface_no_ip_pim,
+ interface_no_ip_pim_cmd,
+ "no ip pim",
+ NO_STR
+ IP_STR
+ PIM_STR)
+{
+ return interface_no_ip_pim_helper(vty);
}
/* boundaries */
@@ -7466,7 +7469,7 @@ DEFUN (interface_pim_use_source,
interface_pim_use_source_cmd,
"ip pim use-source A.B.C.D",
IP_STR
- "pim multicast routing\n"
+ PIM_STR
"Configure primary IP address\n"
"source ip address\n")
{
@@ -7478,7 +7481,7 @@ DEFUN (interface_no_pim_use_source,
"no ip pim use-source [A.B.C.D]",
NO_STR
IP_STR
- "pim multicast routing\n"
+ PIM_STR
"Delete source IP address\n"
"source ip address\n")
{
@@ -8634,8 +8637,6 @@ void pim_cmd_init(void)
install_node(&debug_node, pim_debug_config_write);
- install_element(CONFIG_NODE, &ip_multicast_routing_cmd);
- install_element(CONFIG_NODE, &no_ip_multicast_routing_cmd);
install_element(CONFIG_NODE, &ip_pim_rp_cmd);
install_element(VRF_NODE, &ip_pim_rp_cmd);
install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
@@ -8721,6 +8722,8 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c
index 95d0278a3..1fb624a6a 100644
--- a/pimd/pim_igmp_mtrace.c
+++ b/pimd/pim_igmp_mtrace.c
@@ -615,7 +615,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
static uint32_t qry_id, qry_src;
char mtrace_buf[MTRACE_HDR_SIZE + MTRACE_MAX_HOPS * MTRACE_RSP_SIZE];
struct interface *ifp;
- struct interface *out_ifp;
+ struct interface *out_ifp = NULL;
struct pim_interface *pim_ifp;
struct pim_instance *pim;
struct igmp_mtrace *mtracep;
diff --git a/pimd/pim_igmp_stats.c b/pimd/pim_igmp_stats.c
index 428816e1f..40851a452 100644
--- a/pimd/pim_igmp_stats.c
+++ b/pimd/pim_igmp_stats.c
@@ -17,6 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "pim_igmp_stats.h"
void igmp_stats_init(struct igmp_stats *stats)
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 88be195be..a4aec710e 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -267,7 +267,7 @@ int pim_interface_config_write(struct vty *vty)
struct pim_interface *pim_ifp = ifp->info;
if (PIM_IF_TEST_PIM(pim_ifp->options)) {
- vty_out(vty, " ip pim sm\n");
+ vty_out(vty, " ip pim\n");
++writes;
}
diff --git a/pimd/subdir.am b/pimd/subdir.am
index 55d56ece9..fef8e3657 100644
--- a/pimd/subdir.am
+++ b/pimd/subdir.am
@@ -8,6 +8,9 @@ sbin_PROGRAMS += pimd/pimd
bin_PROGRAMS += pimd/mtracebis
noinst_PROGRAMS += pimd/test_igmpv3_join
dist_examples_DATA += pimd/pimd.conf.sample
+vtysh_scan += $(top_srcdir)/pimd/pim_cmd.c
+man8 += $(MANBUILD)/pimd.8
+man8 += $(MANBUILD)/mtracebis.8
endif
pimd_libpim_a_SOURCES = \
diff --git a/pkgsrc/.gitignore b/pkgsrc/.gitignore
index 63e9a66d8..c97f963b3 100644
--- a/pkgsrc/.gitignore
+++ b/pkgsrc/.gitignore
@@ -1,8 +1 @@
-Makefile
-Makefile.in
*.sh
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
diff --git a/ports/.gitignore b/ports/.gitignore
deleted file mode 100644
index dd5bf7c67..000000000
--- a/ports/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-
diff --git a/ports/files/.gitignore b/ports/files/.gitignore
deleted file mode 100644
index dd5bf7c67..000000000
--- a/ports/files/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-
diff --git a/ports/pkg/.gitignore b/ports/pkg/.gitignore
deleted file mode 100644
index dd5bf7c67..000000000
--- a/ports/pkg/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-
diff --git a/python/clidef.py b/python/clidef.py
index 4134f4c94..a140ce3d5 100644
--- a/python/clidef.py
+++ b/python/clidef.py
@@ -96,7 +96,7 @@ class IP4Handler(IPBase):
code = Template('_fail = !inet_aton(argv[_i]->arg, &$varname);')
class IP6Handler(IPBase):
argtype = 'struct in6_addr'
- decl = Template('struct in6_addr $varname = IN6ADDR_ANY_INIT;')
+ decl = Template('struct in6_addr $varname = {};')
code = Template('_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);')
class IPGenHandler(IPBase):
argtype = 'const union sockunion *'
diff --git a/qpb/.gitignore b/qpb/.gitignore
deleted file mode 100644
index 17e90443e..000000000
--- a/qpb/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-!Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
diff --git a/qpb/qpb_allocator.c b/qpb/qpb_allocator.c
index 7e5ba5b0c..aca611ba1 100644
--- a/qpb/qpb_allocator.c
+++ b/qpb/qpb_allocator.c
@@ -22,6 +22,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "linear_allocator.h"
#include "qpb_allocator.h"
diff --git a/qpb/subdir.am b/qpb/subdir.am
index 3c006fd22..75a733f8f 100644
--- a/qpb/subdir.am
+++ b/qpb/subdir.am
@@ -2,24 +2,45 @@ if HAVE_PROTOBUF
lib_LTLIBRARIES += qpb/libfrr_pb.la
endif
-qpb_libfrr_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \
- $(Q_PROTOBUF_C_CLIENT_INCLUDES)
+qpb_libfrr_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS)
+qpb_libfrr_pb_la_LIBADD = $(PROTOBUF_C_LIBS)
qpb_libfrr_pb_la_LDFLAGS = -version-info 0:0:0
qpb_libfrr_pb_la_SOURCES = \
+ qpb/qpb.c \
+ qpb/qpb_allocator.c \
+ # end
+nodist_qpb_libfrr_pb_la_SOURCES = \
+ qpb/qpb.pb-c.c \
+ # end
+
+noinst_HEADERS += \
qpb/linear_allocator.h \
qpb/qpb.h \
- qpb/qpb.c \
qpb/qpb_allocator.h \
# end
-if HAVE_PROTOBUF
-qpb_libfrr_pb_la_SOURCES += qpb/qpb_allocator.c
-nodist_qpb_libfrr_pb_la_SOURCES = qpb/qpb.pb-c.c
CLEANFILES += \
qpb/qpb.pb-c.c \
qpb/qpb.pb-c.h \
# end
-endif
EXTRA_DIST += qpb/qpb.proto
+
+if HAVE_PROTOBUF
+
+# Rules
+.proto.pb.h:
+ $(PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^
+
+AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V))
+am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY))
+am__v_PROTOC_C_0 = @echo " PROTOC_C" $@;
+am__v_PROTOC_C_1 =
+
+.proto.pb-c.c:
+ $(AM_V_PROTOC_C)$(PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^
+.pb-c.c.pb-c.h:
+ @/bin/true
+
+endif # HAVE_PROTOBUF
diff --git a/redhat/.gitignore b/redhat/.gitignore
index a38f1c06e..15804cea0 100644
--- a/redhat/.gitignore
+++ b/redhat/.gitignore
@@ -1,10 +1,2 @@
zebra.spec
frr.spec
-Makefile
-Makefile.in
-.nfs*
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
diff --git a/redhat/README.rpm_build.md b/redhat/README.rpm_build.md
index c461e543d..a3f095786 100644
--- a/redhat/README.rpm_build.md
+++ b/redhat/README.rpm_build.md
@@ -3,16 +3,15 @@ Building your own FRRouting RPM
(Tested on CentOS 6, CentOS 7 and Fedora 24.)
1. On CentOS 6 (which doesn't provide a bison/automake/autoconf of a recent enough version):
- - Check out ../doc/Building_FRR_on_CentOS6.md for details on installing
+ - Check out ../doc/developer/building-frr-for-centos6.rst for details on installing
a bison/automake/autoconf to support frr building.
Newer automake/autoconf/bison is only needed to build the rpm and is
**not** needed to install the binary rpm package
-2. Install the build packages as documented in doc/Building_on_xxxxx.md
- and the following additional packages:
+2. Install the build packages as documented in doc/developer/building-frr-for-xxxxx.rst and the following additional packages:
- yum install rpm-build net-snmp-devel pam-devel
+ yum install rpm-build net-snmp-devel pam-devel libcap-devel
Additionally, on systems with systemd (CentOS 7, Fedora)
@@ -28,8 +27,9 @@ Building your own FRRouting RPM
cd frr
./bootstrap.sh
- ./configure --with-pkg-extra-version=-MyRPMVersion
- make SPHINXBUILD=sphinx-build2.7 dist
+ ./configure --with-pkg-extra-version=-MyRPMVersion \
+ SPHINXBUILD=sphinx-build2.7
+ make dist
Note: configure parameters are not important for the RPM building - except the `with-pkg-extra-version` if you want to give the RPM a specific name to
mark your own unoffical build
diff --git a/redhat/daemons b/redhat/daemons
index de708cf4f..c301a1c23 100644
--- a/redhat/daemons
+++ b/redhat/daemons
@@ -53,6 +53,7 @@ sharpd=no
pbrd=no
staticd=no
bfdd=no
+fabricd=no
#
# Command line options for the daemons
@@ -73,6 +74,7 @@ sharpd_options=("-A 127.0.0.1")
pbrd_options=("-A 127.0.0.1")
staticd_options=("-A 127.0.0.1")
bfdd_options=("-A 127.0.0.1")
+fabricd_options=("-A 127.0.0.1")
#
# If the vtysh_enable is yes, then the unified config is read
diff --git a/redhat/frr.init b/redhat/frr.init
index 2e33aee17..47a92eed3 100755
--- a/redhat/frr.init
+++ b/redhat/frr.init
@@ -33,7 +33,7 @@ V_PATH=/var/run/frr
# Local Daemon selection may be done by using /etc/frr/daemons.
# See /usr/share/doc/frr/README.Debian.gz for further information.
# Keep zebra first and do not list watchfrr!
-DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd pbrd ldpd nhrpd eigrpd babeld staticd sharpd bfdd"
+DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd pbrd ldpd nhrpd eigrpd babeld staticd sharpd bfdd fabricd"
MAX_INSTANCES=5
RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py
diff --git a/redhat/frr.logrotate b/redhat/frr.logrotate
index 654d355fd..df7c5da54 100644
--- a/redhat/frr.logrotate
+++ b/redhat/frr.logrotate
@@ -93,3 +93,11 @@
/bin/kill -USR1 `cat /var/run/frr/bfdd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
+
+/var/log/frr/fabricd.log {
+ notifempty
+ missingok
+ postrotate
+ /bin/kill -USR1 `cat /var/run/frr/fabricd.pid 2> /dev/null` 2> /dev/null || true
+ endscript
+}
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index 25b48506a..bff0b4051 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -86,7 +86,7 @@
%{!?frr_gid: %global frr_gid 92 }
%{!?vty_gid: %global vty_gid 85 }
-%define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd staticd bfdd
+%define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd staticd bfdd fabricd
%if %{with_ldpd}
%define daemon_ldpd ldpd
@@ -343,22 +343,23 @@ developing OSPF-API and frr applications.
--disable-rpki \
%endif
%if %{with_bfdd}
- --enable-bfdd
+ --enable-bfdd \
%else
- --disable-bfdd
+ --disable-bfdd \
%endif
+ SPHINXBUILD=%{sphinx}
-make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" SPHINXBUILD=%{sphinx}
+make %{?_smp_mflags} MAKEINFO="makeinfo --no-split"
pushd doc
-make SPHINXBUILD=%{sphinx} info
+make info
popd
%install
mkdir -p %{buildroot}%{_sysconfdir}/{frr,sysconfig,logrotate.d,pam.d,default} \
%{buildroot}%{_localstatedir}/log/frr %{buildroot}%{_infodir}
-make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" SPHINXBUILD=%{sphinx} install
+make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install
# Remove this file, as it is uninstalled and causes errors when building on RH9
rm -rf %{buildroot}/usr/share/info/dir
@@ -459,6 +460,7 @@ zebra_spec_add_service isisd 2608/tcp "ISISd vty"
%if %{with_bfdd}
zebra_spec_add_service bfdd 2617/tcp "BFDd vty"
%endif
+zebra_spec_add_service fabricd 2618/tcp "Fabricd vty"
%if "%{initsystem}" == "systemd"
for daemon in %all_daemons ; do
@@ -559,9 +561,9 @@ fi
%files
-%doc */*.sample* AUTHORS COPYING
+%doc */*.sample* COPYING
%doc doc/mpls
-%doc ChangeLog NEWS README
+%doc README.md
%if 0%{?frr_user:1}
%dir %attr(751,%{frr_user},%{frr_user}) %{configdir}
%dir %attr(750,%{frr_user},%{frr_user}) %{_localstatedir}/log/frr
@@ -594,6 +596,7 @@ fi
%{_sbindir}/pbrd
%endif
%{_sbindir}/isisd
+%{_sbindir}/fabricd
%if %{with_ldpd}
%{_sbindir}/ldpd
%endif
diff --git a/ripd/.gitignore b/ripd/.gitignore
index 177250ca6..f149501d6 100644
--- a/ripd/.gitignore
+++ b/ripd/.gitignore
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
ripd
ripd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
diff --git a/ripd/subdir.am b/ripd/subdir.am
index 612db1a7a..0d06e7e65 100644
--- a/ripd/subdir.am
+++ b/ripd/subdir.am
@@ -6,9 +6,18 @@ if RIPD
noinst_LIBRARIES += ripd/librip.a
sbin_PROGRAMS += ripd/ripd
dist_examples_DATA += ripd/ripd.conf.sample
+vtysh_scan += \
+ $(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
+
if SNMP
module_LTLIBRARIES += ripd/ripd_snmp.la
endif
+man8 += $(MANBUILD)/ripd.8
endif
ripd_librip_a_SOURCES = \
diff --git a/ripngd/.gitignore b/ripngd/.gitignore
index 213384d13..e6a8ee6be 100644
--- a/ripngd/.gitignore
+++ b/ripngd/.gitignore
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
ripngd
ripngd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
diff --git a/ripngd/subdir.am b/ripngd/subdir.am
index 1f7ff09d6..8f834a1d2 100644
--- a/ripngd/subdir.am
+++ b/ripngd/subdir.am
@@ -5,6 +5,14 @@
if RIPNGD
noinst_LIBRARIES += ripngd/libripng.a
sbin_PROGRAMS += ripngd/ripngd
+vtysh_scan += \
+ $(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 = \
diff --git a/sharpd/.gitignore b/sharpd/.gitignore
index cc33cfc18..91b9f2e90 100644
--- a/sharpd/.gitignore
+++ b/sharpd/.gitignore
@@ -1,17 +1,2 @@
-Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
sharpd
sharpd.conf
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
index 9462eb575..797e336c2 100644
--- a/sharpd/sharp_vty.c
+++ b/sharpd/sharp_vty.c
@@ -191,6 +191,18 @@ DEFPY (remove_routes,
return CMD_SUCCESS;
}
+DEFUN_NOSH (show_debugging_sharpd,
+ show_debugging_sharpd_cmd,
+ "show debugging [sharp]",
+ SHOW_STR
+ DEBUG_STR
+ "Sharp Information\n")
+{
+ vty_out(vty, "Sharp debugging status\n");
+
+ return CMD_SUCCESS;
+}
+
void sharp_vty_init(void)
{
install_element(ENABLE_NODE, &install_routes_cmd);
@@ -198,5 +210,8 @@ void sharp_vty_init(void)
install_element(ENABLE_NODE, &vrf_label_cmd);
install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
+
+ install_element(VIEW_NODE, &show_debugging_sharpd_cmd);
+
return;
}
diff --git a/sharpd/subdir.am b/sharpd/subdir.am
index 490a2ba78..2a34aecfb 100644
--- a/sharpd/subdir.am
+++ b/sharpd/subdir.am
@@ -6,6 +6,8 @@ if SHARPD
noinst_LIBRARIES += sharpd/libsharp.a
sbin_PROGRAMS += sharpd/sharpd
dist_examples_DATA += sharpd/sharpd.conf.sample
+vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c
+man8 += $(MANBUILD)/sharpd.8
endif
sharpd_libsharp_a_SOURCES = \
diff --git a/snapcraft/.gitignore b/snapcraft/.gitignore
index ac7860290..a4796fd73 100644
--- a/snapcraft/.gitignore
+++ b/snapcraft/.gitignore
@@ -3,4 +3,3 @@ parts
prime
stage
frr*.snap
-!*/Makefile
diff --git a/solaris/.gitignore b/solaris/.gitignore
index a249b6199..3f1a0385a 100644
--- a/solaris/.gitignore
+++ b/solaris/.gitignore
@@ -17,6 +17,3 @@ depend.smf
frr.init
*.pkg
*.pkg.gz
-*~
-*.loT
-*.a
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index 771d8d1de..f697969a7 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -88,8 +88,8 @@ static struct list *static_list;
static int static_list_compare_helper(const char *s1, const char *s2)
{
- /* Are Both NULL */
- if (s1 == s2)
+ /* extra (!s1 && !s2) to keep SA happy */
+ if (s1 == s2 || (!s1 && !s2))
return 0;
if (!s1 && s2)
@@ -1390,6 +1390,18 @@ DEFPY(ipv6_route_vrf,
table_str);
}
+DEFUN_NOSH (show_debugging_staticd,
+ show_debugging_staticd_cmd,
+ "show debugging [static]",
+ SHOW_STR
+ DEBUG_STR
+ "Static Information\n")
+{
+ vty_out(vty, "Static debugging status\n");
+
+ return CMD_SUCCESS;
+}
+
void static_vty_init(void)
{
install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
@@ -1408,6 +1420,8 @@ void static_vty_init(void)
install_element(CONFIG_NODE, &ipv6_route_cmd);
install_element(VRF_NODE, &ipv6_route_vrf_cmd);
+ install_element(VIEW_NODE, &show_debugging_staticd_cmd);
+
static_list = list_new();
static_list->cmp = (int (*)(void *, void *))static_list_compare;
static_list->del = (void (*)(void *))static_list_delete;
diff --git a/staticd/subdir.am b/staticd/subdir.am
index 3b06a92e2..33cc0e205 100644
--- a/staticd/subdir.am
+++ b/staticd/subdir.am
@@ -6,6 +6,8 @@ if STATICD
noinst_LIBRARIES += staticd/libstatic.a
sbin_PROGRAMS += staticd/staticd
dist_examples_DATA += staticd/staticd.conf.sample
+vtysh_scan += $(top_srcdir)/staticd/static_vty.c
+man8 += $(MANBUILD)/staticd.8
endif
staticd_libstatic_a_SOURCES = \
diff --git a/tests/.gitignore b/tests/.gitignore
index c8368b39b..37cd245de 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,24 +1,6 @@
-Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.cache
-.deps
-.nfs*
-*~
-*.loT
-*.lo
-*.la
-*.libs
-*.bak
*.log
*.sum
*.xml
-*.pyc
-.arch-inventory
-.arch-ids
-__pycache__
.pytest_cache
/bgpd/test_aspath
/bgpd/test_bgp_table
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 000000000..dd4594feb
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,10 @@
+all: ALWAYS
+ @$(MAKE) -s -C .. check
+%: ALWAYS
+ @$(MAKE) -s -C .. tests/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/tests/Makefile.am b/tests/Makefile.am
deleted file mode 100644
index a7dec6734..000000000
--- a/tests/Makefile.am
+++ /dev/null
@@ -1,235 +0,0 @@
-include ../common.am
-
-PYTHON ?= python
-
-AUTOMAKE_OPTIONS = subdir-objects
-AM_CPPFLAGS += \
- -I.. \
- -I$(top_srcdir) \
- -I$(top_srcdir)/lib \
- -I$(top_builddir)/lib \
- -I$(top_srcdir)/tests/helpers/c \
- -I$(top_builddir)/tests/helpers/c \
- -O
-DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
-
-if BGPD
-TESTS_BGPD = \
- bgpd/test_aspath \
- bgpd/test_capability \
- bgpd/test_packet \
- bgpd/test_peer_attr \
- bgpd/test_ecommunity \
- bgpd/test_mp_attr \
- bgpd/test_mpath \
- bgpd/test_bgp_table
-else
-TESTS_BGPD =
-endif
-
-if ISISD
-if SOLARIS
-TESTS_ISISD =
-else
-TESTS_ISISD = \
- isisd/test_fuzz_isis_tlv \
- isisd/test_isis_vertex_queue \
- # end
-endif
-else
-TESTS_ISISD =
-endif
-
-if OSPF6D
-TESTS_OSPF6D = \
- ospf6d/test_lsdb \
- # end
-else
-TESTS_OSPF6D =
-endif
-
-if ENABLE_BGP_VNC
-BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a
-else
-BGP_VNC_RFP_LIB =
-endif
-
-lib/cli/test_cli.o: lib/cli/test_cli_clippy.c
-ospf6d/test_lsdb.o: ospf6d/test_lsdb_clippy.c
-
-check_PROGRAMS = \
- lib/test_buffer \
- lib/test_checksum \
- lib/test_heavy_thread \
- lib/test_heavy_wq \
- lib/test_heavy \
- lib/test_memory \
- lib/test_nexthop_iter \
- lib/test_privs \
- lib/test_ringbuf \
- lib/test_srcdest_table \
- lib/test_segv \
- lib/test_sig \
- lib/test_stream \
- lib/test_table \
- lib/test_timer_correctness \
- lib/test_timer_performance \
- lib/test_ttable \
- lib/test_zlog \
- lib/test_graph \
- lib/cli/test_cli \
- lib/cli/test_commands \
- $(TESTS_BGPD) \
- $(TESTS_ISISD) \
- $(TESTS_OSPF6D) \
- # end
-
-if ZEROMQ
-check_PROGRAMS += \
- lib/test_zmq \
- # end
-endif
-
-../vtysh/vtysh_cmd.c:
- $(MAKE) -C ../vtysh vtysh_cmd.c
-
-lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c
- sed \
- -e 's/"vtysh\.h"/"tests.h"/' \
- -e 's/vtysh_init_cmd/test_init_cmd/' \
- -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \
- < ../vtysh/vtysh_cmd.c \
- > "$@"
-
-isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
- gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@"
-
-noinst_HEADERS = \
- ./helpers/c/prng.h \
- ./helpers/c/tests.h \
- ./lib/cli/common_cli.h
-
-lib_test_buffer_SOURCES = lib/test_buffer.c
-lib_test_checksum_SOURCES = lib/test_checksum.c
-lib_test_heavy_thread_SOURCES = lib/test_heavy_thread.c helpers/c/main.c
-lib_test_heavy_wq_SOURCES = lib/test_heavy_wq.c helpers/c/main.c
-lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c
-lib_test_memory_SOURCES = lib/test_memory.c
-lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c
-lib_test_privs_SOURCES = lib/test_privs.c
-lib_test_ringbuf_SOURCES = lib/test_ringbuf.c
-lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \
- helpers/c/prng.c
-lib_test_segv_SOURCES = lib/test_segv.c
-lib_test_sig_SOURCES = lib/test_sig.c
-lib_test_stream_SOURCES = lib/test_stream.c
-lib_test_table_SOURCES = lib/test_table.c
-lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \
- helpers/c/prng.c
-lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \
- helpers/c/prng.c
-lib_test_ttable_SOURCES = lib/test_ttable.c
-lib_test_zlog_SOURCES = lib/test_zlog.c
-lib_test_graph_SOURCES = lib/test_graph.c
-lib_test_zmq_SOURCES = lib/test_zmq.c
-lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS)
-lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c
-lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \
- lib/cli/test_commands.c \
- helpers/c/prng.c
-bgpd_test_aspath_SOURCES = bgpd/test_aspath.c
-bgpd_test_capability_SOURCES = bgpd/test_capability.c
-bgpd_test_packet_SOURCES = bgpd/test_packet.c
-bgpd_test_peer_attr_SOURCES = bgpd/test_peer_attr.c
-bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c
-bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c
-bgpd_test_mpath_SOURCES = bgpd/test_mpath.c
-bgpd_test_bgp_table_SOURCES = bgpd/test_bgp_table.c
-isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c
-nodist_isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv_tests.h
-BUILT_SOURCES=isisd/test_fuzz_isis_tlv_tests.h
-CLEANFILES=isisd/test_fuzz_isis_tlv_tests.h
-isisd_test_fuzz_isis_tlv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/tests/isisd
-isisd_test_isis_vertex_queue_SOURCES = isisd/test_isis_vertex_queue.c
-
-ospf6d_test_lsdb_SOURCES = ospf6d/test_lsdb.c lib/cli/common_cli.c
-
-ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@
-BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm
-ISISD_TEST_LDADD = ../isisd/libisis.a $(ALL_TESTS_LDADD)
-OSPF6_TEST_LDADD = ../ospf6d/libospf6.a $(ALL_TESTS_LDADD)
-
-lib_test_buffer_LDADD = $(ALL_TESTS_LDADD)
-lib_test_checksum_LDADD = $(ALL_TESTS_LDADD)
-lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm
-lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm
-lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm
-lib_test_memory_LDADD = $(ALL_TESTS_LDADD)
-lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD)
-lib_test_privs_LDADD = $(ALL_TESTS_LDADD)
-lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD)
-lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD)
-lib_test_segv_LDADD = $(ALL_TESTS_LDADD)
-lib_test_sig_LDADD = $(ALL_TESTS_LDADD)
-lib_test_stream_LDADD = $(ALL_TESTS_LDADD)
-lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm
-lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD)
-lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD)
-lib_test_ttable_LDADD = $(ALL_TESTS_LDADD)
-lib_test_zlog_LDADD = $(ALL_TESTS_LDADD)
-lib_test_graph_LDADD = $(ALL_TESTS_LDADD)
-lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS)
-lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD)
-lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD)
-bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD)
-bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
-bgpd_test_packet_LDADD = $(BGP_TEST_LDADD)
-bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD)
-bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
-bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
-bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
-bgpd_test_bgp_table_LDADD = $(BGP_TEST_LDADD)
-isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
-isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
-ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD)
-
-EXTRA_DIST = \
- runtests.py \
- bgpd/test_aspath.py \
- bgpd/test_capability.py \
- bgpd/test_ecommunity.py \
- bgpd/test_mp_attr.py \
- bgpd/test_mpath.py \
- bgpd/test_peer_attr.py \
- helpers/python/frrsix.py \
- helpers/python/frrtest.py \
- isisd/test_fuzz_isis_tlv.py \
- isisd/test_fuzz_isis_tlv_tests.h.gz \
- isisd/test_isis_vertex_queue.py \
- lib/cli/test_commands.in \
- lib/cli/test_commands.py \
- lib/cli/test_commands.refout \
- lib/cli/test_cli.in \
- lib/cli/test_cli.py \
- lib/cli/test_cli.refout \
- lib/test_nexthop_iter.py \
- lib/test_ringbuf.py \
- lib/test_srcdest_table.py \
- lib/test_stream.py \
- lib/test_stream.refout \
- lib/test_table.py \
- lib/test_timer_correctness.py \
- lib/test_ttable.py \
- lib/test_ttable.refout \
- lib/test_zlog.py \
- lib/test_graph.py \
- lib/test_graph.refout \
- ospf6d/test_lsdb.py \
- ospf6d/test_lsdb.in \
- ospf6d/test_lsdb.refout \
- # end
-
-.PHONY: tests.xml
-tests.xml: $(check_PROGRAMS)
- $(PYTHON) $(srcdir)/runtests.py --junitxml=$@ -v $(srcdir)
-check: tests.xml
diff --git a/tests/helpers/python/frrtest.py b/tests/helpers/python/frrtest.py
index da9e447fc..60bee5c88 100644
--- a/tests/helpers/python/frrtest.py
+++ b/tests/helpers/python/frrtest.py
@@ -176,8 +176,14 @@ class TestRefOut(object):
basedir = os.path.dirname(inspect.getsourcefile(type(self)))
program = os.path.join(basedir, self.program)
- refin = program + '.in'
- refout = program + '.refout'
+ if getattr(self, 'built_refin', False):
+ refin = binpath(program) + '.in'
+ else:
+ refin = program + '.in'
+ if getattr(self, 'built_refout', False):
+ refout = binpath(program) + '.refout'
+ else:
+ refout = program + '.refout'
intext = ''
if os.path.exists(refin):
diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c
index 67a159350..b75c1002d 100644
--- a/tests/isisd/test_fuzz_isis_tlv.c
+++ b/tests/isisd/test_fuzz_isis_tlv.c
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "test_fuzz_isis_tlv_tests.h"
#include <zebra.h>
@@ -114,7 +118,11 @@ static int test(FILE *input, FILE *output)
const char *s_tlvs = isis_format_tlvs(tlvs);
fprintf(output, "Unpacked TLVs:\n%s", s_tlvs);
+ struct isis_item *orig_auth = tlvs->isis_auth.head;
+ tlvs->isis_auth.head = NULL;
+ s_tlvs = isis_format_tlvs(tlvs);
struct isis_tlvs *tlv_copy = isis_copy_tlvs(tlvs);
+ tlvs->isis_auth.head = orig_auth;
isis_free_tlvs(tlvs);
struct stream *s2 = stream_new(TEST_STREAM_SIZE);
diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
index 4abbe8149..4a89bda84 100644
--- a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
+++ b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Binary files differ
diff --git a/tests/isisd/test_isis_vertex_queue.c b/tests/isisd/test_isis_vertex_queue.c
index 3e31b8335..869dd732e 100644
--- a/tests/isisd/test_isis_vertex_queue.c
+++ b/tests/isisd/test_isis_vertex_queue.c
@@ -16,42 +16,46 @@ static size_t vertex_count;
static void setup_test_vertices(void)
{
- union isis_N nid, nip = {
- .ip.dest.family = AF_UNSPEC
+ struct isis_spftree t = {
};
+ struct prefix_pair p = {
+ };
+ uint8_t node_id[7];
vertices = XMALLOC(MTYPE_TMP, sizeof(*vertices) * 16);
- nip.ip.dest.family = AF_INET;
- nip.ip.dest.prefixlen = 24;
- inet_pton(AF_INET, "192.168.1.0", &nip.ip.dest.u.prefix4);
- vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
+ p.dest.family = AF_INET;
+ p.dest.prefixlen = 24;
+ inet_pton(AF_INET, "192.168.1.0", &p.dest.u.prefix4);
+ vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE);
vertices[vertex_count]->d_N = 20;
vertex_count++;
- nip.ip.dest.family = AF_INET;
- nip.ip.dest.prefixlen = 24;
- inet_pton(AF_INET, "192.168.2.0", &nip.ip.dest.u.prefix4);
- vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
+ p.dest.family = AF_INET;
+ p.dest.prefixlen = 24;
+ inet_pton(AF_INET, "192.168.2.0", &p.dest.u.prefix4);
+ vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE);
vertices[vertex_count]->d_N = 20;
vertex_count++;
- memset(nid.id, 0, sizeof(nid.id));
- nid.id[6] = 1;
- vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_PSEUDO_TE_IS);
+ memset(node_id, 0, sizeof(node_id));
+ node_id[6] = 1;
+ vertices[vertex_count] = isis_vertex_new(&t, node_id,
+ VTYPE_PSEUDO_TE_IS);
vertices[vertex_count]->d_N = 15;
vertex_count++;
- memset(nid.id, 0, sizeof(nid.id));
- nid.id[5] = 2;
- vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_NONPSEUDO_TE_IS);
+ memset(node_id, 0, sizeof(node_id));
+ node_id[5] = 2;
+ vertices[vertex_count] = isis_vertex_new(&t, node_id,
+ VTYPE_NONPSEUDO_TE_IS);
vertices[vertex_count]->d_N = 15;
vertex_count++;
- nip.ip.dest.family = AF_INET;
- nip.ip.dest.prefixlen = 24;
- inet_pton(AF_INET, "192.168.3.0", &nip.ip.dest.u.prefix4);
- vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
+ p.dest.family = AF_INET;
+ p.dest.prefixlen = 24;
+ inet_pton(AF_INET, "192.168.3.0", &p.dest.u.prefix4);
+ vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE);
vertices[vertex_count]->d_N = 20;
vertex_count++;
};
diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c
index 4cc15ba23..8f062d8b5 100644
--- a/tests/lib/cli/test_cli.c
+++ b/tests/lib/cli/test_cli.c
@@ -41,7 +41,7 @@ DUMMY_DEFUN(cmd13, "alt a X:X::X:X");
DUMMY_DEFUN(cmd14,
"pat g { foo A.B.C.D$foo|foo|bar X:X::X:X$bar| baz } [final]");
-#include "lib/cli/test_cli_clippy.c"
+#include "tests/lib/cli/test_cli_clippy.c"
DEFPY(magic_test, magic_test_cmd,
"magic (0-100) {ipv4net A.B.C.D/M|X:X::X:X$ipv6}",
diff --git a/tests/lib/cli/test_cli.py b/tests/lib/cli/test_cli.py
index e3c31c2d9..7371db283 100644
--- a/tests/lib/cli/test_cli.py
+++ b/tests/lib/cli/test_cli.py
@@ -2,3 +2,4 @@ import frrtest
class TestCli(frrtest.TestRefOut):
program = './test_cli'
+ built_refout = True
diff --git a/tests/ospf6d/test_lsdb.c b/tests/ospf6d/test_lsdb.c
index ec0835c71..24821febe 100644
--- a/tests/ospf6d/test_lsdb.c
+++ b/tests/ospf6d/test_lsdb.c
@@ -29,7 +29,7 @@
#include "ospf6d/ospf6_lsdb.h"
#include "tests/lib/cli/common_cli.h"
-#include "ospf6d/test_lsdb_clippy.c"
+#include "tests/ospf6d/test_lsdb_clippy.c"
static struct ospf6_lsdb *lsdb;
diff --git a/tests/subdir.am b/tests/subdir.am
new file mode 100644
index 000000000..739a0e86f
--- /dev/null
+++ b/tests/subdir.am
@@ -0,0 +1,295 @@
+#
+# tests
+#
+
+PYTHON ?= python
+
+if BGPD
+TESTS_BGPD = \
+ tests/bgpd/test_aspath \
+ tests/bgpd/test_capability \
+ tests/bgpd/test_packet \
+ tests/bgpd/test_peer_attr \
+ tests/bgpd/test_ecommunity \
+ tests/bgpd/test_mp_attr \
+ tests/bgpd/test_mpath \
+ tests/bgpd/test_bgp_table
+else
+TESTS_BGPD =
+endif
+
+if ISISD
+if SOLARIS
+TESTS_ISISD =
+else
+TESTS_ISISD = \
+ tests/isisd/test_fuzz_isis_tlv \
+ tests/isisd/test_isis_vertex_queue \
+ # end
+endif
+else
+TESTS_ISISD =
+endif
+
+if OSPF6D
+TESTS_OSPF6D = \
+ tests/ospf6d/test_lsdb \
+ # end
+else
+TESTS_OSPF6D =
+endif
+
+tests/lib/cli/tests_lib_cli_test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c
+tests/lib/cli/test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c
+tests/ospf6d/tests_ospf6d_test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c
+tests/ospf6d/test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c
+
+check_PROGRAMS = \
+ tests/lib/test_buffer \
+ tests/lib/test_checksum \
+ tests/lib/test_heavy_thread \
+ tests/lib/test_heavy_wq \
+ tests/lib/test_heavy \
+ tests/lib/test_memory \
+ tests/lib/test_nexthop_iter \
+ tests/lib/test_privs \
+ tests/lib/test_ringbuf \
+ tests/lib/test_srcdest_table \
+ tests/lib/test_segv \
+ tests/lib/test_sig \
+ tests/lib/test_stream \
+ tests/lib/test_table \
+ tests/lib/test_timer_correctness \
+ tests/lib/test_timer_performance \
+ tests/lib/test_ttable \
+ tests/lib/test_zlog \
+ tests/lib/test_graph \
+ tests/lib/cli/test_cli \
+ tests/lib/cli/test_commands \
+ $(TESTS_BGPD) \
+ $(TESTS_ISISD) \
+ $(TESTS_OSPF6D) \
+ # end
+
+if ZEROMQ
+check_PROGRAMS += \
+ tests/lib/test_zmq \
+ # end
+endif
+
+tests/lib/cli/test_commands_defun.c: vtysh/vtysh_cmd.c
+ sed \
+ -e 's%"vtysh/vtysh\.h"%"tests/helpers/c/tests.h"%' \
+ -e 's/vtysh_init_cmd/test_init_cmd/' \
+ -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \
+ < vtysh/vtysh_cmd.c \
+ > "$@"
+
+tests/isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
+ gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@"
+CLEANFILES += tests/isisd/test_fuzz_isis_tlv_tests.h
+
+tests/isisd/tests_isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \
+ tests/isisd/test_fuzz_isis_tlv_tests.h
+tests/isisd/test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \
+ tests/isisd/test_fuzz_isis_tlv_tests.h
+
+noinst_HEADERS += \
+ tests/helpers/c/prng.h \
+ tests/helpers/c/tests.h \
+ tests/lib/cli/common_cli.h \
+ # end
+
+#
+# *sigh* - there is no way to get CPPFLAGS or CFLAGS for a group of files :(
+#
+
+TESTS_CPPFLAGS = $(AM_CPPFLAGS) \
+ -I$(top_srcdir)/tests/helpers/c \
+ -I$(top_builddir)/tests/helpers/c \
+ # end
+TESTS_CFLAGS = $(SAN_FLAGS)
+# note no -Werror
+
+ALL_TESTS_LDADD = lib/libfrr.la @LIBCAP@
+BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) -lm
+ISISD_TEST_LDADD = isisd/libisis.a $(ALL_TESTS_LDADD)
+OSPF6_TEST_LDADD = ospf6d/libospf6.a $(ALL_TESTS_LDADD)
+
+tests_bgpd_test_aspath_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_aspath_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_aspath_SOURCES = tests/bgpd/test_aspath.c
+tests_bgpd_test_bgp_table_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_bgp_table_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_bgp_table_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_bgp_table_SOURCES = tests/bgpd/test_bgp_table.c
+tests_bgpd_test_capability_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_capability_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_capability_SOURCES = tests/bgpd/test_capability.c
+tests_bgpd_test_ecommunity_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_ecommunity_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_ecommunity_SOURCES = tests/bgpd/test_ecommunity.c
+tests_bgpd_test_mp_attr_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_mp_attr_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_mp_attr_SOURCES = tests/bgpd/test_mp_attr.c
+tests_bgpd_test_mpath_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_mpath_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_mpath_SOURCES = tests/bgpd/test_mpath.c
+tests_bgpd_test_packet_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_packet_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_packet_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_packet_SOURCES = tests/bgpd/test_packet.c
+tests_bgpd_test_peer_attr_CFLAGS = $(TESTS_CFLAGS)
+tests_bgpd_test_peer_attr_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD)
+tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c
+
+tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd
+tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd
+tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
+tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c
+nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h
+tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS)
+tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
+tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c
+
+tests_lib_cli_test_cli_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_cli_test_cli_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_cli_test_cli_SOURCES = tests/lib/cli/test_cli.c tests/lib/cli/common_cli.c
+tests_lib_cli_test_commands_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_cli_test_commands_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_cli_test_commands_SOURCES = tests/lib/cli/test_commands_defun.c tests/lib/cli/test_commands.c tests/helpers/c/prng.c
+tests_lib_test_buffer_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_buffer_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_buffer_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_buffer_SOURCES = tests/lib/test_buffer.c
+tests_lib_test_checksum_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_checksum_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_checksum_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_checksum_SOURCES = tests/lib/test_checksum.c
+tests_lib_test_graph_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_graph_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_graph_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_graph_SOURCES = tests/lib/test_graph.c
+tests_lib_test_heavy_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_heavy_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm
+tests_lib_test_heavy_SOURCES = tests/lib/test_heavy.c tests/helpers/c/main.c
+tests_lib_test_heavy_thread_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_heavy_thread_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm
+tests_lib_test_heavy_thread_SOURCES = tests/lib/test_heavy_thread.c tests/helpers/c/main.c
+tests_lib_test_heavy_wq_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_heavy_wq_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm
+tests_lib_test_heavy_wq_SOURCES = tests/lib/test_heavy_wq.c tests/helpers/c/main.c
+tests_lib_test_memory_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_memory_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_memory_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_memory_SOURCES = tests/lib/test_memory.c
+tests_lib_test_nexthop_iter_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_nexthop_iter_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_nexthop_iter_SOURCES = tests/lib/test_nexthop_iter.c tests/helpers/c/prng.c
+tests_lib_test_privs_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_privs_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_privs_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_privs_SOURCES = tests/lib/test_privs.c
+tests_lib_test_ringbuf_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_ringbuf_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_ringbuf_SOURCES = tests/lib/test_ringbuf.c
+tests_lib_test_segv_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_segv_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_segv_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_segv_SOURCES = tests/lib/test_segv.c
+tests_lib_test_sig_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_sig_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_sig_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_sig_SOURCES = tests/lib/test_sig.c
+tests_lib_test_srcdest_table_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_srcdest_table_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_srcdest_table_SOURCES = tests/lib/test_srcdest_table.c tests/helpers/c/prng.c
+tests_lib_test_stream_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_stream_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_stream_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_stream_SOURCES = tests/lib/test_stream.c
+tests_lib_test_table_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_table_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm
+tests_lib_test_table_SOURCES = tests/lib/test_table.c
+tests_lib_test_timer_correctness_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_timer_correctness_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_timer_correctness_SOURCES = tests/lib/test_timer_correctness.c tests/helpers/c/prng.c
+tests_lib_test_timer_performance_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_timer_performance_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_timer_performance_SOURCES = tests/lib/test_timer_performance.c tests/helpers/c/prng.c
+tests_lib_test_ttable_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_ttable_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_ttable_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_ttable_SOURCES = tests/lib/test_ttable.c
+tests_lib_test_zlog_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_zlog_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_zlog_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_zlog_SOURCES = tests/lib/test_zlog.c
+tests_lib_test_zmq_CFLAGS = $(TESTS_CFLAGS) $(ZEROMQ_CFLAGS)
+tests_lib_test_zmq_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_zmq_LDADD = lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS)
+tests_lib_test_zmq_SOURCES = tests/lib/test_zmq.c
+
+tests_ospf6d_test_lsdb_CFLAGS = $(TESTS_CFLAGS)
+tests_ospf6d_test_lsdb_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD)
+tests_ospf6d_test_lsdb_SOURCES = tests/ospf6d/test_lsdb.c tests/lib/cli/common_cli.c
+
+EXTRA_DIST += \
+ tests/runtests.py \
+ tests/bgpd/test_aspath.py \
+ tests/bgpd/test_capability.py \
+ tests/bgpd/test_ecommunity.py \
+ tests/bgpd/test_mp_attr.py \
+ tests/bgpd/test_mpath.py \
+ tests/bgpd/test_peer_attr.py \
+ tests/helpers/python/frrsix.py \
+ tests/helpers/python/frrtest.py \
+ tests/isisd/test_fuzz_isis_tlv.py \
+ tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
+ tests/isisd/test_isis_vertex_queue.py \
+ tests/lib/cli/test_commands.in \
+ tests/lib/cli/test_commands.py \
+ tests/lib/cli/test_commands.refout \
+ tests/lib/cli/test_cli.in \
+ tests/lib/cli/test_cli.py \
+ tests/lib/cli/test_cli.refout \
+ tests/lib/test_nexthop_iter.py \
+ tests/lib/test_ringbuf.py \
+ tests/lib/test_srcdest_table.py \
+ tests/lib/test_stream.py \
+ tests/lib/test_stream.refout \
+ tests/lib/test_table.py \
+ tests/lib/test_timer_correctness.py \
+ tests/lib/test_ttable.py \
+ tests/lib/test_ttable.refout \
+ tests/lib/test_zlog.py \
+ tests/lib/test_graph.py \
+ tests/lib/test_graph.refout \
+ tests/ospf6d/test_lsdb.py \
+ tests/ospf6d/test_lsdb.in \
+ tests/ospf6d/test_lsdb.refout \
+ # end
+
+.PHONY: tests/tests.xml
+tests/tests.xml: $(check_PROGRAMS)
+ ( cd tests; $(PYTHON) ../$(srcdir)/tests/runtests.py --junitxml=tests.xml -v ../$(srcdir)/tests; )
+check: tests/tests.xml
diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c
index c751c0b12..652d7618a 100644
--- a/tests/test_lblmgr.c
+++ b/tests/test_lblmgr.c
@@ -21,6 +21,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "lib/stream.h"
#include "lib/zclient.h"
diff --git a/tools/.gitignore b/tools/.gitignore
index 7bf3be9db..d400dfe8f 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -1,10 +1,2 @@
-!Makefile
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-.libs
-*.o
/permutations
/ssd
diff --git a/tools/etc/iproute2/rt_protos.d/frr.conf b/tools/etc/iproute2/rt_protos.d/frr.conf
index 4c6968ac2..bbb358fc6 100644
--- a/tools/etc/iproute2/rt_protos.d/frr.conf
+++ b/tools/etc/iproute2/rt_protos.d/frr.conf
@@ -11,3 +11,4 @@
194 sharp
195 pbr
196 static
+197 openfabric
diff --git a/tools/frr b/tools/frr
index 0b170d33f..9c8a8e904 100755
--- a/tools/frr
+++ b/tools/frr
@@ -587,6 +587,7 @@ case "$1" in
ip route flush proto 194
ip route flush proto 195
ip route flush proto 196
+ ip route flush proto 197
else
[ -n "$dmn" ] && eval "${dmn/-/_}=0"
start_watchfrr
diff --git a/tools/permutations.c b/tools/permutations.c
index 80441753e..c5109dc3e 100644
--- a/tools/permutations.c
+++ b/tools/permutations.c
@@ -20,6 +20,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "command.h"
#include "graph.h"
#include "vector.h"
diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c
index de58e0a20..cc0315c13 100644
--- a/tools/start-stop-daemon.c
+++ b/tools/start-stop-daemon.c
@@ -25,12 +25,17 @@
* the whole automake/config.h dance.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef HAVE_LXC
#define _GNU_SOURCE
#include <sched.h>
#endif /* HAVE_LXC */
#include <stddef.h>
+#undef VERSION
#define VERSION "1.9.18"
#define MIN_POLL_INTERVAL 20000 /*us*/
@@ -602,7 +607,7 @@ static int pid_is_exec(pid_t pid, const struct stat *esb)
struct stat sb;
char buf[32];
- sprintf(buf, "/proc/%d/exe", pid);
+ sprintf(buf, "/proc/%ld/exe", (long)pid);
if (stat(buf, &sb) != 0)
return 0;
return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
@@ -614,7 +619,7 @@ static int pid_is_user(pid_t pid, uid_t uid)
struct stat sb;
char buf[32];
- sprintf(buf, "/proc/%d", pid);
+ sprintf(buf, "/proc/%ld", (long)pid);
if (stat(buf, &sb) != 0)
return 0;
return (sb.st_uid == uid);
@@ -627,7 +632,7 @@ static int pid_is_cmd(pid_t pid, const char *name)
FILE *f;
int c;
- sprintf(buf, "/proc/%d/stat", pid);
+ sprintf(buf, "/proc/%ld/stat", (long)pid);
f = fopen(buf, "r");
if (!f)
return 0;
@@ -659,12 +664,12 @@ static void check(pid_t pid)
static void do_pidfile(const char *name)
{
FILE *f;
- pid_t pid;
+ long pid;
f = fopen(name, "r");
if (f) {
- if (fscanf(f, "%d", &pid) == 1)
- check(pid);
+ if (fscanf(f, "%ld", &pid) == 1)
+ check((pid_t)pid);
fclose(f);
} else if (errno != ENOENT)
fatal("open pidfile %s: %s", name, strerror(errno));
@@ -677,7 +682,7 @@ static void do_procinit(void)
DIR *procdir;
struct dirent *entry;
int foundany;
- pid_t pid;
+ long pid;
procdir = opendir("/proc");
if (!procdir)
@@ -685,10 +690,10 @@ static void do_procinit(void)
foundany = 0;
while ((entry = readdir(procdir)) != NULL) {
- if (sscanf(entry->d_name, "%d", &pid) != 1)
+ if (sscanf(entry->d_name, "%ld", &pid) != 1)
continue;
foundany++;
- check(pid);
+ check((pid_t)pid);
}
closedir(procdir);
if (!foundany)
@@ -723,21 +728,21 @@ static void do_stop(int signal_nr, int quietmode, int *n_killed,
for (p = found; p; p = p->next) {
if (testmode)
- printf("Would send signal %d to %d.\n", signal_nr,
- p->pid);
+ printf("Would send signal %d to %ld.\n", signal_nr,
+ (long)p->pid);
else if (kill(p->pid, signal_nr) == 0) {
push(&killed, p->pid);
(*n_killed)++;
} else {
- printf("%s: warning: failed to kill %d: %s\n", progname,
- p->pid, strerror(errno));
+ printf("%s: warning: failed to kill %ld: %s\n",
+ progname, (long)p->pid, strerror(errno));
(*n_notkilled)++;
}
}
if (quietmode < 0 && killed) {
printf("Stopped %s (pid", what_stop);
for (p = killed; p; p = p->next)
- printf(" %d", p->pid);
+ printf(" %ld", (long)p->pid);
putchar(')');
if (retry_nr > 0)
printf(", retry #%d", retry_nr);
@@ -1050,7 +1055,7 @@ int main(int argc, char **argv)
if (pidf == NULL)
fatal("Unable to open pidfile `%s' for writing: %s",
pidfile, strerror(errno));
- fprintf(pidf, "%d\n", pidt);
+ fprintf(pidf, "%ld\n", (long)pidt);
fclose(pidf);
}
set_namespaces();
diff --git a/vtysh/.gitignore b/vtysh/.gitignore
index 5856eac25..c1a39b8a1 100644
--- a/vtysh/.gitignore
+++ b/vtysh/.gitignore
@@ -1,16 +1,3 @@
-Makefile
-Makefile.in
-*.o
vtysh
-tags
-TAGS
-.deps
vtysh_cmd.c
-.nfs*
extract.pl
-.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
diff --git a/vtysh/Makefile b/vtysh/Makefile
new file mode 100644
index 000000000..07e093b0f
--- /dev/null
+++ b/vtysh/Makefile
@@ -0,0 +1,10 @@
+all: ALWAYS
+ @$(MAKE) -s -C .. vtysh/vtysh
+%: ALWAYS
+ @$(MAKE) -s -C .. vtysh/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
deleted file mode 100644
index 936640c83..000000000
--- a/vtysh/Makefile.am
+++ /dev/null
@@ -1,178 +0,0 @@
-## Process this file with Automake to create Makefile.in
-
-include ../common.am
-
-if ENABLE_BGP_VNC
-BGP_VNC_RFP_SRCDIR = @top_srcdir@/@LIBRFP@
-BGP_VNC_RFP_INCDIR = -I$(BGP_VNC_RFP_SRCDIR)
-BGP_VNC_RFP_SRC = $(BGP_VNC_RFP_SRCDIR)/*.c
-BGP_VNC_RFAPI_SRCDIR = @top_srcdir@/bgpd/rfapi
-BGP_VNC_RFAPI_INCDIR = -I$(BGP_VNC_RFAPI_SRCDIR) -I$(top_srcdir)/bgpd
-BGP_VNC_RFAPI_SRC = $(BGP_VNC_RFAPI_SRCDIR)/*.c
-else
-BGP_VNC_RFP_INCDIR =
-BGP_VNC_RFP_SRCDIR =
-BGP_VNC_RFP_SRC =
-BGP_VNC_RFAPI_INCDIR =
-BGP_VNC_RFAPI_SRCDIR =
-BGP_VNC_RFAPI_SRC =
-endif
-AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
- $(BGP_VNC_RFAPI_INCDIR) $(BGP_VNC_RFP_INCDIR)
-DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
-
-LIBS = @LIBS@ @CURSES@ @LIBPAM@
-
-bin_PROGRAMS = vtysh
-
-vtysh_SOURCES = vtysh_main.c vtysh.c vtysh_user.c vtysh_config.c
-nodist_vtysh_SOURCES = vtysh_cmd.c
-CLEANFILES = vtysh_cmd.c
-noinst_HEADERS = vtysh.h vtysh_user.h
-vtysh_LDADD = ../lib/libfrr.la @LIBCAP@ @LIBREADLINE@
-
-examplesdir = $(exampledir)
-dist_examples_DATA = vtysh.conf.sample
-
-EXTRA_DIST = extract.pl
-
-vtysh_scan =
-
-if PIMD
-vtysh_scan += $(top_srcdir)/pimd/pim_cmd.c
-endif
-
-if BGPD
-vtysh_scan += $(top_srcdir)/bgpd/bgp_bfd.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_debug.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_dump.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_evpn_vty.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_filter.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_mplsvpn.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_nexthop.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_route.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_routemap.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_vty.c
-vtysh_scan += $(top_srcdir)/bgpd/bgp_flowspec_vty.c
-endif
-
-if RPKI
-vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c
-endif
-
-if ISISD
-vtysh_scan += $(top_srcdir)/isisd/isis_redist.c
-vtysh_scan += $(top_srcdir)/isisd/isis_spf.c
-vtysh_scan += $(top_srcdir)/isisd/isis_te.c
-vtysh_scan += $(top_srcdir)/isisd/isis_vty.c
-vtysh_scan += $(top_srcdir)/isisd/isisd.c
-endif
-
-if OSPFD
-vtysh_scan += $(top_srcdir)/ospfd/ospf_bfd.c
-vtysh_scan += $(top_srcdir)/ospfd/ospf_dump.c
-vtysh_scan += $(top_srcdir)/ospfd/ospf_opaque.c
-vtysh_scan += $(top_srcdir)/ospfd/ospf_ri.c
-vtysh_scan += $(top_srcdir)/ospfd/ospf_routemap.c
-vtysh_scan += $(top_srcdir)/ospfd/ospf_te.c
-vtysh_scan += $(top_srcdir)/ospfd/ospf_sr.c
-vtysh_scan += $(top_srcdir)/ospfd/ospf_vty.c
-endif
-
-if OSPF6D
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_abr.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_asbr.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_area.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_bfd.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_flood.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_interface.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_intra.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_lsa.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_message.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_neighbor.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_route.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_spf.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_top.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6_zebra.c
-vtysh_scan += $(top_srcdir)/ospf6d/ospf6d.c
-endif
-
-if RIPD
-vtysh_scan += $(top_srcdir)/ripd/rip_debug.c
-vtysh_scan += $(top_srcdir)/ripd/rip_interface.c
-vtysh_scan += $(top_srcdir)/ripd/rip_offset.c
-vtysh_scan += $(top_srcdir)/ripd/rip_zebra.c
-vtysh_scan += $(top_srcdir)/ripd/ripd.c
-endif
-
-if RIPNGD
-vtysh_scan += $(top_srcdir)/ripngd/ripng_debug.c
-vtysh_scan += $(top_srcdir)/ripngd/ripng_interface.c
-vtysh_scan += $(top_srcdir)/ripngd/ripng_offset.c
-vtysh_scan += $(top_srcdir)/ripngd/ripng_zebra.c
-vtysh_scan += $(top_srcdir)/ripngd/ripngd.c
-endif
-
-if LDPD
-vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c
-endif
-
-if NHRPD
-vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c
-endif
-
-if EIGRPD
-vtysh_scan += $(top_srcdir)/eigrpd/eigrp_dump.c
-#vtysh_scan += $(top_srcdir)/eigrpd/eigrp_routemap.c
-vtysh_scan += $(top_srcdir)/eigrpd/eigrp_vty.c
-endif
-
-if BABELD
-vtysh_scan += $(top_srcdir)/babeld/babel_interface.c
-vtysh_scan += $(top_srcdir)/babeld/babel_zebra.c
-vtysh_scan += $(top_srcdir)/babeld/babeld.c
-endif
-
-if SHARPD
-vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c
-endif
-
-if SNMP
-vtysh_scan += $(top_srcdir)/lib/agentx.c
-endif
-
-if PBRD
-vtysh_scan += $(top_srcdir)/pbrd/pbr_vty.c
-vtysh_scan += $(top_srcdir)/pbrd/pbr_debug.c
-endif
-
-if STATICD
-vtysh_scan += $(top_srcdir)/staticd/static_vty.c
-endif
-
-if BFDD
-vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c
-endif
-
-vtysh_cmd_FILES = $(vtysh_scan) \
- $(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \
- $(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \
- $(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \
- $(top_srcdir)/lib/vrf.c $(top_srcdir)/lib/if.c \
- $(top_srcdir)/lib/vty.c $(top_srcdir)/zebra/debug.c \
- $(top_srcdir)/lib/logicalrouter.c \
- $(top_srcdir)/lib/nexthop_group.c \
- $(top_srcdir)/zebra/interface.c \
- $(top_srcdir)/zebra/irdp_interface.c \
- $(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \
- $(top_srcdir)/zebra/zserv.c $(top_srcdir)/zebra/router-id.c \
- $(top_srcdir)/zebra/zebra_routemap.c \
- $(top_srcdir)/zebra/zebra_fpm.c \
- $(top_srcdir)/zebra/zebra_ptm.c \
- $(top_srcdir)/zebra/zebra_mpls_vty.c \
- $(top_srcdir)/zebra/zebra_pw.c \
- $(top_srcdir)/watchfrr/watchfrr_vty.c \
- $(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC)
-
-vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl
- ./extract.pl $(vtysh_cmd_FILES) > vtysh_cmd.c
diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index 92b5686a9..0f68e58d6 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -29,16 +29,18 @@ print <<EOF;
#include "command.h"
#include "linklist.h"
-#include "vtysh.h"
+#include "vtysh/vtysh.h"
EOF
my $cli_stomp = 0;
-foreach (@ARGV) {
- $file = $_;
+sub scan_file {
+ my ( $file, $fabricd) = @_;
+
+ $cppadd = $fabricd ? "-DFABRICD=1" : "";
- open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -I@top_builddir@ -I@srcdir@/ -I@srcdir@/.. -I@top_srcdir@/lib -I@top_builddir@/lib -I@top_srcdir@/bgpd -I@top_srcdir@/@LIBRFP@ -I@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $file |");
+ open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $cppadd $file |");
local $/; undef $/;
$line = <FH>;
close (FH);
@@ -77,6 +79,10 @@ foreach (@ARGV) {
$cmd =~ s/^\s+//g;
$cmd =~ s/\s+$//g;
+ if ($fabricd) {
+ $cmd = "fabricd_" . $cmd;
+ }
+
# $protocol is VTYSH_PROTO format for redirection of user input
if ($file =~ /lib\/keychain\.c$/) {
$protocol = "VTYSH_RIPD";
@@ -107,9 +113,9 @@ foreach (@ARGV) {
}
elsif ($file =~ /lib\/plist\.c$/) {
if ($defun_array[1] =~ m/ipv6/) {
- $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_BABELD|VTYSH_ISISD";
+ $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD";
} else {
- $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD";
+ $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD";
}
}
elsif ($file =~ /lib\/distribute\.c$/) {
@@ -132,6 +138,9 @@ foreach (@ARGV) {
elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) {
$protocol = "VTYSH_BGPD";
}
+ elsif ($fabricd) {
+ $protocol = "VTYSH_FABRICD";
+ }
else {
($protocol) = ($file =~ /^.*\/([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/);
$protocol = "VTYSH_" . uc $protocol;
@@ -170,6 +179,10 @@ foreach (@ARGV) {
$ecmd =~ s/^\s+//g;
$ecmd =~ s/\s+$//g;
+ if ($fabricd) {
+ $ecmd = "fabricd_" . $ecmd;
+ }
+
# Register $ecmd
if (defined ($cmd2str{$ecmd})) {
my ($key);
@@ -187,6 +200,24 @@ foreach (@ARGV) {
}
}
+foreach (@ARGV) {
+ if (/\/isisd\//) {
+ # We scan all the IS-IS files twice, once for isisd,
+ # once for fabricd. Exceptions are made for the files
+ # that are not shared between the two.
+ if (/isis_vty_isisd.c/) {
+ scan_file($_, 0);
+ } elsif (/isis_vty_fabricd.c/) {
+ scan_file($_, 1);
+ } else {
+ scan_file($_, 0);
+ scan_file($_, 1);
+ }
+ } else {
+ scan_file($_, 0);
+ }
+}
+
# When we have cli commands that map to the same function name, we
# can introduce subtle bugs due to code not being called when
# we think it is.
diff --git a/vtysh/subdir.am b/vtysh/subdir.am
new file mode 100644
index 000000000..932429a87
--- /dev/null
+++ b/vtysh/subdir.am
@@ -0,0 +1,37 @@
+#
+# vtysh
+#
+
+if VTYSH
+bin_PROGRAMS += vtysh/vtysh
+dist_examples_DATA += vtysh/vtysh.conf.sample
+man1 += $(MANBUILD)/vtysh.1
+endif
+
+vtysh_vtysh_SOURCES = \
+ vtysh/vtysh_main.c \
+ vtysh/vtysh.c \
+ vtysh/vtysh_user.c \
+ vtysh/vtysh_config.c \
+ # end
+nodist_vtysh_vtysh_SOURCES = \
+ vtysh/vtysh_cmd.c \
+ # end
+CLEANFILES += vtysh/vtysh_cmd.c
+
+noinst_HEADERS += \
+ vtysh/vtysh.h \
+ vtysh/vtysh_user.h \
+ # end
+
+vtysh_vtysh_LDADD = lib/libfrr.la @LIBCAP@ @LIBREADLINE@ @LIBS@ @CURSES@ @LIBPAM@
+
+EXTRA_DIST += vtysh/extract.pl
+
+AM_V_EXTRACT = $(am__v_EXTRACT_$(V))
+am__v_EXTRACT_ = $(am__v_EXTRACT_$(AM_DEFAULT_VERBOSITY))
+am__v_EXTRACT_0 = @echo " EXTRACT " $@;
+am__v_EXTRACT_1 =
+
+vtysh/vtysh_cmd.c: $(vtysh_scan) vtysh/extract.pl
+ $(AM_V_EXTRACT) vtysh/extract.pl $(vtysh_scan) > vtysh/vtysh_cmd.c
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index c249115fd..6a92b9081 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -132,6 +132,7 @@ struct vtysh_client vtysh_client[] = {
{.fd = -1, .name = "eigrpd", .flag = VTYSH_EIGRPD, .next = NULL},
{.fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .next = NULL},
{.fd = -1, .name = "sharpd", .flag = VTYSH_SHARPD, .next = NULL},
+ {.fd = -1, .name = "fabricd", .flag = VTYSH_FABRICD, .next = NULL},
{.fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL},
{.fd = -1, .name = "pbrd", .flag = VTYSH_PBRD, .next = NULL},
{.fd = -1, .name = "staticd", .flag = VTYSH_STATICD, .next = NULL},
@@ -1112,7 +1113,7 @@ static char *command_generator(const char *text, int state)
return NULL;
}
-static char **new_completion(char *text, int start, int end)
+static char **new_completion(const char *text, int start, int end)
{
char **matches;
@@ -1141,6 +1142,10 @@ static struct cmd_node isis_node = {
ISIS_NODE, "%s(config-router)# ",
};
+static struct cmd_node openfabric_node = {
+ OPENFABRIC_NODE, "%s(config-router)# ",
+};
+
static struct cmd_node interface_node = {
INTERFACE_NODE, "%s(config-if)# ",
};
@@ -1252,9 +1257,7 @@ struct cmd_node link_params_node = {
LINK_PARAMS_NODE, "%s(config-link-params)# ",
};
-#if defined(HAVE_RPKI)
static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1};
-#endif
#if HAVE_BFDD > 0
static struct cmd_node bfd_node = {
@@ -1424,7 +1427,6 @@ DEFUNSH(VTYSH_BGPD, address_family_ipv6_labeled_unicast,
return CMD_SUCCESS;
}
-#if defined(HAVE_RPKI)
DEFUNSH(VTYSH_BGPD,
rpki,
rpki_cmd,
@@ -1435,8 +1437,6 @@ DEFUNSH(VTYSH_BGPD,
return CMD_SUCCESS;
}
-#endif
-
DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
"address-family <l2vpn evpn>",
"Enter Address Family command mode\n"
@@ -1653,6 +1653,15 @@ DEFUNSH(VTYSH_ISISD, router_isis, router_isis_cmd, "router isis WORD",
return CMD_SUCCESS;
}
+DEFUNSH(VTYSH_FABRICD, router_openfabric, router_openfabric_cmd, "router openfabric WORD",
+ ROUTER_STR
+ "OpenFabric routing protocol\n"
+ "ISO Routing area tag\n")
+{
+ vty->node = OPENFABRIC_NODE;
+ return CMD_SUCCESS;
+}
+
DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd,
"route-map WORD <deny|permit> (1-65535)",
"Create route-map or enter route-map command mode\n"
@@ -1767,6 +1776,7 @@ static int vtysh_exit(struct vty *vty)
case LDP_NODE:
case LDP_L2VPN_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
case VTY_NODE:
@@ -1869,7 +1879,6 @@ DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc",
}
-#if defined(HAVE_RPKI)
DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit",
"Exit current mode and down to previous mode\n")
{
@@ -1882,7 +1891,6 @@ DEFUNSH(VTYSH_BGPD, rpki_quit, rpki_quit_cmd, "quit",
{
return rpki_exit(self, vty, argc, argv);
}
-#endif /* HAVE_RPKI */
DEFUNSH(VTYSH_PIMD|VTYSH_ZEBRA, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf",
"Exit from VRF configuration mode\n")
@@ -2042,6 +2050,18 @@ ALIAS(vtysh_exit_bfdd, vtysh_quit_bfdd_cmd, "quit",
"Exit current mode and down to previous mode\n")
#endif
+DEFUNSH(VTYSH_FABRICD, vtysh_exit_fabricd, vtysh_exit_fabricd_cmd, "exit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit(vty);
+}
+
+DEFUNSH(VTYSH_FABRICD, vtysh_quit_fabricd, vtysh_quit_fabricd_cmd, "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_fabricd(self, vty, argc, argv);
+}
+
DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit",
"Exit current mode and down to previous mode\n")
{
@@ -2245,7 +2265,7 @@ DEFUN (vtysh_show_work_queues,
DEFUN (vtysh_show_work_queues_daemon,
vtysh_show_work_queues_daemon_cmd,
- "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pbrd>",
+ "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pbrd|fabricd>",
SHOW_STR
"Work Queue information\n"
"For the zebra daemon\n"
@@ -2255,7 +2275,8 @@ DEFUN (vtysh_show_work_queues_daemon,
"For the ospfv6 daemon\n"
"For the bgp daemon\n"
"For the isis daemon\n"
- "For the pbr daemon\n")
+ "For the pbr daemon\n"
+ "For the fabricd daemon\n")
{
int idx_protocol = 2;
unsigned int i;
@@ -2593,7 +2614,7 @@ DEFUNSH(VTYSH_ALL, no_vtysh_config_enable_password,
DEFUN (vtysh_write_terminal,
vtysh_write_terminal_cmd,
- "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
+ "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|fabricd|pimd>]",
"Write running configuration to memory, network, or terminal\n"
"Write to terminal\n"
"For the zebra daemon\n"
@@ -2604,6 +2625,7 @@ DEFUN (vtysh_write_terminal,
"For the ldpd daemon\n"
"For the bgp daemon\n"
"For the isis daemon\n"
+ "For the fabricd daemon\n"
"For the pim daemon\n")
{
unsigned int i;
@@ -2630,7 +2652,7 @@ DEFUN (vtysh_write_terminal,
DEFUN (vtysh_show_running_config,
vtysh_show_running_config_cmd,
- "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
+ "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|fabricd|pimd>]",
SHOW_STR
"Current operating configuration\n"
"For the zebra daemon\n"
@@ -2641,6 +2663,7 @@ DEFUN (vtysh_show_running_config,
"For the ldp daemon\n"
"For the bgp daemon\n"
"For the isis daemon\n"
+ "For the fabricd daemon\n"
"For the pim daemon\n")
{
return vtysh_write_terminal(self, vty, argc, argv);
@@ -3386,8 +3409,7 @@ void vtysh_readline_init(void)
rl_initialize();
rl_bind_key('?', (rl_command_func_t *)vtysh_rl_describe);
rl_completion_entry_function = vtysh_completion_entry_function;
- rl_attempted_completion_function =
- (rl_completion_func_t *)new_completion;
+ rl_attempted_completion_function = new_completion;
}
char *vtysh_prompt(void)
@@ -3494,10 +3516,9 @@ void vtysh_init_vty(void)
install_node(&keychain_node, NULL);
install_node(&keychain_key_node, NULL);
install_node(&isis_node, NULL);
+ install_node(&openfabric_node, NULL);
install_node(&vty_node, NULL);
-#if defined(HAVE_RPKI)
install_node(&rpki_node, NULL);
-#endif
#if HAVE_BFDD > 0
install_node(&bfd_node, NULL);
install_node(&bfd_peer_node, NULL);
@@ -3588,6 +3609,8 @@ void vtysh_init_vty(void)
#endif
install_element(ISIS_NODE, &vtysh_exit_isisd_cmd);
install_element(ISIS_NODE, &vtysh_quit_isisd_cmd);
+ install_element(OPENFABRIC_NODE, &vtysh_exit_fabricd_cmd);
+ install_element(OPENFABRIC_NODE, &vtysh_quit_fabricd_cmd);
install_element(KEYCHAIN_NODE, &vtysh_exit_ripd_cmd);
install_element(KEYCHAIN_NODE, &vtysh_quit_ripd_cmd);
install_element(KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd);
@@ -3648,6 +3671,7 @@ void vtysh_init_vty(void)
install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd);
install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd);
install_element(ISIS_NODE, &vtysh_end_all_cmd);
+ install_element(OPENFABRIC_NODE, &vtysh_end_all_cmd);
install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd);
install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
install_element(RMAP_NODE, &vtysh_end_all_cmd);
@@ -3697,6 +3721,7 @@ void vtysh_init_vty(void)
install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd);
#endif
install_element(CONFIG_NODE, &router_isis_cmd);
+ install_element(CONFIG_NODE, &router_openfabric_cmd);
install_element(CONFIG_NODE, &router_bgp_cmd);
install_element(BGP_NODE, &address_family_vpnv4_cmd);
install_element(BGP_NODE, &address_family_vpnv6_cmd);
@@ -3732,12 +3757,10 @@ void vtysh_init_vty(void)
install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd);
install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd);
-#if defined(HAVE_RPKI)
install_element(CONFIG_NODE, &rpki_cmd);
install_element(RPKI_NODE, &rpki_exit_cmd);
install_element(RPKI_NODE, &rpki_quit_cmd);
install_element(RPKI_NODE, &vtysh_end_all_cmd);
-#endif
/* EVPN commands */
install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd);
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index 5bff01a50..ee980d512 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -41,6 +41,7 @@ DECLARE_MGROUP(MVTYSH)
#define VTYSH_PBRD 0x04000
#define VTYSH_STATICD 0x08000
#define VTYSH_BFDD 0x10000
+#define VTYSH_FABRICD 0x20000
#define VTYSH_WAS_ACTIVE (-2)
@@ -49,9 +50,9 @@ DECLARE_MGROUP(MVTYSH)
/* watchfrr is not in ALL since library CLI functions should not be
* run on it (logging & co. should stay in a fixed/frozen config, and
* things like prefix lists are not even initialised) */
-#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD
-#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD
-#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD
+#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD|VTYSH_FABRICD
+#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD|VTYSH_FABRICD
+#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD|VTYSH_FABRICD
#define VTYSH_NS VTYSH_ZEBRA
#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 42f08342c..9f6e20f2b 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -245,6 +245,9 @@ void vtysh_config_parse_line(void *arg, const char *line)
else if (strncmp(line, "router isis", strlen("router isis"))
== 0)
config = config_get(ISIS_NODE, line);
+ else if (strncmp(line, "router openfabric", strlen("router openfabric"))
+ == 0)
+ config = config_get(OPENFABRIC_NODE, line);
else if (strncmp(line, "route-map", strlen("route-map")) == 0)
config = config_get(RMAP_NODE, line);
else if (strncmp(line, "pbr-map", strlen("pbr-map")) == 0)
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 86fa62f47..7e979f2c8 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -30,6 +30,16 @@
#include <readline/readline.h>
#include <readline/history.h>
+/*
+ * The append_history function only appears in newer versions
+ * of the readline library it appears like. Since we don't
+ * need this just silently ignore the code on these
+ * ancient platforms.
+ */
+#if !defined HAVE_APPEND_HISTORY
+#define append_history(A, B)
+#endif
+
#include <lib/version.h>
#include "getopt.h"
#include "command.h"
diff --git a/watchfrr/.gitignore b/watchfrr/.gitignore
index b8c020c04..b3f5a6cd9 100644
--- a/watchfrr/.gitignore
+++ b/watchfrr/.gitignore
@@ -1,16 +1 @@
-!Makefile
-Makefile.in
-*.o
watchfrr
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am
index 931f11ef6..f0b49c9a8 100644
--- a/watchfrr/subdir.am
+++ b/watchfrr/subdir.am
@@ -4,6 +4,8 @@
if WATCHFRR
sbin_PROGRAMS += watchfrr/watchfrr
+vtysh_scan += $(top_srcdir)/watchfrr/watchfrr_vty.c
+man8 += $(MANBUILD)/watchfrr.8
endif
noinst_HEADERS += \
diff --git a/zebra/.gitignore b/zebra/.gitignore
index 4a06756a2..41a86e7d7 100644
--- a/zebra/.gitignore
+++ b/zebra/.gitignore
@@ -1,15 +1,3 @@
-!Makefile
-Makefile.in
-*.o
zebra
zebra.conf
client
-tags
-TAGS
-.deps
-.nfs*
-.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c
index 6ad590973..1f12d4c02 100644
--- a/zebra/if_ioctl_solaris.c
+++ b/zebra/if_ioctl_solaris.c
@@ -39,6 +39,7 @@
#include "zebra/interface.h"
#include "zebra/ioctl_solaris.h"
#include "zebra/rib.h"
+#include "zebra/rt.h"
#include "zebra/zebra_errors.h"
static int if_get_addr(struct interface *, struct sockaddr *, const char *);
@@ -56,7 +57,6 @@ static int interface_list_ioctl(int af)
struct lifconf lifconf;
struct interface *ifp;
int n;
- int save_errno;
size_t needed, lastneeded = 0;
char *buf = NULL;
@@ -77,14 +77,12 @@ calculate_lifc_len:
lifn.lifn_flags = LIFC_NOXMIT;
/* we want NOXMIT interfaces too */
ret = ioctl(sock, SIOCGLIFNUM, &lifn);
- save_errno = errno;
-
}
if (ret < 0) {
flog_err_sys(LIB_ERR_SYSTEM_CALL,
"interface_list_ioctl: SIOCGLIFNUM failed %s",
- safe_strerror(save_errno));
+ safe_strerror(errno));
close(sock);
return -1;
}
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 588f1259c..184c5a4fa 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -1048,67 +1048,6 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
return 0;
}
-/* helper function called by if_netlink_change
- * to delete interfaces in case the interface moved
- * to an other netns
- */
-static void if_netlink_check_ifp_instance_consistency(uint16_t cmd,
- struct interface *ifp,
- ns_id_t ns_id)
-{
- struct interface *other_ifp;
-
- /*
- * look if interface name is also found on other netns
- * - only if vrf backend is netns
- * - do not concern lo interface
- * - then remove previous one
- * - for new link case, check found interface is not active
- */
- if (!vrf_is_backend_netns() ||
- !strcmp(ifp->name, "lo"))
- return;
- other_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name);
- if (!other_ifp)
- return;
- /* because previous interface may be inactive,
- * interface is moved back to default vrf
- * then one may find the same pointer; ignore
- */
- if (other_ifp == ifp)
- return;
- if ((cmd == RTM_NEWLINK)
- && (CHECK_FLAG(other_ifp->status, ZEBRA_INTERFACE_ACTIVE)))
- return;
- if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_NEWLINK) {
- zlog_debug("RTM_NEWLINK %s(%u, VRF %u) replaces %s(%u, VRF %u)\n",
- ifp->name,
- ifp->ifindex,
- ifp->vrf_id,
- other_ifp->name,
- other_ifp->ifindex,
- other_ifp->vrf_id);
- } else if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_DELLINK) {
- zlog_debug("RTM_DELLINK %s(%u, VRF %u) is replaced by %s(%u, VRF %u)\n",
- ifp->name,
- ifp->ifindex,
- ifp->vrf_id,
- other_ifp->name,
- other_ifp->ifindex,
- other_ifp->vrf_id);
- }
- /* the found interface replaces the current one
- * remove it
- */
- if (cmd == RTM_DELLINK)
- if_delete(ifp);
- else
- if_delete(other_ifp);
- /* the found interface is replaced by the current one
- * suppress it
- */
-}
-
int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
{
int len;
@@ -1283,8 +1222,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);
- if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
- ifp, ns_id);
} else if (ifp->vrf_id != vrf_id) {
/* VRF change for an interface. */
if (IS_ZEBRA_DEBUG_KERNEL)
@@ -1358,8 +1295,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);
- if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
- ifp, ns_id);
}
} else {
/* Delete interface notification from kernel */
@@ -1385,8 +1320,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (!IS_ZEBRA_IF_VRF(ifp))
if_delete_update(ifp);
- if_netlink_check_ifp_instance_consistency(RTM_DELLINK,
- ifp, ns_id);
}
return 0;
diff --git a/zebra/interface.c b/zebra/interface.c
index eabf0638a..488980c46 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -203,7 +203,6 @@ struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)
if (rn->info) {
ifp = (struct interface *)rn->info;
route_unlock_node(rn); /* get */
- ifp->node = rn;
return ifp;
}
@@ -254,30 +253,6 @@ struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns,
return NULL;
}
-/* this function must be used only if the vrf backend
- * is a netns backend
- */
-struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id,
- const char *ifname)
-{
- struct interface *ifp;
- struct ns *ns;
-
- RB_FOREACH (ns, ns_head, &ns_tree) {
- if (ns->ns_id == ns_id)
- continue;
- /* if_delete_update has removed interface
- * from zns->if_table
- * so to look for interface, use the vrf list
- */
- ifp = if_lookup_by_name(ifname, (vrf_id_t)ns->ns_id);
- if (!ifp)
- continue;
- return ifp;
- }
- return NULL;
-}
-
const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
{
struct interface *ifp;
@@ -757,8 +732,12 @@ void if_delete_update(struct interface *ifp)
ifp->node = NULL;
/* if the ifp is in a vrf, move it to default so vrf can be deleted if
- * desired */
- if (ifp->vrf_id)
+ * desired. This operation is not done for netns implementation to avoid
+ * collision with interface with the same name in the default vrf (can
+ * occur with this implementation whereas it is not possible with
+ * vrf-lite).
+ */
+ if (ifp->vrf_id && !vrf_is_backend_netns())
if_handle_vrf_change(ifp, VRF_DEFAULT);
/* Reset some zebra interface params to default values. */
diff --git a/zebra/interface.h b/zebra/interface.h
index 956d430cf..02a05e614 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -328,8 +328,6 @@ extern void zebra_if_init(void);
extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t);
extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *,
const char *);
-extern struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id,
- const char *ifname);
extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *);
extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int);
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index a6b350de7..63bb2754e 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -100,7 +100,7 @@ static inline int is_selfroute(int proto)
|| (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP)
|| (proto == RTPROT_LDP) || (proto == RTPROT_BABEL)
|| (proto == RTPROT_RIP) || (proto == RTPROT_SHARP)
- || (proto == RTPROT_PBR)) {
+ || (proto == RTPROT_PBR) || (proto == RTPROT_OPENFABRIC)) {
return 1;
}
@@ -147,6 +147,9 @@ static inline int zebra2proto(int proto)
case ZEBRA_ROUTE_PBR:
proto = RTPROT_PBR;
break;
+ case ZEBRA_ROUTE_OPENFABRIC:
+ proto = RTPROT_OPENFABRIC;
+ break;
default:
/*
* When a user adds a new protocol this will show up
@@ -205,6 +208,9 @@ static inline int proto2zebra(int proto, int family)
case RTPROT_PBR:
proto = ZEBRA_ROUTE_PBR;
break;
+ case RTPROT_OPENFABRIC:
+ proto = ZEBRA_ROUTE_OPENFABRIC;
+ break;
default:
/*
* When a user adds a new protocol this will show up
diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h
index c4f21d150..cefd1996a 100644
--- a/zebra/rt_netlink.h
+++ b/zebra/rt_netlink.h
@@ -54,6 +54,7 @@
#define RTPROT_SHARP 194
#define RTPROT_PBR 195
#define RTPROT_ZSTATIC 196
+#define RTPROT_OPENFABRIC 197
void rt_netlink_init(void);
diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c
index c82f68984..40982639c 100644
--- a/zebra/rtread_getmsg.c
+++ b/zebra/rtread_getmsg.c
@@ -32,6 +32,7 @@
#include "zebra/rib.h"
#include "zebra/rt.h"
+#include "zebra/zebra_pbr.h"
#include "zebra/zebra_errors.h"
/* Thank you, Solaris, for polluting application symbol namespace. */
diff --git a/zebra/subdir.am b/zebra/subdir.am
index 5dc375031..a87fcec41 100644
--- a/zebra/subdir.am
+++ b/zebra/subdir.am
@@ -5,6 +5,22 @@
if ZEBRA
sbin_PROGRAMS += zebra/zebra
dist_examples_DATA += zebra/zebra.conf.sample
+vtysh_scan += \
+ $(top_srcdir)/zebra/debug.c \
+ $(top_srcdir)/zebra/interface.c \
+ $(top_srcdir)/zebra/router-id.c \
+ $(top_srcdir)/zebra/rtadv.c \
+ $(top_srcdir)/zebra/zebra_mpls_vty.c \
+ $(top_srcdir)/zebra/zebra_ptm.c \
+ $(top_srcdir)/zebra/zebra_pw.c \
+ $(top_srcdir)/zebra/zebra_routemap.c \
+ $(top_srcdir)/zebra/zebra_vty.c \
+ $(top_srcdir)/zebra/zserv.c \
+ # end
+
+# can be loaded as DSO - always include for vtysh
+vtysh_scan += $(top_srcdir)/zebra/irdp_interface.c
+vtysh_scan += $(top_srcdir)/zebra/zebra_fpm.c
if IRDP
module_LTLIBRARIES += zebra/zebra_irdp.la
@@ -16,6 +32,7 @@ if FPM
module_LTLIBRARIES += zebra/zebra_fpm.la
endif
+man8 += $(MANBUILD)/zebra.8
## endif ZEBRA
endif
@@ -132,10 +149,11 @@ zebra_zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
zebra_zebra_snmp_la_LIBADD = lib/libfrrsnmp.la
zebra_zebra_fpm_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
-zebra_zebra_fpm_la_LIBADD = $(Q_FPM_PB_CLIENT_LDOPTS)
+zebra_zebra_fpm_la_LIBADD =
zebra_zebra_fpm_la_SOURCES = zebra/zebra_fpm.c
zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_netlink.c
if HAVE_PROTOBUF
+zebra_zebra_fpm_la_LIBADD += fpm/libfrrfpm_pb.la qpb/libfrr_pb.la $(PROTOBUF_C_LIBS)
zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_protobuf.c
if DEV_BUILD
zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_dt.c
diff --git a/zebra/zebra_fpm_protobuf.c b/zebra/zebra_fpm_protobuf.c
index ebd632270..be0f6a23b 100644
--- a/zebra/zebra_fpm_protobuf.c
+++ b/zebra/zebra_fpm_protobuf.c
@@ -129,6 +129,7 @@ static inline int add_nexthop(qpb_allocator_t *allocator, Fpm__AddRoute *msg,
}
// TODO: Use src.
+ (void)src;
return 1;
}
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 5a0c722e3..2eb789d74 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -266,7 +266,8 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
There was a crash because ifp here was coming to be NULL */
if (ifp)
if (connected_is_unnumbered(ifp)
- || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) {
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
}
@@ -303,8 +304,10 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
nexthop->gate.ipv6 = *ipv6;
nexthop->ifindex = ifindex;
- if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
+ }
route_entry_nexthop_add(re, nexthop);
@@ -428,8 +431,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
/* Skip nexthops that have been filtered out due to route-map */
/* The nexthops are specific to this route and so the same */
/* nexthop for a different route may not have this flag set */
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED))
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Nexthop Filtered",
+ __PRETTY_FUNCTION__);
return 0;
+ }
/*
* Check to see if we should trust the passed in information
@@ -438,13 +445,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
*/
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) {
ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
- if (ifp && connected_is_unnumbered(ifp)) {
+ if ((ifp && connected_is_unnumbered(ifp))
+ || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
if (if_is_operative(ifp))
return 1;
- else
+ else {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Onlink and interface %s is not operative",
+ __PRETTY_FUNCTION__, ifp->name);
return 0;
- } else
+ }
+ } else {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Interface %s is not unnumbered",
+ __PRETTY_FUNCTION__,
+ ifp ? ifp->name : "Unknown");
return 0;
+ }
}
/* Make lookup prefix. */
@@ -466,8 +485,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
}
/* Lookup table. */
table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id);
- if (!table)
+ if (!table) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Table not found",
+ __PRETTY_FUNCTION__);
return 0;
+ }
rn = route_node_match(table, (struct prefix *)&p);
while (rn) {
@@ -480,15 +503,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
*/
if (top && rn == top)
if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
- || ((afi == AFI_IP6) && (rn->p.prefixlen != 128)))
+ || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Matched against ourself and prefix length is not max bit length",
+ __PRETTY_FUNCTION__);
return 0;
+ }
/* Pick up selected route. */
/* However, do not resolve over default route unless explicitly
* allowed. */
if (is_default_prefix(&rn->p)
- && !rnh_resolve_via_default(p.family))
+ && !rnh_resolve_via_default(p.family)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t:%s: Resolved against default route",
+ __PRETTY_FUNCTION__);
return 0;
+ }
dest = rib_dest_from_rnode(rn);
if (dest && dest->selected_fib
@@ -540,6 +573,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
}
if (resolved && set)
re->nexthop_mtu = match->mtu;
+ if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Recursion failed to find",
+ __PRETTY_FUNCTION__);
return resolved;
} else if (re->type == ZEBRA_ROUTE_STATIC) {
resolved = 0;
@@ -558,6 +594,11 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
}
if (resolved && set)
re->nexthop_mtu = match->mtu;
+
+ if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "\t%s: Static route unable to resolve",
+ __PRETTY_FUNCTION__);
return resolved;
} else {
return 0;
@@ -900,8 +941,12 @@ static unsigned nexthop_active_check(struct route_node *rn,
default:
break;
}
- if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Unable to find a active nexthop",
+ __PRETTY_FUNCTION__);
return 0;
+ }
/* XXX: What exactly do those checks do? Do we support
* e.g. IPv4 routes with IPv6 nexthops or vice versa? */
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 1570edcad..a0a90ac28 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -207,6 +207,9 @@ static int host_rb_entry_compare(const struct host_rb_entry *hle1,
return 1;
return 0;
+ } else if (hle1->p.family == AF_INET6) {
+ return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6,
+ IPV6_MAX_BYTELEN);
} else {
zlog_debug("%s: Unexpected family type: %d",
__PRETTY_FUNCTION__, hle1->p.family);