]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #2944 from thbtcllt/master
authorRuss White <russ@riw.us>
Tue, 11 Sep 2018 15:33:27 +0000 (11:33 -0400)
committerGitHub <noreply@github.com>
Tue, 11 Sep 2018 15:33:27 +0000 (11:33 -0400)
fix zebra crash when a vrf interface changes with netns implementation for vrf

384 files changed:
.github/ISSUE_TEMPLATE.md [new file with mode: 0644]
.github/PULL_REQUEST_TEMPLATE.md [new file with mode: 0644]
.gitignore
AUTHORS [deleted file]
ChangeLog [deleted file]
Makefile.am
NEWS [deleted file]
README [deleted file]
README.md [new file with mode: 0644]
babeld/babel_filter.c
babeld/kernel.c
babeld/neighbour.c
babeld/net.c
babeld/resend.c
babeld/source.c
babeld/subdir.am
babeld/util.c
bfdd/.gitignore
bfdd/bfd.c
bfdd/bfd.h
bfdd/bfd_packet.c
bfdd/bfdctl.h
bfdd/bfdd.c
bfdd/bfdd_vty.c
bfdd/bsd.c
bfdd/config.c
bfdd/event.c
bfdd/linux.c
bfdd/ptm_adapter.c
bfdd/subdir.am
bgpd/.gitignore
bgpd/Makefile [new file with mode: 0644]
bgpd/Makefile.am [deleted file]
bgpd/bgp_bfd.c
bgpd/bgp_bfd.h
bgpd/bgp_damp.c
bgpd/bgp_damp.h
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_evpn_vty.c
bgpd/bgp_filter.c
bgpd/bgp_flowspec.c
bgpd/bgp_flowspec.h
bgpd/bgp_flowspec_vty.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_open.c
bgpd/bgp_open.h
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_rpki.c
bgpd/bgp_vpn.c
bgpd/bgp_vpn.h
bgpd/bgp_vty.c
bgpd/bgp_vty.h
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h
bgpd/rfapi/bgp_rfapi_cfg.c
bgpd/rfapi/bgp_rfapi_cfg.h
bgpd/rfapi/rfapi.c
bgpd/rfapi/rfapi_ap.c
bgpd/rfapi/rfapi_descriptor_rfp_utils.c
bgpd/rfapi/rfapi_import.c
bgpd/rfapi/rfapi_import.h
bgpd/rfapi/rfapi_monitor.c
bgpd/rfapi/rfapi_monitor.h
bgpd/rfapi/rfapi_nve_addr.c
bgpd/rfapi/rfapi_private.h
bgpd/rfapi/rfapi_rib.c
bgpd/rfapi/rfapi_rib.h
bgpd/rfapi/rfapi_vty.c
bgpd/rfapi/rfapi_vty.h
bgpd/rfapi/vnc_export_bgp.c
bgpd/rfapi/vnc_export_bgp_p.h
bgpd/rfapi/vnc_export_table.c
bgpd/rfapi/vnc_export_table.h
bgpd/rfapi/vnc_import_bgp.c
bgpd/rfapi/vnc_import_bgp_p.h
bgpd/rfapi/vnc_zebra.c
bgpd/rfapi/vnc_zebra.h
bgpd/rfp-example/librfp/Makefile [new file with mode: 0644]
bgpd/rfp-example/librfp/Makefile.am [deleted file]
bgpd/rfp-example/librfp/rfp_example.c
bgpd/rfp-example/librfp/subdir.am [new file with mode: 0644]
bgpd/rfp-example/rfptest/Makefile [new file with mode: 0644]
bgpd/rfp-example/rfptest/Makefile.am [deleted file]
bgpd/rfp-example/rfptest/rfptest.c
bgpd/rfp-example/rfptest/subdir.am [new file with mode: 0644]
bgpd/subdir.am [new file with mode: 0644]
common.am [deleted file]
configure.ac
debianpkg/Makefile.am [deleted file]
debianpkg/frr-doc.docs
debianpkg/subdir.am [new file with mode: 0644]
doc/.gitignore
doc/Makefile [new file with mode: 0644]
doc/Makefile.am [deleted file]
doc/developer/Makefile [new file with mode: 0644]
doc/developer/Makefile.am [deleted file]
doc/developer/building-frr-for-alpine.rst [new file with mode: 0644]
doc/developer/building-frr-for-centos6.rst [new file with mode: 0644]
doc/developer/building-frr-for-centos7.rst [new file with mode: 0644]
doc/developer/building-frr-for-debian8.rst [new file with mode: 0644]
doc/developer/building-frr-for-debian9.rst [new file with mode: 0644]
doc/developer/building-frr-for-fedora24.rst [new file with mode: 0644]
doc/developer/building-frr-for-freebsd10.rst [new file with mode: 0644]
doc/developer/building-frr-for-freebsd11.rst [new file with mode: 0644]
doc/developer/building-frr-for-freebsd9.rst [new file with mode: 0644]
doc/developer/building-frr-for-netbsd6.rst [new file with mode: 0644]
doc/developer/building-frr-for-netbsd7.rst [new file with mode: 0644]
doc/developer/building-frr-for-omnios.rst [new file with mode: 0644]
doc/developer/building-frr-for-openbsd6.rst [new file with mode: 0644]
doc/developer/building-frr-for-ubuntu1204.rst [new file with mode: 0644]
doc/developer/building-frr-for-ubuntu1404.rst [new file with mode: 0644]
doc/developer/building-frr-for-ubuntu1604.rst [new file with mode: 0644]
doc/developer/building-frr-for-ubuntu1804.rst [new file with mode: 0644]
doc/developer/building-frr-on-alpine.rst [deleted file]
doc/developer/building-frr-on-centos6.rst [deleted file]
doc/developer/building-frr-on-centos7.rst [deleted file]
doc/developer/building-frr-on-debian8.rst [deleted file]
doc/developer/building-frr-on-debian9.rst [deleted file]
doc/developer/building-frr-on-fedora24.rst [deleted file]
doc/developer/building-frr-on-freebsd10.rst [deleted file]
doc/developer/building-frr-on-freebsd11.rst [deleted file]
doc/developer/building-frr-on-freebsd9.rst [deleted file]
doc/developer/building-frr-on-netbsd6.rst [deleted file]
doc/developer/building-frr-on-netbsd7.rst [deleted file]
doc/developer/building-frr-on-omnios.rst [deleted file]
doc/developer/building-frr-on-openbsd6.rst [deleted file]
doc/developer/building-frr-on-ubuntu1204.rst [deleted file]
doc/developer/building-frr-on-ubuntu1404.rst [deleted file]
doc/developer/building-frr-on-ubuntu1604.rst [deleted file]
doc/developer/building-frr-on-ubuntu1804.rst [deleted file]
doc/developer/building.rst
doc/developer/cli.rst
doc/developer/subdir.am [new file with mode: 0644]
doc/frr-sphinx.mk [deleted file]
doc/manpages/Makefile [new file with mode: 0644]
doc/manpages/Makefile.am [deleted file]
doc/manpages/common-options.rst
doc/manpages/conf.py
doc/manpages/fabricd.rst [new file with mode: 0644]
doc/manpages/index.rst
doc/manpages/subdir.am [new file with mode: 0644]
doc/mpls/.gitignore [deleted file]
doc/subdir.am [new file with mode: 0644]
doc/user/Makefile [new file with mode: 0644]
doc/user/Makefile.am [deleted file]
doc/user/_static/overrides.css
doc/user/fabricd.rst [new file with mode: 0644]
doc/user/index.rst
doc/user/installation.rst
doc/user/isisd.rst
doc/user/overview.rst
doc/user/setup.rst
doc/user/sharp.rst
doc/user/subdir.am [new file with mode: 0644]
doc/user/zebra.rst
eigrpd/.gitignore
eigrpd/eigrp_fsm.c
eigrpd/eigrp_vty.c
eigrpd/subdir.am
fpm/.gitignore [deleted file]
fpm/subdir.am
init/.gitignore [deleted file]
isisd/.gitignore
isisd/fabricd.c [new file with mode: 0644]
isisd/fabricd.conf.sample [new file with mode: 0644]
isisd/fabricd.h [new file with mode: 0644]
isisd/isis_adjacency.c
isisd/isis_bpf.c
isisd/isis_circuit.c
isisd/isis_circuit.h
isisd/isis_lsp.c
isisd/isis_lsp.h
isisd/isis_lsp_hash.c [deleted file]
isisd/isis_lsp_hash.h [deleted file]
isisd/isis_main.c
isisd/isis_mt.c
isisd/isis_pdu.c
isisd/isis_pdu.h
isisd/isis_redist.c
isisd/isis_spf.c
isisd/isis_spf.h
isisd/isis_spf_private.h [new file with mode: 0644]
isisd/isis_te.c
isisd/isis_tlvs.c
isisd/isis_tlvs.h
isisd/isis_tx_queue.c [new file with mode: 0644]
isisd/isis_tx_queue.h [new file with mode: 0644]
isisd/isis_vty.c [deleted file]
isisd/isis_vty_common.c [new file with mode: 0644]
isisd/isis_vty_common.h [new file with mode: 0644]
isisd/isis_vty_fabricd.c [new file with mode: 0644]
isisd/isis_vty_isisd.c [new file with mode: 0644]
isisd/isis_zebra.c
isisd/isisd.c
isisd/isisd.h
isisd/subdir.am
ldpd/.gitignore
ldpd/lde.c
ldpd/pfkey.c
ldpd/subdir.am
lib/.gitignore
lib/agg_table.c [new file with mode: 0644]
lib/agg_table.h [new file with mode: 0644]
lib/bfd.c
lib/bfd.h
lib/command.c
lib/command.h
lib/command_lex.l
lib/csv.c
lib/defun_lex.l
lib/ferr.c
lib/frr_pthread.c
lib/frr_pthread.h
lib/frrstr.c
lib/grammar_sandbox.c
lib/grammar_sandbox_main.c
lib/hook.c
lib/if.c
lib/imsg-buffer.c
lib/imsg.c
lib/json.c
lib/json.h
lib/lib_errors.c
lib/libfrr.c
lib/log.c
lib/memory.c
lib/memory.h
lib/memory_vty.c
lib/openbsd-tree.c
lib/plist.c
lib/plist.h
lib/ptm_lib.c
lib/queue.h
lib/route_types.txt
lib/routemap.c
lib/skiplist.c
lib/stream.c
lib/strlcat.c
lib/strlcpy.c
lib/subdir.am
lib/table.h
lib/vty.c
lib/zclient.h
lib/zebra.h
m4/.gitignore
m4/pkg.m4
nhrpd/.gitignore
nhrpd/linux.c
nhrpd/netlink_arp.c
nhrpd/netlink_gre.c
nhrpd/nhrp_event.c
nhrpd/nhrp_interface.c
nhrpd/nhrp_main.c
nhrpd/nhrp_packet.c
nhrpd/nhrp_peer.c
nhrpd/nhrp_route.c
nhrpd/nhrp_shortcut.c
nhrpd/resolver.c
nhrpd/subdir.am
nhrpd/vici.c
nhrpd/zbuf.c
nhrpd/znl.c
ospf6d/.gitignore
ospf6d/ospf6_asbr.c
ospf6d/ospf6_lsa.c
ospf6d/ospf6_lsa.h
ospf6d/ospf6_neighbor.c
ospf6d/ospf6_route.c
ospf6d/ospf6_top.c
ospf6d/subdir.am
ospfclient/.gitignore
ospfclient/subdir.am
ospfd/.gitignore
ospfd/ospf_bfd.c
ospfd/ospf_bfd.h
ospfd/ospf_snmp.c
ospfd/ospf_sr.c
ospfd/ospf_vty.c
ospfd/subdir.am
pbrd/.gitignore
pbrd/subdir.am
pimd/.gitignore
pimd/mtracebis.c
pimd/mtracebis_netlink.c
pimd/mtracebis_routeget.c
pimd/pim_bfd.c
pimd/pim_bfd.h
pimd/pim_cmd.c
pimd/pim_igmp_mtrace.c
pimd/pim_igmp_stats.c
pimd/pim_rp.c
pimd/pim_rp.h
pimd/pim_vty.c
pimd/subdir.am
pkgsrc/.gitignore
ports/.gitignore [deleted file]
ports/files/.gitignore [deleted file]
ports/pkg/.gitignore [deleted file]
python/clidef.py
qpb/.gitignore [deleted file]
qpb/qpb_allocator.c
qpb/subdir.am
redhat/.gitignore
redhat/README.rpm_build.md
redhat/daemons
redhat/frr.init
redhat/frr.logrotate
redhat/frr.spec.in
ripd/.gitignore
ripd/subdir.am
ripngd/.gitignore
ripngd/ripng_interface.c
ripngd/ripng_route.c
ripngd/ripng_route.h
ripngd/ripng_zebra.c
ripngd/ripngd.c
ripngd/ripngd.h
ripngd/subdir.am
sharpd/.gitignore
sharpd/sharp_vty.c
sharpd/sharp_zebra.c
sharpd/subdir.am
snapcraft/.gitignore
solaris/.gitignore
solaris/Makefile.am [deleted file]
solaris/Makefile.in [new file with mode: 0644]
solaris/pkginfo.tmpl.in
solaris/subdir.am [new file with mode: 0644]
staticd/static_nht.c
staticd/static_vrf.c
staticd/static_vty.c
staticd/static_zebra.c
staticd/subdir.am
tests/.gitignore
tests/Makefile [new file with mode: 0644]
tests/Makefile.am [deleted file]
tests/helpers/python/frrtest.py
tests/isisd/test_fuzz_isis_tlv.c
tests/isisd/test_fuzz_isis_tlv_tests.h.gz
tests/isisd/test_isis_vertex_queue.c
tests/lib/cli/test_cli.c
tests/lib/cli/test_cli.py
tests/ospf6d/test_lsdb.c
tests/subdir.am [new file with mode: 0644]
tests/test_lblmgr.c
tools/.gitignore
tools/etc/iproute2/rt_protos.d/frr.conf
tools/frr
tools/permutations.c
tools/start-stop-daemon.c
vtysh/.gitignore
vtysh/Makefile [new file with mode: 0644]
vtysh/Makefile.am [deleted file]
vtysh/extract.pl.in
vtysh/subdir.am [new file with mode: 0644]
vtysh/vtysh.c
vtysh/vtysh.h
vtysh/vtysh_config.c
vtysh/vtysh_main.c
watchfrr/.gitignore
watchfrr/subdir.am
zebra/.gitignore
zebra/if_ioctl_solaris.c
zebra/if_netlink.c
zebra/interface.c
zebra/interface.h
zebra/rt_netlink.c
zebra/rt_netlink.h
zebra/rtread_getmsg.c
zebra/subdir.am
zebra/zebra_fpm_protobuf.c
zebra/zebra_mpls.c
zebra/zebra_mpls.h
zebra/zebra_mpls_vty.c
zebra/zebra_rib.c
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zebra_vxlan_null.c
zebra/zebra_vxlan_private.h

diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644 (file)
index 0000000..cedca17
--- /dev/null
@@ -0,0 +1,43 @@
+### How to submit an issue
+Please use this text as a template and replace text in the sections or remove
+the entire section if it does not apply to your issue. For example in case of
+a question or feature request, just a description with some example is probably
+fine. Also remember to use GitHub Flavored Markdown properly, especially if
+posting output or code listings.
+
+### Things you may try first
+(put "x" in "[ ]" if you already tried following)
+* [ ] Did you check if this is a duplicate issue?
+* [ ] Did you test it on the latest FRRouting/frr master branch?
+
+**Related Issue:**
+[fill here if applicable]
+
+### Description
+[Description of the bug or feature]
+
+### Steps to Reproduce
+1. [First Step]
+2. [Second Step]
+3. [and so on...]
+
+**Expected behavior:**
+[What you expected to happen]
+
+**Actual behavior:**
+[What actually happened]
+
+### Components
+[bgpd, build, doc, isisd, ospfd, etc.]
+
+### Versions
+* OS: [name] [version]
+* Kernel: [Linux/BSD] [version]
+* FRR: [version]
+
+### Attachments
+[Attach if applicable. For example log-files, log-lines. etc. etc.]
+
+You're also welcomed to provide us with any other data you think may be useful.
+
+Thanks!
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644 (file)
index 0000000..0a8aa03
--- /dev/null
@@ -0,0 +1,12 @@
+### Summary
+[fill here]
+
+### Related Issue
+[fill here if applicable]
+
+### Components
+[bgpd, build, doc, ripd, ospfd, eigrpd, isisd, etc. etc.]
+
+Always remember to follow proper coding style etc. as
+described in the FRRouting Dev Guide.
+http://docs.frrouting.org/projects/dev-guide/en/latest/workflow.html
index c5fd0ced9b34a10e1ccaac706ca5a8321ea383ef..8c62f05539e483d457055b83567920e575f12843 100644 (file)
@@ -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 (file)
index 61867a8..0000000
--- 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 (file)
index ec7e6cd..0000000
--- 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/
index 3e268f703da3beb8bac5fae4171962db2e04c075..fb052a8dea721ae605f48d4b847e63b08c9857e3 100644 (file)
@@ -1,13 +1,78 @@
 ## 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@
 
+# these two targets are provided to easily grab autoconf/Makefile variables
+# you can use either:
+#   eval `make VARFD=3 shvar-CFLAGS 3>&1 1>&2`
+#   CFLAGS="`make VARFD=3 var-CFLAGS 3>&1 1>&2`"
+# where the former can be used to set several variables at once.  Note the
+# fd redirections -- this is to prevent garbage from make rebuilding other
+# targets from causing issues.
+.PHONY: shvar-% var-%
+VARFD ?= 1
+shvar-%:
+       @echo "$*=\"$($*)\"" >&$(VARFD)
+var-%:
+       @echo "$($*)" >&$(VARFD)
+
+# overwriting these vars breaks cross-compilation.  let's be helpful and warn.
+#
+# note: "#AUTODERP# " will be removed from Makefile by configure.  These are
+# GNU make directives & automake will f*ck them up by trying to process them
+# as automake directives.
+#
+#AUTODERP# null=
+#AUTODERP# SPACE=$(null) $(null)
+#AUTODERP# mkcheck_CC =       $(findstring $(SPACE)CC=,      $(SPACE)$(MAKEOVERRIDES))
+#AUTODERP# mkcheck_CFLAGS =   $(findstring $(SPACE)CFLAGS=,  $(SPACE)$(MAKEOVERRIDES))
+#AUTODERP# mkcheck_CPPFLAGS = $(findstring $(SPACE)CPPFLAGS=,$(SPACE)$(MAKEOVERRIDES))
+#AUTODERP# mkcheck_CCLD =     $(findstring $(SPACE)CCLD=,    $(SPACE)$(MAKEOVERRIDES))
+#AUTODERP# mkcheck_LD =       $(findstring $(SPACE)LD=,      $(SPACE)$(MAKEOVERRIDES))
+#AUTODERP# mkcheck_LDFLAGS =  $(findstring $(SPACE)LDFLAGS=, $(SPACE)$(MAKEOVERRIDES))
+#AUTODERP# #
+#AUTODERP# ifneq ($(mkcheck_CC),)
+#AUTODERP#   $(warning WARNING: you have overwritten the "CC" variable on the make command line.)
+#AUTODERP# endif
+#AUTODERP# ifneq ($(mkcheck_CFLAGS),)
+#AUTODERP#   $(warning WARNING: you have overwritten the "CFLAGS" variable on the make command line.)
+#AUTODERP# endif
+#AUTODERP# ifneq ($(mkcheck_CPPFLAGS),)
+#AUTODERP#   $(warning WARNING: you have overwritten the "CPPFLAGS" variable on the make command line.)
+#AUTODERP# endif
+#AUTODERP# ifneq ($(mkcheck_CCLD),)
+#AUTODERP#   $(warning WARNING: you have overwritten the "CCLD" variable on the make command line.)
+#AUTODERP# endif
+#AUTODERP# ifneq ($(mkcheck_LD),)
+#AUTODERP#   $(warning WARNING: you have overwritten the "LD" variable on the make command line.)
+#AUTODERP# endif
+#AUTODERP# ifneq ($(mkcheck_LDFLAGS),)
+#AUTODERP#   $(warning WARNING: you have overwritten the "LDFLAGS" variable on the make command line.)
+#AUTODERP# endif
+#AUTODERP# #
+#AUTODERP# ifneq ($(mkcheck_CC)$(mkcheck_CFLAGS)$(mkcheck_CPPFLAGS)$(mkcheck_CCLD)$(mkcheck_LD)$(mkcheck_LDFLAGS),)
+#AUTODERP#   $(warning ------)
+#AUTODERP#   $(warning While overwriting these variables works most of the time, it is not recommended and can cause confusing build errors.)
+#AUTODERP#   $(warning This is especially problematic when cross-compiling, since tools that run on the build system during the build process will not be compiled correctly.)
+#AUTODERP#   $(warning All of these variables should be supplied to 'configure', and they will be remembered and correctly applied during 'make'.)
+#AUTODERP#   $(warning ------)
+#AUTODERP# endif
+
 EXTRA_DIST =
 BUILT_SOURCES =
 CLEANFILES =
@@ -20,11 +85,14 @@ sbin_SCRIPTS =
 noinst_PROGRAMS =
 noinst_HEADERS =
 noinst_LIBRARIES =
+nodist_noinst_DATA =
 lib_LTLIBRARIES =
 module_LTLIBRARIES =
 pkginclude_HEADERS =
 nodist_pkginclude_HEADERS =
 dist_examples_DATA =
+man_MANS =
+vtysh_scan =
 
 ## libtool, the self-made GNU scourge
 ## ... this should fix relinking
@@ -34,6 +102,10 @@ $(AUTOMAKE_DUMMY)install-moduleLTLIBRARIES: install-libLTLIBRARIES
 $(AUTOMAKE_DUMMY)install-binPROGRAMS: install-libLTLIBRARIES
 $(AUTOMAKE_DUMMY)install-sbinPROGRAMS: install-libLTLIBRARIES
 
+include doc/subdir.am
+include doc/user/subdir.am
+include doc/manpages/subdir.am
+include doc/developer/subdir.am
 include include/subdir.am
 include lib/subdir.am
 include zebra/subdir.am
@@ -41,7 +113,12 @@ include watchfrr/subdir.am
 include qpb/subdir.am
 include fpm/subdir.am
 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
@@ -58,17 +135,8 @@ include pbrd/subdir.am
 include staticd/subdir.am
 include bfdd/subdir.am
 
-SUBDIRS = . @LIBRFP@ @RFPTEST@ \
-        @BGPD@ \
-        @VTYSH@ @DOC@ \
-         @SOLARIS@ tests
-
-DIST_SUBDIRS = . bgpd \
-         vtysh doc tests \
-         solaris bgpd/rfp-example/librfp \
-         bgpd/rfp-example/rfptest \
-         debianpkg \
-         # end
+include vtysh/subdir.am
+include tests/subdir.am
 
 if PKGSRC
 rcdir=@pkgsrcrcdir@
@@ -84,6 +152,7 @@ endif
 
 EXTRA_DIST += \
        aclocal.m4 \
+       README.md \
        m4/README.txt \
        \
        python/clidef.py \
@@ -106,12 +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 (file)
index 8f9dd7a..0000000
--- 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 (file)
index 7600ec5..0000000
--- 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 (file)
index 0000000..48142f2
--- /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
+```
index ff5cca42a0a89c688054db4253a3e1454d9d3a37..31778901a62efb8567c6ee8edbaa60c15ebb1246 100644 (file)
@@ -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"
index ba2b58131c96ccac9036c519f7846aa9b53bbe55..d4c962af3b4390d38ce78ab57e1f742defe09003 100644 (file)
@@ -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>
index c1592fb18a11c6167f05631e1f34063e170dff64..512b60e29a11491818dabfaf249ccf8b345cccb5 100644 (file)
@@ -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>
index ad9a6bad92afad787eeb8a4e103cb676e4b18817..d1f6a4414291b2da7475c943f9ff96bc8bac7e1d 100644 (file)
@@ -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>
index 1f219774424cc57a7e2ff33d6462b05524720804..8949075f67d0beaced0dddd29f878780f726305d 100644 (file)
@@ -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>
index d6dd848952cb404f13c43cf2502fe49b643c9c96..75bca0620639d32f9f17cd01ea7b017818f8f0b0 100644 (file)
@@ -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>
index 6f91f739307989a836dfbb9bb9ceb6c5a5d82032..e1f2cb0a00d78b2ecdfeb6b0736419bfc99baf1b 100644 (file)
@@ -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 = \
index 4a3ecace0ccad0748ac8dca4463b93fa273586fc..880cda2fce7ceb540fa067642192081cb9e303f6 100644 (file)
@@ -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>
index e554d1b33f68dcf17f10612280d4798d27fabcc0..2b020911fbe3d58ee9342efe8d36d69e0aabe33d 100644 (file)
@@ -1,3 +1,2 @@
 # ignore binary files
-*.a
 bfdd
index b3253a14d75150a26a4ed1ace5f50218c390277f..cf7c027db5d8f8022c1825a5473589cca5dae11a 100644 (file)
@@ -78,7 +78,7 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
        } else {
                memset(&shop, 0, sizeof(shop));
                shop.peer = bpc->bpc_peer;
-               if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif)
+               if (bpc->bpc_has_localif)
                        strlcpy(shop.port_name, bpc->bpc_localif,
                                sizeof(shop.port_name));
 
@@ -311,33 +311,6 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name,
        return l_bfd;
 }
 
-#if 0  /* TODO VxLAN Support */
-static void
-_update_vxlan_sess_parms(struct bfd_session *bfd, bfd_sess_parms *sess_parms)
-{
-       struct bfd_session_vxlan_info *vxlan_info = &bfd->vxlan_info;
-       bfd_parms_list *parms = &sess_parms->parms;
-
-       vxlan_info->vnid = parms->vnid;
-       vxlan_info->check_tnl_key = parms->check_tnl_key;
-       vxlan_info->forwarding_if_rx = parms->forwarding_if_rx;
-       vxlan_info->cpath_down = parms->cpath_down;
-       vxlan_info->decay_min_rx = parms->decay_min_rx;
-
-       inet_aton(parms->local_dst_ip, &vxlan_info->local_dst_ip);
-       inet_aton(parms->remote_dst_ip, &vxlan_info->peer_dst_ip);
-
-       memcpy(vxlan_info->local_dst_mac, parms->local_dst_mac, ETH_ALEN);
-       memcpy(vxlan_info->peer_dst_mac, parms->remote_dst_mac, ETH_ALEN);
-
-       /* The interface may change for Vxlan BFD sessions, so update
-        * the local mac and ifindex
-        */
-       bfd->ifindex = sess_parms->ifindex;
-       memcpy(bfd->local_mac, sess_parms->local_mac, sizeof(bfd->local_mac));
-}
-#endif /* VxLAN support */
-
 int bfd_xmt_cb(struct thread *t)
 {
        struct bfd_session *bs = THREAD_ARG(t);
@@ -364,7 +337,7 @@ int bfd_recvtimer_cb(struct thread *t)
        switch (bs->ses_state) {
        case PTM_BFD_INIT:
        case PTM_BFD_UP:
-               ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME);
+               ptm_bfd_ses_dn(bs, BD_CONTROL_EXPIRED);
                bfd_recvtimer_update(bs);
                break;
 
@@ -387,7 +360,7 @@ int bfd_echo_recvtimer_cb(struct thread *t)
        switch (bs->ses_state) {
        case PTM_BFD_INIT:
        case PTM_BFD_UP:
-               ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME);
+               ptm_bfd_ses_dn(bs, BD_ECHO_FAILED);
                break;
        }
 
@@ -535,8 +508,6 @@ static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc)
 
        _bfd_session_update(bs, bpc);
 
-       /* TODO add VxLAN support. */
-
        control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs);
 
        return 0;
@@ -606,9 +577,6 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
                ptm_bfd_fetch_local_mac(bpc->bpc_localif, bfd->local_mac);
        }
 
-       if (bpc->bpc_has_vxlan)
-               BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN);
-
        if (bpc->bpc_ipv4 == false) {
                BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
 
@@ -644,30 +612,13 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
                bfd_mhop_insert(bfd);
        } else {
                bfd->shop.peer = bpc->bpc_peer;
-               if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif)
+               if (bpc->bpc_has_localif)
                        strlcpy(bfd->shop.port_name, bpc->bpc_localif,
                                sizeof(bfd->shop.port_name));
 
                bfd_shop_insert(bfd);
        }
 
-       if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) {
-               static uint8_t bfd_def_vxlan_dmac[] = {0x00, 0x23, 0x20,
-                                                      0x00, 0x00, 0x01};
-               memcpy(bfd->peer_mac, bfd_def_vxlan_dmac,
-                      sizeof(bfd_def_vxlan_dmac));
-       }
-#if 0 /* TODO */
-       else if (event->rmac) {
-               if (sscanf(event->rmac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-                   &bfd->peer_mac[0], &bfd->peer_mac[1], &bfd->peer_mac[2],
-                   &bfd->peer_mac[3], &bfd->peer_mac[4], &bfd->peer_mac[5])
-                   != 6)
-                       DLOG("%s: Assigning remote mac = %s", __func__,
-                            event->rmac);
-       }
-#endif
-
        /*
         * XXX: session update triggers echo start, so we must have our
         * discriminator ID set first.
index d665448abf79f1e0791db3d7bb6fd8eea525c00a..3a58a8d53cfeab25e889167cb18a1267c19bc882 100644 (file)
@@ -105,9 +105,6 @@ struct bfd_echo_pkt {
 #define BFD_CBIT 0x08
 #define BFD_ABIT 0x04
 #define BFD_DEMANDBIT 0x02
-#define BFD_DIAGNEIGHDOWN 3
-#define BFD_DIAGDETECTTIME 1
-#define BFD_DIAGADMINDOWN 7
 #define BFD_SETDEMANDBIT(flags, val)                                           \
        {                                                                      \
                if ((val))                                                     \
@@ -133,18 +130,27 @@ struct bfd_echo_pkt {
 #define BFD_GETSTATE(flags) ((flags >> 6) & 0x3)
 #define BFD_ECHO_VERSION 1
 #define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt)
-#define BFD_CTRL_PKT_LEN sizeof(struct bfd_pkt)
-#define IP_HDR_LEN 20
-#define UDP_HDR_LEN 8
-#define ETH_HDR_LEN 14
-#define VXLAN_HDR_LEN 8
-#define HEADERS_MIN_LEN (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN)
-#define BFD_ECHO_PKT_TOT_LEN                                                   \
-       ((int)(ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN))
-#define BFD_VXLAN_PKT_TOT_LEN                                                  \
-       ((int)(VXLAN_HDR_LEN + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN          \
-              + BFD_CTRL_PKT_LEN))
-#define BFD_RX_BUF_LEN 160
+
+enum bfd_diagnosticis {
+       BD_OK = 0,
+       /* Control Detection Time Expired. */
+       BD_CONTROL_EXPIRED = 1,
+       /* Echo Function Failed. */
+       BD_ECHO_FAILED = 2,
+       /* Neighbor Signaled Session Down. */
+       BD_NEIGHBOR_DOWN = 3,
+       /* Forwarding Plane Reset. */
+       BD_FORWARDING_RESET = 4,
+       /* Path Down. */
+       BD_PATH_DOWN = 5,
+       /* Concatenated Path Down. */
+       BD_CONCATPATH_DOWN = 6,
+       /* Administratively Down. */
+       BD_ADMIN_DOWN = 7,
+       /* Reverse Concatenated Path Down. */
+       BD_REVCONCATPATH_DOWN = 8,
+       /* 9..31: reserved. */
+};
 
 /* BFD session flags */
 enum bfd_session_flags {
@@ -154,9 +160,6 @@ enum bfd_session_flags {
                                             * actively
                                             */
        BFD_SESS_FLAG_MH = 1 << 2,        /* BFD Multi-hop session */
-       BFD_SESS_FLAG_VXLAN = 1 << 3,       /* BFD Multi-hop session which is
-                                            * used to monitor vxlan tunnel
-                                            */
        BFD_SESS_FLAG_IPV6 = 1 << 4,    /* BFD IPv6 session */
        BFD_SESS_FLAG_SEND_EVT_ACTIVE = 1 << 5, /* send event timer active */
        BFD_SESS_FLAG_SEND_EVT_IGNORE = 1 << 6, /* ignore send event when timer
@@ -191,18 +194,6 @@ struct bfd_session_stats {
        uint64_t znotification;
 };
 
-struct bfd_session_vxlan_info {
-       uint32_t vnid;
-       uint32_t decay_min_rx;
-       uint8_t forwarding_if_rx;
-       uint8_t cpath_down;
-       uint8_t check_tnl_key;
-       uint8_t local_dst_mac[ETHERNET_ADDRESS_LENGTH];
-       uint8_t peer_dst_mac[ETHERNET_ADDRESS_LENGTH];
-       struct in_addr local_dst_ip;
-       struct in_addr peer_dst_ip;
-};
-
 /* bfd_session shortcut label forwarding. */
 struct peer_label;
 
@@ -249,16 +240,11 @@ struct bfd_session {
        int ifindex;
        uint8_t local_mac[ETHERNET_ADDRESS_LENGTH];
        uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH];
-       uint16_t ip_id;
 
        /* BFD session flags */
        enum bfd_session_flags flags;
 
-       uint8_t echo_pkt[BFD_ECHO_PKT_TOT_LEN]; /* Save the Echo Packet
-                                                * which will be transmitted
-                                                */
        struct bfd_session_stats stats;
-       struct bfd_session_vxlan_info vxlan_info;
 
        struct timeval uptime;   /* last up time */
        struct timeval downtime; /* last down time */
@@ -407,7 +393,7 @@ struct bfd_global {
        int bg_shop6;
        int bg_mhop6;
        int bg_echo;
-       int bg_vxlan;
+       int bg_echov6;
        struct thread *bg_ev[6];
 
        int bg_csock;
@@ -473,10 +459,10 @@ void log_fatal(const char *fmt, ...);
  *
  * Contains the code related with receiving/seding, packing/unpacking BFD data.
  */
-int bp_set_ttlv6(int sd);
-int bp_set_ttl(int sd);
-int bp_set_tosv6(int sd);
-int bp_set_tos(int sd);
+int bp_set_ttlv6(int sd, uint8_t value);
+int bp_set_ttl(int sd, uint8_t value);
+int bp_set_tosv6(int sd, uint8_t value);
+int bp_set_tos(int sd, uint8_t value);
 int bp_bind_dev(int sd, const char *dev);
 
 int bp_udp_shop(void);
@@ -485,14 +471,14 @@ int bp_udp6_shop(void);
 int bp_udp6_mhop(void);
 int bp_peer_socket(struct bfd_peer_cfg *bpc);
 int bp_peer_socketv6(struct bfd_peer_cfg *bpc);
+int bp_echo_socket(void);
+int bp_echov6_socket(void);
 
 void ptm_bfd_snd(struct bfd_session *bfd, int fbit);
 void ptm_bfd_echo_snd(struct bfd_session *bfd);
 
 int bfd_recv_cb(struct thread *t);
 
-uint16_t checksum(uint16_t *buf, int len);
-
 
 /*
  * event.c
@@ -602,30 +588,13 @@ int ptm_bfd_notify(struct bfd_session *bs);
 /*
  * OS compatibility functions.
  */
-struct udp_psuedo_header {
-       uint32_t saddr;
-       uint32_t daddr;
-       uint8_t reserved;
-       uint8_t protocol;
-       uint16_t len;
-};
-
-#define UDP_PSUEDO_HDR_LEN sizeof(struct udp_psuedo_header)
-
 #if defined(BFD_LINUX) || defined(BFD_BSD)
 int ptm_bfd_fetch_ifindex(const char *ifname);
 void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac);
 void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen);
-int ptm_bfd_echo_sock_init(void);
-int ptm_bfd_vxlan_sock_init(void);
 #endif /* BFD_LINUX || BFD_BSD */
 
-#ifdef BFD_LINUX
-uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len);
-#endif /* BFD_LINUX */
-
 #ifdef BFD_BSD
-uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len);
 ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen,
                           struct sockaddr_storage *ss, socklen_t *sslen,
                           uint8_t *ttl, uint32_t *id);
index 543181a12a1af719934ed537e132ec685910621e..8acb9438c564662af5ccc903ce3becb3229ebe5b 100644 (file)
 
 #include "bfd.h"
 
-/*
- * Definitions
- */
-
-/* iov for BFD control frames */
-#define CMSG_HDR_LEN sizeof(struct cmsghdr)
-#define CMSG_TTL_LEN (CMSG_HDR_LEN + sizeof(uint32_t))
-#define CMSG_IN_PKT_INFO_LEN (CMSG_HDR_LEN + sizeof(struct in_pktinfo) + 4)
-#define CMSG_IN6_PKT_INFO_LEN                                                  \
-       (CMSG_HDR_LEN + sizeof(struct in6_addr) + sizeof(int) + 4)
-
-struct bfd_raw_echo_pkt {
-#ifdef BFD_LINUX
-       struct iphdr ip;
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD
-       struct ip ip;
-#endif /* BFD_BSD */
-       struct udphdr udp;
-       struct bfd_echo_pkt data;
-};
-
-#if 0 /* TODO: VxLAN support. */
-struct bfd_raw_ctrl_pkt {
-       struct iphdr ip;
-       struct udphdr udp;
-       struct bfd_pkt data;
-};
-#endif
-
-struct vxlan_hdr {
-       uint32_t flags;
-       uint32_t vnid;
-};
-
-#define IP_ECHO_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN)
-#define UDP_ECHO_PKT_LEN (UDP_HDR_LEN + BFD_ECHO_PKT_LEN)
-#define IP_CTRL_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_PKT_LEN)
-#define UDP_CTRL_PKT_LEN (UDP_HDR_LEN + BFD_PKT_LEN)
-
-static uint8_t msgbuf[BFD_PKT_LEN];
-
-static int ttlval = BFD_TTL_VAL;
-static int tosval = BFD_TOS_VAL;
-static int rcvttl = BFD_RCV_TTL_VAL;
 
 /*
  * Prototypes
  */
-static uint16_t ptm_bfd_gen_IP_ID(struct bfd_session *bfd);
-static void ptm_bfd_echo_pkt_create(struct bfd_session *bfd);
-static int ptm_bfd_echo_loopback(uint8_t *pkt, int pkt_len, struct sockaddr *ss,
-                                socklen_t sslen);
-static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd, int fbit);
 static int ptm_bfd_process_echo_pkt(int s);
-static bool
-ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd,
-                          struct bfd_session_vxlan_info *vxlan_info);
+int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
+                 size_t datalen);
 
 static void bfd_sd_reschedule(int sd);
-static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
-                            char *vrfname, size_t vrfnamelen,
-                            struct sockaddr_any *local,
-                            struct sockaddr_any *peer);
-static ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
-                            char *vrfname, size_t vrfnamelen,
-                            struct sockaddr_any *local,
-                            struct sockaddr_any *peer);
+ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
+                     char *port, size_t portlen, char *vrfname,
+                     size_t vrfnamelen, struct sockaddr_any *local,
+                     struct sockaddr_any *peer);
+ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
+                     char *port, size_t portlen, char *vrfname,
+                     size_t vrfnamelen, struct sockaddr_any *local,
+                     struct sockaddr_any *peer);
+int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen,
+               struct sockaddr *to, socklen_t tolen);
+int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr);
 
 /* socket related prototypes */
 static void bp_set_ipopts(int sd);
@@ -116,68 +68,17 @@ static void bp_bind_ipv6(int sd, uint16_t port);
 /*
  * Functions
  */
-uint16_t checksum(uint16_t *buf, int len)
-{
-       int nbytes = len;
-       int sum = 0;
-       uint16_t csum = 0;
-       int size = sizeof(uint16_t);
-
-       while (nbytes > 1) {
-               sum += *buf++;
-               nbytes -= size;
-       }
-
-       if (nbytes == 1) {
-               *(uint8_t *)(&csum) = *(uint8_t *)buf;
-               sum += csum;
-       }
-
-       sum = (sum >> 16) + (sum & 0xFFFF);
-       sum += (sum >> 16);
-       csum = ~sum;
-       return csum;
-}
-
-static uint16_t ptm_bfd_gen_IP_ID(struct bfd_session *bfd)
-{
-       return (++bfd->ip_id);
-}
-
-static int _ptm_bfd_send(struct bfd_session *bs, bool use_layer2,
-                        uint16_t *port, const void *data, size_t datalen)
+int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
+                 size_t datalen)
 {
        struct sockaddr *sa;
        struct sockaddr_in sin;
        struct sockaddr_in6 sin6;
-#ifdef BFD_LINUX
-       struct sockaddr_ll dll;
-#endif /* BFD_LINUX */
        socklen_t slen;
        ssize_t rv;
        int sd = -1;
 
-       if (use_layer2) {
-#ifdef BFD_LINUX
-               memset(&dll, 0, sizeof(dll));
-               dll.sll_family = AF_PACKET;
-               dll.sll_protocol = htons(ETH_P_IP);
-               memcpy(dll.sll_addr, bs->peer_mac, ETHERNET_ADDRESS_LENGTH);
-               dll.sll_halen = htons(ETHERNET_ADDRESS_LENGTH);
-               dll.sll_ifindex = bs->ifindex;
-
-               sd = bglobal.bg_echo;
-               sa = (struct sockaddr *)&dll;
-               slen = sizeof(dll);
-#else
-               /*
-                * TODO: implement layer 2 send for *BSDs. This is
-                * needed for VxLAN.
-                */
-               log_warning("packet-send: not implemented");
-               return -1;
-#endif
-       } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) {
+       if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) {
                memset(&sin6, 0, sizeof(sin6));
                sin6.sin6_family = AF_INET6;
                sin6.sin6_addr = bs->shop.peer.sa_sin6.sin6_addr;
@@ -219,332 +120,63 @@ static int _ptm_bfd_send(struct bfd_session *bs, bool use_layer2,
        return 0;
 }
 
-static void ptm_bfd_echo_pkt_create(struct bfd_session *bfd)
-{
-       struct bfd_raw_echo_pkt ep;
-       uint8_t *pkt = bfd->echo_pkt;
-
-       memset(&ep, 0, sizeof(ep));
-       memset(bfd->echo_pkt, 0, sizeof(bfd->echo_pkt));
-
-       /* Construct ethernet header information */
-       memcpy(pkt, bfd->peer_mac, ETHERNET_ADDRESS_LENGTH);
-       pkt = pkt + ETHERNET_ADDRESS_LENGTH;
-       memcpy(pkt, bfd->local_mac, ETHERNET_ADDRESS_LENGTH);
-       pkt = pkt + ETHERNET_ADDRESS_LENGTH;
-#ifdef BFD_LINUX
-       pkt[0] = ETH_P_IP / 256;
-       pkt[1] = ETH_P_IP % 256;
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD
-       pkt[0] = ETHERTYPE_IP / 256;
-       pkt[1] = ETHERTYPE_IP % 256;
-#endif /* BFD_BSD */
-       pkt += 2;
-
-       /* Construct IP header information */
-#ifdef BFD_LINUX
-       ep.ip.version = 4;
-       ep.ip.ihl = 5;
-       ep.ip.tos = 0;
-       ep.ip.tot_len = htons(IP_ECHO_PKT_LEN);
-       ep.ip.id = htons(ptm_bfd_gen_IP_ID(bfd));
-       ep.ip.frag_off = 0;
-       ep.ip.ttl = BFD_TTL_VAL;
-       ep.ip.protocol = IPPROTO_UDP;
-       ep.ip.saddr = bfd->local_ip.sa_sin.sin_addr.s_addr;
-       ep.ip.daddr = bfd->shop.peer.sa_sin.sin_addr.s_addr;
-       ep.ip.check = checksum((uint16_t *)&ep.ip, IP_HDR_LEN);
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD
-       ep.ip.ip_v = 4;
-       ep.ip.ip_hl = 5;
-       ep.ip.ip_tos = 0;
-       ep.ip.ip_len = htons(IP_ECHO_PKT_LEN);
-       ep.ip.ip_id = htons(ptm_bfd_gen_IP_ID(bfd));
-       ep.ip.ip_off = 0;
-       ep.ip.ip_ttl = BFD_TTL_VAL;
-       ep.ip.ip_p = IPPROTO_UDP;
-       ep.ip.ip_src = bfd->local_ip.sa_sin.sin_addr;
-       ep.ip.ip_dst = bfd->shop.peer.sa_sin.sin_addr;
-       ep.ip.ip_sum = checksum((uint16_t *)&ep.ip, IP_HDR_LEN);
-#endif /* BFD_BSD */
-
-       /* Construct UDP header information */
-#ifdef BFD_LINUX
-       ep.udp.source = htons(BFD_DEF_ECHO_PORT);
-       ep.udp.dest = htons(BFD_DEF_ECHO_PORT);
-       ep.udp.len = htons(UDP_ECHO_PKT_LEN);
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD
-       ep.udp.uh_sport = htons(BFD_DEF_ECHO_PORT);
-       ep.udp.uh_dport = htons(BFD_DEF_ECHO_PORT);
-       ep.udp.uh_ulen = htons(UDP_ECHO_PKT_LEN);
-#endif /* BFD_BSD */
-
-       /* Construct Echo packet information */
-       ep.data.ver = BFD_ECHO_VERSION;
-       ep.data.len = BFD_ECHO_PKT_LEN;
-       ep.data.my_discr = htonl(bfd->discrs.my_discr);
-#ifdef BFD_LINUX
-       ep.udp.check =
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD
-       ep.udp.uh_sum =
-#endif /* BFD_BSD */
-               udp4_checksum(&ep.ip, (uint8_t *)&ep.udp,
-                             UDP_ECHO_PKT_LEN);
-
-       memcpy(pkt, &ep, sizeof(ep));
-}
-
 void ptm_bfd_echo_snd(struct bfd_session *bfd)
 {
-       struct bfd_raw_echo_pkt *ep;
-       bool use_layer2 = false;
-       const void *pkt;
-       size_t pktlen;
-       uint16_t port = htons(BFD_DEF_ECHO_PORT);
+       struct sockaddr_any *sa;
+       socklen_t salen;
+       int sd;
+       struct bfd_echo_pkt bep;
+       struct sockaddr_in sin;
+       struct sockaddr_in6 sin6;
 
-       if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) {
-               ptm_bfd_echo_pkt_create(bfd);
+       if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
                BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE);
-       } else {
-               /* just update the checksum and ip Id */
-               ep = (struct bfd_raw_echo_pkt *)(bfd->echo_pkt + ETH_HDR_LEN);
-#ifdef BFD_LINUX
-               ep->ip.id = htons(ptm_bfd_gen_IP_ID(bfd));
-               ep->ip.check = 0;
-               ep->ip.check = checksum((uint16_t *)&ep->ip, IP_HDR_LEN);
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD
-               ep->ip.ip_id = htons(ptm_bfd_gen_IP_ID(bfd));
-               ep->ip.ip_sum = 0;
-               ep->ip.ip_sum = checksum((uint16_t *)&ep->ip, IP_HDR_LEN);
-#endif /* BFD_BSD */
-       }
 
-       if (use_layer2) {
-               pkt = bfd->echo_pkt;
-               pktlen = BFD_ECHO_PKT_TOT_LEN;
+       memset(&bep, 0, sizeof(bep));
+       bep.ver = BFD_ECHO_VERSION;
+       bep.len = BFD_ECHO_PKT_LEN;
+       bep.my_discr = htonl(bfd->discrs.my_discr);
+
+       sa = BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_MH) ? &bfd->mhop.peer
+                                                         : &bfd->shop.peer;
+       if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6)) {
+               sd = bglobal.bg_echov6;
+               sin6 = sa->sa_sin6;
+               sin6.sin6_port = htons(BFD_DEF_ECHO_PORT);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+               sin6.sin6_len = sizeof(sin6);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+               sa = (struct sockaddr_any *)&sin6;
+               salen = sizeof(sin6);
        } else {
-               pkt = &bfd->echo_pkt[ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN];
-               pktlen = BFD_ECHO_PKT_TOT_LEN
-                        - (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN);
-       }
+               sd = bglobal.bg_echo;
+               sin = sa->sa_sin;
+               sin.sin_port = htons(BFD_DEF_ECHO_PORT);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+               sin.sin_len = sizeof(sin);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
 
-       if (_ptm_bfd_send(bfd, use_layer2, &port, pkt, pktlen) != 0) {
-               log_debug("echo-packet: send failure: %s", strerror(errno));
-               return;
+               sa = (struct sockaddr_any *)&sin;
+               salen = sizeof(sin);
        }
+       if (bp_udp_send(sd, BFD_TTL_VAL, (uint8_t *)&bep, sizeof(bep),
+                       (struct sockaddr *)sa, salen)
+           == -1)
+               return;
 
        bfd->stats.tx_echo_pkt++;
 }
 
-static int ptm_bfd_echo_loopback(uint8_t *pkt, int pkt_len, struct sockaddr *ss,
-                                socklen_t sslen)
-{
-#ifdef BFD_LINUX
-       struct bfd_raw_echo_pkt *ep =
-               (struct bfd_raw_echo_pkt *)(pkt + ETH_HDR_LEN);
-       uint8_t temp_mac[ETHERNET_ADDRESS_LENGTH];
-       uint32_t temp_ip;
-       struct ethhdr *eth = (struct ethhdr *)pkt;
-
-       /* swap the mac addresses */
-       memcpy(temp_mac, eth->h_source, ETHERNET_ADDRESS_LENGTH);
-       memcpy(eth->h_source, eth->h_dest, ETHERNET_ADDRESS_LENGTH);
-       memcpy(eth->h_dest, temp_mac, ETHERNET_ADDRESS_LENGTH);
-
-       /* swap ip addresses */
-       temp_ip = ep->ip.saddr;
-       ep->ip.saddr = ep->ip.daddr;
-       ep->ip.daddr = temp_ip;
-
-       ep->ip.ttl = ep->ip.ttl - 1;
-       ep->ip.check = 0;
-       ep->ip.check = checksum((uint16_t *)ep, IP_HDR_LEN);
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD_FILTER
-       struct bfd_raw_echo_pkt_t *ep =
-               (struct bfd_raw_echo_pkt *)(pkt + ETH_HDR_LEN);
-       uint8_t temp_mac[ETHERNET_ADDRESS_LENGTH];
-       struct in_addr temp_ip;
-       struct ether_header *ether = (struct ether_header *)pkt;
-
-       /*
-        * TODO: this is not yet implemented and requires BPF code for
-        * OmniOS, NetBSD and FreeBSD9.
-        */
-
-       /* swap the mac addresses */
-       memcpy(temp_mac, ether->ether_shost, ETHERNET_ADDRESS_LENGTH);
-       memcpy(ether->ether_shost, ether->ether_dhost, ETHERNET_ADDRESS_LENGTH);
-       memcpy(ether->ether_dhost, temp_mac, ETHERNET_ADDRESS_LENGTH);
-
-       /* swap ip addresses */
-       temp_ip = ep->ip.ip_src;
-       ep->ip.ip_src = ep->ip.ip_dst;
-       ep->ip.ip_dst = temp_ip;
-
-       ep->ip.ip_ttl = ep->ip.ip_ttl - 1;
-       ep->ip.ip_sum = 0;
-       ep->ip.ip_sum = checksum((uint16_t *)ep, IP_HDR_LEN);
-#endif /* BFD_BSD_FILTER */
-
-       if (sendto(bglobal.bg_echo, pkt, pkt_len, 0, ss, sslen) < 0) {
-               log_debug("echo-loopback: send failure: %s", strerror(errno));
-               return -1;
-       }
-
-       return 0;
-}
-
-static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd
-                                 __attribute__((__unused__)),
-                                 int fbit __attribute__((__unused__)))
-{
-#if 0 /* TODO: VxLAN support. */
-       struct bfd_raw_ctrl_pkt cp;
-       uint8_t vxlan_pkt[BFD_VXLAN_PKT_TOT_LEN];
-       uint8_t *pkt = vxlan_pkt;
-       struct sockaddr_in sin;
-       struct vxlan_hdr *vhdr;
-
-       memset(vxlan_pkt, 0, sizeof(vxlan_pkt));
-       memset(&cp, 0, sizeof(cp));
-
-       /* Construct VxLAN header information */
-       vhdr = (struct vxlan_hdr *)pkt;
-       vhdr->flags = htonl(0x08000000);
-       vhdr->vnid = htonl(bfd->vxlan_info.vnid << 8);
-       pkt += VXLAN_HDR_LEN;
-
-       /* Construct ethernet header information */
-       memcpy(pkt, bfd->vxlan_info.peer_dst_mac, ETHERNET_ADDRESS_LENGTH);
-       pkt = pkt + ETHERNET_ADDRESS_LENGTH;
-       memcpy(pkt, bfd->vxlan_info.local_dst_mac, ETHERNET_ADDRESS_LENGTH);
-       pkt = pkt + ETHERNET_ADDRESS_LENGTH;
-       pkt[0] = ETH_P_IP / 256;
-       pkt[1] = ETH_P_IP % 256;
-       pkt += 2;
-
-       /* Construct IP header information */
-       cp.ip.version = 4;
-       cp.ip.ihl = 5;
-       cp.ip.tos = 0;
-       cp.ip.tot_len = htons(IP_CTRL_PKT_LEN);
-       cp.ip.id = ptm_bfd_gen_IP_ID(bfd);
-       cp.ip.frag_off = 0;
-       cp.ip.ttl = BFD_TTL_VAL;
-       cp.ip.protocol = IPPROTO_UDP;
-       cp.ip.daddr = bfd->vxlan_info.peer_dst_ip.s_addr;
-       cp.ip.saddr = bfd->vxlan_info.local_dst_ip.s_addr;
-       cp.ip.check = checksum((uint16_t *)&cp.ip, IP_HDR_LEN);
-
-       /* Construct UDP header information */
-       cp.udp.source = htons(BFD_DEFDESTPORT);
-       cp.udp.dest = htons(BFD_DEFDESTPORT);
-       cp.udp.len = htons(UDP_CTRL_PKT_LEN);
-
-       /* Construct BFD control packet information */
-       cp.data.diag = bfd->local_diag;
-       BFD_SETVER(cp.data.diag, BFD_VERSION);
-       BFD_SETSTATE(cp.data.flags, bfd->ses_state);
-       BFD_SETDEMANDBIT(cp.data.flags, BFD_DEF_DEMAND);
-       BFD_SETPBIT(cp.data.flags, bfd->polling);
-       BFD_SETFBIT(cp.data.flags, fbit);
-       cp.data.detect_mult = bfd->detect_mult;
-       cp.data.len = BFD_PKT_LEN;
-       cp.data.discrs.my_discr = htonl(bfd->discrs.my_discr);
-       cp.data.discrs.remote_discr = htonl(bfd->discrs.remote_discr);
-       cp.data.timers.desired_min_tx = htonl(bfd->timers.desired_min_tx);
-       cp.data.timers.required_min_rx = htonl(bfd->timers.required_min_rx);
-       cp.data.timers.required_min_echo = htonl(bfd->timers.required_min_echo);
-
-       cp.udp.check =
-               udp4_checksum(&cp.ip, (uint8_t *)&cp.udp, UDP_CTRL_PKT_LEN);
-
-       memcpy(pkt, &cp, sizeof(cp));
-       sin.sin_family = AF_INET;
-       sin.sin_addr = bfd->shop.peer.sa_sin.sin_addr;
-       sin.sin_port = htons(4789);
-
-       if (sendto(bfd->sock, vxlan_pkt, BFD_VXLAN_PKT_TOT_LEN, 0,
-                  (struct sockaddr *)&sin, sizeof(struct sockaddr_in))
-           < 0) {
-               ERRLOG("Error sending vxlan bfd pkt: %s", strerror(errno));
-       } else {
-               bfd->stats.tx_ctrl_pkt++;
-       }
-#endif
-}
-
 static int ptm_bfd_process_echo_pkt(int s)
 {
-       uint32_t my_discr = 0;
-       struct sockaddr_storage ss;
-       socklen_t sslen = sizeof(ss);
-       uint8_t rx_pkt[BFD_RX_BUF_LEN];
-       ssize_t pkt_len = sizeof(rx_pkt);
        struct bfd_session *bfd;
-#ifdef BFD_LINUX
-       struct bfd_raw_echo_pkt *ep;
-
-       /*
-        * valgrind: memset() ss so valgrind doesn't complain about
-        * uninitialized memory.
-        */
-       memset(&ss, 0, sizeof(ss));
-       pkt_len = recvfrom(s, rx_pkt, sizeof(rx_pkt), MSG_DONTWAIT,
-                          (struct sockaddr *)&ss, &sslen);
-       if (pkt_len <= 0) {
-               if (errno != EAGAIN)
-                       log_error("echo-packet: read failure: %s",
-                                 strerror(errno));
-
-               return -1;
-       }
-
-       /* Check if we have at least the basic headers to send back. */
-       if (pkt_len < BFD_ECHO_PKT_TOT_LEN) {
-               log_debug("echo-packet: too short (got %ld, expected %d)",
-                         pkt_len, BFD_ECHO_PKT_TOT_LEN);
-               return -1;
-       }
-
-       ep = (struct bfd_raw_echo_pkt *)(rx_pkt + ETH_HDR_LEN);
-       /* if TTL = 255, assume that the received echo packet has
-        * to be looped back
-        */
-       if (ep->ip.ttl == BFD_TTL_VAL)
-               return ptm_bfd_echo_loopback(rx_pkt, pkt_len,
-                                            (struct sockaddr *)&ss,
-                                            sizeof(struct sockaddr_ll));
-
-       my_discr = ntohl(ep->data.my_discr);
-       if (ep->data.my_discr == 0) {
-               log_debug("echo-packet: 'my discriminator' is zero");
-               return -1;
-       }
-#endif /* BFD_LINUX */
-#ifdef BFD_BSD
-       int rv;
-       uint8_t ttl;
-
-       /*
-        * bsd_echo_sock_read() already treats invalid TTL values and
-        * zeroed discriminators.
-        */
-       rv = bsd_echo_sock_read(s, rx_pkt, &pkt_len, &ss, &sslen, &ttl,
-                               &my_discr);
-       if (rv == -1)
-               return -1;
+       uint32_t my_discr = 0;
+       uint8_t ttl = 0;
 
-       if (ttl == BFD_TTL_VAL)
-               return ptm_bfd_echo_loopback(rx_pkt, pkt_len,
-                                            (struct sockaddr *)&ss, sslen);
-#endif /* BFD_BSD */
+       /* Receive and parse echo packet. */
+       if (bp_bfd_echo_in(s, &ttl, &my_discr) == -1)
+               return 0;
 
        /* Your discriminator not zero - use it to find session */
        bfd = bfd_id_lookup(my_discr);
@@ -554,8 +186,8 @@ static int ptm_bfd_process_echo_pkt(int s)
        }
 
        if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) {
-               log_debug("echo-packet: echo disabled [%s]", my_discr,
-                         bs_to_string(bfd));
+               log_debug("echo-packet: echo disabled [%s] (id:%u)",
+                         bs_to_string(bfd), my_discr);
                return -1;
        }
 
@@ -574,14 +206,6 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit)
 {
        struct bfd_pkt cp;
 
-       /* if the BFD session is for VxLAN tunnel, then construct and
-        * send bfd raw packet
-        */
-       if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) {
-               ptm_bfd_vxlan_pkt_snd(bfd, fbit);
-               return;
-       }
-
        /* Set fields according to section 6.5.7 */
        cp.diag = bfd->local_diag;
        BFD_SETVER(cp.diag, BFD_VERSION);
@@ -605,98 +229,16 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit)
        }
        cp.timers.required_min_echo = htonl(bfd->timers.required_min_echo);
 
-       if (_ptm_bfd_send(bfd, false, NULL, &cp, BFD_PKT_LEN) != 0)
+       if (_ptm_bfd_send(bfd, NULL, &cp, BFD_PKT_LEN) != 0)
                return;
 
        bfd->stats.tx_ctrl_pkt++;
 }
 
-#if 0  /* TODO VxLAN Support */
-static struct bfd_pkt *
-ptm_bfd_process_vxlan_pkt(int s, ptm_sockevent_e se, void *udata, int *ifindex,
-                         struct sockaddr_in *sin,
-                         struct bfd_session_vxlan_info_t *vxlan_info,
-                         uint8_t *rx_pkt, int *mlen)
-{
-       struct sockaddr_ll sll;
-       uint32_t from_len = sizeof(struct sockaddr_ll);
-       struct bfd_raw_ctrl_pkt *cp;
-       uint8_t *pkt = rx_pkt;
-       struct iphdr *iph;
-       struct ethhdr *inner_ethh;
-
-       *mlen = recvfrom(s, rx_pkt, BFD_RX_BUF_LEN, MSG_DONTWAIT,
-                        (struct sockaddr *)&sll, &from_len);
-
-       if (*mlen < 0) {
-               if (errno != EAGAIN)
-                       ERRLOG("Error receiving from BFD Vxlan socket %d: %m",
-                              s);
-               return NULL;
-       }
-
-       iph = (struct iphdr *)(pkt + ETH_HDR_LEN);
-       pkt = pkt + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN;
-       vxlan_info->vnid = ntohl(*((int *)(pkt + 4)));
-       vxlan_info->vnid = vxlan_info->vnid >> 8;
-
-       pkt = pkt + VXLAN_HDR_LEN;
-       inner_ethh = (struct ethhdr *)pkt;
-
-       cp = (struct bfd_raw_ctrl_pkt *)(pkt + ETH_HDR_LEN);
-
-       /* Discard the non BFD packets */
-       if (ntohs(cp->udp.dest) != BFD_DEFDESTPORT)
-               return NULL;
-
-       *ifindex = sll.sll_ifindex;
-       sin->sin_addr.s_addr = iph->saddr;
-       sin->sin_port = ntohs(cp->udp.dest);
-
-       vxlan_info->local_dst_ip.s_addr = cp->ip.daddr;
-       memcpy(vxlan_info->local_dst_mac, inner_ethh->h_dest,
-              ETHERNET_ADDRESS_LENGTH);
-
-       return &cp->data;
-}
-#endif /* VxLAN */
-
-static bool
-ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd,
-                          struct bfd_session_vxlan_info *vxlan_info)
-{
-       if (bfd->vxlan_info.check_tnl_key && (vxlan_info->vnid != 0)) {
-               log_error("vxlan-packet: vnid not zero: %d", vxlan_info->vnid);
-               return false;
-       }
-
-       if (bfd->vxlan_info.local_dst_ip.s_addr
-           != vxlan_info->local_dst_ip.s_addr) {
-               log_error("vxlan-packet: wrong inner destination",
-                         inet_ntoa(vxlan_info->local_dst_ip));
-               return false;
-       }
-
-       if (memcmp(bfd->vxlan_info.local_dst_mac, vxlan_info->local_dst_mac,
-                  ETHERNET_ADDRESS_LENGTH)) {
-               log_error(
-                       "vxlan-packet: wrong inner mac: %02x:%02x:%02x:%02x:%02x:%02x",
-                       vxlan_info->local_dst_mac[0],
-                       vxlan_info->local_dst_mac[1],
-                       vxlan_info->local_dst_mac[2],
-                       vxlan_info->local_dst_mac[3],
-                       vxlan_info->local_dst_mac[4],
-                       vxlan_info->local_dst_mac[5]);
-               return false;
-       }
-
-       return true;
-}
-
-static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
-                            char *vrfname, size_t vrfnamelen,
-                            struct sockaddr_any *local,
-                            struct sockaddr_any *peer)
+ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
+                     char *port, size_t portlen, char *vrfname,
+                     size_t vrfnamelen, struct sockaddr_any *local,
+                     struct sockaddr_any *peer)
 {
        struct cmsghdr *cm;
        int ifindex;
@@ -706,9 +248,11 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
        struct iovec iov[1];
        uint8_t cmsgbuf[255];
 
+       port[0] = '\0';
+
        /* Prepare the recvmsg params. */
        iov[0].iov_base = msgbuf;
-       iov[0].iov_len = sizeof(msgbuf);
+       iov[0].iov_len = msgbuflen;
 
        memset(&msghdr, 0, sizeof(msghdr));
        msghdr.msg_name = &msgaddr;
@@ -739,16 +283,14 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
                switch (cm->cmsg_type) {
 #ifdef BFD_LINUX
                case IP_TTL: {
-                       uint32_t ttl;
-
-                       memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl));
-                       if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
-                               log_debug(
-                                       "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)",
-                                       satostr(peer), ttl, BFD_TTL_VAL,
-                                       msghdr.msg_flags);
+                       uint32_t ttlval;
+
+                       memcpy(&ttlval, CMSG_DATA(cm), sizeof(ttlval));
+                       if (ttlval > 255) {
+                               log_debug("ipv4-recv: invalid TTL: %u", ttlval);
                                return -1;
                        }
+                       *ttl = ttlval;
                        break;
                }
 
@@ -768,16 +310,7 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
 #endif /* BFD_LINUX */
 #ifdef BFD_BSD
                case IP_RECVTTL: {
-                       uint8_t ttl;
-
-                       memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl));
-                       if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
-                               log_debug(
-                                       "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)",
-                                       satostr(peer), ttl, BFD_TTL_VAL,
-                                       msghdr.msg_flags);
-                               return -1;
-                       }
+                       memcpy(ttl, CMSG_DATA(cm), sizeof(*ttl));
                        break;
                }
 
@@ -812,14 +345,16 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen,
        return mlen;
 }
 
-ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
-                     char *vrfname, size_t vrfnamelen,
-                     struct sockaddr_any *local, struct sockaddr_any *peer)
+ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
+                     char *port, size_t portlen, char *vrfname,
+                     size_t vrfnamelen, struct sockaddr_any *local,
+                     struct sockaddr_any *peer)
 {
        struct cmsghdr *cm;
        struct in6_pktinfo *pi6 = NULL;
        int ifindex = 0;
        ssize_t mlen;
+       uint32_t ttlval;
        struct sockaddr_in6 msgaddr6;
        struct msghdr msghdr6;
        struct iovec iov[1];
@@ -827,7 +362,7 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
 
        /* Prepare the recvmsg params. */
        iov[0].iov_base = msgbuf;
-       iov[0].iov_len = sizeof(msgbuf);
+       iov[0].iov_len = msgbuflen;
 
        memset(&msghdr6, 0, sizeof(msghdr6));
        msghdr6.msg_name = &msgaddr6;
@@ -840,7 +375,7 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
        mlen = recvmsg(sd, &msghdr6, MSG_DONTWAIT);
        if (mlen == -1) {
                if (errno != EAGAIN)
-                       log_error("ipv4-recv: recv failed: %s",
+                       log_error("ipv6-recv: recv failed: %s",
                                  strerror(errno));
 
                return -1;
@@ -856,14 +391,13 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
                        continue;
 
                if (cm->cmsg_type == IPV6_HOPLIMIT) {
-                       memcpy(&ttlval, CMSG_DATA(cm), 4);
-                       if ((is_mhop == false) && (ttlval != BFD_TTL_VAL)) {
-                               log_debug(
-                                       "ipv6-recv: invalid TTL from %s (expected %d, got %d flags %d)",
-                                       satostr(peer), ttlval, BFD_TTL_VAL,
-                                       msghdr6.msg_flags);
+                       memcpy(&ttlval, CMSG_DATA(cm), sizeof(ttlval));
+                       if (ttlval > 255) {
+                               log_debug("ipv6-recv: invalid TTL: %u", ttlval);
                                return -1;
                        }
+
+                       *ttl = ttlval;
                } else if (cm->cmsg_type == IPV6_PKTINFO) {
                        pi6 = (struct in6_pktinfo *)CMSG_DATA(cm);
                        if (pi6) {
@@ -888,28 +422,28 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen,
 static void bfd_sd_reschedule(int sd)
 {
        if (sd == bglobal.bg_shop) {
-               bglobal.bg_ev[0] = NULL;
+               THREAD_OFF(bglobal.bg_ev[0]);
                thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop,
                                &bglobal.bg_ev[0]);
        } else if (sd == bglobal.bg_mhop) {
-               bglobal.bg_ev[1] = NULL;
+               THREAD_OFF(bglobal.bg_ev[1]);
                thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop,
                                &bglobal.bg_ev[1]);
        } else if (sd == bglobal.bg_shop6) {
-               bglobal.bg_ev[2] = NULL;
+               THREAD_OFF(bglobal.bg_ev[2]);
                thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop6,
                                &bglobal.bg_ev[2]);
        } else if (sd == bglobal.bg_mhop6) {
-               bglobal.bg_ev[3] = NULL;
+               THREAD_OFF(bglobal.bg_ev[3]);
                thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop6,
                                &bglobal.bg_ev[3]);
        } else if (sd == bglobal.bg_echo) {
-               bglobal.bg_ev[4] = NULL;
+               THREAD_OFF(bglobal.bg_ev[4]);
                thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo,
                                &bglobal.bg_ev[4]);
-       } else if (sd == bglobal.bg_vxlan) {
-               bglobal.bg_ev[5] = NULL;
-               thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan,
+       } else if (sd == bglobal.bg_echov6) {
+               THREAD_OFF(bglobal.bg_ev[5]);
+               thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6,
                                &bglobal.bg_ev[5]);
        }
 }
@@ -955,18 +489,19 @@ int bfd_recv_cb(struct thread *t)
        int sd = THREAD_FD(t);
        struct bfd_session *bfd;
        struct bfd_pkt *cp;
-       bool is_mhop, is_vxlan;
+       bool is_mhop;
        ssize_t mlen = 0;
        uint32_t oldEchoXmt_TO, oldXmtTime;
+       uint8_t ttl;
        struct sockaddr_any local, peer;
        char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1];
-       struct bfd_session_vxlan_info vxlan_info;
+       uint8_t msgbuf[1516];
 
        /* Schedule next read. */
        bfd_sd_reschedule(sd);
 
        /* Handle echo packets. */
-       if (sd == bglobal.bg_echo) {
+       if (sd == bglobal.bg_echo || sd == bglobal.bg_echov6) {
                ptm_bfd_process_echo_pkt(sd);
                return 0;
        }
@@ -978,28 +513,18 @@ int bfd_recv_cb(struct thread *t)
        memset(&peer, 0, sizeof(peer));
 
        /* Handle control packets. */
-       is_mhop = is_vxlan = false;
+       is_mhop = false;
        if (sd == bglobal.bg_shop || sd == bglobal.bg_mhop) {
                is_mhop = sd == bglobal.bg_mhop;
-               mlen = bfd_recv_ipv4(sd, is_mhop, port, sizeof(port), vrfname,
-                                    sizeof(vrfname), &local, &peer);
+               mlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), &ttl, port,
+                                    sizeof(port), vrfname, sizeof(vrfname),
+                                    &local, &peer);
        } else if (sd == bglobal.bg_shop6 || sd == bglobal.bg_mhop6) {
                is_mhop = sd == bglobal.bg_mhop6;
-               mlen = bfd_recv_ipv6(sd, is_mhop, port, sizeof(port), vrfname,
-                                    sizeof(vrfname), &local, &peer);
+               mlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), &ttl, port,
+                                    sizeof(port), vrfname, sizeof(vrfname),
+                                    &local, &peer);
        }
-#if 0 /* TODO vxlan handling */
-       cp = ptm_bfd_process_vxlan_pkt(s, se, udata, &local_ifindex,
-                                      &sin, &vxlan_info, rx_pkt, &mlen);
-       if (!cp)
-               return -1;
-
-       is_vxlan = true;
-       /* keep in network-byte order */
-       peer.ip4_addr.s_addr = sin.sin_addr.s_addr;
-       peer.family = AF_INET;
-       strcpy(peer_addr, inet_ntoa(sin.sin_addr));
-#endif
 
        /* Implement RFC 5880 6.8.6 */
        if (mlen < BFD_PKT_LEN) {
@@ -1008,6 +533,13 @@ int bfd_recv_cb(struct thread *t)
                return 0;
        }
 
+       /* Validate packet TTL. */
+       if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
+               cp_debug(is_mhop, &peer, &local, port, vrfname,
+                        "invalid TTL: %d expected %d", ttl, BFD_TTL_VAL);
+               return 0;
+       }
+
        /*
         * Parse the control header for inconsistencies:
         * - Invalid version;
@@ -1047,10 +579,6 @@ int bfd_recv_cb(struct thread *t)
                return 0;
        }
 
-       /* Handle VxLAN cases. */
-       if (is_vxlan && !ptm_bfd_validate_vxlan_pkt(bfd, &vxlan_info))
-               return 0;
-
        bfd->stats.rx_ctrl_pkt++;
 
        /*
@@ -1058,10 +586,10 @@ int bfd_recv_cb(struct thread *t)
         * Single hop: set local address that received the packet.
         */
        if (is_mhop) {
-               if ((BFD_TTL_VAL - bfd->mh_ttl) > ttlval) {
+               if ((BFD_TTL_VAL - bfd->mh_ttl) > BFD_TTL_VAL) {
                        cp_debug(is_mhop, &peer, &local, port, vrfname,
                                 "exceeded max hop count (expected %d, got %d)",
-                                bfd->mh_ttl, ttlval);
+                                bfd->mh_ttl, BFD_TTL_VAL);
                        return 0;
                }
        } else if (bfd->local_ip.sa_sin.sin_family == AF_UNSPEC) {
@@ -1111,7 +639,7 @@ int bfd_recv_cb(struct thread *t)
        /* State switch from section 6.8.6 */
        if (BFD_GETSTATE(cp->flags) == PTM_BFD_ADM_DOWN) {
                if (bfd->ses_state != PTM_BFD_DOWN)
-                       ptm_bfd_ses_dn(bfd, BFD_DIAGNEIGHDOWN);
+                       ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN);
        } else {
                switch (bfd->ses_state) {
                case (PTM_BFD_DOWN):
@@ -1127,7 +655,7 @@ int bfd_recv_cb(struct thread *t)
                        break;
                case (PTM_BFD_UP):
                        if (BFD_GETSTATE(cp->flags) == PTM_BFD_DOWN)
-                               ptm_bfd_ses_dn(bfd, BFD_DIAGNEIGHDOWN);
+                               ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN);
                        break;
                }
        }
@@ -1209,6 +737,121 @@ int bfd_recv_cb(struct thread *t)
        return 0;
 }
 
+/*
+ * bp_bfd_echo_in: proccesses an BFD echo packet. On TTL == BFD_TTL_VAL
+ * the packet is looped back or returns the my discriminator ID along
+ * with the TTL.
+ *
+ * Returns -1 on error or loopback or 0 on success.
+ */
+int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr)
+{
+       struct bfd_echo_pkt *bep;
+       ssize_t rlen;
+       struct sockaddr_any local, peer;
+       char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1];
+       uint8_t msgbuf[1516];
+
+       if (sd == bglobal.bg_echo)
+               rlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), ttl, port,
+                                    sizeof(port), vrfname, sizeof(vrfname),
+                                    &local, &peer);
+       else
+               rlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), ttl, port,
+                                    sizeof(port), vrfname, sizeof(vrfname),
+                                    &local, &peer);
+
+       /* Short packet, better not risk reading it. */
+       if (rlen < (ssize_t)sizeof(*bep)) {
+               cp_debug(false, &peer, &local, port, vrfname,
+                        "small echo packet");
+               return -1;
+       }
+
+       /* Test for loopback. */
+       if (*ttl == BFD_TTL_VAL) {
+               bp_udp_send(sd, *ttl - 1, msgbuf, rlen,
+                           (struct sockaddr *)&peer,
+                           (sd == bglobal.bg_echo) ? sizeof(peer.sa_sin)
+                                                   : sizeof(peer.sa_sin6));
+               return -1;
+       }
+
+       /* Read my discriminator from BFD Echo packet. */
+       bep = (struct bfd_echo_pkt *)msgbuf;
+       *my_discr = ntohl(bep->my_discr);
+       if (*my_discr == 0) {
+               cp_debug(false, &peer, &local, port, vrfname,
+                        "invalid echo packet discriminator (zero)");
+               return -1;
+       }
+
+       return 0;
+}
+
+int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen,
+               struct sockaddr *to, socklen_t tolen)
+{
+       struct cmsghdr *cmsg;
+       ssize_t wlen;
+       int ttlval = ttl;
+       bool is_ipv6 = to->sa_family == AF_INET6;
+       struct msghdr msg;
+       struct iovec iov[1];
+       uint8_t msgctl[255];
+
+       /* Prepare message data. */
+       iov[0].iov_base = data;
+       iov[0].iov_len = datalen;
+
+       memset(&msg, 0, sizeof(msg));
+       memset(msgctl, 0, sizeof(msgctl));
+       msg.msg_name = to;
+       msg.msg_namelen = tolen;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       /* Prepare the packet TTL information. */
+       if (ttl > 0) {
+               /* Use ancillary data. */
+               msg.msg_control = msgctl;
+               msg.msg_controllen = CMSG_LEN(sizeof(ttlval));
+
+               /* Configure the ancillary data. */
+               cmsg = CMSG_FIRSTHDR(&msg);
+               cmsg->cmsg_len = CMSG_LEN(sizeof(ttlval));
+               if (is_ipv6) {
+                       cmsg->cmsg_level = IPPROTO_IPV6;
+                       cmsg->cmsg_type = IPV6_HOPLIMIT;
+               } else {
+#if BFD_LINUX
+                       cmsg->cmsg_level = IPPROTO_IP;
+                       cmsg->cmsg_type = IP_TTL;
+#else
+                       /* FreeBSD does not support TTL in ancillary data. */
+                       msg.msg_control = NULL;
+                       msg.msg_controllen = 0;
+
+                       bp_set_ttl(sd, ttl);
+#endif /* BFD_BSD */
+               }
+               memcpy(CMSG_DATA(cmsg), &ttlval, sizeof(ttlval));
+       }
+
+       /* Send echo back. */
+       wlen = sendmsg(sd, &msg, 0);
+       if (wlen <= 0) {
+               log_debug("udp-send: loopback failure: (%d) %s", errno, strerror(errno));
+               return -1;
+       } else if (wlen < (ssize_t)datalen) {
+               log_debug("udp-send: partial send: %ld expected %ld", wlen,
+                         datalen);
+               return -1;
+       }
+
+       return 0;
+}
+
 
 /*
  * Sockets creation.
@@ -1218,10 +861,12 @@ int bfd_recv_cb(struct thread *t)
 /*
  * IPv4 sockets
  */
-int bp_set_ttl(int sd)
+int bp_set_ttl(int sd, uint8_t value)
 {
-       if (setsockopt(sd, IPPROTO_IP, IP_TTL, &ttlval, sizeof(ttlval)) == -1) {
-               log_warning("%s: setsockopt(IP_TTL): %s", __func__,
+       int ttl = value;
+
+       if (setsockopt(sd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) {
+               log_warning("set-ttl: setsockopt(IP_TTL, %d): %s", value,
                            strerror(errno));
                return -1;
        }
@@ -1229,10 +874,12 @@ int bp_set_ttl(int sd)
        return 0;
 }
 
-int bp_set_tos(int sd)
+int bp_set_tos(int sd, uint8_t value)
 {
-       if (setsockopt(sd, IPPROTO_IP, IP_TOS, &tosval, sizeof(tosval)) == -1) {
-               log_warning("%s: setsockopt(IP_TOS): %s", __func__,
+       int tos = value;
+
+       if (setsockopt(sd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1) {
+               log_warning("set-tos: setsockopt(IP_TOS, %d): %s", value,
                            strerror(errno));
                return -1;
        }
@@ -1242,20 +889,23 @@ int bp_set_tos(int sd)
 
 static void bp_set_ipopts(int sd)
 {
-       if (bp_set_ttl(sd) != 0)
-               log_fatal("%s: TTL configuration failed", __func__);
+       int rcvttl = BFD_RCV_TTL_VAL;
+
+       if (bp_set_ttl(sd, BFD_TTL_VAL) != 0)
+               log_fatal("set-ipopts: TTL configuration failed");
 
        if (setsockopt(sd, IPPROTO_IP, IP_RECVTTL, &rcvttl, sizeof(rcvttl))
            == -1)
-               log_fatal("%s: setsockopt(IP_RECVTTL): %s", __func__,
+               log_fatal("set-ipopts: setsockopt(IP_RECVTTL, %d): %s", rcvttl,
                          strerror(errno));
 
 #ifdef BFD_LINUX
        int pktinfo = BFD_PKT_INFO_VAL;
+
        /* Figure out address and interface to do the peer matching. */
        if (setsockopt(sd, IPPROTO_IP, IP_PKTINFO, &pktinfo, sizeof(pktinfo))
            == -1)
-               log_fatal("%s: setsockopt(IP_PKTINFO): %s", __func__,
+               log_fatal("set-ipopts: setsockopt(IP_PKTINFO, %d): %s", pktinfo,
                          strerror(errno));
 #endif /* BFD_LINUX */
 #ifdef BFD_BSD
@@ -1263,12 +913,12 @@ static void bp_set_ipopts(int sd)
 
        /* Find out our address for peer matching. */
        if (setsockopt(sd, IPPROTO_IP, IP_RECVDSTADDR, &yes, sizeof(yes)) == -1)
-               log_fatal("%s: setsockopt(IP_RECVDSTADDR): %s", __func__,
+               log_fatal("set-ipopts: setsockopt(IP_RECVDSTADDR, %d): %s", yes,
                          strerror(errno));
 
        /* Find out interface where the packet came in. */
        if (setsockopt_ifindex(AF_INET, sd, yes) == -1)
-               log_fatal("%s: setsockopt_ipv4_ifindex: %s", __func__,
+               log_fatal("set-ipopts: setsockopt_ipv4_ifindex(%d): %s", yes,
                          strerror(errno));
 #endif /* BFD_BSD */
 }
@@ -1282,7 +932,7 @@ static void bp_bind_ip(int sd, uint16_t port)
        sin.sin_addr.s_addr = htonl(INADDR_ANY);
        sin.sin_port = htons(port);
        if (bind(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
-               log_fatal("%s: bind: %s", __func__, strerror(errno));
+               log_fatal("bind-ip: bind: %s", strerror(errno));
 }
 
 int bp_udp_shop(void)
@@ -1291,7 +941,7 @@ int bp_udp_shop(void)
 
        sd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
        if (sd == -1)
-               log_fatal("%s: socket: %s", __func__, strerror(errno));
+               log_fatal("udp-shop: socket: %s", strerror(errno));
 
        bp_set_ipopts(sd);
        bp_bind_ip(sd, BFD_DEFDESTPORT);
@@ -1305,7 +955,7 @@ int bp_udp_mhop(void)
 
        sd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
        if (sd == -1)
-               log_fatal("%s: socket: %s", __func__, strerror(errno));
+               log_fatal("udp-mhop: socket: %s", strerror(errno));
 
        bp_set_ipopts(sd);
        bp_bind_ip(sd, BFD_DEF_MHOP_DEST_PORT);
@@ -1326,22 +976,19 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc)
                return -1;
        }
 
-       if (!bpc->bpc_has_vxlan) {
-               /* Set TTL to 255 for all transmitted packets */
-               if (bp_set_ttl(sd) != 0) {
-                       close(sd);
-                       return -1;
-               }
+       /* Set TTL to 255 for all transmitted packets */
+       if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) {
+               close(sd);
+               return -1;
        }
 
        /* Set TOS to CS6 for all transmitted packets */
-       if (bp_set_tos(sd) != 0) {
+       if (bp_set_tos(sd, BFD_TOS_VAL) != 0) {
                close(sd);
                return -1;
        }
 
-       /* dont bind-to-device incase of vxlan */
-       if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) {
+       if (bpc->bpc_has_localif) {
                if (bp_bind_dev(sd, bpc->bpc_localif) != 0) {
                        close(sd);
                        return -1;
@@ -1360,7 +1007,7 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc)
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
        sin.sin_len = sizeof(sin);
 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
-       if (bpc->bpc_mhop || bpc->bpc_has_vxlan)
+       if (bpc->bpc_mhop)
                sin.sin_addr = bpc->bpc_local.sa_sin.sin_addr;
        else
                sin.sin_addr.s_addr = INADDR_ANY;
@@ -1400,16 +1047,14 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc)
                return -1;
        }
 
-       if (!bpc->bpc_has_vxlan) {
-               /* Set TTL to 255 for all transmitted packets */
-               if (bp_set_ttlv6(sd) != 0) {
-                       close(sd);
-                       return -1;
-               }
+       /* Set TTL to 255 for all transmitted packets */
+       if (bp_set_ttlv6(sd, BFD_TTL_VAL) != 0) {
+               close(sd);
+               return -1;
        }
 
        /* Set TOS to CS6 for all transmitted packets */
-       if (bp_set_tosv6(sd) != 0) {
+       if (bp_set_tosv6(sd, BFD_TOS_VAL) != 0) {
                close(sd);
                return -1;
        }
@@ -1454,24 +1099,27 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc)
        return sd;
 }
 
-int bp_set_ttlv6(int sd)
+int bp_set_ttlv6(int sd, uint8_t value)
 {
-       if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttlval,
-                      sizeof(ttlval))
+       int ttl = value;
+
+       if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl))
            == -1) {
-               log_warning("%s: setsockopt(IPV6_UNICAST_HOPS): %s", __func__,
-                           strerror(errno));
+               log_warning("set-ttlv6: setsockopt(IPV6_UNICAST_HOPS, %d): %s",
+                           value, strerror(errno));
                return -1;
        }
 
        return 0;
 }
 
-int bp_set_tosv6(int sd)
+int bp_set_tosv6(int sd, uint8_t value)
 {
-       if (setsockopt(sd, IPPROTO_IPV6, IPV6_TCLASS, &tosval, sizeof(tosval))
+       int tos = value;
+
+       if (setsockopt(sd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos))
            == -1) {
-               log_warning("%s: setsockopt(IPV6_TCLASS): %s", __func__,
+               log_warning("set-tosv6: setsockopt(IPV6_TCLASS, %d): %s", value,
                            strerror(errno));
                return -1;
        }
@@ -1481,28 +1129,26 @@ int bp_set_tosv6(int sd)
 
 static void bp_set_ipv6opts(int sd)
 {
-       static int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL;
-       static int ipv6_only = BFD_IPV6_ONLY_VAL;
+       int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL;
+       int ipv6_only = BFD_IPV6_ONLY_VAL;
 
-       if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttlval,
-                      sizeof(ttlval))
-           == -1)
-               log_fatal("%s: setsockopt(IPV6_UNICAST_HOPS): %s", __func__,
-                         strerror(errno));
+       if (bp_set_ttlv6(sd, BFD_TTL_VAL) == -1)
+               log_fatal("set-ipv6opts: setsockopt(IPV6_UNICAST_HOPS, %d): %s",
+                         BFD_TTL_VAL, strerror(errno));
 
-       if (setsockopt_ipv6_hoplimit(sd, rcvttl) == -1)
-               log_fatal("%s: setsockopt(IPV6_HOPLIMIT): %s", __func__,
-                         strerror(errno));
+       if (setsockopt_ipv6_hoplimit(sd, BFD_RCV_TTL_VAL) == -1)
+               log_fatal("set-ipv6opts: setsockopt(IPV6_HOPLIMIT, %d): %s",
+                         BFD_RCV_TTL_VAL, strerror(errno));
 
        if (setsockopt_ipv6_pktinfo(sd, ipv6_pktinfo) == -1)
-               log_fatal("%s: setsockopt(IPV6_PKTINFO): %s", __func__,
-                         strerror(errno));
+               log_fatal("set-ipv6opts: setsockopt(IPV6_PKTINFO, %d): %s",
+                         ipv6_pktinfo, strerror(errno));
 
        if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6_only,
                       sizeof(ipv6_only))
            == -1)
-               log_fatal("%s: setsockopt(IPV6_V6ONLY): %s", __func__,
-                         strerror(errno));
+               log_fatal("set-ipv6opts: setsockopt(IPV6_V6ONLY, %d): %s",
+                         ipv6_only, strerror(errno));
 }
 
 static void bp_bind_ipv6(int sd, uint16_t port)
@@ -1517,7 +1163,7 @@ static void bp_bind_ipv6(int sd, uint16_t port)
        sin6.sin6_len = sizeof(sin6);
 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
        if (bind(sd, (struct sockaddr *)&sin6, sizeof(sin6)) == -1)
-               log_fatal("%s: bind: %s", __func__, strerror(errno));
+               log_fatal("bind-ipv6: bind: %s", strerror(errno));
 }
 
 int bp_udp6_shop(void)
@@ -1526,7 +1172,7 @@ int bp_udp6_shop(void)
 
        sd = socket(AF_INET6, SOCK_DGRAM, PF_UNSPEC);
        if (sd == -1)
-               log_fatal("%s: socket: %s", __func__, strerror(errno));
+               log_fatal("udp6-shop: socket: %s", strerror(errno));
 
        bp_set_ipv6opts(sd);
        bp_bind_ipv6(sd, BFD_DEFDESTPORT);
@@ -1540,10 +1186,38 @@ int bp_udp6_mhop(void)
 
        sd = socket(AF_INET6, SOCK_DGRAM, PF_UNSPEC);
        if (sd == -1)
-               log_fatal("%s: socket: %s", __func__, strerror(errno));
+               log_fatal("udp6-mhop: socket: %s", strerror(errno));
 
        bp_set_ipv6opts(sd);
        bp_bind_ipv6(sd, BFD_DEF_MHOP_DEST_PORT);
 
        return sd;
 }
+
+int bp_echo_socket(void)
+{
+       int s;
+
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       if (s == -1)
+               log_fatal("echo-socket: socket: %s", strerror(errno));
+
+       bp_set_ipopts(s);
+       bp_bind_ip(s, BFD_DEF_ECHO_PORT);
+
+       return s;
+}
+
+int bp_echov6_socket(void)
+{
+       int s;
+
+       s = socket(AF_INET6, SOCK_DGRAM, 0);
+       if (s == -1)
+               log_fatal("echov6-socket: socket: %s", strerror(errno));
+
+       bp_set_ipv6opts(s);
+       bp_bind_ipv6(s, BFD_DEF_ECHO_PORT);
+
+       return s;
+}
index 940efd161447bbcb46fb46c83d1795478934e88f..0da1ca8df6c7e14cbe70262f8a7e112eefcd165a 100644 (file)
@@ -66,9 +66,6 @@ struct bfd_peer_cfg {
        bool bpc_has_label;
        char bpc_label[MAXNAMELEN];
 
-       bool bpc_has_vxlan;
-       unsigned int bpc_vxlan;
-
        bool bpc_has_localif;
        char bpc_localif[MAXNAMELEN + 1];
 
index 144619088d3a3ca733cb01bbaa7b087825611499..250f8d21c0d30aaf5ed77b3d0871fa627d746b3b 100644 (file)
@@ -90,7 +90,6 @@ static void sigterm_handler(void)
        socket_close(&bglobal.bg_mhop);
        socket_close(&bglobal.bg_shop6);
        socket_close(&bglobal.bg_mhop6);
-       socket_close(&bglobal.bg_vxlan);
 
        /* Terminate and free() FRR related memory. */
        frr_fini();
@@ -131,17 +130,22 @@ static struct option longopts[] = {
 struct bfd_global bglobal;
 
 struct bfd_diag_str_list diag_list[] = {
-       {.str = "NeighDown", .type = BFD_DIAGNEIGHDOWN},
-       {.str = "DetectTime", .type = BFD_DIAGDETECTTIME},
-       {.str = "AdminDown", .type = BFD_DIAGADMINDOWN},
+       {.str = "control-expired", .type = BD_CONTROL_EXPIRED},
+       {.str = "echo-failed", .type = BD_ECHO_FAILED},
+       {.str = "neighbor-down", .type = BD_NEIGHBOR_DOWN},
+       {.str = "forwarding-reset", .type = BD_FORWARDING_RESET},
+       {.str = "path-down", .type = BD_PATH_DOWN},
+       {.str = "concatenated-path-down", .type = BD_CONCATPATH_DOWN},
+       {.str = "administratively-down", .type = BD_ADMIN_DOWN},
+       {.str = "reverse-concat-path-down", .type = BD_REVCONCATPATH_DOWN},
        {.str = NULL},
 };
 
 struct bfd_state_str_list state_list[] = {
-       {.str = "AdminDown", .type = PTM_BFD_ADM_DOWN},
-       {.str = "Down", .type = PTM_BFD_DOWN},
-       {.str = "Init", .type = PTM_BFD_INIT},
-       {.str = "Up", .type = PTM_BFD_UP},
+       {.str = "admin-down", .type = PTM_BFD_ADM_DOWN},
+       {.str = "down", .type = PTM_BFD_DOWN},
+       {.str = "init", .type = PTM_BFD_INIT},
+       {.str = "up", .type = PTM_BFD_UP},
        {.str = NULL},
 };
 
@@ -154,8 +158,8 @@ static void bg_init(void)
        bglobal.bg_mhop = bp_udp_mhop();
        bglobal.bg_shop6 = bp_udp6_shop();
        bglobal.bg_mhop6 = bp_udp6_mhop();
-       bglobal.bg_echo = ptm_bfd_echo_sock_init();
-       bglobal.bg_vxlan = ptm_bfd_vxlan_sock_init();
+       bglobal.bg_echo = bp_echo_socket();
+       bglobal.bg_echov6 = bp_echov6_socket();
 }
 
 int main(int argc, char *argv[])
@@ -216,10 +220,8 @@ int main(int argc, char *argv[])
                        &bglobal.bg_ev[3]);
        thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo,
                        &bglobal.bg_ev[4]);
-#if 0 /* TODO VxLAN support. */
-       thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan,
+       thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6,
                        &bglobal.bg_ev[5]);
-#endif
        thread_add_read(master, control_accept, NULL, bglobal.bg_csock,
                        &bglobal.bg_csockev);
 
index ae6081f01ad360f18c50dff55e06eddaf2f38b35..1c6d03195c8a5754f99fe9f5a4f63e38357bb220 100644 (file)
@@ -827,7 +827,7 @@ DEFPY(bfd_show_peers_counters, bfd_show_peers_counters_cmd,
  * Configuration rules:
  *
  * Single hop:
- * peer + (optional vxlan or interface name)
+ * peer + (interface name)
  *
  * Multi hop:
  * peer + local + (optional vrf)
@@ -896,23 +896,6 @@ static int bfd_configure_peer(struct bfd_peer_cfg *bpc, bool mhop,
 
        bpc->bpc_mhop = mhop;
 
-#if 0
-       /* Handle VxLAN configuration. */
-       if (vxlan >= 0) {
-               if (vxlan > ((1 << 24) - 1)) {
-                       snprintf(ebuf, ebuflen, "invalid VxLAN %d", vxlan);
-                       return -1;
-               }
-               if (bpc->bpc_mhop) {
-                       snprintf(ebuf, ebuflen,
-                                "multihop doesn't accept VxLAN");
-                       return -1;
-               }
-
-               bpc->bpc_vxlan = vxlan;
-       }
-#endif /* VxLAN */
-
        /* Handle interface specification configuration. */
        if (ifname) {
                if (bpc->bpc_mhop) {
index 34a3a1a801e22268954488f14553221ae44d6ac7..e0fb340e30e3087bd6fdb935b2bd42380f6d0f93 100644 (file)
 
 #include "bfd.h"
 
-/*
- * Prototypes
- */
-static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen);
-
 /*
  * Definitions.
  */
-static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen)
-{
-       const struct sockaddr *sa = sv;
-       const struct sockaddr_in *sin = sv;
-       const struct sockaddr_in6 *sin6 = sv;
-       int unknown = 1;
-
-       switch (sa->sa_family) {
-       case AF_INET:
-               if (inet_ntop(AF_INET, &sin->sin_addr, buf, buflen) != NULL)
-                       unknown = 0;
-               break;
-
-       case AF_INET6:
-               if (inet_ntop(AF_INET6, &sin6->sin6_addr, buf, buflen) != NULL)
-                       unknown = 0;
-               break;
-       }
-       if (unknown == 0)
-               return buf;
-
-       snprintf(buf, buflen, "unknown (af=%d)", sa->sa_family);
-       return buf;
-}
-
 int ptm_bfd_fetch_ifindex(const char *ifname)
 {
        return if_nametoindex(ifname);
@@ -129,133 +99,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen)
                            __LINE__);
 }
 
-int ptm_bfd_echo_sock_init(void)
-{
-       int s, ttl, yes = 1;
-       struct sockaddr_in sin;
-
-       s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
-       if (s == -1) {
-               log_error("echo-socket: creation failed: %s", strerror(errno));
-               return -1;
-       }
-
-       memset(&sin, 0, sizeof(sin));
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-       /* OmniOS doesn't have this field, but uses this code. */
-       sin.sin_len = sizeof(sin);
-#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
-       sin.sin_family = AF_INET;
-       sin.sin_port = htons(3785);
-       if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
-               log_error("echo-socket: bind failure: %s", strerror(errno));
-               close(s);
-               return -1;
-       }
-
-       if (setsockopt(s, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) == -1) {
-               log_error("echo-socket: setsockopt(IP_RECVTTL): %s",
-                         strerror(errno));
-               close(s);
-               return -1;
-       }
-
-       ttl = BFD_TTL_VAL;
-       if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) {
-               log_error("echo-socket: setsockopt(IP_TTL): %s",
-                         strerror(errno));
-               close(s);
-               return -1;
-       }
-
-       return s;
-}
-
-ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen,
-                          struct sockaddr_storage *ss, socklen_t *sslen,
-                          uint8_t *ttl, uint32_t *id)
-{
-       struct cmsghdr *cmsg;
-       struct bfd_echo_pkt *bep;
-       ssize_t readlen;
-       struct iovec iov;
-       struct msghdr msg;
-       uint8_t msgctl[255];
-       char errbuf[255];
-
-       /* Prepare socket read. */
-       memset(ss, 0, sizeof(*ss));
-       memset(&msg, 0, sizeof(msg));
-       iov.iov_base = buf;
-       iov.iov_len = *buflen;
-       msg.msg_iov = &iov;
-       msg.msg_iovlen = 1;
-       msg.msg_control = msgctl;
-       msg.msg_controllen = sizeof(msgctl);
-       msg.msg_name = ss;
-       msg.msg_namelen = *sslen;
-
-       /* Read the socket and treat errors. */
-       readlen = recvmsg(sd, &msg, 0);
-       if (readlen == 0) {
-               log_error("%s: recvmsg: socket closed", __func__);
-               return -1;
-       }
-       if (readlen == -1) {
-               if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
-                       return -1;
-
-               log_error("%s: recvmsg: (%d) %s", __func__, errno,
-                         strerror(errno));
-               return -1;
-       }
-       /* Short packet, better not risk reading it. */
-       if (readlen < (ssize_t)sizeof(*bep)) {
-               log_warning("%s: short packet (%ld of %d) from %s", __func__,
-                           readlen, sizeof(*bep),
-                           sockaddr_to_string(ss, errbuf, sizeof(errbuf)));
-               return -1;
-       }
-       *buflen = readlen;
-
-       /* Read TTL information. */
-       *ttl = 0;
-       for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
-            cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-               if (cmsg->cmsg_level != IPPROTO_IP)
-                       continue;
-               if (cmsg->cmsg_type != IP_RECVTTL)
-                       continue;
-
-               *ttl = *(uint8_t *)CMSG_DATA(cmsg);
-               break;
-       }
-       if (*ttl == 0) {
-               log_debug("%s: failed to read TTL", __func__);
-               return -1;
-       }
-
-       /* Read my discriminator from BFD Echo packet. */
-       bep = (struct bfd_echo_pkt *)buf;
-       *id = bep->my_discr;
-       if (*id == 0) {
-               log_debug("%s: invalid packet discriminator from: %s", __func__,
-                         sockaddr_to_string(ss, errbuf, sizeof(errbuf)));
-               return -1;
-       }
-
-       /* Set the returned sockaddr new length. */
-       *sslen = msg.msg_namelen;
-
-       return 0;
-}
-
-int ptm_bfd_vxlan_sock_init(void)
-{
-       /* TODO: not supported yet. */
-       return -1;
-}
-
 int bp_bind_dev(int sd, const char *dev)
 {
        /*
@@ -266,25 +109,4 @@ int bp_bind_dev(int sd, const char *dev)
        return 0;
 }
 
-uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len)
-{
-       char *ptr;
-       struct udp_psuedo_header pudp_hdr;
-       uint16_t csum;
-
-       pudp_hdr.saddr = ip->ip_src.s_addr;
-       pudp_hdr.daddr = ip->ip_dst.s_addr;
-       pudp_hdr.reserved = 0;
-       pudp_hdr.protocol = ip->ip_p;
-       pudp_hdr.len = htons(len);
-
-       ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len);
-       memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN);
-       memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len);
-
-       csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len);
-       XFREE(MTYPE_BFDD_TMP, ptr);
-       return csum;
-}
-
 #endif /* BFD_BSD */
index 0e0d8b7d706ff0238c6b89db70c9a94e4663beba..06089780c6ba8c163d2e8db142f7076c5607cc02 100644 (file)
@@ -218,10 +218,6 @@ static int parse_peer_config(struct json_object *jo, struct bfd_peer_cfg *bpc)
                        } else {
                                log_debug("\tlocal-interface: %s", sval);
                        }
-               } else if (strcmp(key, "vxlan") == 0) {
-                       bpc->bpc_vxlan = json_object_get_int64(jo_val);
-                       bpc->bpc_has_vxlan = true;
-                       log_debug("\tvxlan: %ld", bpc->bpc_vxlan);
                } else if (strcmp(key, "vrf-name") == 0) {
                        bpc->bpc_has_vrfname = true;
                        sval = json_object_get_string(jo_val);
index ba12f5b4e80066dc8086cb1ee019518824d3cb2d..63f64077ebd40da8ff35fc5f695e2c5f412a96e9 100644 (file)
@@ -49,8 +49,7 @@ void bfd_recvtimer_update(struct bfd_session *bs)
 #endif /* BFD_EVENT_DEBUG */
 
        /* Remove previous schedule if any. */
-       if (bs->recvtimer_ev)
-               bfd_recvtimer_delete(bs);
+       bfd_recvtimer_delete(bs);
 
        thread_add_timer_tv(master, bfd_recvtimer_cb, bs, &tv,
                            &bs->recvtimer_ev);
@@ -70,8 +69,7 @@ void bfd_echo_recvtimer_update(struct bfd_session *bs)
 #endif /* BFD_EVENT_DEBUG */
 
        /* Remove previous schedule if any. */
-       if (bs->echo_recvtimer_ev)
-               bfd_echo_recvtimer_delete(bs);
+       bfd_echo_recvtimer_delete(bs);
 
        thread_add_timer_tv(master, bfd_echo_recvtimer_cb, bs, &tv,
                            &bs->echo_recvtimer_ev);
@@ -91,8 +89,7 @@ void bfd_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
 #endif /* BFD_EVENT_DEBUG */
 
        /* Remove previous schedule if any. */
-       if (bs->xmttimer_ev)
-               bfd_xmttimer_delete(bs);
+       bfd_xmttimer_delete(bs);
 
        thread_add_timer_tv(master, bfd_xmt_cb, bs, &tv, &bs->xmttimer_ev);
 }
@@ -111,8 +108,7 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
 #endif /* BFD_EVENT_DEBUG */
 
        /* Remove previous schedule if any. */
-       if (bs->echo_xmttimer_ev)
-               bfd_echo_xmttimer_delete(bs);
+       bfd_echo_xmttimer_delete(bs);
 
        thread_add_timer_tv(master, bfd_echo_xmt_cb, bs, &tv,
                            &bs->echo_xmttimer_ev);
@@ -120,36 +116,20 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter)
 
 void bfd_recvtimer_delete(struct bfd_session *bs)
 {
-       if (bs->recvtimer_ev == NULL)
-               return;
-
-       thread_cancel(bs->recvtimer_ev);
-       bs->recvtimer_ev = NULL;
+       THREAD_OFF(bs->recvtimer_ev);
 }
 
 void bfd_echo_recvtimer_delete(struct bfd_session *bs)
 {
-       if (bs->echo_recvtimer_ev == NULL)
-               return;
-
-       thread_cancel(bs->echo_recvtimer_ev);
-       bs->echo_recvtimer_ev = NULL;
+       THREAD_OFF(bs->echo_recvtimer_ev);
 }
 
 void bfd_xmttimer_delete(struct bfd_session *bs)
 {
-       if (bs->xmttimer_ev == NULL)
-               return;
-
-       thread_cancel(bs->xmttimer_ev);
-       bs->xmttimer_ev = NULL;
+       THREAD_OFF(bs->xmttimer_ev);
 }
 
 void bfd_echo_xmttimer_delete(struct bfd_session *bs)
 {
-       if (bs->echo_xmttimer_ev == NULL)
-               return;
-
-       thread_cancel(bs->echo_xmttimer_ev);
-       bs->echo_xmttimer_ev = NULL;
+       THREAD_OFF(bs->echo_xmttimer_ev);
 }
index 5f24ef4d19cc573e122806f2c860e055760322a9..e260851ddba6a229573406c7540c3e20b3a99ec0 100644 (file)
 
 #ifdef BFD_LINUX
 
-/* XXX: fix compilation error on Ubuntu 16.04 or older. */
-#ifndef _UAPI_IPV6_H
-#define _UAPI_IPV6_H
-#endif /* _UAPI_IPV6_H */
-
-#include <linux/filter.h>
-#include <linux/if_packet.h>
-
-#include <netinet/if_ether.h>
-
-#include <net/if.h>
-#include <sys/ioctl.h>
-
 #include "bfd.h"
 
-/* Berkeley Packet filter code to filter out BFD Echo packets.
- * tcpdump -dd "(udp dst port 3785)"
- */
-static struct sock_filter bfd_echo_filter[] = {
-       {0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd},
-       {0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011},
-       {0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x00000ec9},
-       {0x15, 0, 8, 0x00000800}, {0x30, 0, 0, 0x00000017},
-       {0x15, 0, 6, 0x00000011}, {0x28, 0, 0, 0x00000014},
-       {0x45, 4, 0, 0x00001fff}, {0xb1, 0, 0, 0x0000000e},
-       {0x48, 0, 0, 0x00000010}, {0x15, 0, 1, 0x00000ec9},
-       {0x6, 0, 0, 0x0000ffff},  {0x6, 0, 0, 0x00000000},
-};
-
-/* Berkeley Packet filter code to filter out BFD vxlan packets.
- * tcpdump -dd "(udp dst port 4789)"
- */
-static struct sock_filter bfd_vxlan_filter[] = {
-       {0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd},
-       {0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011},
-       {0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x000012b5},
-       {0x15, 0, 8, 0x00000800}, {0x30, 0, 0, 0x00000017},
-       {0x15, 0, 6, 0x00000011}, {0x28, 0, 0, 0x00000014},
-       {0x45, 4, 0, 0x00001fff}, {0xb1, 0, 0, 0x0000000e},
-       {0x48, 0, 0, 0x00000010}, {0x15, 0, 1, 0x000012b5},
-       {0x6, 0, 0, 0x0000ffff},  {0x6, 0, 0, 0x00000000},
-};
-
 
 /*
  * Definitions.
@@ -128,55 +87,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen)
                          ifr.ifr_name, ifname);
 }
 
-int ptm_bfd_echo_sock_init(void)
-{
-       int s;
-       struct sock_fprog bpf = {.len = sizeof(bfd_echo_filter)
-                                       / sizeof(bfd_echo_filter[0]),
-                                .filter = bfd_echo_filter};
-
-       s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
-       if (s == -1) {
-               log_error("echo-socket: creation failure: %s", strerror(errno));
-               return -1;
-       }
-
-       if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))
-           == -1) {
-               log_error("echo-socket: setsockopt(SO_ATTACH_FILTER): %s",
-                         strerror(errno));
-               close(s);
-               return -1;
-       }
-
-       return s;
-}
-
-int ptm_bfd_vxlan_sock_init(void)
-{
-       int s;
-       struct sock_fprog bpf = {.len = sizeof(bfd_vxlan_filter)
-                                       / sizeof(bfd_vxlan_filter[0]),
-                                .filter = bfd_vxlan_filter};
-
-       s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
-       if (s == -1) {
-               log_error("vxlan-socket: creation failure: %s",
-                         strerror(errno));
-               return -1;
-       }
-
-       if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))
-           == -1) {
-               log_error("vxlan-socket: setsockopt(SO_ATTACH_FILTER): %s",
-                         strerror(errno));
-               close(s);
-               return -1;
-       }
-
-       return s;
-}
-
 int bp_bind_dev(int sd __attribute__((__unused__)),
                const char *dev __attribute__((__unused__)))
 {
@@ -197,25 +107,4 @@ int bp_bind_dev(int sd __attribute__((__unused__)),
        return 0;
 }
 
-uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len)
-{
-       char *ptr;
-       struct udp_psuedo_header pudp_hdr;
-       uint16_t csum;
-
-       pudp_hdr.saddr = iph->saddr;
-       pudp_hdr.daddr = iph->daddr;
-       pudp_hdr.reserved = 0;
-       pudp_hdr.protocol = iph->protocol;
-       pudp_hdr.len = htons(len);
-
-       ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len);
-       memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN);
-       memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len);
-
-       csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len);
-       XFREE(MTYPE_BFDD_TMP, ptr);
-       return csum;
-}
-
 #endif /* BFD_LINUX */
index 4287891621f06306c589b96ebeb9be04708508bb..a5fae3383cd7248ba0994f318e2e877dd90f283f 100644 (file)
@@ -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:
index 86923f5cec50dfef6d884e8e8e148a7d980d8931..334e974b048a9eb1676666b4e63c8eaa65e3d97c 100644 (file)
@@ -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 = \
index 105be2299503e9b435b7ada521e2c4f733c9ce1d..2e77195b90088e07a8ddb644dd05d0a5a069ab3a 100644 (file)
@@ -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 (file)
index 0000000..b8664a8
--- /dev/null
@@ -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 (file)
index b6b125f..0000000
+++ /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
-
index 47dffd146ab63a58e4f300ed3669f912ea570f1a..663bc4894a842aae8e262a7c4f7e3b5e60902d07 100644 (file)
@@ -530,7 +530,7 @@ void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
 /*
  * bgp_bfd_show_info - Show the peer BFD information.
  */
-void bgp_bfd_show_info(struct vty *vty, struct peer *peer, uint8_t use_json,
+void bgp_bfd_show_info(struct vty *vty, struct peer *peer, bool use_json,
                       json_object *json_neigh)
 {
        bfd_show_info(vty, (struct bfd_info *)peer->bfd_info,
index a3cfca9c0d8ae03bd19a41d469d316256de33dbd..caa5651e3ac646241728729e6e366b9e7da11f73 100644 (file)
@@ -34,8 +34,8 @@ extern void bgp_bfd_deregister_peer(struct peer *peer);
 extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer,
                                      char *addr);
 
-extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer,
-                             uint8_t use_json, json_object *json_neigh);
+extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer, bool use_json,
+                             json_object *json_neigh);
 
 extern int bgp_bfd_is_peer_multihop(struct peer *peer);
 
index bce6056ded4adaae98f71431e86ebcffd618ccfb..071ee6b9c67632af697d4115f6a1189b54c2f798 100644 (file)
@@ -523,7 +523,7 @@ void bgp_config_write_damp(struct vty *vty)
 }
 
 static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
-                                     size_t len, uint8_t use_json,
+                                     size_t len, bool use_json,
                                      json_object *json)
 {
        time_t reuse_time = 0;
@@ -641,7 +641,7 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo,
 }
 
 const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo,
-                                   char *timebuf, size_t len, uint8_t use_json,
+                                   char *timebuf, size_t len, bool use_json,
                                    json_object *json)
 {
        struct bgp_damp_info *bdi;
index d3b0ae42aa0836325b1b34ed69c438b1ca689a8f..8326bae697731b55ef76097423b40a8c199594ec 100644 (file)
@@ -140,9 +140,10 @@ extern int bgp_damp_decay(time_t, int);
 extern void bgp_config_write_damp(struct vty *);
 extern void bgp_damp_info_vty(struct vty *, struct bgp_info *,
                              json_object *json_path);
-extern const char *bgp_damp_reuse_time_vty(struct vty *, struct bgp_info *,
-                                          char *, size_t, uint8_t,
-                                          json_object *);
+extern const char *bgp_damp_reuse_time_vty(struct vty *vty,
+                                          struct bgp_info *binfo,
+                                          char *timebuf, size_t len,
+                                          bool use_json, json_object *json);
 extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t);
 
 #endif /* _QUAGGA_BGP_DAMP_H */
index 9e814516b73dfc31957b280020023ab0c717cac3..a104a2e16d669439539cc71bde0ac39606a40825 100644 (file)
@@ -543,7 +543,7 @@ static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
 static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
                                       struct prefix_evpn *p,
                                       struct in_addr remote_vtep_ip, int add,
-                                      uint8_t flags)
+                                      uint8_t flags, uint32_t seq)
 {
        struct stream *s;
        int ipa_len;
@@ -579,19 +579,22 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
        stream_put_in_addr(s, &remote_vtep_ip);
 
        /* TX flags - MAC sticky status and/or gateway mac */
-       if (add)
+       /* Also TX the sequence number of the best route. */
+       if (add) {
                stream_putc(s, flags);
+               stream_putl(s, seq);
+       }
 
        stream_putw_at(s, 0, stream_get_endp(s));
 
        if (bgp_debug_zebra(NULL))
                zlog_debug(
-                       "Tx %s MACIP, VNI %u MAC %s IP %s (flags: 0x%x) remote VTEP %s",
+                       "Tx %s MACIP, VNI %u MAC %s IP %s flags 0x%x seq %u remote VTEP %s",
                        add ? "ADD" : "DEL", vpn->vni,
                        prefix_mac2str(&p->prefix.macip_addr.mac,
                                       buf1, sizeof(buf1)),
                        ipaddr2str(&p->prefix.macip_addr.ip,
-                                  buf3, sizeof(buf3)), flags,
+                                  buf3, sizeof(buf3)), flags, seq,
                        inet_ntop(AF_INET, &remote_vtep_ip, buf2,
                                  sizeof(buf2)));
 
@@ -875,13 +878,14 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
 /* Install EVPN route into zebra. */
 static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
                              struct prefix_evpn *p,
-                             struct in_addr remote_vtep_ip, uint8_t flags)
+                             struct in_addr remote_vtep_ip, uint8_t flags,
+                             uint32_t seq)
 {
        int ret;
 
        if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
                ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
-                                                 1, flags);
+                                                 1, flags, seq);
        else
                ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1);
 
@@ -897,7 +901,7 @@ static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
 
        if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
                ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
-                                                 0, 0);
+                                                 0, 0, 0);
        else
                ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 0);
 
@@ -1141,7 +1145,8 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
 
                        ret = evpn_zebra_install(
                                bgp, vpn, (struct prefix_evpn *)&rn->p,
-                               old_select->attr->nexthop, flags);
+                               old_select->attr->nexthop, flags,
+                               mac_mobility_seqnum(old_select->attr));
                }
                UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG);
                bgp_zebra_clear_route_change_flags(rn);
@@ -1177,7 +1182,8 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
                        SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
 
                ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
-                                        new_select->attr->nexthop, flags);
+                                        new_select->attr->nexthop, flags,
+                                        mac_mobility_seqnum(new_select->attr));
                /* If an old best existed and it was a "local" route, the only
                 * reason
                 * it would be supplanted is due to MAC mobility procedures. So,
@@ -1557,11 +1563,12 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
  */
 static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                                   afi_t afi, safi_t safi, struct bgp_node *rn,
-                                  struct attr *attr, int add, int vni_table,
-                                  struct bgp_info **ri, uint8_t flags)
+                                  struct attr *attr, int add,
+                                  struct bgp_info **ri, uint8_t flags,
+                                  uint32_t seq)
 {
        struct bgp_info *tmp_ri;
-       struct bgp_info *local_ri, *remote_ri;
+       struct bgp_info *local_ri;
        struct attr *attr_new;
        mpls_label_t label[BGP_MAX_LABELS];
        uint32_t num_labels = 1;
@@ -1573,28 +1580,13 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
        evp = (struct prefix_evpn *)&rn->p;
        memset(&label, 0, sizeof(label));
 
-       /* See if this is an update of an existing route, or a new add. Also,
-        * identify if already known from remote, and if so, the one with the
-        * highest sequence number; this is only when adding to the VNI routing
-        * table.
-        */
-       local_ri = remote_ri = NULL;
+       /* See if this is an update of an existing route, or a new add. */
+       local_ri = NULL;
        for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
                if (tmp_ri->peer == bgp->peer_self
                    && tmp_ri->type == ZEBRA_ROUTE_BGP
                    && tmp_ri->sub_type == BGP_ROUTE_STATIC)
                        local_ri = tmp_ri;
-               if (vni_table) {
-                       if (tmp_ri->type == ZEBRA_ROUTE_BGP
-                           && tmp_ri->sub_type == BGP_ROUTE_IMPORTED
-                           && CHECK_FLAG(tmp_ri->flags, BGP_INFO_VALID)) {
-                               if (!remote_ri)
-                                       remote_ri = tmp_ri;
-                               else if (mac_mobility_seqnum(tmp_ri->attr)
-                                        > mac_mobility_seqnum(remote_ri->attr))
-                                       remote_ri = tmp_ri;
-                       }
-               }
        }
 
        /* If route doesn't exist already, create a new one, if told to.
@@ -1604,22 +1596,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
        if (!local_ri && !add)
                return 0;
 
-       if (!local_ri) {
-               /* When learnt locally for the first time but already known from
-                * remote, we have to initiate appropriate MAC mobility steps.
-                * This is applicable when updating the VNI routing table.
-                * We need to skip mobility steps for g/w macs (local mac on g/w
-                * SVI) advertised in EVPN.
-                * This will ensure that local routes are preferred for g/w macs
-                */
-               if (remote_ri && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
-                       uint32_t cur_seqnum;
-
-                       /* Add MM extended community to route. */
-                       cur_seqnum = mac_mobility_seqnum(remote_ri->attr);
-                       add_mac_mobility_to_attr(cur_seqnum + 1, attr);
-               }
+       /* For non-GW MACs, update MAC mobility seq number, if needed. */
+       if (seq && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW))
+               add_mac_mobility_to_attr(seq, attr);
 
+       if (!local_ri) {
                /* Add (or update) attribute to hash. */
                attr_new = bgp_attr_intern(attr);
 
@@ -1685,6 +1666,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                        attr_new = bgp_attr_intern(attr);
                        bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
 
+                       /* Extract MAC mobility sequence number, if any. */
+                       attr_new->mm_seqnum =
+                               bgp_attr_mac_mobility_seqnum(attr_new, &sticky);
+                       attr_new->sticky = sticky;
+
                        /* Restore route, if needed. */
                        if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
                                bgp_info_restore(rn, tmp_ri);
@@ -1706,7 +1692,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
  * and schedule for processing.
  */
 static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
-                            struct prefix_evpn *p, uint8_t flags)
+                            struct prefix_evpn *p, uint8_t flags,
+                            uint32_t seq)
 {
        struct bgp_node *rn;
        struct attr attr;
@@ -1758,7 +1745,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
 
        /* Create or update route entry. */
        route_change = update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr,
-                                              1, 1, &ri, flags);
+                                              1, &ri, flags, seq);
        assert(ri);
        attr_new = ri->attr;
 
@@ -1778,8 +1765,8 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
 
                rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
                                      (struct prefix *)p, &vpn->prd);
-               update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, 0,
-                                       &global_ri, flags);
+               update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1,
+                                       &global_ri, flags, seq);
 
                /* Schedule for processing and unlock node. */
                bgp_process(bgp, rn, afi, safi);
@@ -1954,58 +1941,14 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
        afi_t afi;
        safi_t safi;
        struct bgp_node *rn;
-       struct bgp_info *ri;
+       struct bgp_info *ri, *tmp_ri;
        struct attr attr;
-       struct attr attr_sticky;
-       struct attr attr_def_gw;
-       struct attr attr_ip6_ll;
        struct attr *attr_new;
+       uint32_t seq;
        int add_l3_ecomm = 0;
 
        afi = AFI_L2VPN;
        safi = SAFI_EVPN;
-       memset(&attr, 0, sizeof(struct attr));
-       memset(&attr_sticky, 0, sizeof(struct attr));
-       memset(&attr_def_gw, 0, sizeof(struct attr));
-       memset(&attr_ip6_ll, 0, sizeof(struct attr));
-
-       /* Build path-attribute - multiple type-2 routes for this VNI will share
-        * the same path attribute, but we need separate structures for sticky
-        * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC).
-        */
-       bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
-       bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP);
-       bgp_attr_default_set(&attr_def_gw, BGP_ORIGIN_IGP);
-       attr.nexthop = vpn->originator_ip;
-       attr.mp_nexthop_global_in = vpn->originator_ip;
-       attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
-       bgpevpn_get_rmac(vpn, &attr.rmac);
-       attr_sticky.nexthop = vpn->originator_ip;
-       attr_sticky.mp_nexthop_global_in = vpn->originator_ip;
-       attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
-       attr_sticky.sticky = 1;
-       bgpevpn_get_rmac(vpn, &attr_sticky.rmac);
-       attr_def_gw.nexthop = vpn->originator_ip;
-       attr_def_gw.mp_nexthop_global_in = vpn->originator_ip;
-       attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
-       attr_def_gw.default_gw = 1;
-       bgpevpn_get_rmac(vpn, &attr_def_gw.rmac);
-       bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP);
-       attr_ip6_ll.nexthop = vpn->originator_ip;
-       attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip;
-       attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
-
-       /* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if
-        * using L3 VNI for type-2 routes also.
-        */
-       if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS) &&
-           bgpevpn_get_l3vni(vpn))
-               add_l3_ecomm = 1;
-
-       build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
-       build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm);
-       build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm);
-       build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0);
 
        /* Walk this VNI's route table and update local type-2 routes. For any
         * routes updated, update corresponding entry in the global table too.
@@ -2019,35 +1962,57 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
                if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
                        continue;
 
-               if (is_evpn_prefix_ipaddr_v6(evp) &&
-                   IN6_IS_ADDR_LINKLOCAL(&evp->prefix.macip_addr.ip.ipaddr_v6))
-                       update_evpn_route_entry(bgp, vpn, afi, safi, rn,
-                                               &attr_ip6_ll, 0, 1, &ri, 0);
-               else {
-                       if (evpn_route_is_sticky(bgp, rn))
-                               update_evpn_route_entry(bgp, vpn, afi, safi, rn,
-                                                       &attr_sticky, 0, 1, &ri,
-                                                       0);
-                       else if (evpn_route_is_def_gw(bgp, rn)) {
-                               if (is_evpn_prefix_ipaddr_v6(evp))
-                                       attr_def_gw.router_flag = 1;
-                               update_evpn_route_entry(bgp, vpn, afi, safi, rn,
-                                                       &attr_def_gw, 0, 1, &ri,
-                                                       0);
-                       } else
-                               update_evpn_route_entry(bgp, vpn, afi, safi, rn,
-                                                       &attr, 0, 1, &ri, 0);
+               /* Identify local route. */
+               for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
+                       if (tmp_ri->peer == bgp->peer_self
+                           && tmp_ri->type == ZEBRA_ROUTE_BGP
+                           && tmp_ri->sub_type == BGP_ROUTE_STATIC)
+                               break;
                }
 
-               /* If a local route exists for this prefix, we need to update
-                * the global routing table too.
-                */
-               if (!ri)
+               if (!tmp_ri)
                        continue;
 
+               /*
+                * Build attribute per local route as the MAC mobility and
+                * some other values could differ for different routes. The
+                * attributes will be shared in the hash table.
+                */
+               bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
+               attr.nexthop = vpn->originator_ip;
+               attr.mp_nexthop_global_in = vpn->originator_ip;
+               attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
+               bgpevpn_get_rmac(vpn, &attr.rmac);
+
+               if (evpn_route_is_sticky(bgp, rn))
+                       attr.sticky = 1;
+               else if (evpn_route_is_def_gw(bgp, rn)) {
+                       attr.default_gw = 1;
+                       if (is_evpn_prefix_ipaddr_v6(evp))
+                               attr.router_flag = 1;
+               }
+
+               /* Add L3 VNI RTs and RMAC for non IPv6 link-local if
+                * using L3 VNI for type-2 routes also.
+                */
+               if ((is_evpn_prefix_ipaddr_v4(evp) ||
+                    !IN6_IS_ADDR_LINKLOCAL(
+                       &evp->prefix.macip_addr.ip.ipaddr_v6)) &&
+                   CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS) &&
+                   bgpevpn_get_l3vni(vpn))
+                       add_l3_ecomm = 1;
+
+               /* Set up extended community. */
+               build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
+
+               seq = mac_mobility_seqnum(tmp_ri->attr);
+
+               /* Update the route entry. */
+               update_evpn_route_entry(bgp, vpn, afi, safi, rn,
+                                       &attr, 0, &ri, 0, seq);
+
                /* Perform route selection; this is just to set the flags
-                * correctly
-                * as local route in the VNI always wins.
+                * correctly as local route in the VNI always wins.
                 */
                evpn_route_select_install(bgp, vpn, rn);
 
@@ -2058,18 +2023,17 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
                                         (struct prefix *)evp, &vpn->prd);
                assert(rd_rn);
                update_evpn_route_entry(bgp, vpn, afi, safi, rd_rn, attr_new, 0,
-                                       0, &global_ri, 0);
+                                       &global_ri, 0,
+                                       mac_mobility_seqnum(attr_new));
 
                /* Schedule for processing and unlock node. */
                bgp_process(bgp, rd_rn, afi, safi);
                bgp_unlock_node(rd_rn);
-       }
 
-       /* Unintern temporary. */
-       aspath_unintern(&attr.aspath);
-       aspath_unintern(&attr_sticky.aspath);
-       aspath_unintern(&attr_def_gw.aspath);
-       aspath_unintern(&attr_ip6_ll.aspath);
+               /* Unintern temporary. */
+               aspath_unintern(&attr.aspath);
+
+       }
 
        return 0;
 }
@@ -2206,7 +2170,7 @@ static int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
         * locally learnt type-2 routes (MACIP) - for this VNI.
         */
        build_evpn_type3_prefix(&p, vpn->originator_ip);
-       ret = update_evpn_route(bgp, vpn, &p, 0);
+       ret = update_evpn_route(bgp, vpn, &p, 0, 0);
        if (ret)
                return ret;
 
@@ -3451,8 +3415,8 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
 
        global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
                                     (struct prefix *)&p, &vpn->prd);
-       update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri,
-                               0);
+       update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, &ri,
+                               0, mac_mobility_seqnum(attr));
 
        /* Schedule for processing and unlock node. */
        bgp_process(bgp, global_rn, afi, safi);
@@ -3485,7 +3449,8 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
                                             (struct prefix *)evp, &vpn->prd);
                assert(global_rn);
                update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1,
-                                       0, &global_ri, 0);
+                                       &global_ri, 0,
+                                       mac_mobility_seqnum(attr));
 
                /* Schedule for processing and unlock node. */
                bgp_process(bgp, global_rn, afi, safi);
@@ -5213,7 +5178,7 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
  * Handle add of a local MACIP.
  */
 int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
-                            struct ipaddr *ip, uint8_t flags)
+                            struct ipaddr *ip, uint8_t flags, uint32_t seq)
 {
        struct bgpevpn *vpn;
        struct prefix_evpn p;
@@ -5228,7 +5193,7 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
 
        /* Create EVPN type-2 route and schedule for processing. */
        build_evpn_type2_prefix(&p, mac, ip);
-       if (update_evpn_route(bgp, vpn, &p, flags)) {
+       if (update_evpn_route(bgp, vpn, &p, flags, seq)) {
                char buf[ETHER_ADDR_STRLEN];
                char buf2[INET6_ADDRSTRLEN];
 
@@ -5525,7 +5490,7 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
 
        /* Create EVPN type-3 route and schedule for processing. */
        build_evpn_type3_prefix(&p, vpn->originator_ip);
-       if (update_evpn_route(bgp, vpn, &p, 0)) {
+       if (update_evpn_route(bgp, vpn, &p, 0, 0)) {
                flog_err(BGP_ERR_EVPN_ROUTE_CREATE,
                          "%u: Type3 route creation failure for VNI %u",
                          bgp->vrf_id, vni);
index 91d4c9fac4a77bd910ecf3913061155d5976f6d9..b002be3d3d70d0b141917e7f9f16b9d6c9b38e89 100644 (file)
@@ -132,7 +132,7 @@ extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
                                    struct ethaddr *mac, struct ipaddr *ip);
 extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
                                    struct ethaddr *mac, struct ipaddr *ip,
-                                   uint8_t flags);
+                                   uint8_t flags, uint32_t seq);
 extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id,
                                    struct ethaddr *rmac,
                                    struct in_addr originator_ip, int filter);
index b553cb42a5ac4169e748ae015a6449fcb1ba9c4c..a6cc2d9b5361e7b120c1323d97c0f4b47f79696c 100644 (file)
@@ -983,7 +983,7 @@ static void show_vni_entry(struct hash_backet *backet, void *args[])
 
 static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
                                 enum bgp_show_type type, void *output_arg,
-                                int option, uint8_t use_json)
+                                int option, bool use_json)
 {
        afi_t afi = AFI_L2VPN;
        struct bgp *bgp;
@@ -1276,7 +1276,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes,
        union sockunion su;
        struct peer *peer;
        int ret;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        argv_find(argv, argc, "A.B.C.D", &idx_ipv4);
 
@@ -1336,7 +1336,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
        union sockunion su;
        struct peer *peer;
        struct prefix_rd prd;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
        argv_find(argv, argc, "A.B.C.D", &idx_ipv4);
@@ -1409,7 +1409,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes,
        int ret;
        struct peer *peer;
        union sockunion su;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        argv_find(argv, argc, "A.B.C.D", &idx_ipv4);
 
@@ -1467,7 +1467,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
        struct peer *peer;
        struct prefix_rd prd;
        union sockunion su;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
        argv_find(argv, argc, "A.B.C.D", &idx_ipv4);
@@ -3172,7 +3172,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni,
        struct bgp *bgp_def;
        vni_t vni;
        int idx = 0;
-       uint8_t uj = 0;
+       bool uj = false;
        json_object *json = NULL;
        uint32_t num_l2vnis = 0;
        uint32_t num_l3vnis = 0;
@@ -3255,7 +3255,7 @@ DEFUN(show_bgp_l2vpn_evpn_es,
       JSON_STR)
 {
        int idx = 0;
-       uint8_t uj = 0;
+       bool uj = false;
        esi_t esi;
        json_object *json = NULL;
        struct bgp *bgp = NULL;
@@ -3312,7 +3312,7 @@ DEFUN(show_bgp_l2vpn_evpn_summary,
       JSON_STR)
 {
        int idx_vrf = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        char *vrf = NULL;
 
        if (argv_find(argv, argc, "vrf", &idx_vrf))
@@ -3341,7 +3341,7 @@ DEFUN(show_bgp_l2vpn_evpn_route,
        struct bgp *bgp;
        int type_idx = 0;
        int type = 0;
-       uint8_t uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        uj = use_json(argc, argv);
@@ -3404,7 +3404,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
        int type = 0;
        int rd_idx = 0;
        int type_idx = 0;
-       int uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        bgp = bgp_get_default();
@@ -3477,7 +3477,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
        int rd_idx = 0;
        int mac_idx = 0;
        int ip_idx = 0;
-       int uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        memset(&mac, 0, sizeof(struct ethaddr));
@@ -3541,7 +3541,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi,
       "ESI ID\n"
       JSON_STR)
 {
-       int uj = 0;
+       bool uj = false;
        esi_t esi;
        struct bgp *bgp = NULL;
        json_object *json = NULL;
@@ -3597,7 +3597,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
        struct in_addr vtep_ip;
        int type = 0;
        int idx = 0;
-       int uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        bgp = bgp_get_default();
@@ -3669,7 +3669,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_macip,
        struct ethaddr mac;
        struct ipaddr ip;
        int idx = 0;
-       int uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        bgp = bgp_get_default();
@@ -3737,7 +3737,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast,
        int ret;
        struct in_addr orig_ip;
        int idx = 0;
-       int uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        bgp = bgp_get_default();
@@ -3793,7 +3793,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all,
        struct bgp *bgp;
        struct in_addr vtep_ip;
        int idx = 0;
-       int uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        bgp = bgp_get_default();
@@ -3841,7 +3841,7 @@ DEFUN(show_bgp_l2vpn_evpn_vrf_import_rt,
       "Show vrf import route target\n"
       JSON_STR)
 {
-       uint8_t uj = 0;
+       bool uj = false;
        struct bgp *bgp_def = NULL;
        json_object *json = NULL;
 
@@ -3878,7 +3878,7 @@ DEFUN(show_bgp_l2vpn_evpn_import_rt,
       JSON_STR)
 {
        struct bgp *bgp;
-       uint8_t uj = 0;
+       bool uj = false;
        json_object *json = NULL;
 
        bgp = bgp_get_default();
@@ -4359,7 +4359,7 @@ DEFUN (show_bgp_vrf_l3vni_info,
        json_object *json_vnis = NULL;
        json_object *json_export_rts = NULL;
        json_object *json_import_rts = NULL;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (uj) {
                json = json_object_new_object();
index ae9d805b055a846fdefc65c0a3170e6318fbf6bc..c7977a9af4c800840ea3245e163194cb72720abc 100644 (file)
@@ -391,16 +391,25 @@ static int as_list_dup_check(struct as_list *aslist, struct as_filter *new)
        return 0;
 }
 
-DEFUN (ip_as_path,
-       ip_as_path_cmd,
-       "ip as-path access-list WORD <deny|permit> LINE...",
-       IP_STR
-       "BGP autonomous system path filter\n"
-       "Specify an access list name\n"
-       "Regular expression access list name\n"
-       "Specify packets to reject\n"
-       "Specify packets to forward\n"
-       "A regular-expression to match the BGP AS paths\n")
+static int config_bgp_aspath_validate(const char *regstr)
+{
+       char valid_chars[] = "1234567890_^|[,{}() ]$*+.?-";
+
+       if (strspn(regstr, valid_chars) == strlen(regstr))
+               return 1;
+
+       return 0;
+}
+
+DEFUN(ip_as_path, ip_as_path_cmd,
+      "ip as-path access-list WORD <deny|permit> LINE...",
+      IP_STR
+      "BGP autonomous system path filter\n"
+      "Specify an access list name\n"
+      "Regular expression access list name\n"
+      "Specify packets to reject\n"
+      "Specify packets to forward\n"
+      "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
 {
        int idx = 0;
        enum as_filter_type type;
@@ -428,6 +437,12 @@ DEFUN (ip_as_path,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
+       if (!config_bgp_aspath_validate(regstr)) {
+               vty_out(vty, "Invalid character in as-path access-list %s\n",
+                       regstr);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        asfilter = as_filter_make(regex, regstr, type);
 
        XFREE(MTYPE_TMP, regstr);
@@ -444,17 +459,15 @@ DEFUN (ip_as_path,
        return CMD_SUCCESS;
 }
 
-DEFUN (no_ip_as_path,
-       no_ip_as_path_cmd,
-       "no ip as-path access-list WORD <deny|permit> LINE...",
-       NO_STR
-       IP_STR
-       "BGP autonomous system path filter\n"
-       "Specify an access list name\n"
-       "Regular expression access list name\n"
-       "Specify packets to reject\n"
-       "Specify packets to forward\n"
-       "A regular-expression to match the BGP AS paths\n")
+DEFUN(no_ip_as_path, no_ip_as_path_cmd,
+      "no ip as-path access-list WORD <deny|permit> LINE...",
+      NO_STR IP_STR
+      "BGP autonomous system path filter\n"
+      "Specify an access list name\n"
+      "Regular expression access list name\n"
+      "Specify packets to reject\n"
+      "Specify packets to forward\n"
+      "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n")
 {
        int idx = 0;
        enum as_filter_type type;
@@ -488,6 +501,12 @@ DEFUN (no_ip_as_path,
        argv_find(argv, argc, "LINE", &idx);
        regstr = argv_concat(argv, argc, idx);
 
+       if (!config_bgp_aspath_validate(regstr)) {
+               vty_out(vty, "Invalid character in as-path access-list %s\n",
+                       regstr);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        regex = bgp_regcomp(regstr);
        if (!regex) {
                vty_out(vty, "can't compile regexp %s\n", regstr);
index e29508bf3680d9e946bb77db9b40cc593a947386..c604135bfd1beccbae4a4310fb139709902d01c9 100644 (file)
@@ -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"
 
index 9f69dbeddac06a2af9672fa1c59e3fbe3f354ba8..f07b696b8d38cf8c223638e4acc19c5272775051 100644 (file)
@@ -34,9 +34,8 @@ extern void bgp_flowspec_vty_init(void);
 
 extern int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
                                   struct bgp_table *table,
-                                  enum bgp_show_type type,
-                                  void *output_arg, uint8_t use_json,
-                                  int is_last,
+                                  enum bgp_show_type type, void *output_arg,
+                                  bool use_json, int is_last,
                                   unsigned long *output_cum,
                                   unsigned long *total_cum);
 
@@ -50,12 +49,10 @@ extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
 extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp,
                                   afi_t afi, safi_t safi);
 
-extern int bgp_flowspec_display_match_per_ip(afi_t afi,
-                               struct bgp_table *rib,
-                               struct prefix *match,
-                               int prefix_check,
-                               struct vty *vty,
-                               uint8_t use_json,
-                               json_object *json_paths);
+extern int bgp_flowspec_display_match_per_ip(afi_t afi, struct bgp_table *rib,
+                                            struct prefix *match,
+                                            int prefix_check, struct vty *vty,
+                                            bool use_json,
+                                            json_object *json_paths);
 
 #endif /* _FRR_BGP_FLOWSPEC_H */
index 31d2c540fa524e2d044a299daad914ea6457cfef..978ce6bf4e14a6f4af646573725eed44a4bce593 100644 (file)
@@ -365,9 +365,8 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
 
 int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
                            struct bgp_table *table, enum bgp_show_type type,
-                           void *output_arg, uint8_t use_json,
-                           int is_last, unsigned long *output_cum,
-                           unsigned long *total_cum)
+                           void *output_arg, bool use_json, int is_last,
+                           unsigned long *output_cum, unsigned long *total_cum)
 {
        struct bgp_info *ri;
        struct bgp_node *rn;
@@ -527,13 +526,11 @@ DEFUN (bgp_fs_local_install_ifname,
        return bgp_fs_local_install_interface(bgp, no, ifname);
 }
 
-extern int bgp_flowspec_display_match_per_ip(afi_t afi,
-                       struct bgp_table *rib,
-                       struct prefix *match,
-                       int prefix_check,
-                       struct vty *vty,
-                       uint8_t use_json,
-                       json_object *json_paths)
+extern int bgp_flowspec_display_match_per_ip(afi_t afi, struct bgp_table *rib,
+                                            struct prefix *match,
+                                            int prefix_check, struct vty *vty,
+                                            bool use_json,
+                                            json_object *json_paths)
 {
        struct bgp_node *rn;
        struct prefix *prefix;
index b89edfe45963f63aa08da710df84920399bbc2fe..459775c8ec0cb977260e11ca5593a2b970ad2376 100644 (file)
@@ -1775,7 +1775,7 @@ DEFUN (no_vpnv6_network,
 
 int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
                      enum bgp_show_type type, void *output_arg, int tags,
-                     uint8_t use_json)
+                     bool use_json)
 {
        struct bgp *bgp;
        struct bgp_table *table;
@@ -1953,7 +1953,7 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
        union sockunion su;
        struct peer *peer;
        int ret;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        afi_t afi;
        int idx = 0;
 
@@ -2017,7 +2017,7 @@ DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
        union sockunion su;
        struct peer *peer;
        struct prefix_rd prd;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        afi_t afi;
        int idx = 0;
 
@@ -2095,7 +2095,7 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
        int ret;
        struct peer *peer;
        union sockunion su;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        afi_t afi;
        int idx = 0;
 
@@ -2157,7 +2157,7 @@ DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
        struct peer *peer;
        struct prefix_rd prd;
        union sockunion su;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        afi_t afi;
        int idx = 0;
 
index 122ae9e905b16afb37c1c0ebed9bca463fac27e2..61b87392a2182754130afd4710d4a069272d9bf2 100644 (file)
@@ -50,7 +50,7 @@ extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
                                     int *index, afi_t *afi);
 extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
                             enum bgp_show_type type, void *output_arg,
-                            int tags, uint8_t use_json);
+                            int tags, bool use_json);
 
 extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
                                     struct bgp_info *info_vrf);
index 7fbc0302420e63abf4e18d28736a401f481457be..5bdee5f512fa572aef759088b9c88178e4660f48 100644 (file)
@@ -52,8 +52,8 @@
    Next, if we send capability to the peer we want to set my capabilty
    inforation at each peer. */
 
-void bgp_capability_vty_out(struct vty *vty, struct peer *peer,
-                           uint8_t use_json, json_object *json_neigh)
+void bgp_capability_vty_out(struct vty *vty, struct peer *peer, bool use_json,
+                           json_object *json_neigh)
 {
        char *pnt;
        char *end;
index 42ebe97f2e64b780954f8ce86f9e4bc43035f596..0fc321bdf3a6af89a31d291d64f4bbfc7667a2ea 100644 (file)
@@ -86,8 +86,8 @@ struct graceful_restart_af {
 
 extern int bgp_open_option_parse(struct peer *, uint8_t, int *);
 extern void bgp_open_capability(struct stream *, struct peer *);
-extern void bgp_capability_vty_out(struct vty *, struct peer *, uint8_t,
-                                  json_object *);
+extern void bgp_capability_vty_out(struct vty *vty, struct peer *peer,
+                                  bool use_json, json_object *json_neigh);
 extern as_t peek_for_as4_capability(struct peer *, uint8_t);
 
 #endif /* _QUAGGA_BGP_OPEN_H */
index 50c484d7de7b8264eef6f1c1b89b9aba986204f3..2107d1f9f9a18ff6e6adfd9a19ca81152655850a 100644 (file)
@@ -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)
@@ -6755,7 +6760,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
 
 /* called from terminal list command */
 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
-                      safi_t safi, uint8_t use_json, json_object *json_ar)
+                      safi_t safi, bool use_json, json_object *json_ar)
 {
        json_object *json_status = NULL;
        json_object *json_net = NULL;
@@ -7084,7 +7089,7 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p,
 /* dampening route */
 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
                               struct bgp_info *binfo, int display, safi_t safi,
-                              uint8_t use_json, json_object *json)
+                              bool use_json, json_object *json)
 {
        struct attr *attr;
        int len;
@@ -7147,7 +7152,7 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p,
 /* flap route */
 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
                               struct bgp_info *binfo, int display, safi_t safi,
-                              uint8_t use_json, json_object *json)
+                              bool use_json, json_object *json)
 {
        struct attr *attr;
        struct bgp_damp_info *bdi;
@@ -8160,12 +8165,12 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
                           afi_t afi, safi_t safi, enum bgp_show_type type);
 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
                              const char *comstr, int exact, afi_t afi,
-                             safi_t safi, uint8_t use_json);
+                             safi_t safi, bool use_json);
 
 
 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                          struct bgp_table *table, enum bgp_show_type type,
-                         void *output_arg, uint8_t use_json, char *rd,
+                         void *output_arg, bool use_json, char *rd,
                          int is_last, unsigned long *output_cum,
                          unsigned long *total_cum,
                          unsigned long *json_header_depth)
@@ -8452,8 +8457,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
 
 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
                      struct bgp_table *table, struct prefix_rd *prd_match,
-                     enum bgp_show_type type, void *output_arg,
-                     uint8_t use_json)
+                     enum bgp_show_type type, void *output_arg, bool use_json)
 {
        struct bgp_node *rn, *next;
        unsigned long output_cum = 0;
@@ -8493,7 +8497,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
        return CMD_SUCCESS;
 }
 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
-                   enum bgp_show_type type, void *output_arg, uint8_t use_json)
+                   enum bgp_show_type type, void *output_arg, bool use_json)
 {
        struct bgp_table *table;
        unsigned long json_header_depth = 0;
@@ -8531,16 +8535,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
 }
 
 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
-                                             safi_t safi, uint8_t use_json)
+                                             safi_t safi, bool use_json)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
        int is_first = 1;
+       bool route_output = false;
 
        if (use_json)
                vty_out(vty, "{\n");
 
        for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               route_output = true;
                if (use_json) {
                        if (!is_first)
                                vty_out(vty, ",\n");
@@ -8563,6 +8569,8 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
 
        if (use_json)
                vty_out(vty, "}\n");
+       else if (!route_output)
+               vty_out(vty, "%% BGP instance not found\n");
 }
 
 /* Header of detailed BGP route information */
@@ -8748,8 +8756,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
                                   struct bgp_table *rib, const char *ip_str,
                                   afi_t afi, safi_t safi,
                                   struct prefix_rd *prd, int prefix_check,
-                                  enum bgp_path_type pathtype,
-                                  uint8_t use_json)
+                                  enum bgp_path_type pathtype, bool use_json)
 {
        int ret;
        int header;
@@ -8885,7 +8892,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
                          afi_t afi, safi_t safi, struct prefix_rd *prd,
                          int prefix_check, enum bgp_path_type pathtype,
-                         uint8_t use_json)
+                         bool use_json)
 {
        if (!bgp) {
                bgp = bgp_get_default();
@@ -8909,7 +8916,7 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
 
 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
                               struct cmd_token **argv, afi_t afi, safi_t safi,
-                              uint8_t uj)
+                              bool uj)
 {
        struct lcommunity *lcom;
        struct buffer *b;
@@ -8946,7 +8953,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
 
 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
                                    const char *lcom, afi_t afi, safi_t safi,
-                                   uint8_t uj)
+                                   bool uj)
 {
        struct community_list *list;
 
@@ -8994,7 +9001,7 @@ DEFUN (show_ip_bgp_large_community_list,
                        safi = bgp_vty_safi_from_str(argv[idx]->text);
        }
 
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        struct bgp *bgp = bgp_lookup_by_name(vrf);
        if (bgp == NULL) {
@@ -9037,7 +9044,7 @@ DEFUN (show_ip_bgp_large_community,
                        safi = bgp_vty_safi_from_str(argv[idx]->text);
        }
 
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        struct bgp *bgp = bgp_lookup_by_name(vrf);
        if (bgp == NULL) {
@@ -9121,7 +9128,7 @@ DEFUN (show_ip_bgp,
        int idx = 0;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, false);
        if (!idx)
                return CMD_WARNING;
 
@@ -9197,16 +9204,16 @@ DEFUN (show_ip_bgp_json,
        int idx = 0;
        int idx_community_type = 0;
        int exact_match = 0;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       int uj = use_json(argc, argv);
-       if (uj)
-               argc--;
-
        if (argv_find(argv, argc, "cidr-only", &idx))
                return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
                                NULL, uj);
@@ -9275,12 +9282,12 @@ DEFUN (show_ip_bgp_route,
        char *prefix = NULL;
        struct bgp *bgp = NULL;
        enum bgp_path_type path_type;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        int idx = 0;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
@@ -9343,7 +9350,7 @@ DEFUN (show_ip_bgp_regexp,
 
        int idx = 0;
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, false);
        if (!idx)
                return CMD_WARNING;
 
@@ -9372,17 +9379,17 @@ DEFUN (show_ip_bgp_instance_all,
        afi_t afi = AFI_IP;
        safi_t safi = SAFI_UNICAST;
        struct bgp *bgp = NULL;
-
        int idx = 0;
-       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
-       if (!idx)
-               return CMD_WARNING;
+       bool uj = use_json(argc, argv);
 
-       int uj = use_json(argc, argv);
        if (uj)
                argc--;
 
+       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+                                           &bgp, uj);
+       if (!idx)
+               return CMD_WARNING;
+
        bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
        return CMD_SUCCESS;
 }
@@ -9453,7 +9460,7 @@ static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
 
 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
                              const char *comstr, int exact, afi_t afi,
-                             safi_t safi, uint8_t use_json)
+                             safi_t safi, bool use_json)
 {
        struct community *com;
        int ret = 0;
@@ -9512,7 +9519,7 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
 }
 
 static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
-                                       const char *ip_str, uint8_t use_json)
+                                       const char *ip_str, bool use_json)
 {
        int ret;
        struct peer *peer;
@@ -9899,7 +9906,7 @@ static int bgp_peer_count_walker(struct thread *t)
 }
 
 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
-                          safi_t safi, uint8_t use_json)
+                          safi_t safi, bool use_json)
 {
        struct peer_pcounts pcounts = {.peer = peer};
        unsigned int i;
@@ -10009,16 +10016,16 @@ DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
        struct peer *peer;
        int idx = 0;
        struct bgp *bgp = NULL;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       int uj = use_json(argc, argv);
-       if (uj)
-               argc--;
-
        argv_find(argv, argc, "neighbors", &idx);
        peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
        if (!peer)
@@ -10045,7 +10052,7 @@ DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
 {
        int idx_peer = 6;
        struct peer *peer;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
        if (!peer)
@@ -10118,7 +10125,7 @@ DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
 
 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                           safi_t safi, enum bgp_show_adj_route_type type,
-                          const char *rmap_name, uint8_t use_json,
+                          const char *rmap_name, bool use_json,
                           json_object *json)
 {
        struct bgp_table *table;
@@ -10389,7 +10396,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
 
 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
                           safi_t safi, enum bgp_show_adj_route_type type,
-                          const char *rmap_name, uint8_t use_json)
+                          const char *rmap_name, bool use_json)
 {
        json_object *json = NULL;
 
@@ -10463,18 +10470,17 @@ DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
        struct bgp *bgp = NULL;
        struct peer *peer;
        enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
-
        int idx = 0;
-       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
-       if (!idx)
-               return CMD_WARNING;
-
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (uj)
                argc--;
 
+       bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+                                           &bgp, uj);
+       if (!idx)
+               return CMD_WARNING;
+
        /* neighbors <A.B.C.D|X:X::X:X|WORD> */
        argv_find(argv, argc, "neighbors", &idx);
        peerstr = argv[++idx]->arg;
@@ -10536,7 +10542,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
        argv_find(argv, argc, "neighbors", &idx);
        peerstr = argv[++idx]->arg;
 
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        ret = str2sockunion(peerstr, &su);
        if (ret < 0) {
@@ -10580,7 +10586,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
 
 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
                                   afi_t afi, safi_t safi,
-                                  enum bgp_show_type type, uint8_t use_json)
+                                  enum bgp_show_type type, bool use_json)
 {
        /* labeled-unicast routes live in the unicast table */
        if (safi == SAFI_LABELED_UNICAST)
@@ -10620,14 +10626,17 @@ DEFUN (show_ip_bgp_flowspec_routes_detailed,
        safi_t safi = SAFI_UNICAST;
        struct bgp *bgp = NULL;
        int idx = 0;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       return bgp_show(vty, bgp, afi, safi,
-                       bgp_show_type_detail, NULL, use_json(argc, argv));
+       return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
 }
 
 DEFUN (show_ip_bgp_neighbor_routes,
@@ -10655,18 +10664,17 @@ DEFUN (show_ip_bgp_neighbor_routes,
        safi_t safi = SAFI_UNICAST;
        struct peer *peer;
        enum bgp_show_type sh_type = bgp_show_type_neighbor;
-
        int idx = 0;
+       bool uj = use_json(argc, argv);
+
+       if (uj)
+               argc--;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
-                                           &bgp);
+                                           &bgp, uj);
        if (!idx)
                return CMD_WARNING;
 
-       int uj = use_json(argc, argv);
-       if (uj)
-               argc--;
-
        /* neighbors <A.B.C.D|X:X::X:X|WORD> */
        argv_find(argv, argc, "neighbors", &idx);
        peerstr = argv[++idx]->arg;
index dfef9a8f79158c20f27cca79f92c59798b9cd018..476bb3aa0508d3586bad6223cca95271ffdeacab 100644 (file)
@@ -435,8 +435,9 @@ extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int,
                          safi_t, json_object *);
 extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *,
                              int, safi_t, json_object *);
-extern void route_vty_out_tmp(struct vty *, struct prefix *, struct attr *,
-                             safi_t, uint8_t, json_object *);
+extern void route_vty_out_tmp(struct vty *vty, struct prefix *p,
+                             struct attr *attr, safi_t safi, bool use_json,
+                             json_object *json_ar);
 extern void route_vty_out_overlay(struct vty *vty, struct prefix *p,
                                  struct bgp_info *binfo, int display,
                                  json_object *json);
@@ -484,5 +485,5 @@ extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
 extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
                             struct bgp_table *table, struct prefix_rd *prd,
                             enum bgp_show_type type, void *output_arg,
-                            uint8_t use_json);
+                            bool use_json);
 #endif /* _QUAGGA_BGP_ROUTE_H */
index 82b268c31d8b487b5d01d2abb5205f379d9fedce..2e0bb1ae6223ee7bbd7e51f47e6174f60919ae07 100644 (file)
@@ -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"
index a771eedf0f74019bc78790bbf23b9821782609ba..2b4477dddef4497b10d2456d974e5dc25b6d5aeb 100644 (file)
@@ -32,7 +32,7 @@
 
 int show_adj_route_vpn(struct vty *vty, struct peer *peer,
                       struct prefix_rd *prd, afi_t afi, safi_t safi,
-                      uint8_t use_json)
+                      bool use_json)
 {
        struct bgp *bgp;
        struct bgp_table *table;
index 98b4d9f1803c9d646ba58b92f0ba9a72826ba22c..a2e86476a2e51108a9a22d4ed2c4c13e267800d7 100644 (file)
@@ -25,6 +25,6 @@
 
 extern int show_adj_route_vpn(struct vty *vty, struct peer *peer,
                              struct prefix_rd *prd, afi_t afi, safi_t safi,
-                             uint8_t use_json);
+                             bool use_json);
 
 #endif /* _QUAGGA_BGP_VPN_H */
index 99c6f3923004fd02645759eced1018b6dbd2c63b..3669ea7736184fe73dd103391e32b7591a086bde 100644 (file)
@@ -301,7 +301,7 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index,
 int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
                                        struct cmd_token **argv, int argc,
                                        int *idx, afi_t *afi, safi_t *safi,
-                                       struct bgp **bgp)
+                                       struct bgp **bgp, bool use_json)
 {
        char *vrf_name = NULL;
 
@@ -325,9 +325,11 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
                else {
                        *bgp = bgp_lookup_by_name(vrf_name);
                        if (!*bgp) {
-                               vty_out(vty,
-                                       "View/Vrf specified is unknown: %s\n",
-                                       vrf_name);
+                               if (use_json)
+                                       vty_out(vty, "{}\n");
+                               else
+                                       vty_out(vty, "View/Vrf %s is unknown\n",
+                                               vrf_name);
                                *idx = 0;
                                return 0;
                        }
@@ -335,7 +337,11 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
        } else {
                *bgp = bgp_get_default();
                if (!*bgp) {
-                       vty_out(vty, "Unable to find default BGP instance\n");
+                       if (use_json)
+                               vty_out(vty, "{}\n");
+                       else
+                               vty_out(vty,
+                                       "Default BGP instance not found\n");
                        *idx = 0;
                        return 0;
                }
@@ -7343,7 +7349,7 @@ DEFUN (show_bgp_vrfs,
        struct list *inst = bm->bgp;
        struct listnode *node;
        struct bgp *bgp;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        json_object *json_vrfs = NULL;
        int count = 0;
@@ -7672,7 +7678,7 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json)
 
 /* Show BGP peer's summary information. */
 static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
-                           uint8_t use_json, json_object *json)
+                           bool use_json, json_object *json)
 {
        struct peer *peer;
        struct listnode *node, *nnode;
@@ -8089,14 +8095,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
 }
 
 static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
-                                     int safi, uint8_t use_json,
+                                     int safi, bool use_json,
                                      json_object *json)
 {
        int is_first = 1;
        int afi_wildcard = (afi == AFI_MAX);
        int safi_wildcard = (safi == SAFI_MAX);
        int is_wildcard = (afi_wildcard || safi_wildcard);
-       bool json_output = false;
+       bool nbr_output = false;
 
        if (use_json && is_wildcard)
                vty_out(vty, "{\n");
@@ -8107,7 +8113,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
                        safi = 1; /* SAFI_UNICAST */
                while (safi < SAFI_MAX) {
                        if (bgp_afi_safi_peer_exists(bgp, afi, safi)) {
-                               json_output = true;
+                               nbr_output = true;
                                if (is_wildcard) {
                                        /*
                                         * So limit output to those afi/safi
@@ -8146,22 +8152,28 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
 
        if (use_json && is_wildcard)
                vty_out(vty, "}\n");
-       else if (use_json && !json_output)
-               vty_out(vty, "{}\n");
+       else if (!nbr_output) {
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% No BGP neighbors found\n");
+       }
 }
 
 static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
-                                              safi_t safi, uint8_t use_json)
+                                              safi_t safi, bool use_json)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
        json_object *json = NULL;
        int is_first = 1;
+       bool nbr_output = false;
 
        if (use_json)
                vty_out(vty, "{\n");
 
        for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               nbr_output = true;
                if (use_json) {
                        json = json_object_new_object();
 
@@ -8185,10 +8197,12 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
 
        if (use_json)
                vty_out(vty, "}\n");
+       else if (!nbr_output)
+               vty_out(vty, "%% BGP instance not found\n");
 }
 
 int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
-                        safi_t safi, uint8_t use_json)
+                        safi_t safi, bool use_json)
 {
        struct bgp *bgp;
 
@@ -8205,7 +8219,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
                                        vty_out(vty, "{}\n");
                                else
                                        vty_out(vty,
-                                               "%% No such BGP instance exist\n");
+                                               "%% BGP instance not found\n");
                                return CMD_WARNING;
                        }
 
@@ -8219,6 +8233,13 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
 
        if (bgp)
                bgp_show_summary_afi_safi(vty, bgp, afi, safi, use_json, NULL);
+       else {
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% BGP instance not found\n");
+               return CMD_WARNING;
+       }
 
        return CMD_SUCCESS;
 }
@@ -8258,7 +8279,7 @@ DEFUN (show_ip_bgp_summary,
                argv_find_and_parse_safi(argv, argc, &idx, &safi);
        }
 
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        return bgp_show_summary_vty(vty, vrf, afi, safi, uj);
 }
@@ -8340,7 +8361,7 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
                                      afi_t afi, safi_t safi,
                                      uint16_t adv_smcap, uint16_t adv_rmcap,
                                      uint16_t rcv_smcap, uint16_t rcv_rmcap,
-                                     uint8_t use_json, json_object *json_pref)
+                                     bool use_json, json_object *json_pref)
 {
        /* Send-Mode */
        if (CHECK_FLAG(p->af_cap[afi][safi], adv_smcap)
@@ -8400,7 +8421,7 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
 }
 
 static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
-                             safi_t safi, uint8_t use_json,
+                             safi_t safi, bool use_json,
                              json_object *json_neigh)
 {
        struct bgp_filter *filter;
@@ -8975,7 +8996,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
        }
 }
 
-static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json,
+static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                          json_object *json)
 {
        struct bgp *bgp;
@@ -10722,12 +10743,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json,
 
 static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                             enum show_type type, union sockunion *su,
-                            const char *conf_if, uint8_t use_json,
+                            const char *conf_if, bool use_json,
                             json_object *json)
 {
        struct listnode *node, *nnode;
        struct peer *peer;
        int find = 0;
+       bool nbr_output = false;
 
        for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
                if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
@@ -10736,6 +10758,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                switch (type) {
                case show_all:
                        bgp_show_peer(vty, peer, use_json, json);
+                       nbr_output = true;
                        break;
                case show_peer:
                        if (conf_if) {
@@ -10765,6 +10788,9 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                        vty_out(vty, "%% No such neighbor in this view/vrf\n");
        }
 
+       if (type != show_peer && !nbr_output && !use_json)
+               vty_out(vty, "%% No BGP neighbors found\n");
+
        if (use_json) {
                vty_out(vty, "%s\n", json_object_to_json_string_ext(
                                             json, JSON_C_TO_STRING_PRETTY));
@@ -10779,18 +10805,20 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
 static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                                                 enum show_type type,
                                                 const char *ip_str,
-                                                uint8_t use_json)
+                                                bool use_json)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
        union sockunion su;
        json_object *json = NULL;
        int ret, is_first = 1;
+       bool nbr_output = false;
 
        if (use_json)
                vty_out(vty, "{\n");
 
        for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               nbr_output = true;
                if (use_json) {
                        if (!(json = json_object_new_object())) {
                                flog_err(
@@ -10843,11 +10871,13 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
 
        if (use_json)
                vty_out(vty, "}\n");
+       else if (!nbr_output)
+               vty_out(vty, "%% BGP instance not found\n");
 }
 
 static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                                 enum show_type type, const char *ip_str,
-                                uint8_t use_json)
+                                bool use_json)
 {
        int ret;
        struct bgp *bgp;
@@ -10864,8 +10894,6 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                        if (!bgp) {
                                if (use_json) {
                                        json = json_object_new_object();
-                                       json_object_boolean_true_add(
-                                               json, "bgpNoSuchInstance");
                                        vty_out(vty, "%s\n",
                                                json_object_to_json_string_ext(
                                                        json,
@@ -10873,7 +10901,7 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                                        json_object_free(json);
                                } else
                                        vty_out(vty,
-                                               "%% No such BGP instance exist\n");
+                                               "%% BGP instance not found\n");
 
                                return CMD_WARNING;
                        }
@@ -10897,6 +10925,11 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                                          json);
                }
                json_object_free(json);
+       } else {
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% BGP instance not found\n");
        }
 
        return CMD_SUCCESS;
@@ -10922,7 +10955,7 @@ DEFUN (show_ip_bgp_neighbors,
        char *sh_arg = NULL;
        enum show_type sh_type;
 
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        int idx = 0;
 
@@ -11037,8 +11070,8 @@ DEFUN (show_ip_bgp_attr_info,
        return CMD_SUCCESS;
 }
 
-static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
-                                  afi_t afi, safi_t safi, uint8_t use_json)
+static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
+                                  safi_t safi, bool use_json)
 {
        struct bgp *bgp;
        struct listnode *node;
@@ -11054,16 +11087,9 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
 
                json = json_object_new_object();
 
-               /* Provide context for the block */
-               json_object_string_add(json, "vrf", name ? name : "default");
-               json_object_string_add(json, "afiSafi",
-                                       afi_safi_print(afi, safi));
-
                bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
 
                if (!bgp) {
-                       json_object_boolean_true_add(json,
-                                                    "bgpNoSuchInstance");
                        vty_out(vty, "%s\n",
                                json_object_to_json_string_ext(
                                        json,
@@ -11073,6 +11099,11 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
                        return CMD_WARNING;
                }
 
+               /* Provide context for the block */
+               json_object_string_add(json, "vrf", name ? name : "default");
+               json_object_string_add(json, "afiSafi",
+                                      afi_safi_print(afi, safi));
+
                if (!CHECK_FLAG(bgp->af_flags[afi][safi],
                                BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
                        json_object_string_add(json, "importFromVrfs", "none");
@@ -11211,7 +11242,7 @@ DEFUN (show_ip_bgp_route_leak,
        afi_t afi = AFI_MAX;
        safi_t safi = SAFI_MAX;
 
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        int idx = 0;
 
        /* show [ip] bgp */
@@ -11536,7 +11567,7 @@ static int bgp_show_peer_group_vty(struct vty *vty, const char *name,
        bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
 
        if (!bgp) {
-               vty_out(vty, "%% No such BGP instance exists\n");
+               vty_out(vty, "%% BGP instance not found\n");
                return CMD_WARNING;
        }
 
index afb85f112b85ad975b1ea3a57bea0adcb2993f32..d9df2b4cfedab1771e36836ea954ebc21a3029e3 100644 (file)
@@ -69,9 +69,10 @@ extern int argv_find_and_parse_safi(struct cmd_token **argv, int argc,
 extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
                                               struct cmd_token **argv,
                                               int argc, int *idx, afi_t *afi,
-                                              safi_t *safi, struct bgp **bgp);
+                                              safi_t *safi, struct bgp **bgp,
+                                              bool use_json);
 extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
-                               safi_t safi, uint8_t use_json);
+                               safi_t safi, bool use_json);
 extern void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
                                            afi_t afi);
 #endif /* _QUAGGA_BGP_VTY_H */
index f42c16c1c1d46a85d99fe9116f086e02ef0dfbb0..43afc317e9b30e9a1ed4b19d2d9deda01842ce64 100644 (file)
@@ -2380,7 +2380,8 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
        int ipa_len;
        char buf[ETHER_ADDR_STRLEN];
        char buf1[INET6_ADDRSTRLEN];
-       uint8_t flags;
+       uint8_t flags = 0;
+       uint32_t seqnum = 0;
 
        memset(&ip, 0, sizeof(ip));
        s = zclient->ibuf;
@@ -2401,20 +2402,24 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
                        (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6;
                stream_get(&ip.ip.addr, s, ipa_len);
        }
-       flags = stream_getc(s);
+       if (command == ZEBRA_MACIP_ADD) {
+               flags = stream_getc(s);
+               seqnum = stream_getl(s);
+       }
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
        if (!bgp)
                return 0;
 
        if (BGP_DEBUG(zebra, ZEBRA))
-               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u",
+               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u",
                           vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
                           flags, prefix_mac2str(&mac, buf, sizeof(buf)),
-                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
+                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum);
 
        if (command == ZEBRA_MACIP_ADD)
-               return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, flags);
+               return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip,
+                                               flags, seqnum);
        else
                return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
 }
index e6c517a9f9b225c4a00bed2acb1d9a89baea166b..a9707a7fc73a3e3de5d2c5d1218e05fe75c2ab59 100644 (file)
@@ -6626,7 +6626,7 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi,
 }
 
 /* Display peer uptime.*/
-char *peer_uptime(time_t uptime2, char *buf, size_t len, uint8_t use_json,
+char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
                  json_object *json)
 {
        time_t uptime1, epoch_tbuf;
index 06eb86da95559f7c679b930405aef52d1a8b3106..8a997413901c0cc0f46d03889a867ab44ac6553e 100644 (file)
@@ -1513,7 +1513,8 @@ extern struct peer *peer_create(union sockunion *, const char *, struct bgp *,
                                struct peer_group *);
 extern struct peer *peer_create_accept(struct bgp *);
 extern void peer_xfer_config(struct peer *dst, struct peer *src);
-extern char *peer_uptime(time_t, char *, size_t, uint8_t, json_object *);
+extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
+                        json_object *json);
 
 extern int bgp_config_write(struct vty *);
 
index 8553846c9025137bbf0b5a0db3f14b6cf60f522c..f1dd08fda0825c12cb9c1f585ffad107e8980fbc 100644 (file)
@@ -23,7 +23,7 @@
 #include "lib/prefix.h"
 #include "lib/memory.h"
 #include "lib/linklist.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/plist.h"
 #include "lib/routemap.h"
 
@@ -126,10 +126,10 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
        struct rfapi_nve_group_cfg *rfg_vn = NULL;
        struct rfapi_nve_group_cfg *rfg_un = NULL;
 
-       struct route_table *rt_vn;
-       struct route_table *rt_un;
-       struct route_node *rn_vn;
-       struct route_node *rn_un;
+       struct agg_table *rt_vn;
+       struct agg_table *rt_un;
+       struct agg_node *rn_vn;
+       struct agg_node *rn_un;
 
        struct rfapi_nve_group_cfg *rfg;
        struct listnode *node, *nnode;
@@ -156,16 +156,16 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
                return NULL;
        }
 
-       rn_vn = route_node_match(rt_vn, vn); /* NB locks node */
+       rn_vn = agg_node_match(rt_vn, vn); /* NB locks node */
        if (rn_vn) {
                rfg_vn = rn_vn->info;
-               route_unlock_node(rn_vn);
+               agg_unlock_node(rn_vn);
        }
 
-       rn_un = route_node_match(rt_un, un); /* NB locks node */
+       rn_un = agg_node_match(rt_un, un); /* NB locks node */
        if (rn_un) {
                rfg_un = rn_un->info;
-               route_unlock_node(rn_un);
+               agg_unlock_node(rn_un);
        }
 
 #if BGP_VNC_DEBUG_MATCH_GROUP
@@ -2304,11 +2304,11 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */
 
        if (rfg->vn_node) {
                rfg->vn_node->info = NULL;
-               route_unlock_node(rfg->vn_node); /* frees */
+               agg_unlock_node(rfg->vn_node); /* frees */
        }
        if (rfg->un_node) {
                rfg->un_node->info = NULL;
-               route_unlock_node(rfg->un_node); /* frees */
+               agg_unlock_node(rfg->un_node); /* frees */
        }
        if (rfg->rfp_cfg)
                XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
@@ -2468,8 +2468,8 @@ DEFUN (vnc_nve_group_prefix,
        VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
        struct prefix p;
        afi_t afi;
-       struct route_table *rt;
-       struct route_node *rn;
+       struct agg_table *rt;
+       struct agg_node *rn;
        int is_un_prefix = 0;
 
        /* make sure it's still in list */
@@ -2497,12 +2497,12 @@ DEFUN (vnc_nve_group_prefix,
                rt = bgp->rfapi_cfg->nve_groups_vn[afi];
        }
 
-       rn = route_node_get(rt, &p); /* NB locks node */
+       rn = agg_node_get(rt, &p); /* NB locks node */
        if (rn->info) {
                /*
                 * There is already a group with this prefix
                 */
-               route_unlock_node(rn);
+               agg_unlock_node(rn);
                if (rn->info != rfg) {
                        /*
                         * different group name: fail
@@ -2535,7 +2535,7 @@ DEFUN (vnc_nve_group_prefix,
                /* detach rfg from previous route table location */
                if (rfg->un_node) {
                        rfg->un_node->info = NULL;
-                       route_unlock_node(rfg->un_node); /* frees */
+                       agg_unlock_node(rfg->un_node); /* frees */
                }
                rfg->un_node = rn; /* back ref */
                rfg->un_prefix = p;
@@ -2545,7 +2545,7 @@ DEFUN (vnc_nve_group_prefix,
                /* detach rfg from previous route table location */
                if (rfg->vn_node) {
                        rfg->vn_node->info = NULL;
-                       route_unlock_node(rfg->vn_node); /* frees */
+                       agg_unlock_node(rfg->vn_node); /* frees */
                }
                rfg->vn_node = rn; /* back ref */
                rfg->vn_prefix = p;
@@ -3761,8 +3761,8 @@ struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
        h->nve_groups_sequential = list_new();
        assert(h->nve_groups_sequential);
        for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               h->nve_groups_vn[afi] = route_table_init();
-               h->nve_groups_un[afi] = route_table_init();
+               h->nve_groups_vn[afi] = agg_table_init();
+               h->nve_groups_un[afi] = agg_table_init();
        }
        h->default_response_lifetime =
                BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
@@ -3820,8 +3820,8 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
        if (h->default_rfp_cfg)
                XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg);
        for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               route_table_finish(h->nve_groups_vn[afi]);
-               route_table_finish(h->nve_groups_un[afi]);
+               agg_table_finish(h->nve_groups_vn[afi]);
+               agg_table_finish(h->nve_groups_un[afi]);
        }
        XFREE(MTYPE_RFAPI_CFG, h);
 }
index a11b0992fa9343052f6565a2760f3b930ff88ef1..b72d38220be4939314a577fbebf6f13487d2a77e 100644 (file)
@@ -47,8 +47,8 @@ typedef enum {
 } rfapi_group_cfg_type_t;
 
 struct rfapi_nve_group_cfg {
-       struct route_node *vn_node; /* backref */
-       struct route_node *un_node; /* backref */
+       struct agg_node *vn_node; /* backref */
+       struct agg_node *un_node; /* backref */
 
        rfapi_group_cfg_type_t type; /* NVE|VPN */
        char *name;                  /* unique by type! */
@@ -135,8 +135,8 @@ struct rfapi_cfg {
        struct list *l2_groups; /* rfapi_l2_group_cfg list */
        /* three views into the same collection of rfapi_nve_group_cfg */
        struct list *nve_groups_sequential;
-       struct route_table *nve_groups_vn[AFI_MAX];
-       struct route_table *nve_groups_un[AFI_MAX];
+       struct agg_table *nve_groups_vn[AFI_MAX];
+       struct agg_table *nve_groups_un[AFI_MAX];
 
        /*
         * For Single VRF export to ordinary routing protocols. This is
index 355cf9205343759fe7a7e08d612c054cfa122249..51504bb0ad5005f907f3ae6060727f0141a1ecd6 100644 (file)
  * 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"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/memory.h"
 #include "lib/routemap.h"
@@ -203,11 +200,11 @@ int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2)
 
 static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
                           struct rfapi_ip_addr *un_addr,
-                          struct route_node **node)
+                          struct agg_node **node)
 {
        struct rfapi *h;
        struct prefix p;
-       struct route_node *rn;
+       struct agg_node *rn;
        int rc;
        afi_t afi;
 
@@ -228,12 +225,12 @@ static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
        if ((rc = rfapiRaddr2Qprefix(un_addr, &p)))
                return rc;
 
-       rn = route_node_lookup(h->un[afi], &p);
+       rn = agg_node_lookup(h->un[afi], &p);
 
        if (!rn)
                return ENOENT;
 
-       route_unlock_node(rn);
+       agg_unlock_node(rn);
 
        *node = rn;
 
@@ -244,7 +241,7 @@ static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
 int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
                   struct rfapi_ip_addr *un_addr, struct rfapi_descriptor **rfd)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
        int rc;
 
        rc = rfapi_find_node(bgp, vn_addr, un_addr, &rn);
@@ -1347,8 +1344,8 @@ static int rfapi_open_inner(struct rfapi_descriptor *rfd, struct bgp *bgp,
 #define RFD_RTINIT_AFI(rh, ary, afi)                                           \
        do {                                                                   \
                if (!ary[afi]) {                                               \
-                       ary[afi] = route_table_init();                         \
-                       ary[afi]->info = rh;                                   \
+                       ary[afi] = agg_table_init();                           \
+                       agg_set_table_info(ary[afi], rh);                      \
                }                                                              \
        } while (0)
 
@@ -1394,7 +1391,7 @@ int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd,
        char buf_un[BUFSIZ];
        afi_t afi_vn, afi_un;
        struct prefix pfx_un;
-       struct route_node *rn;
+       struct agg_node *rn;
 
 
        rfapi_time(&rfd->open_time);
@@ -1423,7 +1420,7 @@ int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd,
                assert(afi_vn && afi_un);
                assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un));
 
-               rn = route_node_get(h->un[afi_un], &pfx_un);
+               rn = agg_node_get(h->un[afi_un], &pfx_un);
                assert(rn);
                rfd->next = rn->info;
                rn->info = rfd;
@@ -1535,7 +1532,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
        afi_t afi;
        struct prefix p;
        struct prefix p_original;
-       struct route_node *rn;
+       struct agg_node *rn;
        struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
        struct bgp *bgp = rfd->bgp;
        struct rfapi_next_hop_entry *pNHE = NULL;
@@ -1704,7 +1701,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
                }
 
                if (rn) {
-                       route_lock_node(rn); /* so we can unlock below */
+                       agg_lock_node(rn); /* so we can unlock below */
                } else {
                        /*
                         * returns locked node. Don't unlock yet because the
@@ -1721,7 +1718,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
 
        assert(rn);
        if (!rn->info) {
-               route_unlock_node(rn);
+               agg_unlock_node(rn);
                vnc_zlog_debug_verbose(
                        "%s: VPN route not found, returning ENOENT", __func__);
                return ENOENT;
@@ -1758,7 +1755,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
                                                  &p_original);
        }
 
-       route_unlock_node(rn);
+       agg_unlock_node(rn);
 
 done:
        if (ppNextHopEntry) {
@@ -2170,7 +2167,7 @@ int rfapi_close(void *handle)
 {
        struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
        int rc;
-       struct route_node *node;
+       struct agg_node *node;
        struct bgp *bgp;
        struct rfapi *h;
 
@@ -2276,7 +2273,7 @@ int rfapi_close(void *handle)
                                }
                        }
                }
-               route_unlock_node(node);
+               agg_unlock_node(node);
        }
 
        /*
@@ -2928,6 +2925,8 @@ static void test_nexthops_callback(
 
        rfapiPrintNhl(stream, next_hops);
 
+       fp(out, "\n");
+
        rfapi_free_next_hop_list(next_hops);
 }
 
@@ -3049,7 +3048,7 @@ DEFUN (debug_rfapi_close_rfd,
 
 DEFUN (debug_rfapi_register_vn_un,
        debug_rfapi_register_vn_un_cmd,
-       "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS",
+       "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS [cost (0-255)]",
        DEBUG_STR
        DEBUG_RFAPI_STR
        "rfapi_register\n"
@@ -3063,7 +3062,9 @@ DEFUN (debug_rfapi_register_vn_un,
        "IPv4 prefix\n"
        "IPv6 prefix\n"
        "indicate lifetime follows\n"
-       "lifetime\n")
+       "lifetime\n"
+       "Cost (localpref = 255-cost)\n"
+       "0-255\n")
 {
        struct rfapi_ip_addr vn;
        struct rfapi_ip_addr un;
@@ -3072,6 +3073,7 @@ DEFUN (debug_rfapi_register_vn_un,
        uint32_t lifetime;
        struct rfapi_ip_prefix hpfx;
        int rc;
+       uint8_t cost = 100;
 
        /*
         * Get VN addr
@@ -3112,8 +3114,12 @@ DEFUN (debug_rfapi_register_vn_un,
                lifetime = strtoul(argv[10]->arg, NULL, 10);
        }
 
+       if (argc >= 13)
+               cost = (uint8_t) strtoul(argv[12]->arg, NULL, 10);
+       hpfx.cost = cost;
 
-       rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, 0);
+       rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL,
+                           RFAPI_REGISTER_ADD);
        if (rc) {
                vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc,
                        strerror(rc));
@@ -3213,7 +3219,8 @@ DEFUN (debug_rfapi_register_vn_un_l2o,
        /* L2 option parsing END */
 
        /* TBD fixme */
-       rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, 0);
+       rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt,
+                           RFAPI_REGISTER_ADD);
        if (rc) {
                vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc,
                        strerror(rc));
@@ -3225,7 +3232,7 @@ DEFUN (debug_rfapi_register_vn_un_l2o,
 
 DEFUN (debug_rfapi_unregister_vn_un,
        debug_rfapi_unregister_vn_un_cmd,
-       "debug rfapi-dev unregister vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
+       "debug rfapi-dev unregister vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> [kill]",
        DEBUG_STR
        DEBUG_RFAPI_STR
        "rfapi_register\n"
@@ -3233,7 +3240,8 @@ DEFUN (debug_rfapi_unregister_vn_un,
        "virtual network interface address\n"
        "indicate xt addr follows\n"
        "underlay network interface address\n"
-       "indicate prefix follows\n" "prefix")
+       "prefix to remove\n"
+       "Remove without holddown")
 {
        struct rfapi_ip_addr vn;
        struct rfapi_ip_addr un;
@@ -3275,7 +3283,9 @@ DEFUN (debug_rfapi_unregister_vn_un,
        }
        rfapiQprefix2Rprefix(&pfx, &hpfx);
 
-       rfapi_register(handle, &hpfx, 0, NULL, NULL, 1);
+       rfapi_register(handle, &hpfx, 0, NULL, NULL,
+                      (argc == 10 ?
+                       RFAPI_REGISTER_KILL : RFAPI_REGISTER_WITHDRAW));
 
        return CMD_SUCCESS;
 }
index 3112505d4b1aefe9bec9fa3cddc1f413db86ee97..c5fda15d33fc03c43e38b4346afcc33d99b0dd38 100644 (file)
  * 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"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/memory.h"
 #include "lib/routemap.h"
index 3217d34e77b37c42e3f22d2598a416de08226b5a..ce5acf002c20fa79932aac298a1946059cc45150 100644 (file)
@@ -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"
index ac3b6da23011472381e032e83278541e38c11d0f..4601718f1209e063b3bc9dff299fa228d79bea65 100644 (file)
  * Purpose:    Handle import of routes from BGP to RFAPI
  */
 
-#include <errno.h>
-
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/memory.h"
 #include "lib/log.h"
@@ -80,7 +78,7 @@
  */
 struct rfapi_withdraw {
        struct rfapi_import_table *import_table;
-       struct route_node *node;
+       struct agg_node *node;
        struct bgp_info *info;
        safi_t safi; /* used only for bulk operations */
        /*
@@ -88,8 +86,8 @@ struct rfapi_withdraw {
         * Normally when a timer expires, lockoffset should be 0. However, if
         * the timer expiration function is called directly (e.g.,
         * rfapiExpireVpnNow), the node could be locked by a preceding
-        * route_top() or route_next() in a loop, so we need to pass this
-        * value in.
+        * agg_route_top() or agg_route_next() in a loop, so we need to pass
+        * this value in.
         */
        int lockoffset;
 };
@@ -140,8 +138,8 @@ void rfapiCheckRouteCount()
        for (it = h->imports; it; it = it->next) {
                for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 
-                       struct route_table *rt;
-                       struct route_node *rn;
+                       struct agg_table *rt;
+                       struct agg_node *rn;
 
                        int holddown_count = 0;
                        int local_count = 0;
@@ -150,7 +148,8 @@ void rfapiCheckRouteCount()
 
                        rt = it->imported_vpn[afi];
 
-                       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                       for (rn = agg_route_top(rt); rn;
+                            rn = agg_route_next(rn)) {
                                struct bgp_info *bi;
                                struct bgp_info *next;
 
@@ -211,11 +210,11 @@ void rfapiCheckRouteCount()
  * Validate reference count for a node in an import table
  *
  * Normally lockoffset is 0 for nodes in quiescent state. However,
- * route_unlock_node will delete the node if it is called when
+ * agg_unlock_node will delete the node if it is called when
  * node->lock == 1, and we have to validate the refcount before
  * the node is deleted. In this case, we specify lockoffset 1.
  */
-void rfapiCheckRefcount(struct route_node *rn, safi_t safi, int lockoffset)
+void rfapiCheckRefcount(struct agg_node *rn, safi_t safi, int lockoffset)
 {
        unsigned int count_bi = 0;
        unsigned int count_monitor = 0;
@@ -613,8 +612,8 @@ struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, uint32_t lni)
                it->rt_import_list = enew;
 
                for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
-                       it->imported_vpn[afi] = route_table_init();
-                       it->imported_encap[afi] = route_table_init();
+                       it->imported_vpn[afi] = agg_table_init();
+                       it->imported_encap[afi] = agg_table_init();
                }
 
                it->l2_logical_net_id = lni;
@@ -633,10 +632,10 @@ struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, uint32_t lni)
  * Returns pointer to the list of moved monitors
  */
 static struct rfapi_monitor_vpn *
-rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset)
+rfapiMonitorMoveShorter(struct agg_node *original_vpn_node, int lockoffset)
 {
        struct bgp_info *bi;
-       struct route_node *par;
+       struct agg_node *par;
        struct rfapi_monitor_vpn *m;
        struct rfapi_monitor_vpn *mlast;
        struct rfapi_monitor_vpn *moved;
@@ -679,7 +678,8 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset)
         *    one route (even if it is only a withdrawn route) with a
         *    valid UN address. Call this node "Node P."
         */
-       for (par = original_vpn_node->parent; par; par = par->parent) {
+       for (par = agg_node_parent(original_vpn_node); par;
+            par = agg_node_parent(par)) {
                for (bi = par->info; bi; bi = bi->next) {
                        struct prefix pfx;
                        if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) {
@@ -699,14 +699,14 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset)
         */
        if (!par) {
                /* this isn't necessarily 0/0 */
-               par = route_top(original_vpn_node->table);
+               par = agg_route_table_top(original_vpn_node);
 
                /*
                 * If we got the top node but it wasn't 0/0,
                 * ignore it
                 */
                if (par && par->p.prefixlen) {
-                       route_unlock_node(par); /* maybe free */
+                       agg_unlock_node(par); /* maybe free */
                        par = NULL;
                }
 
@@ -725,7 +725,8 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset)
                pfx_default.family = original_vpn_node->p.family;
 
                /* creates default node if none exists */
-               par = route_node_get(original_vpn_node->table, &pfx_default);
+               par = agg_node_get(agg_get_table(original_vpn_node),
+                                  &pfx_default);
                ++parent_already_refcounted;
        }
 
@@ -764,18 +765,18 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset)
        RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN,
                             parent_already_refcounted - movecount);
        while (movecount > parent_already_refcounted) {
-               route_lock_node(par);
+               agg_lock_node(par);
                ++parent_already_refcounted;
        }
        while (movecount < parent_already_refcounted) {
                /* unlikely, but code defensively */
-               route_unlock_node(par);
+               agg_unlock_node(par);
                --parent_already_refcounted;
        }
        RFAPI_CHECK_REFCOUNT(original_vpn_node, SAFI_MPLS_VPN,
                             movecount + lockoffset);
        while (movecount--) {
-               route_unlock_node(original_vpn_node);
+               agg_unlock_node(original_vpn_node);
        }
 
 #if DEBUG_MONITOR_MOVE_SHORTER
@@ -796,12 +797,12 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset)
  * Implement MONITOR_MOVE_LONGER(new_node) from
  * RFAPI-Import-Event-Handling.txt
  */
-static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node)
+static void rfapiMonitorMoveLonger(struct agg_node *new_vpn_node)
 {
        struct rfapi_monitor_vpn *monitor;
        struct rfapi_monitor_vpn *mlast;
        struct bgp_info *bi;
-       struct route_node *par;
+       struct agg_node *par;
 
        RFAPI_CHECK_REFCOUNT(new_vpn_node, SAFI_MPLS_VPN, 0);
 
@@ -824,7 +825,8 @@ static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node)
        /*
         * Find first parent node that has monitors
         */
-       for (par = new_vpn_node->parent; par; par = par->parent) {
+       for (par = agg_node_parent(new_vpn_node); par;
+            par = agg_node_parent(par)) {
                if (RFAPI_MONITOR_VPN(par))
                        break;
        }
@@ -860,14 +862,14 @@ static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node)
                        RFAPI_MONITOR_VPN_W_ALLOC(new_vpn_node) = monitor;
                        monitor->node = new_vpn_node;
 
-                       route_lock_node(new_vpn_node); /* incr refcount */
+                       agg_lock_node(new_vpn_node); /* incr refcount */
 
                        monitor = mlast ? mlast->next : RFAPI_MONITOR_VPN(par);
 
                        RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, 1);
                        /* decr refcount after we're done with par as this might
                         * free it */
-                       route_unlock_node(par);
+                       agg_unlock_node(par);
 
                        continue;
                }
@@ -919,10 +921,10 @@ static void rfapiImportTableFlush(struct rfapi_import_table *it)
 
        for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 
-               struct route_node *rn;
+               struct agg_node *rn;
 
-               for (rn = route_top(it->imported_vpn[afi]); rn;
-                    rn = route_next(rn)) {
+               for (rn = agg_route_top(it->imported_vpn[afi]); rn;
+                    rn = agg_route_next(rn)) {
                        /*
                         * Each route_node has:
                         * aggregate: points to rfapi_it_extra with monitor
@@ -936,8 +938,8 @@ static void rfapiImportTableFlush(struct rfapi_import_table *it)
                        rfapiMonitorExtraFlush(SAFI_MPLS_VPN, rn);
                }
 
-               for (rn = route_top(it->imported_encap[afi]); rn;
-                    rn = route_next(rn)) {
+               for (rn = agg_route_top(it->imported_encap[afi]); rn;
+                    rn = agg_route_next(rn)) {
                        /* free bgp_info and its children */
                        rfapiBgpInfoChainFree(rn->info);
                        rn->info = NULL;
@@ -945,8 +947,8 @@ static void rfapiImportTableFlush(struct rfapi_import_table *it)
                        rfapiMonitorExtraFlush(SAFI_ENCAP, rn);
                }
 
-               route_table_finish(it->imported_vpn[afi]);
-               route_table_finish(it->imported_encap[afi]);
+               agg_table_finish(it->imported_vpn[afi]);
+               agg_table_finish(it->imported_encap[afi]);
        }
        if (it->monitor_exterior_orphans) {
                skiplist_free(it->monitor_exterior_orphans);
@@ -1293,9 +1295,9 @@ int rfapi_extract_l2o(
 
 static struct rfapi_next_hop_entry *
 rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix,
-                           struct bgp_info *bi,   /* route to encode */
-                           uint32_t lifetime,     /* use this in nhe */
-                           struct route_node *rn) /* req for L2 eth addr */
+                           struct bgp_info *bi, /* route to encode */
+                           uint32_t lifetime,   /* use this in nhe */
+                           struct agg_node *rn) /* req for L2 eth addr */
 {
        struct rfapi_next_hop_entry *new;
        int have_vnc_tunnel_un = 0;
@@ -1481,7 +1483,7 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix,
        return new;
 }
 
-int rfapiHasNonRemovedRoutes(struct route_node *rn)
+int rfapiHasNonRemovedRoutes(struct agg_node *rn)
 {
        struct bgp_info *bi;
 
@@ -1501,7 +1503,7 @@ int rfapiHasNonRemovedRoutes(struct route_node *rn)
 /*
  * DEBUG FUNCTION
  */
-void rfapiDumpNode(struct route_node *rn)
+void rfapiDumpNode(struct agg_node *rn)
 {
        struct bgp_info *bi;
 
@@ -1527,14 +1529,14 @@ void rfapiDumpNode(struct route_node *rn)
 #endif
 
 static int rfapiNhlAddNodeRoutes(
-       struct route_node *rn,                /* in */
+       struct agg_node *rn,                  /* in */
        struct rfapi_ip_prefix *rprefix,      /* in */
        uint32_t lifetime,                    /* in */
        int removed,                          /* in */
        struct rfapi_next_hop_entry **head,   /* in/out */
        struct rfapi_next_hop_entry **tail,   /* in/out */
        struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_node *rfd_rib_node,      /* preload this NVE rib node */
+       struct agg_node *rfd_rib_node,  /* preload this NVE rib node */
        struct prefix *pfx_target_original)   /* query target */
 {
        struct bgp_info *bi;
@@ -1544,15 +1546,17 @@ static int rfapiNhlAddNodeRoutes(
        int count = 0;
        int is_l2 = (rn->p.family == AF_ETHERNET);
 
-       if (rfd_rib_node && rfd_rib_node->table && rfd_rib_node->table->info) {
+       if (rfd_rib_node) {
+               struct agg_table *atable = agg_get_table(rfd_rib_node);
                struct rfapi_descriptor *rfd;
 
-               rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info);
-
-               if (rfapiRibFTDFilterRecentPrefix(
-                       rfd, rn, pfx_target_original))
+               if (atable) {
+                       rfd = agg_get_table_info(atable);
 
-                       return 0;
+                       if (rfapiRibFTDFilterRecentPrefix(rfd, rn,
+                                                         pfx_target_original))
+                               return 0;
+               }
        }
 
        seen_nexthops =
@@ -1657,13 +1661,13 @@ static int rfapiNhlAddNodeRoutes(
  * matches (of course, we still travel down its child subtrees).
  */
 static int rfapiNhlAddSubtree(
-       struct route_node *rn,                /* in */
+       struct agg_node *rn,                  /* in */
        uint32_t lifetime,                    /* in */
        struct rfapi_next_hop_entry **head,   /* in/out */
        struct rfapi_next_hop_entry **tail,   /* in/out */
-       struct route_node *omit_node,    /* in */
+       struct agg_node *omit_node,        /* in */
        struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_table *rfd_rib_table,    /* preload here */
+       struct agg_table *rfd_rib_table,      /* preload here */
        struct prefix *pfx_target_original)   /* query target */
 {
        struct rfapi_ip_prefix rprefix;
@@ -1671,65 +1675,67 @@ static int rfapiNhlAddSubtree(
 
        /* FIXME: need to find a better way here to work without sticking our
         * hands in node->link */
-       if (rn->l_left && rn->l_left != omit_node) {
-               if (rn->l_left->info) {
+       if (agg_node_left(rn) && agg_node_left(rn) != omit_node) {
+               if (agg_node_left(rn)->info) {
                        int count = 0;
-                       struct route_node *rib_rn = NULL;
+                       struct agg_node *rib_rn = NULL;
 
-                       rfapiQprefix2Rprefix(&rn->l_left->p, &rprefix);
+                       rfapiQprefix2Rprefix(&agg_node_left(rn)->p, &rprefix);
                        if (rfd_rib_table) {
-                               rib_rn = route_node_get(rfd_rib_table,
-                                                       &rn->l_left->p);
+                               rib_rn = agg_node_get(rfd_rib_table,
+                                                     &agg_node_left(rn)->p);
                        }
 
                        count = rfapiNhlAddNodeRoutes(
-                               rn->l_left, &rprefix, lifetime, 0, head, tail,
-                               exclude_vnaddr, rib_rn, pfx_target_original);
+                               agg_node_left(rn), &rprefix, lifetime, 0, head,
+                               tail, exclude_vnaddr, rib_rn,
+                               pfx_target_original);
                        if (!count) {
                                count = rfapiNhlAddNodeRoutes(
-                                       rn->l_left, &rprefix, lifetime, 1, head,
-                                       tail, exclude_vnaddr, rib_rn,
+                                       agg_node_left(rn), &rprefix, lifetime,
+                                       1, head, tail, exclude_vnaddr, rib_rn,
                                        pfx_target_original);
                        }
                        rcount += count;
                        if (rib_rn)
-                               route_unlock_node(rib_rn);
+                               agg_unlock_node(rib_rn);
                }
        }
 
-       if (rn->l_right && rn->l_right != omit_node) {
-               if (rn->l_right->info) {
+       if (agg_node_right(rn) && agg_node_right(rn) != omit_node) {
+               if (agg_node_right(rn)->info) {
                        int count = 0;
-                       struct route_node *rib_rn = NULL;
+                       struct agg_node *rib_rn = NULL;
 
-                       rfapiQprefix2Rprefix(&rn->l_right->p, &rprefix);
+                       rfapiQprefix2Rprefix(&agg_node_right(rn)->p, &rprefix);
                        if (rfd_rib_table) {
-                               rib_rn = route_node_get(rfd_rib_table,
-                                                       &rn->l_right->p);
+                               rib_rn = agg_node_get(rfd_rib_table,
+                                                     &agg_node_right(rn)->p);
                        }
                        count = rfapiNhlAddNodeRoutes(
-                               rn->l_right, &rprefix, lifetime, 0, head, tail,
-                               exclude_vnaddr, rib_rn, pfx_target_original);
+                               agg_node_right(rn), &rprefix, lifetime, 0, head,
+                               tail, exclude_vnaddr, rib_rn,
+                               pfx_target_original);
                        if (!count) {
                                count = rfapiNhlAddNodeRoutes(
-                                       rn->l_right, &rprefix, lifetime, 1,
-                                       head, tail, exclude_vnaddr, rib_rn,
+                                       agg_node_right(rn), &rprefix, lifetime,
+                                       1, head, tail, exclude_vnaddr, rib_rn,
                                        pfx_target_original);
                        }
                        rcount += count;
                        if (rib_rn)
-                               route_unlock_node(rib_rn);
+                               agg_unlock_node(rib_rn);
                }
        }
 
-       if (rn->l_left) {
+       if (agg_node_left(rn)) {
                rcount += rfapiNhlAddSubtree(
-                       rn->l_left, lifetime, head, tail, omit_node,
+                       agg_node_left(rn), lifetime, head, tail, omit_node,
                        exclude_vnaddr, rfd_rib_table, pfx_target_original);
        }
-       if (rn->l_right) {
+       if (agg_node_right(rn)) {
                rcount += rfapiNhlAddSubtree(
-                       rn->l_right, lifetime, head, tail, omit_node,
+                       agg_node_right(rn), lifetime, head, tail, omit_node,
                        exclude_vnaddr, rfd_rib_table, pfx_target_original);
        }
 
@@ -1748,17 +1754,17 @@ static int rfapiNhlAddSubtree(
  * next less-specific node (i.e., this node's parent) at the end.
  */
 struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
-       struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */
-       struct rfapi_ip_addr *exclude_vnaddr,     /* omit routes to same NVE */
-       struct route_table *rfd_rib_table,      /* preload here */
-       struct prefix *pfx_target_original)       /* query target */
+       struct agg_node *rn, uint32_t lifetime, /* put into nexthop entries */
+       struct rfapi_ip_addr *exclude_vnaddr,   /* omit routes to same NVE */
+       struct agg_table *rfd_rib_table,        /* preload here */
+       struct prefix *pfx_target_original)     /* query target */
 {
        struct rfapi_ip_prefix rprefix;
        struct rfapi_next_hop_entry *answer = NULL;
        struct rfapi_next_hop_entry *last = NULL;
-       struct route_node *parent;
+       struct agg_node *parent;
        int count = 0;
-       struct route_node *rib_rn;
+       struct agg_node *rib_rn;
 
 #if DEBUG_RETURNED_NHL
        {
@@ -1773,7 +1779,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
 
        rfapiQprefix2Rprefix(&rn->p, &rprefix);
 
-       rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL;
+       rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, &rn->p) : NULL;
 
        /*
         * Add non-withdrawn routes at this node
@@ -1795,7 +1801,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
                rfapiPrintNhl(NULL, answer);
 #endif
                if (rib_rn)
-                       route_unlock_node(rib_rn);
+                       agg_unlock_node(rib_rn);
                return answer;
        }
 
@@ -1806,7 +1812,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
                                      exclude_vnaddr, rib_rn,
                                      pfx_target_original);
        if (rib_rn)
-               route_unlock_node(rib_rn);
+               agg_unlock_node(rib_rn);
 
        // rfapiPrintNhl(NULL, answer);
 
@@ -1814,7 +1820,8 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
         * walk up the tree until we find a node with non-deleted
         * routes, then add them
         */
-       for (parent = rn->parent; parent; parent = parent->parent) {
+       for (parent = agg_node_parent(rn); parent;
+            parent = agg_node_parent(parent)) {
                if (rfapiHasNonRemovedRoutes(parent)) {
                        break;
                }
@@ -1824,9 +1831,8 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
         * Add non-withdrawn routes from less-specific prefix
         */
        if (parent) {
-               rib_rn = rfd_rib_table
-                                ? route_node_get(rfd_rib_table, &parent->p)
-                                : NULL;
+               rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, &parent->p)
+                                      : NULL;
                rfapiQprefix2Rprefix(&parent->p, &rprefix);
                count += rfapiNhlAddNodeRoutes(parent, &rprefix, lifetime, 0,
                                               &answer, &last, exclude_vnaddr,
@@ -1835,7 +1841,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
                                            rn, exclude_vnaddr, rfd_rib_table,
                                            pfx_target_original);
                if (rib_rn)
-                       route_unlock_node(rib_rn);
+                       agg_unlock_node(rib_rn);
        } else {
                /*
                 * There is no parent with non-removed routes. Still need to
@@ -1861,19 +1867,18 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
  * Construct nexthop list of all routes in table
  */
 struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList(
-       struct route_table *rt,
-       uint32_t lifetime,                    /* put into nexthop entries */
-       struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_table *rfd_rib_table,    /* preload this NVE rib table */
-       struct prefix *pfx_target_original)   /* query target */
+       struct agg_table *rt, uint32_t lifetime, /* put into nexthop entries */
+       struct rfapi_ip_addr *exclude_vnaddr,    /* omit routes to same NVE */
+       struct agg_table *rfd_rib_table,    /* preload this NVE rib table */
+       struct prefix *pfx_target_original) /* query target */
 {
-       struct route_node *rn;
+       struct agg_node *rn;
        struct rfapi_next_hop_entry *biglist = NULL;
        struct rfapi_next_hop_entry *nhl;
        struct rfapi_next_hop_entry *tail = NULL;
        int count = 0;
 
-       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+       for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
 
                nhl = rfapiRouteNode2NextHopList(rn, lifetime, exclude_vnaddr,
                                                 rfd_rib_table,
@@ -1898,18 +1903,18 @@ struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList(
 }
 
 struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
-       struct route_node *rn, struct rfapi_ip_prefix *rprefix,
+       struct agg_node *rn, struct rfapi_ip_prefix *rprefix,
        uint32_t lifetime,                    /* put into nexthop entries */
        struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_table *rfd_rib_table,    /* preload NVE rib table */
+       struct agg_table *rfd_rib_table,      /* preload NVE rib table */
        struct prefix *pfx_target_original)   /* query target */
 {
        int count = 0;
        struct rfapi_next_hop_entry *answer = NULL;
        struct rfapi_next_hop_entry *last = NULL;
-       struct route_node *rib_rn;
+       struct agg_node *rib_rn;
 
-       rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL;
+       rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, &rn->p) : NULL;
 
        count = rfapiNhlAddNodeRoutes(rn, rprefix, lifetime, 0, &answer, &last,
                                      NULL, rib_rn, pfx_target_original);
@@ -1928,7 +1933,7 @@ struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
        }
 
        if (rib_rn)
-               route_unlock_node(rib_rn);
+               agg_unlock_node(rib_rn);
 
 #if DEBUG_RETURNED_NHL
        rfapiPrintNhl(NULL, answer);
@@ -1945,13 +1950,13 @@ struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList(
        uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix,
        uint32_t lifetime,                    /* put into nexthop entries */
        struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_table *rfd_rib_table,    /* preload NVE rib node */
+       struct agg_table *rfd_rib_table,      /* preload NVE rib node */
        struct prefix *pfx_target_original)   /* query target */
 {
        struct rfapi_import_table *it;
        struct bgp *bgp = bgp_get_default();
-       struct route_table *rt;
-       struct route_node *rn;
+       struct agg_table *rt;
+       struct agg_node *rn;
        struct rfapi_next_hop_entry *biglist = NULL;
        struct rfapi_next_hop_entry *nhl;
        struct rfapi_next_hop_entry *tail = NULL;
@@ -1961,7 +1966,7 @@ struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList(
        it = rfapiMacImportTableGet(bgp, logical_net_id);
        rt = it->imported_vpn[AFI_L2VPN];
 
-       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+       for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
 
                nhl = rfapiEthRouteNode2NextHopList(
                        rn, rprefix, lifetime, exclude_vnaddr, rfd_rib_table,
@@ -1989,7 +1994,7 @@ struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList(
  * Insert a new bi to the imported route table node,
  * keeping the list of BIs sorted best route first
  */
-static void rfapiBgpInfoAttachSorted(struct route_node *rn,
+static void rfapiBgpInfoAttachSorted(struct agg_node *rn,
                                     struct bgp_info *info_new, afi_t afi,
                                     safi_t safi)
 {
@@ -2031,7 +2036,7 @@ static void rfapiBgpInfoAttachSorted(struct route_node *rn,
        bgp_attr_intern(info_new->attr);
 }
 
-static void rfapiBgpInfoDetach(struct route_node *rn, struct bgp_info *bi)
+static void rfapiBgpInfoDetach(struct agg_node *rn, struct bgp_info *bi)
 {
        /*
         * Remove the route (doubly-linked)
@@ -2127,8 +2132,8 @@ static int rfapi_bi_peer_rd_aux_cmp(void *b1, void *b2)
 /*
  * Index on RD and Peer
  */
-static void rfapiItBiIndexAdd(struct route_node *rn, /* Import table VPN node */
-                             struct bgp_info *bi)   /* new BI */
+static void rfapiItBiIndexAdd(struct agg_node *rn, /* Import table VPN node */
+                             struct bgp_info *bi) /* new BI */
 {
        struct skiplist *sl;
 
@@ -2153,15 +2158,15 @@ static void rfapiItBiIndexAdd(struct route_node *rn, /* Import table VPN node */
                        sl = skiplist_new(0, rfapi_bi_peer_rd_cmp, NULL);
                }
                RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd = sl;
-               route_lock_node(rn); /* for skiplist */
+               agg_lock_node(rn); /* for skiplist */
        }
        assert(!skiplist_insert(sl, (void *)bi, (void *)bi));
-       route_lock_node(rn); /* for skiplist entry */
+       agg_lock_node(rn); /* for skiplist entry */
 
        /* NB: BIs in import tables are not refcounted */
 }
 
-static void rfapiItBiIndexDump(struct route_node *rn)
+static void rfapiItBiIndexDump(struct agg_node *rn)
 {
        struct skiplist *sl;
        void *cursor = NULL;
@@ -2192,7 +2197,7 @@ static void rfapiItBiIndexDump(struct route_node *rn)
 }
 
 static struct bgp_info *rfapiItBiIndexSearch(
-       struct route_node *rn, /* Import table VPN node */
+       struct agg_node *rn, /* Import table VPN node */
        struct prefix_rd *prd, struct peer *peer,
        struct prefix *aux_prefix) /* optional L3 addr for L2 ITs */
 {
@@ -2298,8 +2303,8 @@ static struct bgp_info *rfapiItBiIndexSearch(
        return bi_result;
 }
 
-static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */
-                             struct bgp_info *bi)   /* old BI */
+static void rfapiItBiIndexDel(struct agg_node *rn, /* Import table VPN node */
+                             struct bgp_info *bi) /* old BI */
 {
        struct skiplist *sl;
        int rc;
@@ -2322,7 +2327,7 @@ static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */
        }
        assert(!rc);
 
-       route_unlock_node(rn); /* for skiplist entry */
+       agg_unlock_node(rn); /* for skiplist entry */
 
        /* NB: BIs in import tables are not refcounted */
 }
@@ -2332,17 +2337,16 @@ static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */
  * refers to it
  */
 static void rfapiMonitorEncapAdd(struct rfapi_import_table *import_table,
-                                struct prefix *p,        /* VN address */
-                                struct route_node *vpn_rn, /* VPN node */
-                                struct bgp_info *vpn_bi)   /* VPN bi/route */
+                                struct prefix *p,      /* VN address */
+                                struct agg_node *vpn_rn, /* VPN node */
+                                struct bgp_info *vpn_bi) /* VPN bi/route */
 {
        afi_t afi = family2afi(p->family);
-       struct route_node *rn;
+       struct agg_node *rn;
        struct rfapi_monitor_encap *m;
 
        assert(afi);
-       rn = route_node_get(import_table->imported_encap[afi],
-                           p); /* locks rn */
+       rn = agg_node_get(import_table->imported_encap[afi], p); /* locks rn */
        assert(rn);
 
        m = XCALLOC(MTYPE_RFAPI_MONITOR_ENCAP,
@@ -2399,7 +2403,7 @@ static void rfapiMonitorEncapDelete(struct bgp_info *vpn_bi)
                         * freed */
                        rfapiMonitorExtraPrune(SAFI_ENCAP, hme->rn);
 
-                       route_unlock_node(hme->rn); /* decr ref count */
+                       agg_unlock_node(hme->rn); /* decr ref count */
                        XFREE(MTYPE_RFAPI_MONITOR_ENCAP, hme);
                        vpn_bi->extra->vnc.import.hme = NULL;
                }
@@ -2533,7 +2537,7 @@ done:
        }
 
        RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset);
-       route_unlock_node(wcb->node); /* decr ref count */
+       agg_unlock_node(wcb->node); /* decr ref count */
        XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
        return 0;
 }
@@ -2660,7 +2664,7 @@ static void rfapiCopyUnEncap2VPN(struct bgp_info *encap_bi,
  */
 static int rfapiWithdrawEncapUpdateCachedUn(
        struct rfapi_import_table *import_table, struct bgp_info *encap_bi,
-       struct route_node *vpn_rn, struct bgp_info *vpn_bi)
+       struct agg_node *vpn_rn, struct bgp_info *vpn_bi)
 {
        if (!encap_bi) {
 
@@ -2762,7 +2766,7 @@ static int rfapiWithdrawTimerEncap(struct thread *t)
        /*
         * for each VPN node referenced in the ENCAP monitors:
         */
-       struct route_node *rn;
+       struct agg_node *rn;
        while (!skiplist_first(vpn_node_sl, (void **)&rn, NULL)) {
                if (!wcb->node->info) {
                        struct rfapi_monitor_vpn *moved;
@@ -2783,7 +2787,7 @@ static int rfapiWithdrawTimerEncap(struct thread *t)
 
 done:
        RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 1);
-       route_unlock_node(wcb->node); /* decr ref count */
+       agg_unlock_node(wcb->node); /* decr ref count */
        XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
        skiplist_free(vpn_node_sl);
        return 0;
@@ -2796,7 +2800,7 @@ done:
  */
 static void
 rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table,
-                         struct route_node *rn, struct bgp_info *bi, afi_t afi,
+                         struct agg_node *rn, struct bgp_info *bi, afi_t afi,
                          safi_t safi,
                          int (*timer_service_func)(struct thread *))
 {
@@ -2886,7 +2890,7 @@ typedef void(rfapi_bi_filtered_import_f)(struct rfapi_import_table *, int,
 
 
 static void rfapiExpireEncapNow(struct rfapi_import_table *it,
-                               struct route_node *rn, struct bgp_info *bi)
+                               struct agg_node *rn, struct bgp_info *bi)
 {
        struct rfapi_withdraw *wcb;
        struct thread t;
@@ -2939,8 +2943,8 @@ static void rfapiBgpInfoFilteredImportEncap(
        uint8_t sub_type,  /* part of bgp_info */
        uint32_t *label)   /* part of bgp_info */
 {
-       struct route_table *rt = NULL;
-       struct route_node *rn;
+       struct agg_table *rt = NULL;
+       struct agg_node *rn;
        struct bgp_info *info_new;
        struct bgp_info *bi;
        struct bgp_info *next;
@@ -3034,10 +3038,10 @@ static void rfapiBgpInfoFilteredImportEncap(
        }
 
        /*
-        * route_node_lookup returns a node only if there is at least
+        * agg_node_lookup returns a node only if there is at least
         * one route attached.
         */
-       rn = route_node_lookup(rt, p);
+       rn = agg_node_lookup(rt, p);
 
 #if DEBUG_ENCAP_MONITOR
        vnc_zlog_debug_verbose("%s: initial encap lookup(it=%p) rn=%p",
@@ -3047,7 +3051,7 @@ static void rfapiBgpInfoFilteredImportEncap(
        if (rn) {
 
                RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 1);
-               route_unlock_node(rn); /* undo lock in route_node_lookup */
+               agg_unlock_node(rn); /* undo lock in agg_node_lookup */
 
 
                /*
@@ -3187,9 +3191,9 @@ static void rfapiBgpInfoFilteredImportEncap(
 
        if (rn) {
                if (!replacing)
-                       route_lock_node(rn); /* incr ref count for new BI */
+                       agg_lock_node(rn); /* incr ref count for new BI */
        } else {
-               rn = route_node_get(rt, p);
+               rn = agg_node_get(rt, p);
        }
 
        vnc_zlog_debug_verbose(
@@ -3254,7 +3258,7 @@ static void rfapiBgpInfoFilteredImportEncap(
                struct rfapi_monitor_encap *m;
                struct rfapi_monitor_encap *mnext;
 
-               struct route_node *referenced_vpn_prefix;
+               struct agg_node *referenced_vpn_prefix;
 
                /*
                 * Optimized approach: build radix tree on the fly to
@@ -3265,9 +3269,9 @@ static void rfapiBgpInfoFilteredImportEncap(
                 * struct rfapi_monitor_encap, each of which refers to a
                 * specific VPN node.
                 */
-               struct route_table *referenced_vpn_table;
+               struct agg_table *referenced_vpn_table;
 
-               referenced_vpn_table = route_table_init();
+               referenced_vpn_table = agg_table_init();
                assert(referenced_vpn_table);
 
 /*
@@ -3306,8 +3310,8 @@ static void rfapiBgpInfoFilteredImportEncap(
                         * per prefix.
                         */
 
-                       referenced_vpn_prefix = route_node_get(
-                               referenced_vpn_table, &m->node->p);
+                       referenced_vpn_prefix =
+                               agg_node_get(referenced_vpn_table, &m->node->p);
                        assert(referenced_vpn_prefix);
                        for (mnext = referenced_vpn_prefix->info; mnext;
                             mnext = mnext->next) {
@@ -3320,7 +3324,7 @@ static void rfapiBgpInfoFilteredImportEncap(
                                /*
                                 * already have an entry for this VPN node
                                 */
-                               route_unlock_node(referenced_vpn_prefix);
+                               agg_unlock_node(referenced_vpn_prefix);
                        } else {
                                mnext = XCALLOC(
                                        MTYPE_RFAPI_MONITOR_ENCAP,
@@ -3335,16 +3339,18 @@ static void rfapiBgpInfoFilteredImportEncap(
                /*
                 * for each VPN node referenced in the ENCAP monitors:
                 */
-               for (referenced_vpn_prefix = route_top(referenced_vpn_table);
-                    referenced_vpn_prefix; referenced_vpn_prefix = route_next(
-                                                   referenced_vpn_prefix)) {
+               for (referenced_vpn_prefix =
+                            agg_route_top(referenced_vpn_table);
+                    referenced_vpn_prefix;
+                    referenced_vpn_prefix =
+                            agg_route_next(referenced_vpn_prefix)) {
 
                        while ((m = referenced_vpn_prefix->info)) {
 
-                               struct route_node *n;
+                               struct agg_node *n;
 
                                rfapiMonitorMoveLonger(m->node);
-                               for (n = m->node; n; n = n->parent) {
+                               for (n = m->node; n; n = agg_node_parent(n)) {
                                        // rfapiDoRouteCallback(import_table, n,
                                        // NULL);
                                }
@@ -3352,18 +3358,18 @@ static void rfapiBgpInfoFilteredImportEncap(
                                                          NULL);
 
                                referenced_vpn_prefix->info = m->next;
-                               route_unlock_node(referenced_vpn_prefix);
+                               agg_unlock_node(referenced_vpn_prefix);
                                XFREE(MTYPE_RFAPI_MONITOR_ENCAP, m);
                        }
                }
-               route_table_finish(referenced_vpn_table);
+               agg_table_finish(referenced_vpn_table);
        }
 
        RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 0);
 }
 
 static void rfapiExpireVpnNow(struct rfapi_import_table *it,
-                             struct route_node *rn, struct bgp_info *bi,
+                             struct agg_node *rn, struct bgp_info *bi,
                              int lockoffset)
 {
        struct rfapi_withdraw *wcb;
@@ -3398,9 +3404,9 @@ void rfapiBgpInfoFilteredImportVPN(
        uint8_t sub_type,  /* part of bgp_info */
        uint32_t *label)   /* part of bgp_info */
 {
-       struct route_table *rt = NULL;
-       struct route_node *rn;
-       struct route_node *n;
+       struct agg_table *rt = NULL;
+       struct agg_node *rn;
+       struct agg_node *n;
        struct bgp_info *info_new;
        struct bgp_info *bi;
        struct bgp_info *next;
@@ -3408,7 +3414,7 @@ void rfapiBgpInfoFilteredImportVPN(
        struct prefix vn_prefix;
        struct prefix un_prefix;
        int un_prefix_valid = 0;
-       struct route_node *ern;
+       struct agg_node *ern;
        int replacing = 0;
        int original_had_routes = 0;
        struct prefix original_nexthop;
@@ -3494,17 +3500,17 @@ void rfapiBgpInfoFilteredImportVPN(
        memset(&original_nexthop, 0, sizeof(original_nexthop));
 
        /*
-        * route_node_lookup returns a node only if there is at least
+        * agg_node_lookup returns a node only if there is at least
         * one route attached.
         */
-       rn = route_node_lookup(rt, p);
+       rn = agg_node_lookup(rt, p);
 
        vnc_zlog_debug_verbose("%s: rn=%p", __func__, rn);
 
        if (rn) {
 
                RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 1);
-               route_unlock_node(rn); /* undo lock in route_node_lookup */
+               agg_unlock_node(rn); /* undo lock in agg_node_lookup */
 
                if (rn->info)
                        original_had_routes = 1;
@@ -3667,10 +3673,10 @@ void rfapiBgpInfoFilteredImportVPN(
        /*
         * lookup un address in encap table
         */
-       ern = route_node_match(import_table->imported_encap[afi], &vn_prefix);
+       ern = agg_node_match(import_table->imported_encap[afi], &vn_prefix);
        if (ern) {
                rfapiCopyUnEncap2VPN(ern->info, info_new);
-               route_unlock_node(ern); /* undo lock in route_note_match */
+               agg_unlock_node(ern); /* undo lock in route_note_match */
        } else {
                char buf[PREFIX_STRLEN];
 
@@ -3683,13 +3689,13 @@ void rfapiBgpInfoFilteredImportVPN(
 
        if (rn) {
                if (!replacing)
-                       route_lock_node(rn);
+                       agg_lock_node(rn);
        } else {
                /*
                 * No need to increment reference count, so only "get"
                 * if the node is not there already
                 */
-               rn = route_node_get(rt, p);
+               rn = agg_node_get(rt, p);
        }
 
        /*
@@ -3856,7 +3862,7 @@ void rfapiBgpInfoFilteredImportVPN(
        }
 
        if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) {
-               for (n = rn; n; n = n->parent) {
+               for (n = rn; n; n = agg_node_parent(n)) {
                        // rfapiDoRouteCallback(import_table, n, NULL);
                }
                rfapiMonitorItNodeChanged(import_table, rn, NULL);
@@ -4108,9 +4114,9 @@ static void rfapiProcessPeerDownRt(struct peer *peer,
                                   struct rfapi_import_table *import_table,
                                   afi_t afi, safi_t safi)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
        struct bgp_info *bi;
-       struct route_table *rt;
+       struct agg_table *rt;
        int (*timer_service_func)(struct thread *);
 
        assert(afi == AFI_IP || afi == AFI_IP6);
@@ -4131,7 +4137,7 @@ static void rfapiProcessPeerDownRt(struct peer *peer,
        }
 
 
-       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+       for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
                for (bi = rn->info; bi; bi = bi->next) {
                        if (bi->peer == peer) {
 
@@ -4274,7 +4280,7 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp)
        h = (struct rfapi *)XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi));
 
        for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               h->un[afi] = route_table_init();
+               h->un[afi] = agg_table_init();
        }
 
        /*
@@ -4282,10 +4288,10 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp)
         */
        h->it_ce = XCALLOC(MTYPE_RFAPI_IMPORTTABLE,
                           sizeof(struct rfapi_import_table));
-       h->it_ce->imported_vpn[AFI_IP] = route_table_init();
-       h->it_ce->imported_vpn[AFI_IP6] = route_table_init();
-       h->it_ce->imported_encap[AFI_IP] = route_table_init();
-       h->it_ce->imported_encap[AFI_IP6] = route_table_init();
+       h->it_ce->imported_vpn[AFI_IP] = agg_table_init();
+       h->it_ce->imported_vpn[AFI_IP6] = agg_table_init();
+       h->it_ce->imported_encap[AFI_IP] = agg_table_init();
+       h->it_ce->imported_encap[AFI_IP6] = agg_table_init();
        rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP, SAFI_MPLS_VPN);
        rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP6, SAFI_MPLS_VPN);
 
@@ -4317,10 +4323,10 @@ void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
                h->resolve_nve_nexthop = NULL;
        }
 
-       route_table_finish(h->it_ce->imported_vpn[AFI_IP]);
-       route_table_finish(h->it_ce->imported_vpn[AFI_IP6]);
-       route_table_finish(h->it_ce->imported_encap[AFI_IP]);
-       route_table_finish(h->it_ce->imported_encap[AFI_IP6]);
+       agg_table_finish(h->it_ce->imported_vpn[AFI_IP]);
+       agg_table_finish(h->it_ce->imported_vpn[AFI_IP6]);
+       agg_table_finish(h->it_ce->imported_encap[AFI_IP]);
+       agg_table_finish(h->it_ce->imported_encap[AFI_IP6]);
 
        if (h->import_mac) {
                struct rfapi_import_table *it;
@@ -4346,7 +4352,7 @@ void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
                rfp_stop(h->rfp);
 
        for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               route_table_finish(h->un[afi]);
+               agg_table_finish(h->un[afi]);
        }
 
        XFREE(MTYPE_RFAPI_IMPORTTABLE, h->it_ce);
@@ -4394,8 +4400,8 @@ rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list,
                 */
                for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 
-                       it->imported_vpn[afi] = route_table_init();
-                       it->imported_encap[afi] = route_table_init();
+                       it->imported_vpn[afi] = agg_table_init();
+                       it->imported_encap[afi] = agg_table_init();
 
                        rfapiBgpTableFilteredImport(bgp, it, afi,
                                                    SAFI_MPLS_VPN);
@@ -4452,8 +4458,8 @@ static void rfapiDeleteRemotePrefixesIt(
 
        for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 
-               struct route_table *rt;
-               struct route_node *rn;
+               struct agg_table *rt;
+               struct agg_node *rn;
 
                if (p && (family2afi(p->family) != afi)) {
                        continue;
@@ -4466,7 +4472,7 @@ static void rfapiDeleteRemotePrefixesIt(
                vnc_zlog_debug_verbose("%s: scanning rt for afi=%d", __func__,
                                       afi);
 
-               for (rn = route_top(rt); rn; rn = route_next(rn)) {
+               for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
                        struct bgp_info *bi;
                        struct bgp_info *next;
 
index 84b7ca3a7699ec6f7ad0ec02b9bda61a5c4e1a65..ae3d248367faa36b8861ef723d815f38da5454b6 100644 (file)
@@ -40,10 +40,10 @@ struct rfapi_import_table {
        struct ecommunity *rt_import_list; /* copied from nve grp */
        int refcount;                      /* nve grps and nves */
        uint32_t l2_logical_net_id;     /* L2 only: EVPN Eth Seg Id */
-       struct route_table *imported_vpn[AFI_MAX];
+       struct agg_table *imported_vpn[AFI_MAX];
        struct rfapi_monitor_vpn *vpn0_queries[AFI_MAX];
        struct rfapi_monitor_eth *eth0_queries;
-       struct route_table *imported_encap[AFI_MAX];
+       struct agg_table *imported_encap[AFI_MAX];
        struct skiplist *monitor_exterior_orphans;
        int local_count[AFI_MAX];
        int remote_count[AFI_MAX];
@@ -80,7 +80,7 @@ extern void rfapiCheckRouteCount(void);
 extern void rfapiPrintBi(void *stream, struct bgp_info *bi);
 
 extern void rfapiShowImportTable(void *stream, const char *label,
-                                struct route_table *rt, int isvpn);
+                                struct agg_table *rt, int isvpn);
 
 extern struct rfapi_import_table *
 rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list,
@@ -100,32 +100,31 @@ extern void rfapiImportTableRefDelByIt(struct bgp *bgp,
  * next less-specific node (i.e., this node's parent) at the end.
  */
 extern struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
-       struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */
-       struct rfapi_ip_addr *exclude_vnaddr,     /* omit routes to same NVE */
-       struct route_table *rfd_rib_table,   /* preload this NVE rib table */
-       struct prefix *pfx_target_original); /* query target */
+       struct agg_node *rn, uint32_t lifetime, /* put into nexthop entries */
+       struct rfapi_ip_addr *exclude_vnaddr,   /* omit routes to same NVE */
+       struct agg_table *rfd_rib_table,        /* preload this NVE rib table */
+       struct prefix *pfx_target_original);    /* query target */
 
 extern struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList(
-       struct route_table *rt,
-       uint32_t lifetime,                    /* put into nexthop entries */
-       struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_table *rfd_rib_table,    /* preload this NVE rib table */
-       struct prefix *pfx_target_original);  /* query target */
+       struct agg_table *rt, uint32_t lifetime, /* put into nexthop entries */
+       struct rfapi_ip_addr *exclude_vnaddr,    /* omit routes to same NVE */
+       struct agg_table *rfd_rib_table,     /* preload this NVE rib table */
+       struct prefix *pfx_target_original); /* query target */
 
 extern struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList(
        uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix,
        uint32_t lifetime,                    /* put into nexthop entries */
        struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_table *rib_route_table,  /* preload NVE rib node */
+       struct agg_table *rib_route_table,    /* preload NVE rib node */
        struct prefix *pfx_target_original);  /* query target */
 
 extern int rfapiEcommunitiesIntersect(struct ecommunity *e1,
                                      struct ecommunity *e2);
 
-extern void rfapiCheckRefcount(struct route_node *rn, safi_t safi,
+extern void rfapiCheckRefcount(struct agg_node *rn, safi_t safi,
                               int lockoffset);
 
-extern int rfapiHasNonRemovedRoutes(struct route_node *rn);
+extern int rfapiHasNonRemovedRoutes(struct agg_node *rn);
 
 extern int rfapiProcessDeferredClose(struct thread *t);
 
@@ -153,10 +152,10 @@ extern void rfapiBgpInfoFilteredImportVPN(
        uint32_t *label);  /* part of bgp_info */
 
 extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList(
-       struct route_node *rn, struct rfapi_ip_prefix *rprefix,
+       struct agg_node *rn, struct rfapi_ip_prefix *rprefix,
        uint32_t lifetime,                    /* put into nexthop entries */
        struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
-       struct route_table *rib_route_table,  /* preload NVE rib table */
+       struct agg_table *rib_route_table,    /* preload NVE rib table */
        struct prefix *pfx_target_original);  /* query target */
 
 extern struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp,
index 30182ba7a6d93694bc9ae8195bbf4f134decfd32..f18c6bfe12999cee193f95707460f09d8f700ecd 100644 (file)
 
 /* TBD remove unneeded includes */
 
-#include <errno.h>
-
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/memory.h"
 #include "lib/log.h"
@@ -68,10 +66,10 @@ static void rfapiMonitorEthDetachImport(struct bgp *bgp,
 /*
  * Debug function, special case
  */
-void rfapiMonitorEthSlCheck(struct route_node *rn, const char *tag1,
+void rfapiMonitorEthSlCheck(struct agg_node *rn, const char *tag1,
                            const char *tag2)
 {
-       struct route_node *rn_saved = NULL;
+       struct agg_node *rn_saved = NULL;
        static struct skiplist *sl_saved = NULL;
        struct skiplist *sl;
 
@@ -118,12 +116,13 @@ void rfapiMonitorDupCheck(struct bgp *bgp)
        struct rfapi_descriptor *rfd;
 
        for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) {
-               struct route_node *mrn;
+               struct agg_node *mrn;
 
                if (!rfd->mon)
                        continue;
 
-               for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) {
+               for (mrn = agg_route_top(rfd->mon); mrn;
+                    mrn = agg_route_next(mrn)) {
                        struct rfapi_monitor_vpn *m;
                        for (m = (struct rfapi_monitor_vpn *)(mrn->info); m;
                             m = m->next)
@@ -132,12 +131,13 @@ void rfapiMonitorDupCheck(struct bgp *bgp)
        }
 
        for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) {
-               struct route_node *mrn;
+               struct agg_node *mrn;
 
                if (!rfd->mon)
                        continue;
 
-               for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) {
+               for (mrn = agg_route_top(rfd->mon); mrn;
+                    mrn = agg_route_next(mrn)) {
                        struct rfapi_monitor_vpn *m;
 
                        for (m = (struct rfapi_monitor_vpn *)(mrn->info); m;
@@ -158,15 +158,17 @@ void rfapiMonitorCleanCheck(struct bgp *bgp)
                assert(!rfd->import_table->vpn0_queries[AFI_IP]);
                assert(!rfd->import_table->vpn0_queries[AFI_IP6]);
 
-               struct route_node *rn;
+               struct agg_node *rn;
 
-               for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP]);
-                    rn; rn = route_next(rn)) {
+               for (rn = agg_route_top(
+                            rfd->import_table->imported_vpn[AFI_IP]);
+                    rn; rn = agg_route_next(rn)) {
 
                        assert(!RFAPI_MONITOR_VPN(rn));
                }
-               for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP6]);
-                    rn; rn = route_next(rn)) {
+               for (rn = agg_route_top(
+                            rfd->import_table->imported_vpn[AFI_IP6]);
+                    rn; rn = agg_route_next(rn)) {
 
                        assert(!RFAPI_MONITOR_VPN(rn));
                }
@@ -180,7 +182,7 @@ void rfapiMonitorCheckAttachAllowed(void)
        assert(!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE));
 }
 
-void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn)
+void rfapiMonitorExtraFlush(safi_t safi, struct agg_node *rn)
 {
        struct rfapi_it_extra *hie;
        struct rfapi_monitor_vpn *v;
@@ -202,7 +204,7 @@ void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn)
                        e_next = e->next;
                        e->next = NULL;
                        XFREE(MTYPE_RFAPI_MONITOR_ENCAP, e);
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                hie->u.encap.e = NULL;
                break;
@@ -212,33 +214,33 @@ void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn)
                        v_next = v->next;
                        v->next = NULL;
                        XFREE(MTYPE_RFAPI_MONITOR, e);
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                hie->u.vpn.v = NULL;
                if (hie->u.vpn.e.source) {
                        while (!skiplist_delete_first(hie->u.vpn.e.source)) {
-                               route_unlock_node(rn);
+                               agg_unlock_node(rn);
                        }
                        skiplist_free(hie->u.vpn.e.source);
                        hie->u.vpn.e.source = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                if (hie->u.vpn.idx_rd) {
                        /* looping through bi->extra->vnc.import.rd is tbd */
                        while (!skiplist_delete_first(hie->u.vpn.idx_rd)) {
-                               route_unlock_node(rn);
+                               agg_unlock_node(rn);
                        }
                        skiplist_free(hie->u.vpn.idx_rd);
                        hie->u.vpn.idx_rd = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                if (hie->u.vpn.mon_eth) {
                        while (!skiplist_delete_first(hie->u.vpn.mon_eth)) {
-                               route_unlock_node(rn);
+                               agg_unlock_node(rn);
                        }
                        skiplist_free(hie->u.vpn.mon_eth);
                        hie->u.vpn.mon_eth = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                break;
 
@@ -247,13 +249,13 @@ void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn)
        }
        XFREE(MTYPE_RFAPI_IT_EXTRA, hie);
        rn->aggregate = NULL;
-       route_unlock_node(rn);
+       agg_unlock_node(rn);
 }
 
 /*
  * If the child lists are empty, release the rfapi_it_extra struct
  */
-void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn)
+void rfapiMonitorExtraPrune(safi_t safi, struct agg_node *rn)
 {
        struct rfapi_it_extra *hie;
 
@@ -279,28 +281,28 @@ void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn)
                                return;
                        skiplist_free(hie->u.vpn.mon_eth);
                        hie->u.vpn.mon_eth = NULL;
-                       route_unlock_node(rn); /* uncount skiplist */
+                       agg_unlock_node(rn); /* uncount skiplist */
                }
                if (hie->u.vpn.e.source) {
                        if (skiplist_count(hie->u.vpn.e.source))
                                return;
                        skiplist_free(hie->u.vpn.e.source);
                        hie->u.vpn.e.source = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                if (hie->u.vpn.idx_rd) {
                        if (skiplist_count(hie->u.vpn.idx_rd))
                                return;
                        skiplist_free(hie->u.vpn.idx_rd);
                        hie->u.vpn.idx_rd = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                if (hie->u.vpn.mon_eth) {
                        if (skiplist_count(hie->u.vpn.mon_eth))
                                return;
                        skiplist_free(hie->u.vpn.mon_eth);
                        hie->u.vpn.mon_eth = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
                break;
 
@@ -309,17 +311,17 @@ void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn)
        }
        XFREE(MTYPE_RFAPI_IT_EXTRA, hie);
        rn->aggregate = NULL;
-       route_unlock_node(rn);
+       agg_unlock_node(rn);
 }
 
 /*
  * returns locked node
  */
-struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
-                                            struct prefix *p)
+struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
+                                          struct prefix *p)
 {
        afi_t afi;
-       struct route_node *rn;
+       struct agg_node *rn;
 
        if (RFAPI_0_PREFIX(p)) {
                assert(1);
@@ -341,7 +343,7 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
         * if a monitor is moved to another node, there must be
         * corresponding unlock/locks
         */
-       for (rn = route_node_match(rfd->import_table->imported_vpn[afi], p);
+       for (rn = agg_node_match(rfd->import_table->imported_vpn[afi], p);
             rn;) {
 
                struct bgp_info *bi;
@@ -369,9 +371,9 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
                if (bi)
                        break;
 
-               route_unlock_node(rn);
-               if ((rn = rn->parent)) {
-                       route_lock_node(rn);
+               agg_unlock_node(rn);
+               if ((rn = agg_node_parent(rn))) {
+                       agg_lock_node(rn);
                }
        }
 
@@ -383,8 +385,8 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
 
                /* creates default node if none exists, and increments ref count
                 */
-               rn = route_node_get(rfd->import_table->imported_vpn[afi],
-                                   &pfx_default);
+               rn = agg_node_get(rfd->import_table->imported_vpn[afi],
+                                 &pfx_default);
        }
 
        return rn;
@@ -396,10 +398,10 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
  * returned (for the benefit of caller which might like to use it
  * to generate an immediate query response).
  */
-static struct route_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd,
-                                                  struct rfapi_monitor_vpn *m)
+static struct agg_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd,
+                                                struct rfapi_monitor_vpn *m)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
 
        rfapiMonitorCheckAttachAllowed();
 
@@ -438,7 +440,7 @@ static struct route_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd,
  */
 void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd)
 {
-       struct route_node *mrn;
+       struct agg_node *mrn;
 
        if (!rfd->mon) {
                /*
@@ -447,7 +449,7 @@ void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd)
                return;
        }
 
-       for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) {
+       for (mrn = agg_route_top(rfd->mon); mrn; mrn = agg_route_next(mrn)) {
 
                if (!mrn->info)
                        continue;
@@ -467,11 +469,11 @@ void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd)
  * are disabled, this function will not perform a lookup, and the
  * caller will have to do its own lookup.
  */
-struct route_node *
-rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *p)
+struct agg_node *rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd,
+                                struct prefix *p)
 {
        struct rfapi_monitor_vpn *m;
-       struct route_node *rn;
+       struct agg_node *rn;
 
        /*
         * Initialize nve's monitor list if needed
@@ -480,15 +482,15 @@ rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *p)
         * or be 0/0 so they won't get mixed up.
         */
        if (!rfd->mon) {
-               rfd->mon = route_table_init();
+               rfd->mon = agg_table_init();
        }
-       rn = route_node_get(rfd->mon, p);
+       rn = agg_node_get(rfd->mon, p);
        if (rn->info) {
                /*
                 * received this query before, no further action needed
                 */
                rfapiMonitorTimerRestart((struct rfapi_monitor_vpn *)rn->info);
-               route_unlock_node(rn);
+               agg_unlock_node(rn);
                return NULL;
        }
 
@@ -575,7 +577,7 @@ rfapiMonitorDetachImport(struct rfapi_monitor_vpn *m)
                                                this->next;
                                }
                                RFAPI_CHECK_REFCOUNT(m->node, SAFI_MPLS_VPN, 1);
-                               route_unlock_node(m->node);
+                               agg_unlock_node(m->node);
                        }
                        m->node = NULL;
                }
@@ -586,12 +588,12 @@ rfapiMonitorDetachImport(struct rfapi_monitor_vpn *m)
 
 void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
 
        if (!rfd->mon)
                return;
 
-       for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) {
+       for (rn = agg_route_top(rfd->mon); rn; rn = agg_route_next(rn)) {
                if (rn->info) {
                        rfapiMonitorDetachImport(
                                (struct rfapi_monitor_vpn *)(rn->info));
@@ -602,11 +604,11 @@ void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd)
 void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
                     struct prefix *p)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
        struct rfapi_monitor_vpn *m;
 
        assert(rfd->mon);
-       rn = route_node_get(rfd->mon, p); /* locks node */
+       rn = agg_node_get(rfd->mon, p); /* locks node */
        m = rn->info;
 
        assert(m);
@@ -628,8 +630,8 @@ void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
         */
        XFREE(MTYPE_RFAPI_MONITOR, m);
        rn->info = NULL;
-       route_unlock_node(rn); /* undo original lock when created */
-       route_unlock_node(rn); /* undo lock in route_node_get */
+       agg_unlock_node(rn); /* undo original lock when created */
+       agg_unlock_node(rn); /* undo lock in agg_node_get */
 
        --rfd->monitor_count;
        --bgp->rfapi->monitor_count;
@@ -640,7 +642,7 @@ void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
  */
 int rfapiMonitorDelHd(struct rfapi_descriptor *rfd)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
        struct bgp *bgp;
        int count = 0;
 
@@ -649,7 +651,8 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd)
        bgp = bgp_get_default();
 
        if (rfd->mon) {
-               for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) {
+               for (rn = agg_route_top(rfd->mon); rn;
+                    rn = agg_route_next(rn)) {
                        struct rfapi_monitor_vpn *m;
                        if ((m = rn->info)) {
                                if (!(bgp->rfapi_cfg->flags
@@ -664,14 +667,14 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd)
 
                                XFREE(MTYPE_RFAPI_MONITOR, m);
                                rn->info = NULL;
-                               route_unlock_node(rn); /* undo original lock
+                               agg_unlock_node(rn); /* undo original lock
                                                          when created */
                                ++count;
                                --rfd->monitor_count;
                                --bgp->rfapi->monitor_count;
                        }
                }
-               route_table_finish(rfd->mon);
+               agg_table_finish(rfd->mon);
                rfd->mon = NULL;
        }
 
@@ -788,7 +791,7 @@ static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m)
  */
 void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
 
        if (AF_ETHERNET == p->family) {
                struct rfapi_monitor_eth *mon_eth;
@@ -812,7 +815,8 @@ void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p)
                }
 
        } else {
-               for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) {
+               for (rn = agg_route_top(rfd->mon); rn;
+                    rn = agg_route_next(rn)) {
                        struct rfapi_monitor_vpn *m;
 
                        if (!((m = rn->info)))
@@ -831,11 +835,11 @@ void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p)
  * rfapiRibUpdatePendingNode with this node and all corresponding NVEs.
  */
 void rfapiMonitorItNodeChanged(
-       struct rfapi_import_table *import_table, struct route_node *it_node,
+       struct rfapi_import_table *import_table, struct agg_node *it_node,
        struct rfapi_monitor_vpn *monitor_list) /* for base it node, NULL=all */
 {
        struct skiplist *nves_seen;
-       struct route_node *rn = it_node;
+       struct agg_node *rn = it_node;
        struct bgp *bgp = bgp_get_default();
        afi_t afi = family2afi(rn->p.family);
 #if DEBUG_L2_EXTRA
@@ -909,7 +913,8 @@ void rfapiMonitorItNodeChanged(
                         * to them
                         * because we haven't sent them an initial route.
                         */
-                       if (!rn->parent && !rn->info && it_node->parent)
+                       if (!agg_node_parent(rn) && !rn->info
+                           && it_node->parent)
                                break;
 
                        for (; m; m = m->next) {
@@ -947,7 +952,7 @@ void rfapiMonitorItNodeChanged(
                                                m->rfd->response_lifetime);
                                }
                        }
-                       rn = rn->parent;
+                       rn = agg_node_parent(rn);
                        if (rn)
                                m = RFAPI_MONITOR_VPN(rn);
                } while (rn);
@@ -1023,8 +1028,7 @@ void rfapiMonitorItNodeChanged(
  * omit old node and its subtree
  */
 void rfapiMonitorMovedUp(struct rfapi_import_table *import_table,
-                        struct route_node *old_node,
-                        struct route_node *new_node,
+                        struct agg_node *old_node, struct agg_node *new_node,
                         struct rfapi_monitor_vpn *monitor_list)
 {
        struct bgp *bgp = bgp_get_default();
@@ -1125,7 +1129,7 @@ static int mon_eth_cmp(void *a, void *b)
 
 static void rfapiMonitorEthAttachImport(
        struct rfapi_import_table *it,
-       struct route_node *rn,   /* it node attach point if non-0 */
+       struct agg_node *rn,       /* it node attach point if non-0 */
        struct rfapi_monitor_eth *mon) /* monitor struct to attach */
 {
        struct skiplist *sl;
@@ -1162,7 +1166,7 @@ static void rfapiMonitorEthAttachImport(
        if (!sl) {
                sl = RFAPI_MONITOR_ETH_W_ALLOC(rn) =
                        skiplist_new(0, NULL, NULL);
-               route_lock_node(rn); /* count skiplist mon_eth */
+               agg_lock_node(rn); /* count skiplist mon_eth */
        }
 
 #if DEBUG_L2_EXTRA
@@ -1175,7 +1179,7 @@ static void rfapiMonitorEthAttachImport(
        assert(!rc);
 
        /* count eth monitor */
-       route_lock_node(rn);
+       agg_lock_node(rn);
 }
 
 /*
@@ -1202,7 +1206,7 @@ static void rfapiMonitorEthAttachImportHd(struct bgp *bgp,
 
                struct rfapi_import_table *it;
                struct prefix pfx_mac_buf;
-               struct route_node *rn;
+               struct agg_node *rn;
 
                it = rfapiMacImportTableGet(bgp, mon->logical_net_id);
                assert(it);
@@ -1212,7 +1216,7 @@ static void rfapiMonitorEthAttachImportHd(struct bgp *bgp,
                pfx_mac_buf.prefixlen = 48;
                pfx_mac_buf.u.prefix_eth = mon->macaddr;
 
-               rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf);
+               rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf);
                assert(rn);
 
                (void)rfapiMonitorEthAttachImport(it, rn, mon);
@@ -1226,7 +1230,7 @@ static void rfapiMonitorEthDetachImport(
        struct rfapi_import_table *it;
        struct prefix pfx_mac_buf;
        struct skiplist *sl;
-       struct route_node *rn;
+       struct agg_node *rn;
        int rc;
 
        it = rfapiMacImportTableGet(bgp, mon->logical_net_id);
@@ -1262,7 +1266,7 @@ static void rfapiMonitorEthDetachImport(
        pfx_mac_buf.prefixlen = 48;
        pfx_mac_buf.u.prefix_eth = mon->macaddr;
 
-       rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf);
+       rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf);
        assert(rn);
 
 #if DEBUG_L2_EXTRA
@@ -1288,19 +1292,19 @@ static void rfapiMonitorEthDetachImport(
        assert(!rc);
 
        /* uncount eth monitor */
-       route_unlock_node(rn);
+       agg_unlock_node(rn);
 }
 
-struct route_node *rfapiMonitorEthAdd(struct bgp *bgp,
-                                     struct rfapi_descriptor *rfd,
-                                     struct ethaddr *macaddr,
-                                     uint32_t logical_net_id)
+struct agg_node *rfapiMonitorEthAdd(struct bgp *bgp,
+                                   struct rfapi_descriptor *rfd,
+                                   struct ethaddr *macaddr,
+                                   uint32_t logical_net_id)
 {
        int rc;
        struct rfapi_monitor_eth mon_buf;
        struct rfapi_monitor_eth *val;
        struct rfapi_import_table *it;
-       struct route_node *rn = NULL;
+       struct agg_node *rn = NULL;
        struct prefix pfx_mac_buf;
 
        if (!rfd->mon_eth) {
@@ -1323,7 +1327,7 @@ struct route_node *rfapiMonitorEthAdd(struct bgp *bgp,
        pfx_mac_buf.u.prefix_eth = *macaddr;
 
        if (!RFAPI_0_ETHERADDR(macaddr)) {
-               rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf);
+               rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf);
                assert(rn);
        }
 
@@ -1453,8 +1457,8 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp)
 {
        struct rfapi_import_table *it;
        afi_t afi;
-       struct route_table *rt;
-       struct route_node *rn;
+       struct agg_table *rt;
+       struct agg_node *rn;
        void *cursor;
        int rc;
        struct rfapi *h = bgp->rfapi;
@@ -1485,7 +1489,8 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp)
 
                        rt = it->imported_vpn[afi];
 
-                       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                       for (rn = agg_route_top(rt); rn;
+                            rn = agg_route_next(rn)) {
                                m = RFAPI_MONITOR_VPN(rn);
                                if (RFAPI_MONITOR_VPN(rn))
                                        RFAPI_MONITOR_VPN_W_ALLOC(rn) = NULL;
@@ -1494,7 +1499,7 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp)
                                        m->next =
                                                NULL; /* gratuitous safeness */
                                        m->node = NULL;
-                                       route_unlock_node(rn); /* uncount */
+                                       agg_unlock_node(rn); /* uncount */
                                }
                        }
 
@@ -1531,12 +1536,12 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp)
                 * Find non-0 monitors (i.e., actual addresses, not FTD
                 * monitors)
                 */
-               for (rn = route_top(rt); rn; rn = route_next(rn)) {
+               for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
                        struct skiplist *sl;
 
                        sl = RFAPI_MONITOR_ETH(rn);
                        while (!skiplist_delete_first(sl)) {
-                               route_unlock_node(rn); /* uncount monitor */
+                               agg_unlock_node(rn); /* uncount monitor */
                        }
                }
 
index edc9744cdb6934dc055b34d427158ee12d7f5759..9b85f6248e41a396c45fca9559f4e43587555eaf 100644 (file)
  * to indicate which nves are interested in a prefix/target
  */
 struct rfapi_monitor_vpn {
-       struct rfapi_monitor_vpn *next; /* chain from struct route_node */
+       struct rfapi_monitor_vpn *next; /* chain from struct agg_node */
        struct rfapi_descriptor *rfd;   /* which NVE requested the route */
        struct prefix p;                /* constant: pfx in original request */
-       struct route_node *node;        /* node we're currently attached to */
+       struct agg_node *node;          /* node we're currently attached to */
        uint32_t flags;
 #define RFAPI_MON_FLAG_NEEDCALLBACK    0x00000001      /* deferred callback */
 
@@ -44,9 +44,9 @@ struct rfapi_monitor_vpn {
 struct rfapi_monitor_encap {
        struct rfapi_monitor_encap *next;
        struct rfapi_monitor_encap *prev;
-       struct route_node *node; /* VPN node */
+       struct agg_node *node;   /* VPN node */
        struct bgp_info *bi;     /* VPN bi */
-       struct route_node *rn;   /* parent node */
+       struct agg_node *rn;     /* parent node */
 };
 
 struct rfapi_monitor_eth {
@@ -98,7 +98,7 @@ struct rfapi_it_extra {
        ((struct rfapi_it_extra                                                \
                  *)((rn)->aggregate                                           \
                             ? (rn)->aggregate                                 \
-                            : (route_lock_node(rn),                           \
+                            : (agg_lock_node(rn),                             \
                                (rn)->aggregate = XCALLOC(                     \
                                        MTYPE_RFAPI_IT_EXTRA,                  \
                                        sizeof(struct rfapi_it_extra)))))
@@ -138,16 +138,16 @@ extern void rfapiMonitorCleanCheck(struct bgp *bgp);
 
 extern void rfapiMonitorCheckAttachAllowed(void);
 
-extern void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn);
+extern void rfapiMonitorExtraFlush(safi_t safi, struct agg_node *rn);
 
-extern struct route_node *
-rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, struct prefix *p);
+extern struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd,
+                                                 struct prefix *p);
 
 extern void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd);
 
-extern struct route_node *rfapiMonitorAdd(struct bgp *bgp,
-                                         struct rfapi_descriptor *rfd,
-                                         struct prefix *p);
+extern struct agg_node *rfapiMonitorAdd(struct bgp *bgp,
+                                       struct rfapi_descriptor *rfd,
+                                       struct prefix *p);
 
 extern void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd);
 
@@ -164,24 +164,24 @@ extern void rfapiMonitorResponseRemovalOff(struct bgp *bgp);
 
 extern void rfapiMonitorResponseRemovalOn(struct bgp *bgp);
 
-extern void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn);
+extern void rfapiMonitorExtraPrune(safi_t safi, struct agg_node *rn);
 
 extern void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd,
                                      struct prefix *p);
 
 extern void rfapiMonitorItNodeChanged(struct rfapi_import_table *import_table,
-                                     struct route_node *it_node,
+                                     struct agg_node *it_node,
                                      struct rfapi_monitor_vpn *monitor_list);
 
 extern void rfapiMonitorMovedUp(struct rfapi_import_table *import_table,
-                               struct route_node *old_node,
-                               struct route_node *new_node,
+                               struct agg_node *old_node,
+                               struct agg_node *new_node,
                                struct rfapi_monitor_vpn *monitor_list);
 
-extern struct route_node *rfapiMonitorEthAdd(struct bgp *bgp,
-                                            struct rfapi_descriptor *rfd,
-                                            struct ethaddr *macaddr,
-                                            uint32_t logical_net_id);
+extern struct agg_node *rfapiMonitorEthAdd(struct bgp *bgp,
+                                          struct rfapi_descriptor *rfd,
+                                          struct ethaddr *macaddr,
+                                          uint32_t logical_net_id);
 
 extern void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
                               struct ethaddr *macaddr,
index 0fb887912c15109bdb23eb7f98daad2678dc2b85..ee54d88c3f46bb82fccea30b9ccb94c1e76f2b66 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/memory.h"
 #include "lib/skiplist.h"
index 9c759fc47eba2ed1705593c3d881a4bcee61273c..4d8072a49bdd74601206a8b0642afb3d8878280d 100644 (file)
@@ -47,7 +47,7 @@ struct rfapi_advertised_prefixes {
 };
 
 struct rfapi_descriptor {
-       struct route_node *un_node; /* backref to un table */
+       struct agg_node *un_node; /* backref to un table */
 
        struct rfapi_descriptor *next; /* next vn_addr */
 
@@ -76,7 +76,7 @@ struct rfapi_descriptor {
        struct rfapi_import_table *import_table;
 
        uint32_t monitor_count;
-       struct route_table *mon;  /* rfapi_monitors */
+       struct agg_table *mon;    /* rfapi_monitors */
        struct skiplist *mon_eth; /* ethernet monitors */
 
        /*
@@ -85,10 +85,10 @@ struct rfapi_descriptor {
         * rsp_times      last time we sent response containing pfx
         */
        uint32_t rib_prefix_count; /* pfxes with routes */
-       struct route_table *rib[AFI_MAX];
-       struct route_table *rib_pending[AFI_MAX];
+       struct agg_table *rib[AFI_MAX];
+       struct agg_table *rib_pending[AFI_MAX];
        struct work_queue *updated_responses_queue;
-       struct route_table *rsp_times[AFI_MAX];
+       struct agg_table *rsp_times[AFI_MAX];
 
        uint32_t rsp_counter;    /* dedup initial rsp */
        time_t rsp_time;              /* dedup initial rsp */
@@ -171,7 +171,7 @@ struct rfapi_global_stats {
  * check vn address to get exact match.
  */
 struct rfapi {
-       struct route_table *un[AFI_MAX];
+       struct agg_table *un[AFI_MAX];
        struct rfapi_import_table *imports; /* IPv4, IPv6 */
        struct list descriptors;            /* debug & resolve-nve imports */
 
@@ -198,8 +198,8 @@ struct rfapi {
         * bgp unicast or zebra, we need to keep track of information
         * related to expiring the routes according to the VNC lifetime
         */
-       struct route_table *rt_export_bgp[AFI_MAX];
-       struct route_table *rt_export_zebra[AFI_MAX];
+       struct agg_table *rt_export_bgp[AFI_MAX];
+       struct agg_table *rt_export_zebra[AFI_MAX];
 
        /*
         * For VNC->BGP unicast exports in CE mode, we need a
index 60534fece0b9d43e843092f27ea3030df74ed173..008da30118a5ab34060436a5ef7b4ef963f1c986 100644 (file)
  * Purpose:    maintain per-nve ribs and generate change lists
  */
 
-#include <errno.h>
-
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/memory.h"
 #include "lib/log.h"
@@ -150,10 +148,10 @@ void rfapiRibCheckCounts(
 
                for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 
-                       struct route_node *rn;
+                       struct agg_node *rn;
 
-                       for (rn = route_top(rfd->rib[afi]); rn;
-                            rn = route_next(rn)) {
+                       for (rn = agg_route_top(rfd->rib[afi]); rn;
+                            rn = agg_route_next(rn)) {
 
                                struct skiplist *sl = rn->info;
                                struct skiplist *dsl = rn->aggregate;
@@ -175,8 +173,8 @@ void rfapiRibCheckCounts(
                                        ++t_pfx_deleted;
                                }
                        }
-                       for (rn = route_top(rfd->rib_pending[afi]); rn;
-                            rn = route_next(rn)) {
+                       for (rn = agg_route_top(rfd->rib_pending[afi]); rn;
+                            rn = agg_route_next(rn)) {
 
                                struct list *l = rn->info; /* sorted by cost */
                                struct skiplist *sl = rn->aggregate;
@@ -286,7 +284,7 @@ struct rfapi_rib_tcb {
        struct rfapi_descriptor *rfd;
        struct skiplist *sl;
        struct rfapi_info *ri;
-       struct route_node *rn;
+       struct agg_node *rn;
        int flags;
 #define RFAPI_RIB_TCB_FLAG_DELETED     0x00000001
 };
@@ -325,7 +323,7 @@ static int rfapiRibExpireTimer(struct thread *t)
                        RFAPI_RIB_PREFIX_COUNT_DECR(tcb->rfd, bgp->rfapi);
                }
                skiplist_free(tcb->sl);
-               route_unlock_node(tcb->rn);
+               agg_unlock_node(tcb->rn);
        }
 
        XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
@@ -335,10 +333,10 @@ static int rfapiRibExpireTimer(struct thread *t)
        return 0;
 }
 
-static void
-rfapiRibStartTimer(struct rfapi_descriptor *rfd, struct rfapi_info *ri,
-                  struct route_node *rn, /* route node attached to */
-                  int deleted)
+static void rfapiRibStartTimer(struct rfapi_descriptor *rfd,
+                              struct rfapi_info *ri,
+                              struct agg_node *rn, /* route node attached to */
+                              int deleted)
 {
        struct thread *t = ri->timer;
        struct rfapi_rib_tcb *tcb = NULL;
@@ -486,12 +484,12 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
 #endif
 
        for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
-               struct route_node *pn;
-               struct route_node *rn;
+               struct agg_node *pn;
+               struct agg_node *rn;
 
                if (rfd->rib_pending[afi]) {
-                       for (pn = route_top(rfd->rib_pending[afi]); pn;
-                            pn = route_next(pn)) {
+                       for (pn = agg_route_top(rfd->rib_pending[afi]); pn;
+                            pn = agg_route_next(pn)) {
                                if (pn->aggregate) {
                                        /*
                                         * free references into the rfapi_info
@@ -502,7 +500,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
                                                (struct skiplist
                                                         *)(pn->aggregate));
                                        pn->aggregate = NULL;
-                                       route_unlock_node(
+                                       agg_unlock_node(
                                                pn); /* skiplist deleted */
                                }
                                /*
@@ -516,13 +514,13 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
                                        }
                                        pn->info = NULL;
                                        /* linklist or 1 deleted */
-                                       route_unlock_node(pn);
+                                       agg_unlock_node(pn);
                                }
                        }
                }
                if (rfd->rib[afi]) {
-                       for (rn = route_top(rfd->rib[afi]); rn;
-                            rn = route_next(rn)) {
+                       for (rn = agg_route_top(rfd->rib[afi]); rn;
+                            rn = agg_route_next(rn)) {
                                if (rn->info) {
 
                                        struct rfapi_info *ri;
@@ -541,7 +539,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
                                        skiplist_free(
                                                (struct skiplist *)rn->info);
                                        rn->info = NULL;
-                                       route_unlock_node(rn);
+                                       agg_unlock_node(rn);
                                        RFAPI_RIB_PREFIX_COUNT_DECR(rfd,
                                                                    bgp->rfapi);
                                }
@@ -566,7 +564,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
                                                         *)(rn->aggregate));
 
                                        rn->aggregate = NULL;
-                                       route_unlock_node(rn);
+                                       agg_unlock_node(rn);
                                }
                        }
                }
@@ -601,15 +599,18 @@ void rfapiRibFree(struct rfapi_descriptor *rfd)
         * Free radix trees
         */
        for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
-               route_table_finish(rfd->rib_pending[afi]);
+               if (rfd->rib_pending[afi])
+                       agg_table_finish(rfd->rib_pending[afi]);
                rfd->rib_pending[afi] = NULL;
 
-               route_table_finish(rfd->rib[afi]);
+               if (rfd->rib[afi])
+                       agg_table_finish(rfd->rib[afi]);
                rfd->rib[afi] = NULL;
 
-               /* NB route_table_finish frees only prefix nodes, not chained
+               /* NB agg_table_finish frees only prefix nodes, not chained
                 * info */
-               route_table_finish(rfd->rsp_times[afi]);
+               if (rfd->rsp_times[afi])
+                       agg_table_finish(rfd->rsp_times[afi]);
                rfd->rib[afi] = NULL;
        }
 }
@@ -730,7 +731,7 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri,
  *     !0      do not include route in response
  */
 int rfapiRibPreloadBi(
-       struct route_node *rfd_rib_node, /* NULL = don't preload or filter */
+       struct agg_node *rfd_rib_node, /* NULL = don't preload or filter */
        struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime,
        struct bgp_info *bi)
 {
@@ -738,7 +739,7 @@ int rfapiRibPreloadBi(
        struct skiplist *slRibPt = NULL;
        struct rfapi_info *ori = NULL;
        struct rfapi_rib_key rk;
-       struct route_node *trn;
+       struct agg_node *trn;
        afi_t afi;
 
        if (!rfd_rib_node)
@@ -746,7 +747,7 @@ int rfapiRibPreloadBi(
 
        afi = family2afi(rfd_rib_node->p.family);
 
-       rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info);
+       rfd = agg_get_table_info(agg_get_table(rfd_rib_node));
 
        memset((void *)&rk, 0, sizeof(rk));
        rk.vn = *pfx_vn;
@@ -784,7 +785,7 @@ int rfapiRibPreloadBi(
                if (!slRibPt) {
                        slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL);
                        rfd_rib_node->info = slRibPt;
-                       route_lock_node(rfd_rib_node);
+                       agg_lock_node(rfd_rib_node);
                        RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfd->bgp->rfapi);
                }
                skiplist_insert(slRibPt, &ori->rk, ori);
@@ -802,11 +803,11 @@ int rfapiRibPreloadBi(
        /*
         * Update last sent time for prefix
         */
-       trn = route_node_get(rfd->rsp_times[afi],
-                            &rfd_rib_node->p); /* locks trn */
+       trn = agg_node_get(rfd->rsp_times[afi],
+                          &rfd_rib_node->p); /* locks trn */
        trn->info = (void *)(uintptr_t)bgp_clock();
        if (trn->lock > 1)
-               route_unlock_node(trn);
+               agg_unlock_node(trn);
 
        return 0;
 }
@@ -837,7 +838,7 @@ int rfapiRibPreloadBi(
  */
 static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                                 afi_t afi,
-                                struct route_node *pn, /* pending node */
+                                struct agg_node *pn, /* pending node */
                                 struct rfapi_next_hop_entry **head,
                                 struct rfapi_next_hop_entry **tail)
 {
@@ -845,7 +846,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
        struct listnode *nnode = NULL;
        struct rfapi_info *ri = NULL;    /* happy valgrind */
        struct rfapi_ip_prefix hp = {0}; /* pfx to put in NHE */
-       struct route_node *rn = NULL;
+       struct agg_node *rn = NULL;
        struct skiplist *slRibPt = NULL; /* rib list */
        struct skiplist *slPendPt = NULL;
        struct list *lPendCost = NULL;
@@ -875,7 +876,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
        /*
         * Find corresponding RIB node
         */
-       rn = route_node_get(rfd->rib[afi], &pn->p); /* locks rn */
+       rn = agg_node_get(rfd->rib[afi], &pn->p); /* locks rn */
 
        /*
         * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info,
@@ -945,30 +946,30 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
 
                        skiplist_free(slRibPt);
                        rn->info = slRibPt = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
 
                        lPendCost = pn->info = NULL;
-                       route_unlock_node(pn);
+                       agg_unlock_node(pn);
 
                        goto callback;
                }
                if (slRibPt) {
                        skiplist_free(slRibPt);
                        rn->info = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
 
                assert(!slPendPt);
                if (slPendPt) { /* TBD I think we can toss this block */
                        skiplist_free(slPendPt);
                        pn->aggregate = NULL;
-                       route_unlock_node(pn);
+                       agg_unlock_node(pn);
                }
 
                pn->info = NULL;
-               route_unlock_node(pn);
+               agg_unlock_node(pn);
 
-               route_unlock_node(rn); /* route_node_get() */
+               agg_unlock_node(rn); /* agg_node_get() */
 
                if (rib_node_started_nonempty) {
                        RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi);
@@ -1076,7 +1077,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                        if (skiplist_empty(slRibPt)) {
                                skiplist_free(slRibPt);
                                slRibPt = rn->info = NULL;
-                               route_unlock_node(rn);
+                               agg_unlock_node(rn);
                        }
                }
        }
@@ -1142,7 +1143,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                                        slRibPt = skiplist_new(
                                                0, rfapi_rib_key_cmp, NULL);
                                        rn->info = slRibPt;
-                                       route_lock_node(rn);
+                                       agg_lock_node(rn);
                                }
                                skiplist_insert(slRibPt, &ori->rk, ori);
 
@@ -1192,7 +1193,7 @@ callback:
                for (ALL_LIST_ELEMENTS(lPendCost, node, nnode, ri)) {
 
                        struct rfapi_next_hop_entry *new;
-                       struct route_node *trn;
+                       struct agg_node *trn;
 
                        new = XCALLOC(MTYPE_RFAPI_NEXTHOP,
                                      sizeof(struct rfapi_next_hop_entry));
@@ -1244,11 +1245,11 @@ callback:
                        /*
                         * update this NVE's timestamp for this prefix
                         */
-                       trn = route_node_get(rfd->rsp_times[afi],
-                                            &pn->p); /* locks trn */
+                       trn = agg_node_get(rfd->rsp_times[afi],
+                                          &pn->p); /* locks trn */
                        trn->info = (void *)(uintptr_t)bgp_clock();
                        if (trn->lock > 1)
-                               route_unlock_node(trn);
+                               agg_unlock_node(trn);
 
                        rfapiRfapiIpAddr2Str(&new->vn_address, buf, BUFSIZ);
                        rfapiRfapiIpAddr2Str(&new->un_address, buf2, BUFSIZ);
@@ -1347,7 +1348,7 @@ callback:
                                                0, rfapi_rib_key_cmp,
                                                (void (*)(void *))
                                                        rfapi_info_free);
-                                       route_lock_node(rn);
+                                       agg_lock_node(rn);
                                }
                                RFAPI_RIB_CHECK_COUNTS(0, delete_list->count);
 
@@ -1438,18 +1439,18 @@ callback:
        RFAPI_RIB_CHECK_COUNTS(0, 0);
 
        /*
-        * Reset pending lists. The final route_unlock_node() will probably
+        * Reset pending lists. The final agg_unlock_node() will probably
         * cause the pending node to be released.
         */
        if (slPendPt) {
                skiplist_free(slPendPt);
                pn->aggregate = NULL;
-               route_unlock_node(pn);
+               agg_unlock_node(pn);
        }
        if (lPendCost) {
                list_delete_and_null(&lPendCost);
                pn->info = NULL;
-               route_unlock_node(pn);
+               agg_unlock_node(pn);
        }
        RFAPI_RIB_CHECK_COUNTS(0, 0);
 
@@ -1466,7 +1467,7 @@ callback:
        if (sendingsomeroutes)
                rfapiMonitorTimersRestart(rfd, &pn->p);
 
-       route_unlock_node(rn); /* route_node_get() */
+       agg_unlock_node(rn); /* agg_node_get() */
 
        RFAPI_RIB_CHECK_COUNTS(1, 0);
 }
@@ -1484,7 +1485,7 @@ static void rib_do_callback_onepass(struct rfapi_descriptor *rfd, afi_t afi)
        struct bgp *bgp = bgp_get_default();
        struct rfapi_next_hop_entry *head = NULL;
        struct rfapi_next_hop_entry *tail = NULL;
-       struct route_node *rn;
+       struct agg_node *rn;
 
 #if DEBUG_L2_EXTRA
        vnc_zlog_debug_verbose("%s: rfd=%p, afi=%d", __func__, rfd, afi);
@@ -1495,7 +1496,8 @@ static void rib_do_callback_onepass(struct rfapi_descriptor *rfd, afi_t afi)
 
        assert(bgp->rfapi);
 
-       for (rn = route_top(rfd->rib_pending[afi]); rn; rn = route_next(rn)) {
+       for (rn = agg_route_top(rfd->rib_pending[afi]); rn;
+            rn = agg_route_next(rn)) {
                process_pending_node(bgp, rfd, afi, rn, &head, &tail);
        }
 
@@ -1585,11 +1587,11 @@ static void updated_responses_queue_init(struct rfapi_descriptor *rfd)
 void rfapiRibUpdatePendingNode(
        struct bgp *bgp, struct rfapi_descriptor *rfd,
        struct rfapi_import_table *it, /* needed for L2 */
-       struct route_node *it_node, uint32_t lifetime)
+       struct agg_node *it_node, uint32_t lifetime)
 {
        struct prefix *prefix;
        struct bgp_info *bi;
-       struct route_node *pn;
+       struct agg_node *pn;
        afi_t afi;
        uint32_t queued_flag;
        int count = 0;
@@ -1609,7 +1611,7 @@ void rfapiRibUpdatePendingNode(
        prefix2str(prefix, buf, sizeof(buf));
        vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf);
 
-       pn = route_node_get(rfd->rib_pending[afi], prefix);
+       pn = agg_node_get(rfd->rib_pending[afi], prefix);
        assert(pn);
 
        vnc_zlog_debug_verbose("%s: pn->info=%p, pn->aggregate=%p", __func__,
@@ -1622,7 +1624,7 @@ void rfapiRibUpdatePendingNode(
                 */
                skiplist_free((struct skiplist *)(pn->aggregate));
                pn->aggregate = NULL;
-               route_unlock_node(pn); /* skiplist deleted */
+               agg_unlock_node(pn); /* skiplist deleted */
        }
 
 
@@ -1634,7 +1636,7 @@ void rfapiRibUpdatePendingNode(
                        list_delete_and_null((struct list **)(&pn->info));
                }
                pn->info = NULL;
-               route_unlock_node(pn); /* linklist or 1 deleted */
+               agg_unlock_node(pn); /* linklist or 1 deleted */
        }
 
        /*
@@ -1689,7 +1691,7 @@ void rfapiRibUpdatePendingNode(
                if (!pn->aggregate) {
                        pn->aggregate =
                                skiplist_new(0, rfapi_rib_key_cmp, NULL);
-                       route_lock_node(pn);
+                       agg_lock_node(pn);
                }
 
                /*
@@ -1715,7 +1717,7 @@ void rfapiRibUpdatePendingNode(
                        pn->info = list_new();
                        ((struct list *)(pn->info))->del =
                                (void (*)(void *))rfapi_info_free;
-                       route_lock_node(pn);
+                       agg_lock_node(pn);
                }
 
                listnode_add((struct list *)(pn->info), ri);
@@ -1730,10 +1732,10 @@ void rfapiRibUpdatePendingNode(
                assert(!pn->aggregate);
                pn->info = (void *)1; /* magic value means this node has no
                                         routes */
-               route_lock_node(pn);
+               agg_lock_node(pn);
        }
 
-       route_unlock_node(pn); /* route_node_get */
+       agg_unlock_node(pn); /* agg_node_get */
 
        queued_flag = RFAPI_QUEUED_FLAG(afi);
 
@@ -1757,25 +1759,30 @@ void rfapiRibUpdatePendingNode(
 
 void rfapiRibUpdatePendingNodeSubtree(
        struct bgp *bgp, struct rfapi_descriptor *rfd,
-       struct rfapi_import_table *it, struct route_node *it_node,
-       struct route_node *omit_subtree, /* may be NULL */
+       struct rfapi_import_table *it, struct agg_node *it_node,
+       struct agg_node *omit_subtree, /* may be NULL */
        uint32_t lifetime)
 {
        /* FIXME: need to find a better way here to work without sticking our
         * hands in node->link */
-       if (it_node->l_left && (it_node->l_left != omit_subtree)) {
-               if (it_node->l_left->info)
-                       rfapiRibUpdatePendingNode(bgp, rfd, it, it_node->l_left,
-                                                 lifetime);
-               rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_left,
+       if (agg_node_left(it_node)
+           && (agg_node_left(it_node) != omit_subtree)) {
+               if (agg_node_left(it_node)->info)
+                       rfapiRibUpdatePendingNode(
+                               bgp, rfd, it, agg_node_left(it_node), lifetime);
+               rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it,
+                                                agg_node_left(it_node),
                                                 omit_subtree, lifetime);
        }
 
-       if (it_node->l_right && (it_node->l_right != omit_subtree)) {
-               if (it_node->l_right->info)
+       if (agg_node_right(it_node)
+           && (agg_node_right(it_node) != omit_subtree)) {
+               if (agg_node_right(it_node)->info)
                        rfapiRibUpdatePendingNode(bgp, rfd, it,
-                                                 it_node->l_right, lifetime);
-               rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_right,
+                                                 agg_node_right(it_node),
+                                                 lifetime);
+               rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it,
+                                                agg_node_right(it_node),
                                                 omit_subtree, lifetime);
        }
 }
@@ -1788,13 +1795,13 @@ void rfapiRibUpdatePendingNodeSubtree(
  */
 int rfapiRibFTDFilterRecentPrefix(
        struct rfapi_descriptor *rfd,
-       struct route_node *it_rn,          /* import table node */
+       struct agg_node *it_rn,             /* import table node */
        struct prefix *pfx_target_original) /* query target */
 {
        struct bgp *bgp = rfd->bgp;
        afi_t afi = family2afi(it_rn->p.family);
        time_t prefix_time;
-       struct route_node *trn;
+       struct agg_node *trn;
 
        /*
         * Not in FTD mode, so allow prefix
@@ -1833,10 +1840,10 @@ int rfapiRibFTDFilterRecentPrefix(
        /*
         * check this NVE's timestamp for this prefix
         */
-       trn = route_node_get(rfd->rsp_times[afi], &it_rn->p); /* locks trn */
+       trn = agg_node_get(rfd->rsp_times[afi], &it_rn->p); /* locks trn */
        prefix_time = (time_t)trn->info;
        if (trn->lock > 1)
-               route_unlock_node(trn);
+               agg_unlock_node(trn);
 
 #if DEBUG_FTD_FILTER_RECENT
        vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu",
@@ -1883,9 +1890,9 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
                afi_t afi;
                struct rfapi_info *ri;
                int need_insert;
-               struct route_node *rn;
+               struct agg_node *rn;
                int rib_node_started_nonempty = 0;
-               struct route_node *trn;
+               struct agg_node *trn;
                int allowed = 0;
 
                /* save in case we delete nhp */
@@ -1947,13 +1954,13 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
                /*
                 * Look up prefix in RIB
                 */
-               rn = route_node_get(rfd->rib[afi], &pfx); /* locks rn */
+               rn = agg_node_get(rfd->rib[afi], &pfx); /* locks rn */
 
                if (rn->info) {
                        rib_node_started_nonempty = 1;
                } else {
                        rn->info = skiplist_new(0, rfapi_rib_key_cmp, NULL);
-                       route_lock_node(rn);
+                       agg_lock_node(rn);
                }
 
                /*
@@ -2063,15 +2070,15 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
                rfapiRibStartTimer(rfd, ri, rn, 0);
                RFAPI_RIB_CHECK_COUNTS(0, 0);
 
-               route_unlock_node(rn);
+               agg_unlock_node(rn);
 
                /*
                 * update this NVE's timestamp for this prefix
                 */
-               trn = route_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */
+               trn = agg_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */
                trn->info = (void *)(uintptr_t)bgp_clock();
                if (trn->lock > 1)
-                       route_unlock_node(trn);
+                       agg_unlock_node(trn);
 
                {
                        char str_pfx[PREFIX_STRLEN];
@@ -2108,7 +2115,7 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
 }
 
 void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it,
-                               afi_t afi, struct route_node *it_node)
+                               afi_t afi, struct agg_node *it_node)
 {
        struct rfapi_descriptor *rfd;
        struct listnode *node;
@@ -2124,7 +2131,7 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it,
                 * identifies the rfd that owns it.
                 */
                struct rfapi_monitor_eth *m;
-               struct route_node *rn;
+               struct agg_node *rn;
                struct skiplist *sl;
                void *cursor;
                int rc;
@@ -2154,12 +2161,12 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it,
                                 * NVE, it's OK to send an update with the
                                 * delete
                                 */
-                               if ((rn = route_node_lookup(m->rfd->rib[afi],
-                                                           &it_node->p))) {
+                               if ((rn = agg_node_lookup(m->rfd->rib[afi],
+                                                         &it_node->p))) {
                                        rfapiRibUpdatePendingNode(
                                                bgp, m->rfd, it, it_node,
                                                m->rfd->response_lifetime);
-                                       route_unlock_node(rn);
+                                       agg_unlock_node(rn);
                                }
                        }
                }
@@ -2177,8 +2184,8 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it,
                         * this
                         * NVE, it's OK to send an update with the delete
                         */
-                       if ((rn = route_node_lookup(m->rfd->rib[afi],
-                                                   &it_node->p))) {
+                       if ((rn = agg_node_lookup(m->rfd->rib[afi],
+                                                 &it_node->p))) {
                                rfapiRibUpdatePendingNode(
                                        bgp, m->rfd, it, it_node,
                                        m->rfd->response_lifetime);
@@ -2192,7 +2199,7 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it,
                for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node,
                                          rfd)) {
 
-                       struct route_node *rn;
+                       struct agg_node *rn;
 
                        vnc_zlog_debug_verbose(
                                "%s: comparing rfd(%p)->import_table=%p to it=%p",
@@ -2209,12 +2216,12 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it,
                         * prefix
                         * previously, we should send an updated response.
                         */
-                       if ((rn = route_node_lookup(rfd->rib[afi],
-                                                   &it_node->p))) {
+                       if ((rn = agg_node_lookup(rfd->rib[afi],
+                                                 &it_node->p))) {
                                rfapiRibUpdatePendingNode(
                                        bgp, rfd, it, it_node,
                                        rfd->response_lifetime);
-                               route_unlock_node(rn);
+                               agg_unlock_node(rn);
                        }
                }
        }
@@ -2406,13 +2413,13 @@ void rfapiRibShowResponses(void *stream, struct prefix *pfx_match,
 
                for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 
-                       struct route_node *rn;
+                       struct agg_node *rn;
 
                        if (!rfd->rib[afi])
                                continue;
 
-                       for (rn = route_top(rfd->rib[afi]); rn;
-                            rn = route_next(rn)) {
+                       for (rn = agg_route_top(rfd->rib[afi]); rn;
+                            rn = agg_route_next(rn)) {
 
                                struct skiplist *sl;
                                char str_pfx[PREFIX_STRLEN];
index 0542727c2e4d80f37e93aba623f79a36cce1ad8c..a8872295cd30088fa0bb3f70128c9e9a7e7b1a43 100644 (file)
@@ -93,17 +93,17 @@ extern void rfapiRibFree(struct rfapi_descriptor *rfd);
 extern void rfapiRibUpdatePendingNode(struct bgp *bgp,
                                      struct rfapi_descriptor *rfd,
                                      struct rfapi_import_table *it,
-                                     struct route_node *it_node,
+                                     struct agg_node *it_node,
                                      uint32_t lifetime);
 
 extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp,
                                             struct rfapi_descriptor *rfd,
                                             struct rfapi_import_table *it,
-                                            struct route_node *it_node,
-                                            struct route_node *omit_subtree,
+                                            struct agg_node *it_node,
+                                            struct agg_node *omit_subtree,
                                             uint32_t lifetime);
 
-extern int rfapiRibPreloadBi(struct route_node *rfd_rib_node,
+extern int rfapiRibPreloadBi(struct agg_node *rfd_rib_node,
                             struct prefix *pfx_vn, struct prefix *pfx_un,
                             uint32_t lifetime, struct bgp_info *bi);
 
@@ -113,7 +113,7 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
 
 extern void rfapiRibPendingDeleteRoute(struct bgp *bgp,
                                       struct rfapi_import_table *it, afi_t afi,
-                                      struct route_node *it_node);
+                                      struct agg_node *it_node);
 
 extern void rfapiRibShowResponsesSummary(void *stream);
 
@@ -124,7 +124,7 @@ extern void rfapiRibShowResponses(void *stream, struct prefix *pfx_match,
 
 extern int rfapiRibFTDFilterRecentPrefix(
        struct rfapi_descriptor *rfd,
-       struct route_node *it_rn,           /* import table node */
+       struct agg_node *it_rn,              /* import table node */
        struct prefix *pfx_target_original); /* query target */
 
 extern void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p);
index cd12edbccb1f9c47c30aadccd64f2684c9e93d27..cd751319eb5da387fd1e94f0a1404172ce368b6f 100644 (file)
  * 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"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/memory.h"
 #include "lib/routemap.h"
@@ -742,7 +739,7 @@ static void rfapiDebugPrintMonitorEncap(void *stream,
           m->bi, HVTYNL);
 }
 
-void rfapiShowItNode(void *stream, struct route_node *rn)
+void rfapiShowItNode(void *stream, struct agg_node *rn)
 {
        struct bgp_info *bi;
        char buf[BUFSIZ];
@@ -766,10 +763,10 @@ void rfapiShowItNode(void *stream, struct route_node *rn)
        /* doesn't show montors */
 }
 
-void rfapiShowImportTable(void *stream, const char *label,
-                         struct route_table *rt, int isvpn)
+void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt,
+                         int isvpn)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
        char buf[BUFSIZ];
 
        int (*fp)(void *, const char *, ...);
@@ -782,7 +779,7 @@ void rfapiShowImportTable(void *stream, const char *label,
 
        fp(out, "Import Table [%s]%s", label, HVTYNL);
 
-       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+       for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
                struct bgp_info *bi;
 
                if (rn->p.family == AF_ETHERNET) {
@@ -851,7 +848,7 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)
 
        for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
 
-               struct route_node *rn;
+               struct agg_node *rn;
                int printedquerier = 0;
 
 
@@ -868,8 +865,8 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)
                 * IP Queries
                 */
                if (rfd->mon) {
-                       for (rn = route_top(rfd->mon); rn;
-                            rn = route_next(rn)) {
+                       for (rn = agg_route_top(rfd->mon); rn;
+                            rn = agg_route_next(rn)) {
                                struct rfapi_monitor_vpn *m;
                                char buf_remain[BUFSIZ];
                                char buf_pfx[BUFSIZ];
@@ -1012,7 +1009,7 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)
 }
 
 static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
-                                struct route_node *rn, struct bgp_info *bi)
+                                struct agg_node *rn, struct bgp_info *bi)
 {
        int (*fp)(void *, const char *, ...);
        struct vty *vty;
@@ -1218,13 +1215,13 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
 
        for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
 
-               struct route_node *rn;
+               struct agg_node *rn;
 
                if (!it->imported_vpn[afi])
                        continue;
 
-               for (rn = route_top(it->imported_vpn[afi]); rn;
-                    rn = route_next(rn)) {
+               for (rn = agg_route_top(it->imported_vpn[afi]); rn;
+                    rn = agg_route_next(rn)) {
 
                        struct bgp_info *bi;
                        int count_only;
index a08183aa461d8baefbb26577ac5d8e83adb799f5..8b881292ac1830661973b40d98e95338c52227de 100644 (file)
@@ -124,7 +124,7 @@ extern char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf,
 extern const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf,
                                          int bufsize);
 
-extern void rfapiShowItNode(void *stream, struct route_node *rn);
+extern void rfapiShowItNode(void *stream, struct agg_node *rn);
 
 extern char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize);
 
index 69426670a12d4bfbf59cfc4dcecd2ca8415b5fbd..62891756457c7a16aa97b78b94462bf2be575c8b 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/log.h"
 #include "lib/stream.h"
@@ -54,7 +54,7 @@
 
 static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
                                       struct rfapi_nve_group_cfg *rfg,
-                                      struct route_node *rn, struct attr *attr,
+                                      struct agg_node *rn, struct attr *attr,
                                       afi_t afi,
                                       struct rfapi_descriptor *irfd);
 
@@ -172,7 +172,7 @@ static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce)
 }
 
 
-void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn,
+void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
                                 struct bgp_info *bi)
 {
        struct attr *attr = bi->attr;
@@ -327,7 +327,7 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn,
 /*
  * "Withdrawing a Route" export process
  */
-void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn,
+void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
                                 struct bgp_info *bi)
 {
        afi_t afi = family2afi(rn->p.family);
@@ -404,7 +404,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn,
 
 static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
 {
-       struct route_node *rn;
+       struct agg_node *rn;
        struct bgp_info *ri;
 
        vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi);
@@ -430,8 +430,8 @@ static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
        /*
         * Go through entire ce import table and export to BGP unicast.
         */
-       for (rn = route_top(bgp->rfapi->it_ce->imported_vpn[afi]); rn;
-            rn = route_next(rn)) {
+       for (rn = agg_route_top(bgp->rfapi->it_ce->imported_vpn[afi]); rn;
+            rn = agg_route_next(rn)) {
 
                if (!rn->info)
                        continue;
@@ -513,7 +513,7 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)
  * Export methods that proxy nexthop BEGIN
  ***********************************************************************/
 
-static struct ecommunity *vnc_route_origin_ecom(struct route_node *rn)
+static struct ecommunity *vnc_route_origin_ecom(struct agg_node *rn)
 {
        struct ecommunity *new;
        struct bgp_info *bi;
@@ -586,8 +586,8 @@ static struct ecommunity *vnc_route_origin_ecom_single(struct in_addr *origin)
 static int
 encap_attr_export(struct attr *new, struct attr *orig,
                  struct prefix *new_nexthop,
-                 struct route_node *rn) /* for VN addrs for ecom list */
-                                        /* if rn is 0, use route's nexthop */
+                 struct agg_node *rn) /* for VN addrs for ecom list */
+                                      /* if rn is 0, use route's nexthop */
 {
        struct prefix orig_nexthop;
        struct prefix *use_nexthop;
@@ -692,7 +692,7 @@ encap_attr_export(struct attr *new, struct attr *orig,
  */
 void vnc_direct_bgp_add_prefix(struct bgp *bgp,
                               struct rfapi_import_table *import_table,
-                              struct route_node *rn)
+                              struct agg_node *rn)
 {
        struct attr attr = {0};
        struct listnode *node, *nnode;
@@ -803,7 +803,7 @@ void vnc_direct_bgp_add_prefix(struct bgp *bgp,
  */
 void vnc_direct_bgp_del_prefix(struct bgp *bgp,
                               struct rfapi_import_table *import_table,
-                              struct route_node *rn)
+                              struct agg_node *rn)
 {
        struct listnode *node, *nnode;
        struct rfapi_rfg_name *rfgn;
@@ -965,8 +965,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
                 */
                if (rfgn->rfg == rfg) {
 
-                       struct route_table *rt = NULL;
-                       struct route_node *rn;
+                       struct agg_table *rt = NULL;
+                       struct agg_node *rn;
                        struct attr attr = {0};
                        struct rfapi_import_table *import_table;
 
@@ -987,7 +987,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
                        /*
                         * Walk the NVE-Group's VNC Import table
                         */
-                       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                       for (rn = agg_route_top(rt); rn;
+                            rn = agg_route_next(rn)) {
 
                                if (rn->info) {
 
@@ -1111,8 +1112,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
                 */
                if (rfg && rfgn->rfg == rfg) {
 
-                       struct route_table *rt = NULL;
-                       struct route_node *rn;
+                       struct agg_table *rt = NULL;
+                       struct agg_node *rn;
                        struct rfapi_import_table *import_table;
 
                        import_table = rfg->rfapi_import_table;
@@ -1128,7 +1129,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
                        /*
                         * Walk the NVE-Group's VNC Import table
                         */
-                       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                       for (rn = agg_route_top(rt); rn;
+                            rn = agg_route_next(rn)) {
 
                                if (rn->info) {
 
@@ -1159,7 +1161,7 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
 
 static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
                                       struct rfapi_nve_group_cfg *rfg,
-                                      struct route_node *rn, struct attr *attr,
+                                      struct agg_node *rn, struct attr *attr,
                                       afi_t afi, struct rfapi_descriptor *irfd)
 {
        struct prefix nhp;
@@ -1279,8 +1281,8 @@ static void vnc_direct_bgp_add_group_afi(struct bgp *bgp,
                                         struct rfapi_nve_group_cfg *rfg,
                                         afi_t afi)
 {
-       struct route_table *rt = NULL;
-       struct route_node *rn;
+       struct agg_table *rt = NULL;
+       struct agg_node *rn;
        struct attr attr = {0};
        struct rfapi_import_table *import_table;
 
@@ -1311,7 +1313,7 @@ static void vnc_direct_bgp_add_group_afi(struct bgp *bgp,
        /*
         * Walk the NVE-Group's VNC Import table
         */
-       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+       for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
 
                if (rn->info) {
 
@@ -1366,7 +1368,7 @@ void vnc_direct_bgp_add_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)
 
 static void vnc_direct_del_rn_group_rd(struct bgp *bgp,
                                       struct rfapi_nve_group_cfg *rfg,
-                                      struct route_node *rn, afi_t afi,
+                                      struct agg_node *rn, afi_t afi,
                                       struct rfapi_descriptor *irfd)
 {
        if (irfd == NULL)
@@ -1388,8 +1390,8 @@ static void vnc_direct_bgp_del_group_afi(struct bgp *bgp,
                                         struct rfapi_nve_group_cfg *rfg,
                                         afi_t afi)
 {
-       struct route_table *rt = NULL;
-       struct route_node *rn;
+       struct agg_table *rt = NULL;
+       struct agg_node *rn;
        struct rfapi_import_table *import_table;
 
        vnc_zlog_debug_verbose("%s: entry", __func__);
@@ -1412,7 +1414,7 @@ static void vnc_direct_bgp_del_group_afi(struct bgp *bgp,
        /*
         * Walk the NVE-Group's VNC Import table
         */
-       for (rn = route_top(rt); rn; rn = route_next(rn))
+       for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn))
                if (rn->info) {
                        if (rfg->type == RFAPI_GROUP_CFG_VRF)
                                vnc_direct_del_rn_group_rd(bgp, rfg, rn, afi,
@@ -1473,14 +1475,14 @@ void vnc_direct_bgp_reexport_group_afi(struct bgp *bgp,
 }
 
 
-static void vnc_direct_bgp_unexport_table(afi_t afi, struct route_table *rt,
+static void vnc_direct_bgp_unexport_table(afi_t afi, struct agg_table *rt,
                                          struct list *nve_list)
 {
        if (nve_list) {
 
-               struct route_node *rn;
+               struct agg_node *rn;
 
-               for (rn = route_top(rt); rn; rn = route_next(rn)) {
+               for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
 
                        if (rn->info) {
 
index c164a35432d5913c4c591cc9dbc428f9a398d849..e074c3eaad272d00ecb40ace57b5f3885e524601 100644 (file)
 
 #include "rfapi_private.h"
 
-extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn,
+extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn,
                                        struct bgp_info *bi);
 
-extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn,
+extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
                                        struct bgp_info *bi);
 
 extern void vnc_direct_bgp_add_prefix(struct bgp *bgp,
                                      struct rfapi_import_table *import_table,
-                                     struct route_node *rn);
+                                     struct agg_node *rn);
 
 extern void vnc_direct_bgp_del_prefix(struct bgp *bgp,
                                      struct rfapi_import_table *import_table,
-                                     struct route_node *rn);
+                                     struct agg_node *rn);
 
 extern void vnc_direct_bgp_add_nve(struct bgp *bgp,
                                   struct rfapi_descriptor *rfd);
index bbdb59c1251d89ba53f3c5d8c935df17365cf0c0..5e00a1017ba31e0d7a22af6588df8f3881a7e653 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/memory.h"
 #include "lib/vty.h"
 
 #include "bgpd/rfapi/rfapi_import.h"
 #include "bgpd/rfapi/vnc_debug.h"
 
-struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
-                              struct prefix *p)
+struct agg_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
+                            struct prefix *p)
 {
-       struct route_table *t = NULL;
-       struct route_node *rn = NULL;
+       struct agg_table *t = NULL;
+       struct agg_node *rn = NULL;
        afi_t afi;
 
        if (!bgp || !bgp->rfapi)
@@ -49,27 +49,27 @@ struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
        switch (type) {
        case EXPORT_TYPE_BGP:
                if (!bgp->rfapi->rt_export_bgp[afi])
-                       bgp->rfapi->rt_export_bgp[afi] = route_table_init();
+                       bgp->rfapi->rt_export_bgp[afi] = agg_table_init();
                t = bgp->rfapi->rt_export_bgp[afi];
                break;
 
        case EXPORT_TYPE_ZEBRA:
                if (!bgp->rfapi->rt_export_zebra[afi])
-                       bgp->rfapi->rt_export_zebra[afi] = route_table_init();
+                       bgp->rfapi->rt_export_zebra[afi] = agg_table_init();
                t = bgp->rfapi->rt_export_zebra[afi];
                break;
        }
 
        if (t)
-               rn = route_node_get(t, p);
+               rn = agg_node_get(t, p);
        return rn;
 }
 
-struct route_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type,
-                                 struct prefix *p)
+struct agg_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type,
+                               struct prefix *p)
 {
-       struct route_table *t = NULL;
-       struct route_node *rn = NULL;
+       struct agg_table *t = NULL;
+       struct agg_node *rn = NULL;
        afi_t afi;
 
        if (!bgp || !bgp->rfapi)
@@ -81,19 +81,19 @@ struct route_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type,
        switch (type) {
        case EXPORT_TYPE_BGP:
                if (!bgp->rfapi->rt_export_bgp[afi])
-                       bgp->rfapi->rt_export_bgp[afi] = route_table_init();
+                       bgp->rfapi->rt_export_bgp[afi] = agg_table_init();
                t = bgp->rfapi->rt_export_bgp[afi];
                break;
 
        case EXPORT_TYPE_ZEBRA:
                if (!bgp->rfapi->rt_export_zebra[afi])
-                       bgp->rfapi->rt_export_zebra[afi] = route_table_init();
+                       bgp->rfapi->rt_export_zebra[afi] = agg_table_init();
                t = bgp->rfapi->rt_export_zebra[afi];
                break;
        }
 
        if (t)
-               rn = route_node_lookup(t, p);
+               rn = agg_node_lookup(t, p);
        return rn;
 }
 
@@ -101,7 +101,7 @@ struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype,
                                    struct prefix *p, struct peer *peer,
                                    uint8_t type, uint8_t subtype)
 {
-       struct route_node *etn;
+       struct agg_node *etn;
        struct vnc_export_info *eti;
 
        etn = vnc_etn_get(bgp, etype, p);
@@ -116,7 +116,7 @@ struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype,
        }
 
        if (eti) {
-               route_unlock_node(etn);
+               agg_unlock_node(etn);
        } else {
                eti = XCALLOC(MTYPE_RFAPI_ETI, sizeof(struct vnc_export_info));
                assert(eti);
@@ -134,7 +134,7 @@ struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype,
 
 void vnc_eti_delete(struct vnc_export_info *goner)
 {
-       struct route_node *etn;
+       struct agg_node *etn;
        struct vnc_export_info *eti;
        struct vnc_export_info *eti_prev = NULL;
 
@@ -160,7 +160,7 @@ void vnc_eti_delete(struct vnc_export_info *goner)
        goner->node = NULL;
        XFREE(MTYPE_RFAPI_ETI, goner);
 
-       route_unlock_node(etn);
+       agg_unlock_node(etn);
 }
 
 struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp,
@@ -168,7 +168,7 @@ struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp,
                                           struct prefix *p, struct peer *peer,
                                           uint8_t type, uint8_t subtype)
 {
-       struct route_node *etn;
+       struct agg_node *etn;
        struct vnc_export_info *eti;
 
        etn = vnc_etn_lookup(bgp, etype, p);
@@ -183,7 +183,7 @@ struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp,
                }
        }
 
-       route_unlock_node(etn);
+       agg_unlock_node(etn);
 
        if (eti && eti->timer)
                return eti;
index 3ccf8661e7c5cee7c1558561b43302f41cd944ce..fdb35e81e173b8e079e2edce46b380da3adb0be0 100644 (file)
@@ -37,7 +37,7 @@ typedef enum vnc_export_type {
 
 struct vnc_export_info {
        struct vnc_export_info *next;
-       struct route_node *node;
+       struct agg_node *node;
        struct peer *peer;
        uint8_t type;
        uint8_t subtype;
@@ -45,11 +45,11 @@ struct vnc_export_info {
        struct thread *timer;
 };
 
-extern struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
-                                     struct prefix *p);
+extern struct agg_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
+                                   struct prefix *p);
 
-extern struct route_node *
-vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, struct prefix *p);
+extern struct agg_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type,
+                                      struct prefix *p);
 
 extern struct vnc_export_info *vnc_eti_get(struct bgp *bgp,
                                           vnc_export_type_t etype,
index 72363f7cfe268917b806db1ca41352e724639cfe..6022e4cc24ac1ba883ed5994b61c0d6a5081614b 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/vty.h"
 #include "lib/log.h"
 #include "lib/memory.h"
@@ -1737,9 +1737,9 @@ static void vnc_import_bgp_exterior_add_route_it(
        rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop);
 
        for (it = h->imports; it; it = it->next) {
-               struct route_table *table;
-               struct route_node *rn;
-               struct route_node *par;
+               struct agg_table *table;
+               struct agg_node *rn;
+               struct agg_node *par;
                struct bgp_info *bi_interior;
                int have_usable_route;
 
@@ -1753,7 +1753,7 @@ static void vnc_import_bgp_exterior_add_route_it(
 
                table = it->imported_vpn[afi];
 
-               for (rn = route_node_match(table, &pfx_orig_nexthop),
+               for (rn = agg_node_match(table, &pfx_orig_nexthop),
                    have_usable_route = 0;
                     (!have_usable_route) && rn;) {
 
@@ -1821,9 +1821,9 @@ static void vnc_import_bgp_exterior_add_route_it(
                                                        0, NULL,
                                                        (void (*)(void *))
                                                                prefix_free);
-                                       route_lock_node(rn); /* for skiplist */
+                                       agg_lock_node(rn); /* for skiplist */
                                }
-                               route_lock_node(rn); /* for skiplist entry */
+                               agg_lock_node(rn); /* for skiplist entry */
                                prefix_copy(pfx_mon, prefix);
                                if (!skiplist_insert(
                                            RFAPI_MONITOR_EXTERIOR(rn)->source,
@@ -1832,14 +1832,14 @@ static void vnc_import_bgp_exterior_add_route_it(
                                        bgp_info_lock(info);
                                }
                        }
-                       par = rn->parent;
+                       par = agg_node_parent(rn);
                        if (par)
-                               route_lock_node(par);
-                       route_unlock_node(rn);
+                               agg_lock_node(par);
+                       agg_unlock_node(rn);
                        rn = par;
                }
                if (rn)
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
 
                if (!have_usable_route) {
                        struct prefix *pfx_mon = prefix_new();
@@ -1928,15 +1928,15 @@ void vnc_import_bgp_exterior_del_route(
        rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop);
 
        for (it = h->imports; it; it = it->next) {
-               struct route_table *table;
-               struct route_node *rn;
-               struct route_node *par;
+               struct agg_table *table;
+               struct agg_node *rn;
+               struct agg_node *par;
                struct bgp_info *bi_interior;
                int have_usable_route;
 
                table = it->imported_vpn[afi];
 
-               for (rn = route_node_match(table, &pfx_orig_nexthop),
+               for (rn = agg_node_match(table, &pfx_orig_nexthop),
                    have_usable_route = 0;
                     (!have_usable_route) && rn;) {
 
@@ -1987,9 +1987,9 @@ void vnc_import_bgp_exterior_del_route(
                                                            info, NULL)) {
 
                                                        bgp_info_unlock(info);
-                                                       route_unlock_node(
+                                                       agg_unlock_node(
                                                                rn); /* sl entry
-                                                                       */
+                                                                     */
                                                }
                                                if (skiplist_empty(
                                                            RFAPI_MONITOR_EXTERIOR(
@@ -2002,7 +2002,7 @@ void vnc_import_bgp_exterior_del_route(
                                                        RFAPI_MONITOR_EXTERIOR(
                                                                rn)
                                                                ->source = NULL;
-                                                       route_unlock_node(
+                                                       agg_unlock_node(
                                                                rn); /* skiplist
                                                                        itself
                                                                        */
@@ -2010,14 +2010,14 @@ void vnc_import_bgp_exterior_del_route(
                                        }
                                }
                        }
-                       par = rn->parent;
+                       par = agg_node_parent(rn);
                        if (par)
-                               route_lock_node(par);
-                       route_unlock_node(rn);
+                               agg_lock_node(par);
+                       agg_unlock_node(rn);
                        rn = par;
                }
                if (rn)
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
 
                if (!have_usable_route) {
                        if (!skiplist_delete(it->monitor_exterior_orphans, info,
@@ -2038,11 +2038,11 @@ void vnc_import_bgp_exterior_del_route(
  */
 void vnc_import_bgp_exterior_add_route_interior(
        struct bgp *bgp, struct rfapi_import_table *it,
-       struct route_node *rn_interior, /* VPN IT node */
-       struct bgp_info *bi_interior)   /* VPN IT route */
+       struct agg_node *rn_interior, /* VPN IT node */
+       struct bgp_info *bi_interior) /* VPN IT route */
 {
        afi_t afi = family2afi(rn_interior->p.family);
-       struct route_node *par;
+       struct agg_node *par;
        struct bgp_info *bi_exterior;
        struct prefix *pfx_exterior; /* exterior pfx */
        void *cursor;
@@ -2161,7 +2161,8 @@ void vnc_import_bgp_exterior_add_route_interior(
         * Look up the tree for possible pulldown candidates.
         * Find nearest parent with an exterior route monitor
         */
-       for (par = rn_interior->parent; par; par = par->parent) {
+       for (par = agg_node_parent(rn_interior); par;
+            par = agg_node_parent(par)) {
                if (RFAPI_HAS_MONITOR_EXTERIOR(par))
                        break;
        }
@@ -2211,13 +2212,13 @@ void vnc_import_bgp_exterior_add_route_interior(
                                                ->source = skiplist_new(
                                                0, NULL,
                                                (void (*)(void *))prefix_free);
-                                       route_lock_node(rn_interior);
+                                       agg_lock_node(rn_interior);
                                }
                                skiplist_insert(
                                        RFAPI_MONITOR_EXTERIOR(rn_interior)
                                                ->source,
                                        bi_exterior, pfx_mon);
-                               route_lock_node(rn_interior);
+                               agg_lock_node(rn_interior);
 
                                /*
                                 * Delete constructed exterior routes based on
@@ -2291,12 +2292,12 @@ void vnc_import_bgp_exterior_add_route_interior(
 
                        skiplist_delete(RFAPI_MONITOR_EXTERIOR(par)->source,
                                        bi_exterior, NULL);
-                       route_unlock_node(par); /* sl entry */
+                       agg_unlock_node(par); /* sl entry */
                }
                if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(par)->source)) {
                        skiplist_free(RFAPI_MONITOR_EXTERIOR(par)->source);
                        RFAPI_MONITOR_EXTERIOR(par)->source = NULL;
-                       route_unlock_node(par); /* sl itself */
+                       agg_unlock_node(par); /* sl itself */
                }
        }
 
@@ -2353,12 +2354,12 @@ void vnc_import_bgp_exterior_add_route_interior(
                                        skiplist_new(
                                                0, NULL,
                                                (void (*)(void *))prefix_free);
-                               route_lock_node(rn_interior); /* sl */
+                               agg_lock_node(rn_interior); /* sl */
                        }
                        skiplist_insert(
                                RFAPI_MONITOR_EXTERIOR(rn_interior)->source,
                                bi_exterior, pfx_mon);
-                       route_lock_node(rn_interior); /* sl entry */
+                       agg_lock_node(rn_interior); /* sl entry */
                        if (!list_adopted) {
                                list_adopted = list_new();
                        }
@@ -2397,7 +2398,7 @@ void vnc_import_bgp_exterior_add_route_interior(
        }
        if (list_adopted) {
                struct listnode *node;
-               struct route_node *bi_exterior;
+               struct agg_node *bi_exterior;
 
                for (ALL_LIST_ELEMENTS_RO(list_adopted, node, bi_exterior)) {
                        skiplist_delete(it->monitor_exterior_orphans,
@@ -2419,11 +2420,11 @@ void vnc_import_bgp_exterior_add_route_interior(
  */
 void vnc_import_bgp_exterior_del_route_interior(
        struct bgp *bgp, struct rfapi_import_table *it,
-       struct route_node *rn_interior, /* VPN IT node */
-       struct bgp_info *bi_interior)   /* VPN IT route */
+       struct agg_node *rn_interior, /* VPN IT node */
+       struct bgp_info *bi_interior) /* VPN IT route */
 {
        afi_t afi = family2afi(rn_interior->p.family);
-       struct route_node *par;
+       struct agg_node *par;
        struct bgp_info *bi_exterior;
        struct prefix *pfx_exterior; /* exterior pfx */
        void *cursor;
@@ -2509,7 +2510,8 @@ void vnc_import_bgp_exterior_del_route_interior(
         * If none is found, par will end up NULL, and we will move
         * the monitors to the orphan list for this import table
         */
-       for (par = rn_interior->parent; par; par = par->parent) {
+       for (par = agg_node_parent(rn_interior); par;
+            par = agg_node_parent(par)) {
                if (RFAPI_MONITOR_EXTERIOR(par)->valid_interior_count)
                        break;
        }
@@ -2540,11 +2542,11 @@ void vnc_import_bgp_exterior_del_route_interior(
                                        skiplist_new(
                                                0, NULL,
                                                (void (*)(void *))prefix_free);
-                               route_lock_node(par); /* sl */
+                               agg_lock_node(par); /* sl */
                        }
                        skiplist_insert(RFAPI_MONITOR_EXTERIOR(par)->source,
                                        bi_exterior, pfx_mon);
-                       route_lock_node(par); /* sl entry */
+                       agg_lock_node(par); /* sl entry */
 
                        /* Add constructed exterior routes based on parent */
                        for (bi = par->info; bi; bi = bi->next) {
@@ -2596,12 +2598,12 @@ void vnc_import_bgp_exterior_del_route_interior(
 
                skiplist_delete_first(
                        RFAPI_MONITOR_EXTERIOR(rn_interior)->source);
-               route_unlock_node(rn_interior); /* sl entry */
+               agg_unlock_node(rn_interior); /* sl entry */
        }
        if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(rn_interior)->source)) {
                skiplist_free(RFAPI_MONITOR_EXTERIOR(rn_interior)->source);
                RFAPI_MONITOR_EXTERIOR(rn_interior)->source = NULL;
-               route_unlock_node(rn_interior); /* sl itself */
+               agg_unlock_node(rn_interior); /* sl itself */
        }
 }
 
index b38fa2276ae4a612c5fda38b6ba7484e66eff87d..a6fcae926dff1e9f658ad9ac6b2f9568fb99dd75 100644 (file)
 
 extern void vnc_import_bgp_exterior_add_route_interior(
        struct bgp *bgp, struct rfapi_import_table *it,
-       struct route_node *rn_interior, /* VPN IT node */
-       struct bgp_info *bi_interior);  /* VPN IT route */
+       struct agg_node *rn_interior,  /* VPN IT node */
+       struct bgp_info *bi_interior); /* VPN IT route */
 
 extern void vnc_import_bgp_exterior_del_route_interior(
        struct bgp *bgp, struct rfapi_import_table *it,
-       struct route_node *rn_interior, /* VPN IT node */
-       struct bgp_info *bi_interior);  /* VPN IT route */
+       struct agg_node *rn_interior,  /* VPN IT node */
+       struct bgp_info *bi_interior); /* VPN IT route */
 
 extern void
 vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi,
index a2871188e69b32b852f3868fe6ca80b1fbebe96e..a93fb60735732eb93b23f955b0191eaadf2af434 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "lib/zebra.h"
 #include "lib/prefix.h"
-#include "lib/table.h"
+#include "lib/agg_table.h"
 #include "lib/log.h"
 #include "lib/command.h"
 #include "lib/zclient.h"
@@ -556,7 +556,7 @@ static void import_table_to_nve_list_zebra(struct bgp *bgp,
 
 static void vnc_zebra_add_del_prefix(struct bgp *bgp,
                                     struct rfapi_import_table *import_table,
-                                    struct route_node *rn,
+                                    struct agg_node *rn,
                                     int add) /* !0 = add, 0 = del */
 {
        struct list *nves;
@@ -611,14 +611,14 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp,
 
 void vnc_zebra_add_prefix(struct bgp *bgp,
                          struct rfapi_import_table *import_table,
-                         struct route_node *rn)
+                         struct agg_node *rn)
 {
        vnc_zebra_add_del_prefix(bgp, import_table, rn, 1);
 }
 
 void vnc_zebra_del_prefix(struct bgp *bgp,
                          struct rfapi_import_table *import_table,
-                         struct route_node *rn)
+                         struct agg_node *rn)
 {
        vnc_zebra_add_del_prefix(bgp, import_table, rn, 0);
 }
@@ -678,8 +678,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd,
                 */
                if (rfgn->rfg == rfg) {
 
-                       struct route_table *rt = NULL;
-                       struct route_node *rn;
+                       struct agg_table *rt = NULL;
+                       struct agg_node *rn;
                        struct rfapi_import_table *import_table;
                        import_table = rfg->rfapi_import_table;
 
@@ -692,7 +692,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd,
                        /*
                         * Walk the NVE-Group's VNC Import table
                         */
-                       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                       for (rn = agg_route_top(rt); rn;
+                            rn = agg_route_next(rn)) {
 
                                if (rn->info) {
 
@@ -721,8 +722,8 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp,
                                        struct rfapi_nve_group_cfg *rfg,
                                        afi_t afi, int add)
 {
-       struct route_table *rt = NULL;
-       struct route_node *rn;
+       struct agg_table *rt = NULL;
+       struct agg_node *rn;
        struct rfapi_import_table *import_table;
        uint8_t family = afi2family(afi);
 
@@ -773,7 +774,8 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp,
                        /*
                         * Walk the NVE-Group's VNC Import table
                         */
-                       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                       for (rn = agg_route_top(rt); rn;
+                            rn = agg_route_next(rn)) {
                                if (rn->info) {
                                        vnc_zebra_route_msg(&rn->p,
                                                            nexthop_count,
index 708aaeef501b3e61bdb51edc2a43193b8710ddea..b8c1cb15c401f3a3f67a36c6b6adef712a437363 100644 (file)
 
 extern void vnc_zebra_add_prefix(struct bgp *bgp,
                                 struct rfapi_import_table *import_table,
-                                struct route_node *rn);
+                                struct agg_node *rn);
 
 extern void vnc_zebra_del_prefix(struct bgp *bgp,
                                 struct rfapi_import_table *import_table,
-                                struct route_node *rn);
+                                struct agg_node *rn);
 
 extern void vnc_zebra_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd);
 
diff --git a/bgpd/rfp-example/librfp/Makefile b/bgpd/rfp-example/librfp/Makefile
new file mode 100644 (file)
index 0000000..8deb93d
--- /dev/null
@@ -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 (file)
index fc66a40..0000000
+++ /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)
index cde2d7b3523123b1dd2ee60e826c2a4e3c7e69e4..af3092232cf851ee10de6d38b54680b875546f71 100644 (file)
  * 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"
@@ -55,6 +59,54 @@ DEFUN (rfp_example_config_value,
        return CMD_SUCCESS;
 }
 
+DEFUN (rfp_holddown_factor,
+       rfp_holddown_factor_cmd,
+       "rfp holddown-factor (0-4294967295)",
+       RFP_SHOW_STR
+       "Set Hold-Down Factor as a percentage of registration lifetime.\n"
+       "Percentage of registration lifetime\n")
+{
+       struct rfp_instance_t *rfi;
+       uint32_t value = 0;
+
+       value = strtoul((argv[--argc]->arg), NULL, 10);
+       rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
+       if (!rfi) {
+               vty_out(vty, "VNC not configured\n");
+               return CMD_WARNING;
+       }
+       rfi->rfapi_config.holddown_factor = value;
+       rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config);
+       return CMD_SUCCESS;
+}
+
+
+DEFUN (rfp_full_table_download,
+       rfp_full_table_download_cmd,
+       "rfp full-table-download <on|off>",
+       RFP_SHOW_STR
+       "RFP full table download support (default=on)\n"
+       "Enable RFP full table download\n"
+       "Disable RFP full table download\n")
+{
+       struct rfp_instance_t *rfi;
+       rfapi_rfp_download_type old;
+
+       rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
+       if (!rfi) {
+               vty_out(vty, "VNC not configured\n");
+               return CMD_WARNING;
+       }
+       old = rfi->rfapi_config.download_type;
+       if (argv[--argc]->arg[1] == 'n' || argv[argc]->arg[1] == 'N')
+               rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_FULL;
+       else
+               rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL;
+       if (old != rfi->rfapi_config.download_type)
+               rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config);
+       return CMD_SUCCESS;
+}
+
 static void rfp_vty_install()
 {
        static int installed = 0;
@@ -63,6 +115,8 @@ static void rfp_vty_install()
        installed = 1;
        /* example of new cli command */
        install_element(BGP_NODE, &rfp_example_config_value_cmd);
+       install_element(BGP_NODE, &rfp_holddown_factor_cmd);
+       install_element(BGP_NODE, &rfp_full_table_download_cmd);
 }
 
 /***********************************************************************
@@ -196,7 +250,15 @@ static int rfp_cfg_write_cb(struct vty *vty, void *rfp_start_val)
                vty_out(vty, "\n");
                write++;
        }
-
+       if (rfi->rfapi_config.holddown_factor != 0) {
+               vty_out(vty, " rfp holddown-factor %u\n",
+                       rfi->rfapi_config.holddown_factor);
+               write++;
+       }
+       if (rfi->rfapi_config.download_type != RFAPI_RFP_DOWNLOAD_FULL) {
+               vty_out(vty, " rfp full-table-download off\n");
+               write++;
+       }
        return write;
 }
 
@@ -230,7 +292,7 @@ void *rfp_start(struct thread_master *master, struct rfapi_rfp_cfg **cfgp,
 
        /* initilize struct rfapi_rfp_cfg, see rfapi.h */
        global_rfi.rfapi_config.download_type =
-               RFAPI_RFP_DOWNLOAD_FULL; /* default=partial */
+               RFAPI_RFP_DOWNLOAD_PARTIAL; /* default=partial */
        global_rfi.rfapi_config.ftd_advertisement_interval =
                RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL;
        global_rfi.rfapi_config.holddown_factor =
diff --git a/bgpd/rfp-example/librfp/subdir.am b/bgpd/rfp-example/librfp/subdir.am
new file mode 100644 (file)
index 0000000..254ab71
--- /dev/null
@@ -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 (file)
index 0000000..659a9ce
--- /dev/null
@@ -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 (file)
index f5db852..0000000
+++ /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 = 
index 53e1c33cfbb0f0406761b4d38b8850c713983014..48df6c0cc7689250b7ece7ffb786764ed7937617 100644 (file)
@@ -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 (file)
index 0000000..fa7c660
--- /dev/null
@@ -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 (file)
index 0000000..4291388
--- /dev/null
@@ -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 (file)
index 73f36ee..0000000
--- 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@ @WERROR@
-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
index be1c2763a1ef5b30d88b975b040dfeba2543043e..08f1c117ec83092b099cf0508ab71a5be72d0252 100755 (executable)
@@ -7,7 +7,7 @@
 ##
 AC_PREREQ(2.60)
 
-AC_INIT(frr, 5.1-dev, [https://github.com/frrouting/frr/issues])
+AC_INIT(frr, 6.1-dev, [https://github.com/frrouting/frr/issues])
 PACKAGE_URL="https://frrouting.org/"
 AC_SUBST(PACKAGE_URL)
 PACKAGE_FULLNAME="FRRouting"
@@ -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)
@@ -132,25 +132,29 @@ dnl - specifically, options to control warnings
 
 AC_USE_SYSTEM_EXTENSIONS
 AC_DEFUN([AC_C_FLAG], [{
+    m4_pushdef([cachename],[m4_translit([frr_cv_$1],[ =-],[___])])
+    AC_CACHE_CHECK([[whether $CC supports $1]], cachename, [
        AC_LANG_PUSH(C)
        ac_c_flag_save="$CFLAGS"
        CFLAGS="$CFLAGS $1"
-       AC_MSG_CHECKING([[whether $CC supports $1]])
        AC_COMPILE_IFELSE(
                [AC_LANG_PROGRAM([[]])],
                [
-                       AC_MSG_RESULT([yes])
-                       m4_if([$3], [], [], [
-                               CFLAGS="$ac_c_flag_save"
-                               $3
-                       ])
+                       cachename=yes
                ], [
-                       CFLAGS="$ac_c_flag_save"
-                       AC_MSG_RESULT([no])
-                       $2
+                       cachename=no
                ])
+       CFLAGS="$ac_c_flag_save"
        AC_LANG_POP(C)
-       }])
+    ])
+    if test "${cachename}" = yes; then
+       m4_if([$3], [], [CFLAGS="$CFLAGS $1"], [$3])
+    else
+       :
+       $2
+    fi
+    m4_popdef([cachename])
+}])
 
 AC_DEFUN([AC_LINK_IFELSE_FLAGS], [{
        AC_LANG_PUSH(C)
@@ -185,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
@@ -283,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
@@ -309,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 --------------
@@ -317,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 -------
@@ -343,6 +319,8 @@ AC_ARG_ENABLE(vtysh,
   AS_HELP_STRING([--disable-vtysh], [do not build integrated vty shell for FRR]))
 AC_ARG_ENABLE(doc,
   AS_HELP_STRING([--disable-doc], [do not build docs]))
+AC_ARG_ENABLE(doc-html,
+  AS_HELP_STRING([--enable-doc-html], [build HTML docs]))
 AC_ARG_ENABLE(zebra,
   AS_HELP_STRING([--disable-zebra], [do not build zebra daemon]))
 AC_ARG_ENABLE(bgpd,
@@ -375,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,
@@ -454,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)
@@ -525,25 +509,10 @@ AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"])
 #
 # Python for clippy
 #
-AS_IF([test "$host" = "$build"], [
-  PYTHONCONFIG=""
-
-  # ordering:
-  # 1.  try python3, but respect the user's preference on which minor ver
-  # 2.  try python, which might be py3 or py2 again on the user's preference
-  # 3.  try python2 (can really only be 2.7 but eh)
-  # 4.  try 3.5 > 3.4 > 3.3 > 3.2 > 2.7 through pkg-config (no user pref)
-  #
-  # (AX_PYTHON_DEVEL has no clue about py3 vs py2)
-  # (AX_PYTHON does not do what we need)
-
-  AC_CHECK_TOOLS([PYTHONCONFIG], [python3-config python-config python2-config])
-  if test -n "$PYTHONCONFIG"; then
-    PYTHON_CFLAGS="`\"${PYTHONCONFIG}\" --includes`"
-    PYTHON_LIBS="`\"${PYTHONCONFIG}\" --libs`"
 
-    AC_MSG_CHECKING([whether we found a working Python version])
-    AC_LINK_IFELSE_FLAGS([$PYTHON_CFLAGS], [$PYTHON_LIBS], [AC_LANG_PROGRAM([
+AC_DEFUN([FRR_PYTHON_CHECK_WORKING], [
+  AC_MSG_CHECKING([whether we found a working Python version])
+  AC_LINK_IFELSE_FLAGS([$PYTHON_CFLAGS], [$PYTHON_LIBS], [AC_LANG_PROGRAM([
 #include <Python.h>
 #if PY_VERSION_HEX < 0x02070000
 #error python too old
@@ -556,23 +525,8 @@ int main(void);
   return 0;
 }
 ])], [
-      PYTHONCONFIG=""
-      unset PYTHON_LIBS
-      unset PYTHON_CFLAGS
-    ])
-  fi
-
-  if test -z "$PYTHONCONFIG"; then
-    PKG_CHECK_MODULES([PYTHON], python-3.5, [], [
-      PKG_CHECK_MODULES([PYTHON], python-3.4, [], [
-        PKG_CHECK_MODULES([PYTHON], python-3.3, [], [
-          PKG_CHECK_MODULES([PYTHON], python-3.2, [], [
-            PKG_CHECK_MODULES([PYTHON], python-2.7, [], [
-              AC_MSG_FAILURE([could not find python-config or pkg-config python, please install Python development files from libpython-dev or similar])
-              ])])])])])
-
-
-    AC_MSG_CHECKING([whether we found a working Python version])
+    # some python installs are missing the zlib dependency...
+    PYTHON_LIBS="${PYTHON_LIBS} -lz"
     AC_LINK_IFELSE_FLAGS([$PYTHON_CFLAGS], [$PYTHON_LIBS], [AC_LANG_PROGRAM([
 #include <Python.h>
 #if PY_VERSION_HEX < 0x02070000
@@ -586,6 +540,56 @@ int main(void);
   return 0;
 }
 ])], [
+      m4_if([$1], [], [
+        PYTHONCONFIG=""
+        unset PYTHON_LIBS
+        unset PYTHON_CFLAGS
+      ], [$1])
+    ])
+  ])
+])
+
+AS_IF([test "$host" = "$build"], [
+  PYTHONCONFIG=""
+
+  # ordering:
+  # 1.  try python3, but respect the user's preference on which minor ver
+  # 2.  try python, which might be py3 or py2 again on the user's preference
+  # 3.  try python2 (can really only be 2.7 but eh)
+  # 4.  try 3.6 > 3.5 > 3.4 > 3.3 > 3.2 > 2.7 through pkg-config (no user pref)
+  #
+  # (AX_PYTHON_DEVEL has no clue about py3 vs py2)
+  # (AX_PYTHON does not do what we need)
+
+  AC_CHECK_TOOLS([PYTHONCONFIG], [ \
+       python3-config \
+       python-config \
+       python2-config \
+       python3.6-config \
+       python3.5-config \
+       python3.4-config \
+       python3.3-config \
+       python3.2-config \
+       python2.7-config ])
+  if test -n "$PYTHONCONFIG"; then
+    PYTHON_CFLAGS="`\"${PYTHONCONFIG}\" --includes`"
+    PYTHON_LIBS="`\"${PYTHONCONFIG}\" --ldflags`"
+
+    FRR_PYTHON_CHECK_WORKING([])
+  fi
+
+  if test -z "$PYTHONCONFIG"; then
+    PKG_CHECK_MODULES([PYTHON], python-3.6, [], [
+      PKG_CHECK_MODULES([PYTHON], python-3.5, [], [
+        PKG_CHECK_MODULES([PYTHON], python-3.4, [], [
+          PKG_CHECK_MODULES([PYTHON], python-3.3, [], [
+            PKG_CHECK_MODULES([PYTHON], python-3.2, [], [
+              PKG_CHECK_MODULES([PYTHON], python-2.7, [], [
+                AC_MSG_FAILURE([could not find python-config or pkg-config python, please install Python development files from libpython-dev or similar])
+                ])])])])])])
+
+
+    FRR_PYTHON_CHECK_WORKING([
       AC_MSG_FAILURE([could not find python-config or pkg-config python, please install Python development files from libpython-dev or similar])
     ])
   fi
@@ -597,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.
@@ -626,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.
 #
@@ -824,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>
@@ -920,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)
@@ -1023,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)
@@ -1171,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
@@ -1313,12 +1315,14 @@ FRR_INCLUDES
 ])dnl
 
 dnl disable doc check
-if test "${enable_doc}" = "no";then
-  DOC=""
-else
-  AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [no])
-  DOC="doc"
+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 --------------------
 dnl Daemon disable check
@@ -1406,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)
@@ -1413,34 +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(DOC)
-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)])
@@ -1518,8 +1501,8 @@ AC_SEARCH_LIBS(dlopen, [dl dld], [], [
 
 AC_CHECK_HEADERS([link.h])
 
-AC_MSG_CHECKING([for dlinfo(RTLD_DI_ORIGIN)])
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+AC_CACHE_CHECK([for dlinfo(RTLD_DI_ORIGIN)], [frr_cv_rtld_di_origin], [
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <stdlib.h>
 #ifdef HAVE_LINK_H
 #include <link.h>
@@ -1529,14 +1512,17 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
   char origin[1];
   dlinfo (NULL, RTLD_DI_ORIGIN, &origin);
 ]])], [
-  AC_MSG_RESULT(yes)
-  AC_DEFINE(HAVE_DLINFO_ORIGIN, 1, [Have dlinfo RTLD_DI_ORIGIN])
-], [
-  AC_MSG_RESULT(no)
+    frr_cv_rtld_di_origin=yes
+  ], [
+    frr_cv_rtld_di_origin=no
+  ])
 ])
+if test "$frr_cv_rtld_di_origin" = yes; then
+  AC_DEFINE(HAVE_DLINFO_ORIGIN, 1, [Have dlinfo RTLD_DI_ORIGIN])
+fi
 
-AC_MSG_CHECKING([for dlinfo(RTLD_DI_LINKMAP)])
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+AC_CACHE_CHECK([for dlinfo(RTLD_DI_LINKMAP)], [frr_cv_rtld_di_linkmap], [
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <stdlib.h>
 #ifdef HAVE_LINK_H
 #include <link.h>
@@ -1546,12 +1532,14 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
   struct link_map *lm = NULL;
   dlinfo (NULL, RTLD_DI_LINKMAP, &lm);
 ]])], [
-  AC_MSG_RESULT(yes)
-  AC_DEFINE(HAVE_DLINFO_LINKMAP, 1, [Have dlinfo RTLD_DI_LINKMAP])
-], [
-  AC_MSG_RESULT(no)
+    frr_cv_rtld_di_linkmap=yes
+  ], [
+    frr_cv_rtld_di_linkmap=no
+  ])
 ])
-
+if test "$frr_cv_rtld_di_linkmap" = yes; then
+  AC_DEFINE(HAVE_DLINFO_LINKMAP, 1, [Have dlinfo RTLD_DI_LINKMAP])
+fi
 
 AM_CONDITIONAL(SNMP, test "x$SNMP_METHOD" = "xagentx")
 
@@ -1806,24 +1794,30 @@ 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_MSG_CHECKING(whether mallinfo is available)
-AC_LINK_IFELSE([AC_LANG_PROGRAM([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
 ]], [[
 struct mallinfo ac_x; ac_x = mallinfo ();
 ]])], [
-  AC_MSG_RESULT(yes)
-  AC_DEFINE(HAVE_MALLINFO,,mallinfo)
-], [
-  AC_MSG_RESULT(no)
+    frr_cv_mallinfo=yes
+  ], [
+    frr_cv_mallinfo=no
+  ])
 ])
+if test "$frr_cv_mallinfo" = yes; then
+  AC_DEFINE(HAVE_MALLINFO,,mallinfo)
+fi
 
 AC_MSG_CHECKING(whether malloc_usable_size is available)
 AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [
@@ -1953,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.])]
   )
@@ -1983,18 +1976,11 @@ AC_CACHE_VAL(ac_cv_htonl_works,
 )
 AC_MSG_RESULT($ac_cv_htonl_works)
 
-AC_CONFIG_FILES([Makefile
-         bgpd/Makefile
-         vtysh/Makefile
-         doc/Makefile
-         doc/user/Makefile
-         doc/manpages/Makefile
-         doc/developer/Makefile
-         tests/Makefile
-         bgpd/rfp-example/rfptest/Makefile
-         bgpd/rfp-example/librfp/Makefile
+AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile])
+
+AC_CONFIG_FILES([
          redhat/frr.spec
-         debianpkg/Makefile
+         solaris/Makefile
          debianpkg/changelog
          alpine/APKBUILD
          snapcraft/snapcraft.yaml
@@ -2004,14 +1990,6 @@ AC_CONFIG_FILES([Makefile
          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([solaris/Makefile])
-
 AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl])
 
 AC_CONFIG_COMMANDS([lib/route_types.h], [
@@ -2053,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}\``
@@ -2065,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/Makefile.am b/debianpkg/Makefile.am
deleted file mode 100644 (file)
index e7ae4bb..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-
-EXTRA_DIST = README.Debian README.Maintainer \
-       changelog compat control copyright \
-       rules source/format tests/control \
-       tests/daemons watchfrr.rc \
-       backports/README backports/rules \
-        backports/debian8/debian/source/format \
-        backports/debian8/exclude \
-        backports/debian8/versionext \
-        backports/debian9/debian/source/format \
-        backports/debian9/exclude \
-        backports/debian9/versionext \
-       backports/ubuntu12.04/debian/control \
-       backports/ubuntu12.04/debian/frr.install \
-       backports/ubuntu12.04/debian/frr.postinst \
-       backports/ubuntu12.04/debian/frr.postrm \
-       backports/ubuntu12.04/debian/rules \
-       backports/ubuntu12.04/debian/source/format \
-       backports/ubuntu12.04/exclude \
-       backports/ubuntu12.04/versionext \
-       backports/ubuntu14.04/debian/control \
-       backports/ubuntu14.04/debian/frr.install \
-       backports/ubuntu14.04/debian/frr.postinst \
-       backports/ubuntu14.04/debian/frr.postrm \
-       backports/ubuntu14.04/debian/rules \
-       backports/ubuntu14.04/debian/source/format \
-       backports/ubuntu14.04/exclude \
-       backports/ubuntu14.04/versionext \
-       backports/ubuntu16.04/debian/source/format \
-       backports/ubuntu16.04/exclude \
-       backports/ubuntu16.04/versionext \
-       backports/ubuntu17.10/debian/control \
-       backports/ubuntu17.10/debian/source/format \
-       backports/ubuntu17.10/exclude \
-       backports/ubuntu17.10/versionext \
-       backports/ubuntu18.04/debian/control \
-       backports/ubuntu18.04/debian/source/format \
-       backports/ubuntu18.04/exclude \
-       backports/ubuntu18.04/versionext \
-       frr-doc.docs frr-doc.info frr-doc.install \
-       frr-doc.lintian-overrides frr.conf \
-       frr-dbg.lintian-overrides \
-       frr.dirs frr.docs frr.install \
-       frr.lintian-overrides frr.logrotate \
-       frr.manpages frr.pam frr.postinst frr.postrm \
-       frr.preinst frr.prerm \
-       frr-pythontools.install
index d2218d00f9bd895f12436351e3d2166b5c78bd74..605353289c178e0dd3df54571f91728430eaf42d 100644 (file)
@@ -1,5 +1,3 @@
-AUTHORS
-NEWS
-README
+README.md
 doc/user/*.rst
 doc/figures/*.png
diff --git a/debianpkg/subdir.am b/debianpkg/subdir.am
new file mode 100644 (file)
index 0000000..b625196
--- /dev/null
@@ -0,0 +1,72 @@
+#
+# debianpkg
+#
+
+EXTRA_DIST += \
+       debianpkg/README.Debian \
+       debianpkg/README.Maintainer \
+       debianpkg/changelog \
+       debianpkg/compat \
+       debianpkg/control \
+       debianpkg/copyright \
+       debianpkg/rules \
+       debianpkg/source/format \
+       debianpkg/tests/control \
+       debianpkg/tests/daemons \
+       debianpkg/watchfrr.rc \
+       \
+       debianpkg/backports/README \
+       debianpkg/backports/rules \
+       debianpkg/backports/debian8/debian/source/format \
+       debianpkg/backports/debian8/exclude \
+       debianpkg/backports/debian8/versionext \
+       debianpkg/backports/debian9/debian/source/format \
+       debianpkg/backports/debian9/exclude \
+       debianpkg/backports/debian9/versionext \
+       debianpkg/backports/ubuntu12.04/debian/control \
+       debianpkg/backports/ubuntu12.04/debian/frr.install \
+       debianpkg/backports/ubuntu12.04/debian/frr.postinst \
+       debianpkg/backports/ubuntu12.04/debian/frr.postrm \
+       debianpkg/backports/ubuntu12.04/debian/rules \
+       debianpkg/backports/ubuntu12.04/debian/source/format \
+       debianpkg/backports/ubuntu12.04/exclude \
+       debianpkg/backports/ubuntu12.04/versionext \
+       debianpkg/backports/ubuntu14.04/debian/control \
+       debianpkg/backports/ubuntu14.04/debian/frr.install \
+       debianpkg/backports/ubuntu14.04/debian/frr.postinst \
+       debianpkg/backports/ubuntu14.04/debian/frr.postrm \
+       debianpkg/backports/ubuntu14.04/debian/rules \
+       debianpkg/backports/ubuntu14.04/debian/source/format \
+       debianpkg/backports/ubuntu14.04/exclude \
+       debianpkg/backports/ubuntu14.04/versionext \
+       debianpkg/backports/ubuntu16.04/debian/source/format \
+       debianpkg/backports/ubuntu16.04/exclude \
+       debianpkg/backports/ubuntu16.04/versionext \
+       debianpkg/backports/ubuntu17.10/debian/control \
+       debianpkg/backports/ubuntu17.10/debian/source/format \
+       debianpkg/backports/ubuntu17.10/exclude \
+       debianpkg/backports/ubuntu17.10/versionext \
+       debianpkg/backports/ubuntu18.04/debian/control \
+       debianpkg/backports/ubuntu18.04/debian/source/format \
+       debianpkg/backports/ubuntu18.04/exclude \
+       debianpkg/backports/ubuntu18.04/versionext \
+       \
+       debianpkg/frr-dbg.lintian-overrides \
+       debianpkg/frr-doc.docs \
+       debianpkg/frr-doc.info \
+       debianpkg/frr-doc.install \
+       debianpkg/frr-doc.lintian-overrides \
+       debianpkg/frr-pythontools.install \
+       debianpkg/frr.conf \
+       debianpkg/frr.dirs \
+       debianpkg/frr.docs \
+       debianpkg/frr.install \
+       debianpkg/frr.lintian-overrides \
+       debianpkg/frr.logrotate \
+       debianpkg/frr.manpages \
+       debianpkg/frr.pam \
+       debianpkg/frr.postinst \
+       debianpkg/frr.postrm \
+       debianpkg/frr.preinst \
+       debianpkg/frr.prerm \
+       # end
index e539d9a97b1a1dd4732a9945e095ab1128144da2..fa2b50832168f17cdefc9227d41c94a407248cc6 100644 (file)
@@ -1,5 +1,3 @@
-Makefile
-Makefile.in
 mdate-sh
 draft-zebra-00.txt
 *.pdf
@@ -7,7 +5,6 @@ draft-zebra-00.txt
 frr.ps
 frr.dvi
 stamp-vti
-.nfs*
 *.aux
 *.cp
 *.cps
@@ -21,8 +18,4 @@ stamp-vti
 *.toc
 *.tp
 *.vr
-.arch-inventory
-.arch-ids
-*~
-*.loT
 refix
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644 (file)
index 0000000..3b4d3d2
--- /dev/null
@@ -0,0 +1,18 @@
+all: ALWAYS
+       @$(MAKE) -s -C .. doc
+%: ALWAYS
+       @$(MAKE) -s -C .. doc/$@
+html:
+       @$(MAKE) -s -C .. doc/user/_build/html/.buildinfo
+info:
+       @$(MAKE) -s -C .. doc/user/_build/texinfo/frr.info
+pdf:
+       @$(MAKE) -s -C .. doc/user/_build/latexpdf
+frr.info: info
+frr.pdf: pdf
+
+Makefile:
+       #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles html info frr.info pdf frr.pdf
+.SUFFIXES:
diff --git a/doc/Makefile.am b/doc/Makefile.am
deleted file mode 100644 (file)
index a2f2f19..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-## Process this file with automake to produce Makefile.in.
-
-# Pass down make invocation to each subdirectory.
-#
-# Each of these directories contains a Sphinx-generated Makefile that has been
-# modified to implement all the targets required by Automake, as documented in
-# the 'Third-Party Makefiles' section of the Automake docs.
-#
-# Note the absence of the 'developer' directory here; development docs are
-# never built as part of a regular build. They are only built when explicitly
-# asked for. See comment further down.
-
-# Sphinx is not designed to be invoked multiple times against the same toctree.
-.NOTPARALLEL:
-
-SUBDIRS = manpages user
-AM_MAKEFLAGS = DESTDIR=${DESTDIR} infodir=${infodir}
-
-MANPAGE_BUILDDIR = manpages/_build/man
-
-# This is a hack, see comment further down.
-man_MANS = $(MANPAGE_BUILDDIR)/frr.1
-
-if PIMD
-man_MANS += $(MANPAGE_BUILDDIR)/pimd.8
-man_MANS += $(MANPAGE_BUILDDIR)/mtracebis.8
-endif
-
-if PBRD
-man_MANS += $(MANPAGE_BUILDDIR)/pbrd.8
-endif
-
-if BGPD
-man_MANS += $(MANPAGE_BUILDDIR)/bgpd.8
-endif
-
-if ISISD
-man_MANS += $(MANPAGE_BUILDDIR)/isisd.8
-endif
-
-if OSPF6D
-man_MANS += $(MANPAGE_BUILDDIR)/ospf6d.8
-endif
-
-if OSPFCLIENT
-man_MANS += $(MANPAGE_BUILDDIR)/ospfclient.8
-endif
-
-if OSPFD
-man_MANS += $(MANPAGE_BUILDDIR)/ospfd.8
-endif
-
-if LDPD
-man_MANS += $(MANPAGE_BUILDDIR)/ldpd.8
-endif
-
-if RIPD
-man_MANS += $(MANPAGE_BUILDDIR)/ripd.8
-endif
-
-if RIPNGD
-man_MANS += $(MANPAGE_BUILDDIR)/ripngd.8
-endif
-
-if NHRPD
-man_MANS += $(MANPAGE_BUILDDIR)/nhrpd.8
-endif
-
-if VTYSH
-man_MANS += $(MANPAGE_BUILDDIR)/vtysh.1
-endif
-
-if WATCHFRR
-man_MANS += $(MANPAGE_BUILDDIR)/watchfrr.8
-endif
-
-if ZEBRA
-man_MANS += $(MANPAGE_BUILDDIR)/zebra.8
-endif
-
-if EIGRPD
-man_MANS += $(MANPAGE_BUILDDIR)/eigrpd.8
-endif
-
-if SHARPD
-man_MANS += $(MANPAGE_BUILDDIR)/sharpd.8
-endif
-
-if STATICD
-man_MANS += $(MANPAGE_BUILDDIR)/staticd.8
-endif
-
-if BFDD
-man_MANS += $(MANPAGE_BUILDDIR)/bfdd.8
-endif
-
-# Automake is particular about manpages. It is aware of them and has some
-# special facilities for handling them, but it assumes that manpages are always
-# given in groff source and so these facilities are limited to simply
-# specifying the path to the groff sources in a special variable. There is no
-# target for building manpages that can be extended, as there are for pdf,
-# html, dvi, etc. Unfortunately this leaves us with hijacking the
-# 'install-data' and 'all' targets in the 3rd-party Makefile in manpages/ to
-# make sure manpages are always built, and then using the special Automake
-# variable defined above in order to take advantage of automatic installation.
-#
-# However, it is conceivable that someone may want to build just the manpages,
-# so here's an explicit target for that.
-man:
-       $(MAKE) -C manpages man
-
-# Automake automatically defines targets for various document formats. All of
-# the child 3rd-party Makefiles are aware of all Automake targets and implement
-# the ones we are interested in.
-#
-# The SUBDIRS variable at the top of this Makefile.am causes the following
-# implicit Automake targets to only build user documentation, and not developer
-# documentation:
-# - info
-# - html
-# - pdf
-#
-# If you wish to build developer documentation, use these targets:
-developer-info:
-       $(MAKE) -C developer info
-
-developer-pdf:
-       $(MAKE) -C developer latexpdf
-
-developer-html:
-       $(MAKE) -C developer html
-
-# If you want to build the developer's docs in other formats, try the
-# following:
-#
-# $ cd developer
-# $ make help
-
-# dist tarballs want doc sources
-EXTRA_DIST = frr-sphinx.mk \
-       manpages/bgpd.rst \
-       manpages/common-options.rst \
-       manpages/conf.py \
-       manpages/defines.rst \
-       manpages/eigrpd.rst \
-       manpages/epilogue.rst \
-       manpages/frr.rst \
-       manpages/index.rst \
-       manpages/isisd.rst \
-       manpages/ldpd.rst \
-       manpages/Makefile.am \
-       manpages/mtracebis.rst \
-       manpages/nhrpd.rst \
-       manpages/ospf6d.rst \
-       manpages/ospfclient.rst \
-       manpages/ospfd.rst \
-       manpages/pimd.rst \
-       manpages/ripd.rst \
-       manpages/pbrd.rst \
-       manpages/ripngd.rst \
-       manpages/sharpd.rst \
-       manpages/staticd.rst \
-       manpages/vtysh.rst \
-       manpages/watchfrr.rst \
-       manpages/zebra.rst \
-       manpages/bfdd.rst \
-       manpages/bfd-options.rst \
-       developer/bgpd.rst \
-       developer/bgp-typecodes.rst \
-       developer/building-frr-for-openwrt.rst \
-       developer/building-frr-on-alpine.rst \
-       developer/building-frr-on-centos6.rst \
-       developer/building-frr-on-centos7.rst \
-       developer/building-frr-on-debian8.rst \
-       developer/building-frr-on-debian9.rst \
-       developer/building-frr-on-fedora24.rst \
-       developer/building-frr-on-freebsd10.rst \
-       developer/building-frr-on-freebsd11.rst \
-       developer/building-frr-on-freebsd9.rst \
-       developer/building-frr-on-netbsd6.rst \
-       developer/building-frr-on-netbsd7.rst \
-       developer/building-frr-on-omnios.rst \
-       developer/building-frr-on-openbsd6.rst \
-       developer/building-frr-on-ubuntu1204.rst \
-       developer/building-frr-on-ubuntu1404.rst \
-       developer/building-frr-on-ubuntu1604.rst \
-       developer/building-frr-on-ubuntu1804.rst \
-       developer/building.rst \
-       developer/cli.rst \
-       developer/conf.py \
-       developer/draft-zebra-00.ms \
-       developer/hooks.rst \
-       developer/index.rst \
-       developer/ldpd-basic-test-setup.md \
-       developer/library.rst \
-       developer/logging.rst \
-       developer/Makefile.in \
-       developer/maintainer-release-build.rst \
-       developer/memtypes.rst \
-       developer/modules.rst \
-       developer/next-hop-tracking.rst \
-       developer/ospf-api.rst \
-       developer/ospf.rst \
-       developer/ospf-sr.rst \
-       developer/workflow.rst \
-       developer/zebra.rst \
-       user/babeld.rst \
-       user/ldpd.rst \
-       user/basic.rst \
-       user/bgp.rst \
-       user/bugs.rst \
-       user/conf.py \
-       user/eigrpd.rst \
-       user/filter.rst \
-       user/glossary.rst \
-       user/index.rst \
-       user/installation.rst \
-       user/ipv6.rst \
-       user/isisd.rst \
-       user/kernel.rst \
-       user/Makefile.am \
-       user/nhrpd.rst \
-       user/ospf6d.rst \
-       user/ospfd.rst \
-       user/ospf_fundamentals.rst \
-       user/overview.rst \
-       user/packet-dumps.rst \
-       user/pim.rst \
-       user/ripd.rst \
-       user/pbr.rst \
-       user/ripngd.rst \
-       user/routemap.rst \
-       user/routeserver.rst \
-       user/rpki.rst \
-       user/setup.rst \
-       user/sharp.rst \
-       user/snmp.rst \
-       user/snmptrap.rst \
-       user/static.rst \
-       user/Useful_Sysctl_Settings.md \
-       user/vnc.rst \
-       user/vtysh.rst \
-       user/zebra.rst \
-       user/bfd.rst \
-       user/flowspec.rst \
-       mpls/ChangeLog.opaque.txt \
-       mpls/ospfd.conf \
-       mpls/cli_summary.txt \
-       mpls/opaque_lsa.txt \
-       figures/cligraph.png \
-       figures/cligraph.svg \
-       figures/fig-normal-processing.dia \
-       figures/fig-normal-processing.png \
-       figures/fig-normal-processing.txt \
-       figures/fig-rs-processing.dia \
-       figures/fig-rs-processing.png \
-       figures/fig-rs-processing.txt \
-       figures/fig_topologies_full.dia \
-       figures/fig_topologies_full.png \
-       figures/fig_topologies_full.txt \
-       figures/fig_topologies_rs.dia \
-       figures/fig_topologies_rs.png \
-       figures/fig_topologies_rs.txt \
-       figures/fig-vnc-commercial-route-reflector.dia \
-       figures/fig-vnc-commercial-route-reflector.png \
-       figures/fig-vnc-commercial-route-reflector.txt \
-       figures/fig-vnc-frr-route-reflector.dia \
-       figures/fig-vnc-frr-route-reflector.png \
-       figures/fig-vnc-frr-route-reflector.txt \
-       figures/fig-vnc-gw.dia \
-       figures/fig-vnc-gw.png \
-       figures/fig-vnc-gw-rr.dia \
-       figures/fig-vnc-gw-rr.png \
-       figures/fig-vnc-gw-rr.txt \
-       figures/fig-vnc-gw.txt \
-       figures/fig-vnc-mesh.dia \
-       figures/fig-vnc-mesh.png \
-       figures/fig-vnc-mesh.txt \
-       figures/fig-vnc-redundant-route-reflectors.dia \
-       figures/fig-vnc-redundant-route-reflectors.png \
-       figures/fig-vnc-redundant-route-reflectors.txt \
-       figures/frr-icon.svg \
-       figures/frr-logo-icon.png \
-       figures/frr-logo-medium.png \
-       figures/frr-logo.png \
-       figures/frr-logo-small.png \
-       figures/git_branches.png \
-       figures/git_branches.svg \
-       figures/ospf_api_architecture.png \
-       figures/ospf_api_msghdr.png \
-       figures/ospf_api_msgs1.png \
-       figures/ospf_api_msgs2.png \
-       extra/frrlexer.py
diff --git a/doc/developer/Makefile b/doc/developer/Makefile
new file mode 100644 (file)
index 0000000..38afb43
--- /dev/null
@@ -0,0 +1,16 @@
+all: ALWAYS
+       @$(MAKE) -s -C ../.. developer-html
+help: ALWAYS
+       @$(MAKE) -s -C ../.. doc/help
+pdf: ALWAYS
+       @$(MAKE) -s -C ../.. doc/developer/_build/latexpdf
+info: ALWAYS
+       @$(MAKE) -s -C ../.. doc/developer/_build/texinfo/frr.info
+%: ALWAYS
+       @$(MAKE) -s -C ../.. doc/developer/_build/$@
+
+Makefile:
+       #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/doc/developer/Makefile.am b/doc/developer/Makefile.am
deleted file mode 100644 (file)
index 76758f9..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# This is necessary to support VPATH builds.
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-# This variable is used as the documentation source location in frr-sphinx.mk
-SOURCESDIR = @srcdir@
-
-include @srcdir@/../frr-sphinx.mk
diff --git a/doc/developer/building-frr-for-alpine.rst b/doc/developer/building-frr-for-alpine.rst
new file mode 100644 (file)
index 0000000..d303784
--- /dev/null
@@ -0,0 +1,112 @@
+Alpine Linux 3.7+
+=========================================================
+
+For building Alpine Linux dev packages, we use docker.
+
+Install docker 17.05 or later
+-----------------------------
+
+Depending on your host, there are different ways of installing docker.  Refer
+to the documentation here for instructions on how to install a free version of
+docker: https://www.docker.com/community-edition
+
+Pre-built packages and docker images
+------------------------------------
+
+The master branch of https://github.com/frrouting/frr.git has a
+continuous delivery of docker images to docker hub at:
+https://hub.docker.com/r/ajones17/frr/. These images have the frr packages
+in /pkgs/apk and have the frr package pre-installed.  To copy Alpine
+packages out of these images:
+
+::
+
+   id=`docker create ajones17/frr:latest`
+   docker cp ${id}:/pkgs _some_directory_
+   docker rm $id
+
+To run the frr daemons (see below for how to configure them):
+
+::
+
+   docker run -it --rm --name frr ajones17/frr:latest
+   docker exec -it frr /bin/sh
+
+Work with sources
+-----------------
+
+::
+
+   git clone https://github.com/frrouting/frr.git frr
+   cd frr
+
+Build apk packages
+------------------
+
+::
+
+   ./docker/alpine/build.sh
+
+This will put the apk packages in:
+
+::
+
+   ./docker/pkgs/apk/x86_64/
+
+Usage
+-----
+
+To create a base image with the frr packages installed:
+
+::
+
+   docker build --rm -f docker/alpine/Dockerfile -t frr:latest .
+
+Or, if you don't have a git checkout of the sources, you can build a base
+image directly off the github account:
+
+::
+
+   docker build --rm -f docker/alpine/Dockerfile -t frr:latest \
+       https://github.com/frrouting/frr.git
+
+And to run the image:
+
+::
+
+   docker run -it --rm --name frr frr:latest
+
+In the default configuration, none of the frr daemons will  be running.
+To configure the daemons, exec into the container and edit the configuration
+files or mount a volume with configuration files into the container on
+startup.  To configure by hand:
+
+::
+
+   docker exec -it frr /bin/sh
+   vi /etc/frr/daemons
+   vi /etc/frr/daemons.conf
+   cp /etc/frr/zebra.conf.sample /etc/frr/zebra.conf
+   vi /etc/frr/zebra.conf
+   /etc/init.d/frr start
+
+Or, to configure the daemons using /etc/frr from a host volume, put the
+config files in, say, ./docker/etc and bind mount that into the
+container:
+
+::
+
+   docker run -it --rm -v `pwd`/docker/etc:/etc/frr frr:latest
+
+We can also build the base image directly from docker-compose, with a
+docker-compose.yml file like this one:
+
+::
+
+   version: '2.2'
+
+   services:
+      frr:
+         build:
+            context: https://github.com/frrouting/frr.git
+            dockerfile: docker/alpine/Dockerfile
diff --git a/doc/developer/building-frr-for-centos6.rst b/doc/developer/building-frr-for-centos6.rst
new file mode 100644 (file)
index 0000000..5f10f37
--- /dev/null
@@ -0,0 +1,270 @@
+CentOS 6
+========================================
+
+(As an alternative to this installation, you may prefer to create a FRR
+rpm package yourself and install that package instead. See instructions
+in redhat/README.rpm\_build.md on how to build a rpm package)
+
+Instructions are tested with ``CentOS 6.8`` on ``x86_64`` platform
+
+Warning:
+--------
+``CentOS 6`` is very old and not fully supported by the FRR community
+anymore. Building FRR takes multiple manual steps to update the build
+system with newer packages than what's available from the archives.
+However, the built packages can still be installed afterwards on
+a standard ``CentOS 6`` without any special packages.
+
+Support for CentOS 6 is now on a best-effort base by the community.
+
+CentOS 6 restrictions:
+----------------------
+
+-  PIMd is not supported on ``CentOS 6``. Upgrade to ``CentOS 7`` if
+   PIMd is needed
+-  MPLS is not supported on ``CentOS 6``. MPLS requires Linux Kernel 4.5
+   or higher (LDP can be built, but may have limited use without MPLS)
+-  Zebra is unable to detect what bridge/vrf an interface is associcated
+   with (IFLA\_INFO\_SLAVE\_KIND does not exist in the kernel headers,
+   you can use a newer kernel + headers to get this functionality)
+-  frr\_reload.py will not work, as this requires Python 2.7, and CentOS
+   6 only has 2.6. You can install Python 2.7 via IUS, but it won't work
+   properly unless you compile and install the ipaddr package for it.
+-  Building the package requires Sphinx >= 1.1. Only a non-standard
+   package provides a newer sphinx and requires manual installation
+   (see below)
+
+
+Install required packages
+-------------------------
+
+Add packages:
+
+.. code-block:: shell
+
+   sudo yum install git autoconf automake libtool make gawk \
+      readline-devel texinfo net-snmp-devel groff pkgconfig \
+      json-c-devel pam-devel flex epel-release perl-XML-LibXML \
+      c-ares-devel
+
+Install newer version of bison (CentOS 6 package source is too old) from CentOS
+7:
+
+.. code-block:: shell
+
+   sudo yum install rpm-build
+   curl -O http://vault.centos.org/7.0.1406/os/Source/SPackages/bison-2.7-4.el7.src.rpm
+   rpmbuild --rebuild ./bison-2.7-4.el7.src.rpm
+   sudo yum install ./rpmbuild/RPMS/x86_64/bison-2.7-4.el6.x86_64.rpm
+   rm -rf rpmbuild
+
+Install newer version of autoconf and automake (Package versions are too old):
+
+.. code-block:: shell
+
+   curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
+   tar xvf autoconf-2.69.tar.gz
+   cd autoconf-2.69
+   ./configure --prefix=/usr
+   make
+   sudo make install
+   cd ..
+
+   curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz
+   tar xvf automake-1.15.tar.gz
+   cd automake-1.15
+   ./configure --prefix=/usr
+   make
+   sudo make install
+   cd ..
+
+Install ``Python 2.7`` in parallel to default 2.6. Make sure you've install
+EPEL (``epel-release`` as above). Then install current ``python27``:
+``python27-devel`` and ``pytest``
+
+.. code-block:: shell
+
+   sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
+   sudo rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm
+   sudo yum install python27 python27-pip python27-devel
+   sudo pip2.7 install pytest
+
+Please note that ``CentOS 6`` needs to keep python pointing to version 2.6 for
+``yum`` to keep working, so don't create a symlink for python2.7 to python.
+
+Install newer ``Sphinx-Build`` based on ``Python 2.7``.
+
+Create a new repo ``/etc/yum.repos.d/puias6.repo`` with the following contents:
+
+::
+
+   ### Name: RPM Repository for RHEL 6 - PUIAS (used for Sphinx-Build)
+   ### URL: http://springdale.math.ias.edu/data/puias/computational
+   [puias-computational]
+   name = RPM Repository for RHEL 6 - Sphinx-Build
+   baseurl = http://springdale.math.ias.edu/data/puias/computational/$releasever/$basearch
+   #mirrorlist =
+   enabled = 1
+   protect = 0
+   gpgkey =
+   gpgcheck = 0
+
+Update rpm database & Install newer sphinx
+
+.. code-block:: shell
+
+   sudo yum update
+   sudo yum install python27-sphinx
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not using any
+packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   sudo groupadd -g 92 frr
+   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
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+.. code-block:: shell
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    ./configure \
+        --bindir=/usr/bin \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --libdir=/usr/lib/frr \
+        --libexecdir=/usr/lib/frr \
+        --localstatedir=/var/run/frr \
+        --with-moduledir=/usr/lib/frr/modules \
+        --disable-pimd \
+        --enable-snmp=agentx \
+        --enable-multipath=64 \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-rtadv \
+        --disable-exampledir \
+        --enable-watchfrr \
+        --disable-ldpd \
+        --enable-fpm \
+        --enable-nhrpd \
+        --enable-eigrpd \
+        --enable-babeld \
+        --with-pkg-git-version \
+        --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
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   sudo mkdir /var/log/frr
+   sudo mkdir /etc/frr
+
+For integrated config file:
+
+.. code-block:: shell
+
+   sudo touch /etc/frr/frr.conf
+
+For individual config files:
+
+.. note:: Integrated config is preferred to individual config.
+
+.. code-block:: shell
+
+   sudo touch /etc/frr/babeld.conf
+   sudo touch /etc/frr/bfdd.conf
+   sudo touch /etc/frr/bgpd.conf
+   sudo touch /etc/frr/eigrpd.conf
+   sudo touch /etc/frr/isisd.conf
+   sudo touch /etc/frr/ldpd.conf
+   sudo touch /etc/frr/nhrpd.conf
+   sudo touch /etc/frr/ospf6d.conf
+   sudo touch /etc/frr/ospfd.conf
+   sudo touch /etc/frr/pbrd.conf
+   sudo touch /etc/frr/pimd.conf
+   sudo touch /etc/frr/ripd.conf
+   sudo touch /etc/frr/ripngd.conf
+   sudo touch /etc/frr/staticd.conf
+   sudo touch /etc/frr/zebra.conf
+   sudo chown -R frr:frr /etc/frr/
+   sudo touch /etc/frr/vtysh.conf
+   sudo chown frr:frrvty /etc/frr/vtysh.conf
+   sudo chmod 640 /etc/frr/*.conf
+
+Install daemon config file
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   sudo install -p -m 644 redhat/daemons /etc/frr/
+   sudo chown frr:frr /etc/frr/daemons
+
+Edit /etc/frr/daemons as needed to select the required daemons
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc.
+Enable the daemons as required by changing the value to ``yes``
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit :file:`/etc/sysctl.conf` and set the following values (ignore the other
+settings)::
+
+   # Controls IP packet forwarding
+   net.ipv4.ip_forward = 1
+   net.ipv6.conf.all.forwarding=1
+
+   # Controls source route verification
+   net.ipv4.conf.default.rp_filter = 0
+
+Load the modifed sysctl's on the system:
+
+.. code-block:: shell
+
+   sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf
+
+Add init.d startup files
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block::
+
+   sudo install -p -m 755 redhat/frr.init /etc/init.d/frr
+   sudo chkconfig --add frr
+
+Enable FRR daemon at startup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block::
+
+   sudo chkconfig frr on
+
+Start FRR manually (or reboot)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block::
+
+   sudo /etc/init.d/frr start
diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst
new file mode 100644 (file)
index 0000000..b157f54
--- /dev/null
@@ -0,0 +1,169 @@
+CentOS 7
+========================================
+
+(As an alternative to this installation, you may prefer to create a FRR
+rpm package yourself and install that package instead. See instructions
+in redhat/README.rpm\_build.md on how to build a rpm package)
+
+CentOS 7 restrictions:
+----------------------
+
+-  MPLS is not supported on ``CentOS 7`` with default kernel. MPLS
+   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
+   limited use without MPLS)
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    sudo yum install git autoconf automake libtool make gawk \
+      readline-devel texinfo net-snmp-devel groff pkgconfig \
+      json-c-devel pam-devel bison flex pytest c-ares-devel \
+      perl-XML-LibXML python-devel systemd-devel python-sphinx
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -g 92 frr
+    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
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    ./configure \
+        --bindir=/usr/bin \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --libdir=/usr/lib/frr \
+        --libexecdir=/usr/lib/frr \
+        --localstatedir=/var/run/frr \
+        --with-moduledir=/usr/lib/frr/modules \
+        --enable-pimd \
+        --enable-snmp=agentx \
+        --enable-multipath=64 \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-rtadv \
+       --enable-systemd=yes \
+        --disable-exampledir \
+        --enable-watchfrr \
+        --disable-ldpd \
+        --enable-fpm \
+        --enable-nhrpd \
+        --enable-eigrpd \
+        --enable-babeld \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    make
+    make check
+    sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo mkdir /var/log/frr
+    sudo mkdir /etc/frr
+    sudo touch /etc/frr/zebra.conf
+    sudo touch /etc/frr/bgpd.conf
+    sudo touch /etc/frr/ospfd.conf
+    sudo touch /etc/frr/ospf6d.conf
+    sudo touch /etc/frr/isisd.conf
+    sudo touch /etc/frr/ripd.conf
+    sudo touch /etc/frr/ripngd.conf
+    sudo touch /etc/frr/pimd.conf
+    sudo touch /etc/frr/nhrpd.conf
+    sudo touch /etc/frr/eigrpd.conf
+    sudo touch /etc/frr/babeld.conf
+    sudo chown -R frr:frr /etc/frr/
+    sudo touch /etc/frr/vtysh.conf
+    sudo chown frr:frrvty /etc/frr/vtysh.conf
+    sudo chmod 640 /etc/frr/*.conf
+
+Install daemon config file
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -p -m 644 redhat/daemons /etc/frr/
+    sudo chown frr:frr /etc/frr/daemons
+
+Edit /etc/frr/daemons as needed to select the required daemons
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc.
+Enable the daemons as required by changing the value to ``yes``
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the
+following content:
+
+::
+
+    # Sysctl for routing
+    #
+    # Routing: We need to forward packets
+    net.ipv4.conf.all.forwarding=1
+    net.ipv6.conf.all.forwarding=1
+
+Load the modifed sysctl's on the system:
+
+::
+
+    sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf
+
+Install frr Service and redhat init files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service
+    sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr
+
+Register the systemd files
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo systemctl preset frr.service
+
+Enable required frr at startup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo systemctl enable frr
+
+Reboot or start FRR manually
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo systemctl start frr
diff --git a/doc/developer/building-frr-for-debian8.rst b/doc/developer/building-frr-for-debian8.rst
new file mode 100644 (file)
index 0000000..d1e65a4
--- /dev/null
@@ -0,0 +1,156 @@
+Debian 8
+========================================
+
+Debian 8 restrictions:
+----------------------
+
+-  MPLS is not supported on ``Debian 8`` with default kernel. MPLS
+   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
+   limited use without MPLS)
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    sudo apt-get install git autoconf automake libtool make gawk \
+       libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
+       python-pip libc-ares-dev python3-dev python3-sphinx
+
+Install newer pytest (>3.0) from pip
+
+::
+
+    sudo pip install pytest
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo addgroup --system --gid 92 frr
+    sudo addgroup --system --gid 85 frrvty
+    sudo adduser --system --ingroup frr --home /var/run/frr/ \
+       --gecos "FRR suite" --shell /bin/false frr
+    sudo usermod -a -G frrvty frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    ./configure \
+        --enable-exampledir=/usr/share/doc/frr/examples/ \
+        --localstatedir=/var/run/frr \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --enable-vtysh \
+        --enable-isisd \
+        --enable-pimd \
+        --enable-watchfrr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --enable-ldpd \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    make
+    make check
+    sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 755 -o frr -g frr -d /var/log/frr
+    sudo install -m 775 -o frr -g frrvty -d /etc/frr
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
+other settings)
+
+::
+
+    # Uncomment the next line to enable packet forwarding for IPv4
+    net.ipv4.ip_forward=1
+
+    # Uncomment the next line to enable packet forwarding for IPv6
+    #  Enabling this option disables Stateless Address Autoconfiguration
+    #  based on Router Advertisements for this host
+    net.ipv6.conf.all.forwarding=1
+
+**Reboot** or use ``sysctl -p`` to apply the same config to the running
+system
+
+Troubleshooting
+^^^^^^^^^^^^^^^
+
+**Local state directory**
+
+The local state directory must exist and have the correct permissions
+applied for the frrouting daemons to start. In the above ./configure
+example the local state directory is set to /var/run/frr
+(--localstatedir=/var/run/frr) Debian considers /var/run/frr to be
+temporary and this is removed after a reboot.
+
+When using a different local state directory you need to create the new
+directory and change the ownership to the frr user, for example:
+
+::
+
+    mkdir /var/opt/frr
+    chown frr /var/opt/frr
+
+**Shared library error**
+
+If you try and start any of the frrouting daemons you may see the below
+error due to the frrouting shared library directory not being found:
+
+::
+
+    ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory
+
+The fix is to add the following line to /etc/ld.so.conf which will
+continue to reference the library directory after the system reboots. To
+load the library directory path immediately run the ldconfig command
+after adding the line to the file eg:
+
+::
+
+    echo include /usr/local/lib >> /etc/ld.so.conf
+    ldconfig
diff --git a/doc/developer/building-frr-for-debian9.rst b/doc/developer/building-frr-for-debian9.rst
new file mode 100644 (file)
index 0000000..7dad9a7
--- /dev/null
@@ -0,0 +1,131 @@
+Debian 9
+========================================
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    sudo apt-get install git autoconf automake libtool make \
+      libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
+      python-pip libc-ares-dev python3-dev python-pytest python3-sphinx
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo addgroup --system --gid 92 frr
+    sudo addgroup --system --gid 85 frrvty
+    sudo adduser --system --ingroup frr --home /var/opt/frr/ \
+       --gecos "FRR suite" --shell /bin/false frr
+    sudo usermod -a -G frrvty frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    git checkout stable/3.0
+    ./bootstrap.sh
+    ./configure \
+        --enable-exampledir=/usr/share/doc/frr/examples/ \
+        --localstatedir=/var/opt/frr \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --enable-vtysh \
+        --enable-isisd \
+        --enable-pimd \
+        --enable-watchfrr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --enable-ldpd \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    make
+    make check
+    sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 755 -o frr -g frr -d /var/log/frr
+    sudo install -m 755 -o frr -g frr -d /var/opt/frr
+    sudo install -m 775 -o frr -g frrvty -d /etc/frr
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
+other settings)
+
+::
+
+    # Uncomment the next line to enable packet forwarding for IPv4
+    net.ipv4.ip_forward=1
+
+    # Uncomment the next line to enable packet forwarding for IPv6
+    #  Enabling this option disables Stateless Address Autoconfiguration
+    #  based on Router Advertisements for this host
+    net.ipv6.conf.all.forwarding=1
+
+**Reboot** or use ``sysctl -p`` to apply the same config to the running
+system
+
+Troubleshooting
+---------------
+
+Shared library error
+^^^^^^^^^^^^^^^^^^^^
+
+If you try and start any of the frrouting daemons you may see the below
+error due to the frrouting shared library directory not being found:
+
+::
+
+   ./zebra: error while loading shared libraries: libfrr.so.0: cannot open
+   shared object file: No such file or directory
+
+The fix is to add the following line to /etc/ld.so.conf which will
+continue to reference the library directory after the system reboots. To
+load the library directory path immediately run the ldconfig command
+after adding the line to the file eg:
+
+::
+
+   echo include /usr/local/lib >> /etc/ld.so.conf
+   ldconfig
diff --git a/doc/developer/building-frr-for-fedora24.rst b/doc/developer/building-frr-for-fedora24.rst
new file mode 100644 (file)
index 0000000..669cc4a
--- /dev/null
@@ -0,0 +1,177 @@
+Fedora 24
+=========================================
+
+(As an alternative to this installation, you may prefer to create a FRR
+rpm package yourself and install that package instead. See instructions
+in redhat/README.rpm\_build.md on how to build a rpm package)
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    sudo dnf install git autoconf automake libtool make gawk \
+      readline-devel texinfo net-snmp-devel groff pkgconfig \
+      json-c-devel pam-devel perl-XML-LibXML pytest bison flex \
+      c-ares-devel python3-devel python3-sphinx
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -g 92 frr
+    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
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    ./configure \
+        --bindir=/usr/bin \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --libdir=/usr/lib/frr \
+        --libexecdir=/usr/lib/frr \
+        --localstatedir=/var/run/frr \
+        --with-moduledir=/usr/lib/frr/modules \
+        --enable-pimd \
+        --enable-snmp=agentx \
+        --enable-multipath=64 \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-rtadv \
+        --disable-exampledir \
+        --enable-watchfrr \
+        --enable-ldpd \
+        --enable-fpm \
+        --enable-nhrpd \
+        --enable-eigrpd \
+        --enable-babeld \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    make
+    make check
+    sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo mkdir /var/log/frr
+    sudo mkdir /etc/frr
+    sudo touch /etc/frr/zebra.conf
+    sudo touch /etc/frr/bgpd.conf
+    sudo touch /etc/frr/ospfd.conf
+    sudo touch /etc/frr/ospf6d.conf
+    sudo touch /etc/frr/isisd.conf
+    sudo touch /etc/frr/ripd.conf
+    sudo touch /etc/frr/ripngd.conf
+    sudo touch /etc/frr/pimd.conf
+    sudo touch /etc/frr/ldpd.conf
+    sudo touch /etc/frr/nhrpd.conf
+    sudo touch /etc/frr/eigrpd.conf
+    sudo touch /etc/frr/babeld.conf
+    sudo chown -R frr:frr /etc/frr/
+    sudo touch /etc/frr/vtysh.conf
+    sudo chown frr:frrvty /etc/frr/vtysh.conf
+    sudo chmod 640 /etc/frr/*.conf
+
+Install daemon config file
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -p -m 644 redhat/daemons /etc/frr/
+    sudo chown frr:frr /etc/frr/daemons
+
+Edit /etc/frr/daemons as needed to select the required daemons
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc.
+Enable the daemons as required by changing the value to ``yes``
+
+Enable IP & IPv6 forwarding (and MPLS)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the
+following content: (Please make sure to list all interfaces with
+required MPLS similar to ``net.mpls.conf.eth0.input=1``)
+
+::
+
+    # Sysctl for routing
+    #
+    # Routing: We need to forward packets
+    net.ipv4.conf.all.forwarding=1
+    net.ipv6.conf.all.forwarding=1
+    #
+    # Enable MPLS Label processing on all interfaces
+    net.mpls.conf.eth0.input=1
+    net.mpls.conf.eth1.input=1
+    net.mpls.conf.eth2.input=1
+    net.mpls.platform_labels=100000
+
+Load the modifed sysctl's on the system:
+
+::
+
+    sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf
+
+Create a new file ``/etc/modules-load.d/mpls.conf`` with the following
+content:
+
+::
+
+    # Load MPLS Kernel Modules
+    mpls-router
+    mpls-iptunnel
+
+And load the kernel modules on the running system:
+
+::
+
+    sudo modprobe mpls-router mpls-iptunnel
+
+Install frr Service and redhat init files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service
+    sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr
+
+Enable required frr at startup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo systemctl enable frr
+
+Reboot or start FRR manually
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo systemctl start frr
diff --git a/doc/developer/building-frr-for-freebsd10.rst b/doc/developer/building-frr-for-freebsd10.rst
new file mode 100644 (file)
index 0000000..95f09e8
--- /dev/null
@@ -0,0 +1,128 @@
+FreeBSD 10
+==========================================
+
+FreeBSD 10 restrictions:
+------------------------
+
+-  MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel
+   (4.5 or higher). LDP can be built, but may have limited use without
+   MPLS
+
+Install required packages
+-------------------------
+
+Add packages: (Allow the install of the package managment tool if this
+is first package install and asked)
+
+::
+
+    pkg install git autoconf automake libtool gmake gawk json-c pkgconf \
+        bison flex py27-pytest c-ares python3 py-sphinx
+
+Make sure there is no /usr/bin/flex preinstalled (and use the newly
+installed in /usr/local/bin): (FreeBSD frequently provides a older flex
+as part of the base OS which takes preference in path)
+
+::
+
+    rm -f /usr/bin/flex
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr group and user
+^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    pw groupadd frr -g 101
+    pw groupadd frrvty -g 102
+    pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \
+        -d /usr/local/etc/frr -s /usr/sbin/nologin
+
+(You may prefer different options on configure statement. These are just
+an example)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    export MAKE=gmake
+    export LDFLAGS="-L/usr/local/lib"
+    export CPPFLAGS="-I/usr/local/include"
+    ./configure \
+        --sysconfdir=/usr/local/etc/frr \
+        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
+        --localstatedir=/var/run/frr \
+        --prefix=/usr/local \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    gmake
+    gmake check
+    sudo gmake install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   sudo mkdir /usr/local/etc/frr
+
+For integrated config file:
+
+.. code-block:: shell
+
+   sudo touch /usr/local/etc/frr/frr.conf
+
+For individual config files:
+
+.. note:: Integrated config is preferred to individual config.
+
+.. code-block:: shell
+
+   sudo touch /usr/local/etc/frr/babeld.conf
+   sudo touch /usr/local/etc/frr/bfdd.conf
+   sudo touch /usr/local/etc/frr/bgpd.conf
+   sudo touch /usr/local/etc/frr/eigrpd.conf
+   sudo touch /usr/local/etc/frr/isisd.conf
+   sudo touch /usr/local/etc/frr/ldpd.conf
+   sudo touch /usr/local/etc/frr/nhrpd.conf
+   sudo touch /usr/local/etc/frr/ospf6d.conf
+   sudo touch /usr/local/etc/frr/ospfd.conf
+   sudo touch /usr/local/etc/frr/pbrd.conf
+   sudo touch /usr/local/etc/frr/pimd.conf
+   sudo touch /usr/local/etc/frr/ripd.conf
+   sudo touch /usr/local/etc/frr/ripngd.conf
+   sudo touch /usr/local/etc/frr/staticd.conf
+   sudo touch /usr/local/etc/frr/zebra.conf
+   sudo chown -R frr:frr /usr/local/etc/frr/
+   sudo touch /usr/local/etc/frr/vtysh.conf
+   sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf
+   sudo chmod 640 /usr/local/etc/frr/*.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following lines to the end of ``/etc/sysctl.conf``:
+
+::
+
+   # Routing: We need to forward packets
+   net.inet.ip.forwarding=1
+   net.inet6.ip6.forwarding=1
+
+**Reboot** or use ``sysctl`` to apply the same config to the running system.
diff --git a/doc/developer/building-frr-for-freebsd11.rst b/doc/developer/building-frr-for-freebsd11.rst
new file mode 100644 (file)
index 0000000..ce59414
--- /dev/null
@@ -0,0 +1,133 @@
+FreeBSD 11
+==========
+
+FreeBSD 11 restrictions:
+------------------------
+
+-  MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel
+   (4.5 or higher). LDP can be built, but may have limited use without
+   MPLS
+
+Install required packages
+-------------------------
+
+Add packages: (Allow the install of the package managment tool if this
+is first package install and asked)
+
+.. code-block:: shell
+
+   pkg install git autoconf automake libtool gmake gawk json-c pkgconf \
+      bison flex py27-pytest c-ares python3 py36-sphinx texinfo
+
+Make sure there is no /usr/bin/flex preinstalled (and use the newly
+installed in /usr/local/bin): (FreeBSD frequently provides a older flex
+as part of the base OS which takes preference in path)
+
+.. code-block:: shell
+
+   rm -f /usr/bin/flex
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not using any
+packages**
+
+Add frr group and user
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   pw groupadd frr -g 101
+   pw groupadd frrvty -g 102
+   pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \
+      -d /usr/local/etc/frr -s /usr/sbin/nologin
+
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example)
+
+.. code-block:: shell
+
+   git clone https://github.com/frrouting/frr.git frr
+   cd frr
+   ./bootstrap.sh
+   setenv MAKE gmake
+   setenv LDFLAGS -L/usr/local/lib
+   setenv CPPFLAGS -I/usr/local/include
+   ln -s /usr/local/bin/sphinx-build-3.6 /usr/local/bin/sphinx-build
+   ./configure \
+       --sysconfdir=/usr/local/etc/frr \
+       --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
+       --localstatedir=/var/run/frr \
+       --prefix=/usr/local \
+       --enable-ospfclient=yes \
+       --enable-ospfapi=yes \
+       --enable-multipath=64 \
+       --enable-user=frr \
+       --enable-group=frr \
+       --enable-vty-group=frrvty \
+       --enable-configfile-mask=0640 \
+       --enable-logfile-mask=0640 \
+       --enable-rtadv \
+       --enable-fpm \
+       --with-pkg-git-version \
+       --with-pkg-extra-version=-MyOwnFRRVersion
+   gmake
+   gmake check
+   sudo gmake install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   sudo mkdir /usr/local/etc/frr
+
+For integrated config file:
+
+.. code-block:: shell
+
+   sudo touch /usr/local/etc/frr/frr.conf
+
+For individual config files:
+
+.. note:: Integrated config is preferred to individual config.
+
+.. code-block:: shell
+
+   sudo touch /usr/local/etc/frr/babeld.conf
+   sudo touch /usr/local/etc/frr/bfdd.conf
+   sudo touch /usr/local/etc/frr/bgpd.conf
+   sudo touch /usr/local/etc/frr/eigrpd.conf
+   sudo touch /usr/local/etc/frr/isisd.conf
+   sudo touch /usr/local/etc/frr/ldpd.conf
+   sudo touch /usr/local/etc/frr/nhrpd.conf
+   sudo touch /usr/local/etc/frr/ospf6d.conf
+   sudo touch /usr/local/etc/frr/ospfd.conf
+   sudo touch /usr/local/etc/frr/pbrd.conf
+   sudo touch /usr/local/etc/frr/pimd.conf
+   sudo touch /usr/local/etc/frr/ripd.conf
+   sudo touch /usr/local/etc/frr/ripngd.conf
+   sudo touch /usr/local/etc/frr/staticd.conf
+   sudo touch /usr/local/etc/frr/zebra.conf
+   sudo chown -R frr:frr /usr/local/etc/frr/
+   sudo touch /usr/local/etc/frr/vtysh.conf
+   sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf
+   sudo chmod 640 /usr/local/etc/frr/*.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following lines to the end of ``/etc/sysctl.conf``:
+
+::
+
+   # Routing: We need to forward packets
+   net.inet.ip.forwarding=1
+   net.inet6.ip6.forwarding=1
+
+**Reboot** or use ``sysctl`` to apply the same config to the running system.
diff --git a/doc/developer/building-frr-for-freebsd9.rst b/doc/developer/building-frr-for-freebsd9.rst
new file mode 100644 (file)
index 0000000..4f859d3
--- /dev/null
@@ -0,0 +1,141 @@
+FreeBSD 9
+=========================================
+
+FreeBSD 9 restrictions:
+-----------------------
+
+-  MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel
+   (4.5 or higher). LDP can be built, but may have limited use without
+   MPLS
+
+Install required packages
+-------------------------
+
+Add packages: (Allow the install of the package managment tool if this
+is first package install and asked)
+
+::
+
+    pkg install -y git autoconf automake libtool gmake gawk \
+        pkgconf texinfo json-c bison flex py27-pytest c-ares \
+        python3 py-sphinx
+
+Make sure there is no /usr/bin/flex preinstalled (and use the newly
+installed in /usr/local/bin): (FreeBSD frequently provides a older flex
+as part of the base OS which takes preference in path)
+
+::
+
+    rm -f /usr/bin/flex
+
+For building with clang (instead of gcc), upgrade clang from 3.4 default
+to 3.6 *This is needed to build FreeBSD packages as well - for packages
+clang is default* (Clang 3.4 as shipped with FreeBSD 9 crashes during
+compile)
+
+::
+
+    pkg install clang36
+    pkg delete clang34
+    mv /usr/bin/clang /usr/bin/clang34
+    ln -s /usr/local/bin/clang36 /usr/bin/clang
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr group and user
+^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    pw groupadd frr -g 101
+    pw groupadd frrvty -g 102
+    pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \
+        -d /usr/local/etc/frr -s /usr/sbin/nologin
+
+(You may prefer different options on configure statement. These are just
+an example)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    export MAKE=gmake
+    export LDFLAGS="-L/usr/local/lib"
+    export CPPFLAGS="-I/usr/local/include"
+    ./configure \
+        --sysconfdir=/usr/local/etc/frr \
+        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
+        --localstatedir=/var/run/frr \
+        --prefix=/usr/local \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    gmake
+    gmake check
+    sudo gmake install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   sudo mkdir /usr/local/etc/frr
+
+For integrated config file:
+
+.. code-block:: shell
+
+   sudo touch /usr/local/etc/frr/frr.conf
+
+For individual config files:
+
+.. note:: Integrated config is preferred to individual config.
+
+.. code-block:: shell
+
+   sudo touch /usr/local/etc/frr/babeld.conf
+   sudo touch /usr/local/etc/frr/bfdd.conf
+   sudo touch /usr/local/etc/frr/bgpd.conf
+   sudo touch /usr/local/etc/frr/eigrpd.conf
+   sudo touch /usr/local/etc/frr/isisd.conf
+   sudo touch /usr/local/etc/frr/ldpd.conf
+   sudo touch /usr/local/etc/frr/nhrpd.conf
+   sudo touch /usr/local/etc/frr/ospf6d.conf
+   sudo touch /usr/local/etc/frr/ospfd.conf
+   sudo touch /usr/local/etc/frr/pbrd.conf
+   sudo touch /usr/local/etc/frr/pimd.conf
+   sudo touch /usr/local/etc/frr/ripd.conf
+   sudo touch /usr/local/etc/frr/ripngd.conf
+   sudo touch /usr/local/etc/frr/staticd.conf
+   sudo touch /usr/local/etc/frr/zebra.conf
+   sudo chown -R frr:frr /usr/local/etc/frr/
+   sudo touch /usr/local/etc/frr/vtysh.conf
+   sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf
+   sudo chmod 640 /usr/local/etc/frr/*.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following lines to the end of ``/etc/sysctl.conf``:
+
+::
+
+   # Routing: We need to forward packets
+   net.inet.ip.forwarding=1
+   net.inet6.ip6.forwarding=1
+
+**Reboot** or use ``sysctl`` to apply the same config to the running system.
diff --git a/doc/developer/building-frr-for-netbsd6.rst b/doc/developer/building-frr-for-netbsd6.rst
new file mode 100644 (file)
index 0000000..ca0845d
--- /dev/null
@@ -0,0 +1,147 @@
+NetBSD 6
+========================================
+
+NetBSD 6 restrictions:
+----------------------
+
+-  MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel
+   (4.5 or higher). LDP can be built, but may have limited use without
+   MPLS
+
+Install required packages
+-------------------------
+
+Configure Package location:
+
+::
+
+    PKG_PATH="ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All"
+    export PKG_PATH
+
+Add packages:
+
+::
+
+    sudo pkg_add git autoconf automake libtool gmake gawk openssl \
+       pkg-config json-c python27 py27-test python35 py-sphinx
+
+Install SSL Root Certificates (for git https access):
+
+::
+
+    sudo pkg_add mozilla-rootcerts
+    sudo touch /etc/openssl/openssl.cnf
+    sudo mozilla-rootcerts install
+
+Select default Python and py.test
+
+::
+
+    sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python
+    sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -g 92 frr
+    sudo groupadd -g 93 frrvty
+    sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \
+        -d /nonexistent -s /sbin/nologin frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    MAKE=gmake
+    export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
+    export CPPFLAGS="-I/usr/pkg/include"
+    ./configure \
+        --sysconfdir=/usr/pkg/etc/frr \
+        --enable-exampledir=/usr/pkg/share/examples/frr \
+        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
+        --localstatedir=/var/run/frr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    gmake
+    gmake check
+    sudo gmake install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo mkdir /var/log/frr
+    sudo mkdir /usr/pkg/etc/frr
+    sudo touch /usr/pkg/etc/frr/zebra.conf
+    sudo touch /usr/pkg/etc/frr/bgpd.conf
+    sudo touch /usr/pkg/etc/frr/ospfd.conf
+    sudo touch /usr/pkg/etc/frr/ospf6d.conf
+    sudo touch /usr/pkg/etc/frr/isisd.conf
+    sudo touch /usr/pkg/etc/frr/ripd.conf
+    sudo touch /usr/pkg/etc/frr/ripngd.conf
+    sudo touch /usr/pkg/etc/frr/pimd.conf
+    sudo chown -R frr:frr /usr/pkg/etc/frr
+    sudo touch /usr/local/etc/frr/vtysh.conf
+    sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf
+    sudo chmod 640 /usr/pkg/etc/frr/*.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following lines to the end of ``/etc/sysctl.conf``:
+
+::
+
+    # Routing: We need to forward packets
+    net.inet.ip.forwarding=1
+    net.inet6.ip6.forwarding=1
+
+**Reboot** or use ``sysctl`` to apply the same config to the running
+system
+
+Install rc.d init files
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    cp pkgsrc/*.sh /etc/rc.d/
+    chmod 555 /etc/rc.d/*.sh
+
+Enable FRR processes
+^^^^^^^^^^^^^^^^^^^^
+
+(Enable the required processes only)
+
+::
+
+    echo "zebra=YES" >> /etc/rc.conf
+    echo "bgpd=YES" >> /etc/rc.conf
+    echo "ospfd=YES" >> /etc/rc.conf
+    echo "ospf6d=YES" >> /etc/rc.conf
+    echo "isisd=YES" >> /etc/rc.conf
+    echo "ripngd=YES" >> /etc/rc.conf
+    echo "ripd=YES" >> /etc/rc.conf
+    echo "pimd=YES" >> /etc/rc.conf
diff --git a/doc/developer/building-frr-for-netbsd7.rst b/doc/developer/building-frr-for-netbsd7.rst
new file mode 100644 (file)
index 0000000..86242ef
--- /dev/null
@@ -0,0 +1,137 @@
+NetBSD 7
+========================================
+
+NetBSD 7 restrictions:
+----------------------
+
+-  MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel
+   (4.5 or higher). LDP can be built, but may have limited use without
+   MPLS
+
+Install required packages
+-------------------------
+
+::
+
+    sudo pkgin install git autoconf automake libtool gmake gawk openssl \
+       pkg-config json-c python27 py27-test python35 py-sphinx
+
+Install SSL Root Certificates (for git https access):
+
+::
+
+    sudo pkgin install mozilla-rootcerts
+    sudo touch /etc/openssl/openssl.cnf
+    sudo mozilla-rootcerts install
+
+Select default Python and py.test
+
+::
+
+    sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python
+    sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -g 92 frr
+    sudo groupadd -g 93 frrvty
+    sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \
+        -d /nonexistent -s /sbin/nologin frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    MAKE=gmake
+    export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
+    export CPPFLAGS="-I/usr/pkg/include"
+    ./configure \
+        --sysconfdir=/usr/pkg/etc/frr \
+        --enable-exampledir=/usr/pkg/share/examples/frr \
+        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
+        --localstatedir=/var/run/frr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    gmake
+    gmake check
+    sudo gmake install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo mkdir /usr/pkg/etc/frr
+    sudo touch /usr/pkg/etc/frr/zebra.conf
+    sudo touch /usr/pkg/etc/frr/bgpd.conf
+    sudo touch /usr/pkg/etc/frr/ospfd.conf
+    sudo touch /usr/pkg/etc/frr/ospf6d.conf
+    sudo touch /usr/pkg/etc/frr/isisd.conf
+    sudo touch /usr/pkg/etc/frr/ripd.conf
+    sudo touch /usr/pkg/etc/frr/ripngd.conf
+    sudo touch /usr/pkg/etc/frr/pimd.conf
+    sudo chown -R frr:frr /usr/pkg/etc/frr
+    sudo touch /usr/local/etc/frr/vtysh.conf
+    sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf
+    sudo chmod 640 /usr/pkg/etc/frr/*.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following lines to the end of ``/etc/sysctl.conf``:
+
+::
+
+    # Routing: We need to forward packets
+    net.inet.ip.forwarding=1
+    net.inet6.ip6.forwarding=1
+
+**Reboot** or use ``sysctl`` to apply the same config to the running
+system
+
+Install rc.d init files
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    cp pkgsrc/*.sh /etc/rc.d/
+    chmod 555 /etc/rc.d/*.sh
+
+Enable FRR processes
+^^^^^^^^^^^^^^^^^^^^
+
+(Enable the required processes only)
+
+::
+
+    echo "zebra=YES" >> /etc/rc.conf
+    echo "bgpd=YES" >> /etc/rc.conf
+    echo "ospfd=YES" >> /etc/rc.conf
+    echo "ospf6d=YES" >> /etc/rc.conf
+    echo "isisd=YES" >> /etc/rc.conf
+    echo "ripngd=YES" >> /etc/rc.conf
+    echo "ripd=YES" >> /etc/rc.conf
+    echo "pimd=YES" >> /etc/rc.conf
diff --git a/doc/developer/building-frr-for-omnios.rst b/doc/developer/building-frr-for-omnios.rst
new file mode 100644 (file)
index 0000000..03f3845
--- /dev/null
@@ -0,0 +1,146 @@
+OmniOS (OpenSolaris)
+====================================================
+
+OmniOS restrictions:
+--------------------
+
+-  MPLS is not supported on ``OmniOS`` or ``Solaris``. MPLS requires a
+   Linux Kernel (4.5 or higher). LDP can be built, but may have limited
+   use without MPLS
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    routeadm -e ipv4-forwarding
+    routeadm -e ipv6-forwarding
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    pkg install \
+      developer/build/autoconf \
+      developer/build/automake \
+      developer/lexer/flex \
+      developer/parser/bison \
+      developer/object-file \
+      developer/linker \
+      developer/library/lint \
+      developer/build/gnu-make \
+      developer/gcc51 \
+      library/idnkit \
+      library/idnkit/header-idnkit \
+      system/header \
+      system/library/math/header-math \
+      git libtool gawk pkg-config
+
+Add additional Solaris packages:
+
+::
+
+    pkgadd -d http://get.opencsw.org/now
+    /opt/csw/bin/pkgutil -U
+    /opt/csw/bin/pkgutil -y -i texinfo
+    /opt/csw/bin/pkgutil -y -i perl
+    /opt/csw/bin/pkgutil -y -i libjson_c_dev
+    /opt/csw/bin/pkgutil -y -i python27 py_pip python27_dev
+
+Add libjson to Solaris equivalent of ld.so.conf
+
+::
+
+    crle -l /opt/csw/lib -u
+
+Add pytest:
+
+::
+
+    pip install pytest
+
+Install Sphinx:::
+
+   pip install sphinx
+
+Select Python 2.7 as default (required for pytest)
+
+::
+
+    rm -f /usr/bin/python
+    ln -s /opt/csw/bin/python2.7 /usr/bin/python
+
+Fix PATH for all users and non-interactive sessions. Edit
+``/etc/default/login`` and add the following default PATH:
+
+::
+
+    PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin
+
+Edit ``~/.profile`` and add the following default PATH:
+
+::
+
+    PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr group and user
+^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -g 93 frr
+    sudo groupadd -g 94 frrvty
+    sudo useradd -g 93 -u 93 -G frrvty -c "FRR suite" \
+        -d /nonexistent -s /bin/false frr
+
+(You may prefer different options on configure statement. These are just
+an example)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    export MAKE=gmake
+    export LDFLAGS="-L/opt/csw/lib"
+    export CPPFLAGS="-I/opt/csw/include"
+    export PKG_CONFIG_PATH=/opt/csw/lib/pkgconfig
+    ./configure \
+        --sysconfdir=/etc/frr \
+        --enable-exampledir=/usr/share/doc/frr/examples/ \
+        --localstatedir=/var/run/frr \
+        --sbindir=/usr/lib/frr \
+        --enable-vtysh \
+        --enable-watchfrr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    gmake
+    gmake check
+    sudo gmake install
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    routeadm -e ipv4-forwarding
+    routeadm -e ipv6-forwarding
diff --git a/doc/developer/building-frr-for-openbsd6.rst b/doc/developer/building-frr-for-openbsd6.rst
new file mode 100644 (file)
index 0000000..46db25a
--- /dev/null
@@ -0,0 +1,169 @@
+OpenBSD 6
+=========================================
+
+Install required packages
+-------------------------
+
+Configure PKG\_PATH
+
+::
+
+    export PKG_PATH=http://ftp5.usa.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(machine -a)/
+
+Add packages:
+
+::
+
+    pkg_add git autoconf-2.69p2 automake-1.15.1 libtool bison
+    pkg_add gmake gawk dejagnu openssl json-c py-test py-sphinx
+
+Select Python2.7 as default (required for pytest)
+
+::
+
+    ln -s /usr/local/bin/python2.7 /usr/local/bin/python
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr group and user
+^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    groupadd -g 525 _frr
+    groupadd -g 526 _frrvty
+    useradd -g 525 -u 525 -c "FRR suite" -G _frrvty \
+        -d /nonexistent -s /sbin/nologin _frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    export AUTOCONF_VERSION="2.69"
+    export AUTOMAKE_VERSION="1.15"
+    ./bootstrap.sh
+    export LDFLAGS="-L/usr/local/lib"
+    export CPPFLAGS="-I/usr/local/include"
+    ./configure \
+        --sysconfdir=/etc/frr \
+        --localstatedir=/var/frr \
+        --enable-pimd \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=_frr \
+        --enable-group=_frr \
+        --enable-vty-group=_frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    gmake
+    gmake check
+    doas gmake install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    doas mkdir /var/frr
+    doas chown _frr:_frr /var/frr
+    doas chmod 755 /var/frr
+    doas mkdir /etc/frr
+    doas touch /etc/frr/zebra.conf
+    doas touch /etc/frr/bgpd.conf
+    doas touch /etc/frr/ospfd.conf
+    doas touch /etc/frr/ospf6d.conf
+    doas touch /etc/frr/isisd.conf
+    doas touch /etc/frr/ripd.conf
+    doas touch /etc/frr/ripngd.conf
+    doas touch /etc/frr/pimd.conf
+    doas touch /etc/frr/ldpd.conf
+    doas touch /etc/frr/nhrpd.conf
+    doas chown -R _frr:_frr /etc/frr
+    doas touch /etc/frr/vtysh.conf
+    doas chown -R _frr:_frrvty /etc/frr/vtysh.conf
+    doas chmod 750 /etc/frr
+    doas chmod 640 /etc/frr/*.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following lines to the end of ``/etc/rc.conf``:
+
+::
+
+    net.inet6.ip6.forwarding=1      # 1=Permit forwarding of IPv6 packets
+    net.inet6.ip6.mforwarding=1     # 1=Permit forwarding of IPv6 multicast packets
+    net.inet6.ip6.multipath=1       # 1=Enable IPv6 multipath routing
+
+**Reboot** to apply the config to the system
+
+Enable MPLS Forwarding
+^^^^^^^^^^^^^^^^^^^^^^
+
+To enable MPLS forwarding on a given interface, use the following
+command:
+
+::
+
+    doas ifconfig em0 mpls
+
+Alternatively, to make MPLS forwarding persistent across reboots, add
+the "mpls" keyword in the hostname.\* files of the desired interfaces.
+Example:
+
+::
+
+    cat /etc/hostname.em0
+    inet 10.0.1.1 255.255.255.0 mpls
+
+Install rc.d init files
+^^^^^^^^^^^^^^^^^^^^^^^
+
+(create them in /etc/rc.d - no example are included at this time with
+FRR source)
+
+Example (for zebra - store as ``/etc/rc.d/frr_zebra.sh``)
+
+::
+
+    #!/bin/sh
+    #
+    # $OpenBSD: frr_zebra.rc,v 1.1 2013/04/18 20:29:08 sthen Exp $
+
+    daemon="/usr/local/sbin/zebra -d"
+
+    . /etc/rc.d/rc.subr
+
+    rc_cmd $1
+
+Enable FRR processes
+^^^^^^^^^^^^^^^^^^^^
+
+(Enable the required processes only)
+
+::
+
+    echo "frr_zebra=YES" >> /etc/rc.conf
+    echo "frr_bgpd=YES" >> /etc/rc.conf
+    echo "frr_ospfd=YES" >> /etc/rc.conf
+    echo "frr_ospf6d=YES" >> /etc/rc.conf
+    echo "frr_isisd=YES" >> /etc/rc.conf
+    echo "frr_ripngd=YES" >> /etc/rc.conf
+    echo "frr_ripd=YES" >> /etc/rc.conf
+    echo "frr_pimd=YES" >> /etc/rc.conf
+    echo "frr_ldpd=YES" >> /etc/rc.conf
diff --git a/doc/developer/building-frr-for-ubuntu1204.rst b/doc/developer/building-frr-for-ubuntu1204.rst
new file mode 100644 (file)
index 0000000..459d411
--- /dev/null
@@ -0,0 +1,188 @@
+Ubuntu 12.04LTS
+===============================================
+
+-  MPLS is not supported on ``Ubuntu 12.04`` with default kernel. MPLS
+   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
+   limited use without MPLS) For an updated Ubuntu Kernel, see
+   http://kernel.ubuntu.com/~kernel-ppa/mainline/
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    apt-get install \
+       git autoconf automake libtool make gawk libreadline-dev texinfo \
+       dejagnu pkg-config libpam0g-dev libjson0-dev flex python-pip \
+       libc-ares-dev python3-dev python3-sphinx install-info
+
+Install newer bison from 14.04 package source (Ubuntu 12.04 package
+source is too old)
+
+::
+
+    mkdir builddir
+    cd builddir
+    wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.dsc
+    wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg.orig.tar.bz2
+    wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.debian.tar.gz
+    tar -jxvf bison_3.0.2.dfsg.orig.tar.bz2
+    cd bison-3.0.2.dfsg/
+    tar xzf ../bison_3.0.2.dfsg-2.debian.tar.gz
+    sudo apt-get build-dep bison
+    debuild -b -uc -us
+    cd ..
+    sudo dpkg -i ./libbison-dev_3.0.2.dfsg-2_amd64.deb ./bison_3.0.2.dfsg-2_amd64.deb
+    cd ..
+    rm -rf builddir
+
+Install newer version of autoconf and automake:
+
+::
+
+    wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
+    tar xvf autoconf-2.69.tar.gz
+    cd autoconf-2.69
+    ./configure --prefix=/usr
+    make
+    sudo make install
+    cd ..
+
+    wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz
+    tar xvf automake-1.15.tar.gz
+    cd automake-1.15
+    ./configure --prefix=/usr
+    make
+    sudo make install
+    cd ..
+
+Install pytest:
+
+::
+
+    pip install pytest
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -r -g 92 frr
+    sudo groupadd -r -g 85 frrvty
+    sudo adduser --system --ingroup frr --home /var/run/frr/ \
+       --gecos "FRR suite" --shell /sbin/nologin frr
+    sudo usermod -a -G frrvty frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    ./configure \
+        --prefix=/usr \
+        --enable-exampledir=/usr/share/doc/frr/examples/ \
+        --localstatedir=/var/run/frr \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --enable-pimd \
+        --enable-watchfrr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    make
+    make check
+    sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 755 -o frr -g frr -d /var/log/frr
+    sudo install -m 775 -o frr -g frrvty -d /etc/frr
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
+other settings)
+
+::
+
+    # Uncomment the next line to enable packet forwarding for IPv4
+    net.ipv4.ip_forward=1
+
+    # Uncomment the next line to enable packet forwarding for IPv6
+    #  Enabling this option disables Stateless Address Autoconfiguration
+    #  based on Router Advertisements for this host
+    net.ipv6.conf.all.forwarding=1
+
+**Reboot** or use ``sysctl -p`` to apply the same config to the running
+system
+
+Install the init.d service
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 755 tools/frr /etc/init.d/frr
+    sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
+    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
+    sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
+
+Enable daemons
+^^^^^^^^^^^^^^
+
+| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for
+  those daemons you want to start by systemd.
+| For example.
+
+::
+
+    zebra=yes
+    bgpd=yes
+    ospfd=yes
+    ospf6d=yes
+    ripd=yes
+    ripngd=yes
+    isisd=yes
+
+Start the init.d service
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+-  /etc/init.d/frr start
+-  use ``/etc/init.d/frr status`` to check its status.
diff --git a/doc/developer/building-frr-for-ubuntu1404.rst b/doc/developer/building-frr-for-ubuntu1404.rst
new file mode 100644 (file)
index 0000000..681cc30
--- /dev/null
@@ -0,0 +1,143 @@
+Ubuntu 14.04LTS
+===============================================
+
+-  MPLS is not supported on ``Ubuntu 14.04`` with default kernel. MPLS
+   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
+   limited use without MPLS) For an updated Ubuntu Kernel, see
+   http://kernel.ubuntu.com/~kernel-ppa/mainline/
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    apt-get install \
+       git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \
+       pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
+       libc-ares-dev python3-dev python3-sphinx install-info
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -r -g 92 frr
+    sudo groupadd -r -g 85 frrvty
+    sudo adduser --system --ingroup frr --home /var/run/frr/ \
+       --gecos "FRR suite" --shell /sbin/nologin frr
+    sudo usermod -a -G frrvty frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    ./configure \
+        --prefix=/usr \
+        --enable-exampledir=/usr/share/doc/frr/examples/ \
+        --localstatedir=/var/run/frr \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --enable-pimd \
+        --enable-watchfrr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --enable-ldpd \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    make
+    make check
+    sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 755 -o frr -g frr -d /var/log/frr
+    sudo install -m 775 -o frr -g frrvty -d /etc/frr
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
+
+Enable IP & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
+other settings)
+
+::
+
+    # Uncomment the next line to enable packet forwarding for IPv4
+    net.ipv4.ip_forward=1
+
+    # Uncomment the next line to enable packet forwarding for IPv6
+    #  Enabling this option disables Stateless Address Autoconfiguration
+    #  based on Router Advertisements for this host
+    net.ipv6.conf.all.forwarding=1
+
+**Reboot** or use ``sysctl -p`` to apply the same config to the running
+system
+
+Install the init.d service
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 755 tools/frr /etc/init.d/frr
+    sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
+    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
+    sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
+
+Enable daemons
+^^^^^^^^^^^^^^
+
+| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for
+  those daemons you want to start by systemd.
+| For example.
+
+::
+
+    zebra=yes
+    bgpd=yes
+    ospfd=yes
+    ospf6d=yes
+    ripd=yes
+    ripngd=yes
+    isisd=yes
+
+Start the init.d service
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+-  /etc/init.d/frr start
+-  use ``/etc/init.d/frr status`` to check its status.
diff --git a/doc/developer/building-frr-for-ubuntu1604.rst b/doc/developer/building-frr-for-ubuntu1604.rst
new file mode 100644 (file)
index 0000000..69c4e44
--- /dev/null
@@ -0,0 +1,177 @@
+Ubuntu 16.04LTS
+===============================================
+
+-  MPLS is not supported on ``Ubuntu 16.04`` with default kernel. MPLS
+   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
+   limited use without MPLS) For an updated Ubuntu Kernel, see
+   http://kernel.ubuntu.com/~kernel-ppa/mainline/
+
+Install required packages
+-------------------------
+
+Add packages:
+
+::
+
+    apt-get install \
+       git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \
+       pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
+       libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
+       install-info
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo groupadd -r -g 92 frr
+    sudo groupadd -r -g 85 frrvty
+    sudo adduser --system --ingroup frr --home /var/run/frr/ \
+       --gecos "FRR suite" --shell /sbin/nologin frr
+    sudo usermod -a -G frrvty frr
+
+Download Source, configure and compile it
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+(You may prefer different options on configure statement. These are just
+an example.)
+
+::
+
+    git clone https://github.com/frrouting/frr.git frr
+    cd frr
+    ./bootstrap.sh
+    ./configure \
+        --prefix=/usr \
+        --enable-exampledir=/usr/share/doc/frr/examples/ \
+        --localstatedir=/var/run/frr \
+        --sbindir=/usr/lib/frr \
+        --sysconfdir=/etc/frr \
+        --enable-pimd \
+        --enable-watchfrr \
+        --enable-ospfclient=yes \
+        --enable-ospfapi=yes \
+        --enable-multipath=64 \
+        --enable-user=frr \
+        --enable-group=frr \
+        --enable-vty-group=frrvty \
+        --enable-configfile-mask=0640 \
+        --enable-logfile-mask=0640 \
+        --enable-rtadv \
+        --enable-fpm \
+        --enable-systemd=yes \
+        --with-pkg-git-version \
+        --with-pkg-extra-version=-MyOwnFRRVersion
+    make
+    make check
+    sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 755 -o frr -g frr -d /var/log/frr
+    sudo install -m 775 -o frr -g frrvty -d /etc/frr
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
+
+Enable IPv4 & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
+other settings)
+
+::
+
+    # Uncomment the next line to enable packet forwarding for IPv4
+    net.ipv4.ip_forward=1
+
+    # Uncomment the next line to enable packet forwarding for IPv6
+    #  Enabling this option disables Stateless Address Autoconfiguration
+    #  based on Router Advertisements for this host
+    net.ipv6.conf.all.forwarding=1
+
+Enable MPLS Forwarding (with Linux Kernel >= 4.5)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit ``/etc/sysctl.conf`` and the following lines. Make sure to add a
+line equal to ``net.mpls.conf.eth0.input`` or each interface used with
+MPLS
+
+::
+
+    # Enable MPLS Label processing on all interfaces
+    net.mpls.conf.eth0.input=1
+    net.mpls.conf.eth1.input=1
+    net.mpls.conf.eth2.input=1
+    net.mpls.platform_labels=100000
+
+Add MPLS kernel modules
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Add the following lines to ``/etc/modules-load.d/modules.conf``:
+
+::
+
+    # Load MPLS Kernel Modules
+    mpls-router
+    mpls-iptunnel
+
+**Reboot** or use ``sysctl -p`` to apply the same config to the running
+system
+
+Install the systemd service (if rebooted from last step, change directory back to frr directory)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
+    sudo install -m 644 tools/etc/default/frr /etc/default/frr
+    sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
+    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
+    sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
+    sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
+
+Enable daemons
+^^^^^^^^^^^^^^
+
+| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for
+  those daemons you want to start by systemd.
+| For example.
+
+::
+
+    zebra=yes
+    bgpd=yes
+    ospfd=yes
+    ospf6d=yes
+    ripd=yes
+    ripngd=yes
+    isisd=yes
+
+Enable the systemd service
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+-  systemctl enable frr
+
+Start the systemd service
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+-  systemctl start frr
+-  use ``systemctl status frr`` to check its status.
diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst
new file mode 100644 (file)
index 0000000..50e90fc
--- /dev/null
@@ -0,0 +1,249 @@
+Ubuntu 18.04 LTS
+================
+
+Install dependencies
+--------------------
+
+Required packages
+^^^^^^^^^^^^^^^^^
+
+::
+
+   sudo apt-get install \
+      git autoconf automake libtool make gawk libreadline-dev texinfo \
+      pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
+      libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
+      install-info
+
+Optional packages
+^^^^^^^^^^^^^^^^^
+
+Dependencies for additional functionality can be installed as-desired.
+
+Protobuf
+~~~~~~~~
+
+::
+
+   sudo apt-get install \
+       protobuf-c-compiler \
+       libprotobuf-c-dev
+
+ZeroMQ
+~~~~~~
+
+::
+
+   sudo apt-get install \
+       libzmq5 \
+       libzmq3-dev
+
+Get FRR, compile it and install it (from Git)
+---------------------------------------------
+
+**This assumes you want to build and install FRR from source and not
+using any packages**
+
+Add frr groups and user
+^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+   sudo groupadd -r -g 92 frr
+   sudo groupadd -r -g 85 frrvty
+   sudo adduser --system --ingroup frr --home /var/run/frr/ \
+      --gecos "FRR suite" --shell /sbin/nologin frr
+   sudo usermod -a -G frrvty frr
+
+Download source
+^^^^^^^^^^^^^^^
+
+::
+
+   git clone https://github.com/frrouting/frr.git frr
+
+Configure
+^^^^^^^^^
+Options below are provided as an example.
+
+.. seealso:: *Installation* section of user guide
+
+.. code-block:: shell
+
+   cd frr
+   ./bootstrap.sh
+   ./configure \
+       --prefix=/usr \
+       --enable-exampledir=/usr/share/doc/frr/examples/ \
+       --localstatedir=/var/run/frr \
+       --sbindir=/usr/lib/frr \
+       --sysconfdir=/etc/frr \
+       --enable-pimd \
+       --enable-watchfrr \
+       --enable-ospfclient=yes \
+       --enable-ospfapi=yes \
+       --enable-multipath=64 \
+       --enable-user=frr \
+       --enable-group=frr \
+       --enable-vty-group=frrvty \
+       --enable-configfile-mask=0640 \
+       --enable-logfile-mask=0640 \
+       --enable-rtadv \
+       --enable-fpm \
+       --enable-systemd=yes \
+       --with-pkg-git-version \
+       --with-pkg-extra-version=-MyOwnFRRVersion
+
+If optional packages were installed, the associated feature may now be
+enabled.
+
+.. option:: --enable-protobuf
+
+Enable support for protobuf transport
+
+.. option:: --enable-zeromq
+
+Enable support for ZeroMQ transport
+
+Compile
+^^^^^^^
+
+::
+
+   make
+   make check
+   sudo make install
+
+Create empty FRR configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Although not strictly necessary, it's good practice to create empty
+configuration files _before_ starting FRR. This assures that the permissions 
+are correct. If the files are not already present, FRR will create them.
+
+It's also important to consider _which_ files to create. FRR supports writing
+configuration to a monolithic file, :file:`/etc/frr/frr.conf`.
+
+.. seealso:: *VTYSH* section of user guide
+
+The presence of :file:`/etc/frr/frr.conf` on startup implicitly configures FRR
+to ignore daemon-specific configuration files.
+
+Daemon-specific configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+   sudo install -m 755 -o frr -g frr -d /var/log/frr
+   sudo install -m 775 -o frr -g frrvty -d /etc/frr
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+
+Monolithic configuration
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+   sudo install -m 755 -o frr -g frr -d /var/log/frr
+   sudo install -m 775 -o frr -g frrvty -d /etc/frr
+   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/frr.conf
+
+Enable IPv4 & IPv6 forwarding
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Edit :file:`/etc/sysctl.conf` and uncomment the following values (ignore the
+other settings):
+
+::
+
+   # Uncomment the next line to enable packet forwarding for IPv4
+   net.ipv4.ip_forward=1
+
+   # Uncomment the next line to enable packet forwarding for IPv6
+   #  Enabling this option disables Stateless Address Autoconfiguration
+   #  based on Router Advertisements for this host
+   net.ipv6.conf.all.forwarding=1
+
+Add MPLS kernel modules
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Ubuntu 18.04 ships with kernel 4.15. MPLS modules are present by default.  To
+enable, add the following lines to :file:`/etc/modules-load.d/modules.conf`:
+
+::
+
+   # Load MPLS Kernel Modules
+   mpls_router
+   mpls_iptunnel
+
+Reboot or use ``sysctl -p`` to apply the same config to the running system.
+
+Enable MPLS Forwarding
+^^^^^^^^^^^^^^^^^^^^^^
+
+Edit :file:`/etc/sysctl.conf` and the following lines. Make sure to add a line
+equal to :file:`net.mpls.conf.eth0.input` for each interface used with MPLS.
+
+::
+
+   # Enable MPLS Label processing on all interfaces
+   net.mpls.conf.eth0.input=1
+   net.mpls.conf.eth1.input=1
+   net.mpls.conf.eth2.input=1
+   net.mpls.platform_labels=100000
+
+Install the systemd service
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+   sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
+   sudo install -m 644 tools/etc/default/frr /etc/default/frr
+   sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
+   sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
+   sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
+   sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
+
+Enable daemons
+^^^^^^^^^^^^^^
+
+Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for those
+daemons you want to start by systemd.  For example:
+
+::
+
+   zebra=yes
+   bgpd=yes
+   ospfd=yes
+   ospf6d=yes
+   ripd=yes
+   ripngd=yes
+   isisd=yes
+
+Enable the systemd service
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Enabling the systemd service causes FRR to be started upon boot. To enable it,
+use the following command:
+
+.. code-block:: shell
+
+   systemctl enable frr
+
+Start the systemd service
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+   systemctl start frr
+
+After starting the service, you can use ``systemctl status frr`` to check its
+status.
diff --git a/doc/developer/building-frr-on-alpine.rst b/doc/developer/building-frr-on-alpine.rst
deleted file mode 100644 (file)
index d303784..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-Alpine Linux 3.7+
-=========================================================
-
-For building Alpine Linux dev packages, we use docker.
-
-Install docker 17.05 or later
------------------------------
-
-Depending on your host, there are different ways of installing docker.  Refer
-to the documentation here for instructions on how to install a free version of
-docker: https://www.docker.com/community-edition
-
-Pre-built packages and docker images
-------------------------------------
-
-The master branch of https://github.com/frrouting/frr.git has a
-continuous delivery of docker images to docker hub at:
-https://hub.docker.com/r/ajones17/frr/. These images have the frr packages
-in /pkgs/apk and have the frr package pre-installed.  To copy Alpine
-packages out of these images:
-
-::
-
-   id=`docker create ajones17/frr:latest`
-   docker cp ${id}:/pkgs _some_directory_
-   docker rm $id
-
-To run the frr daemons (see below for how to configure them):
-
-::
-
-   docker run -it --rm --name frr ajones17/frr:latest
-   docker exec -it frr /bin/sh
-
-Work with sources
------------------
-
-::
-
-   git clone https://github.com/frrouting/frr.git frr
-   cd frr
-
-Build apk packages
-------------------
-
-::
-
-   ./docker/alpine/build.sh
-
-This will put the apk packages in:
-
-::
-
-   ./docker/pkgs/apk/x86_64/
-
-Usage
------
-
-To create a base image with the frr packages installed:
-
-::
-
-   docker build --rm -f docker/alpine/Dockerfile -t frr:latest .
-
-Or, if you don't have a git checkout of the sources, you can build a base
-image directly off the github account:
-
-::
-
-   docker build --rm -f docker/alpine/Dockerfile -t frr:latest \
-       https://github.com/frrouting/frr.git
-
-And to run the image:
-
-::
-
-   docker run -it --rm --name frr frr:latest
-
-In the default configuration, none of the frr daemons will  be running.
-To configure the daemons, exec into the container and edit the configuration
-files or mount a volume with configuration files into the container on
-startup.  To configure by hand:
-
-::
-
-   docker exec -it frr /bin/sh
-   vi /etc/frr/daemons
-   vi /etc/frr/daemons.conf
-   cp /etc/frr/zebra.conf.sample /etc/frr/zebra.conf
-   vi /etc/frr/zebra.conf
-   /etc/init.d/frr start
-
-Or, to configure the daemons using /etc/frr from a host volume, put the
-config files in, say, ./docker/etc and bind mount that into the
-container:
-
-::
-
-   docker run -it --rm -v `pwd`/docker/etc:/etc/frr frr:latest
-
-We can also build the base image directly from docker-compose, with a
-docker-compose.yml file like this one:
-
-::
-
-   version: '2.2'
-
-   services:
-      frr:
-         build:
-            context: https://github.com/frrouting/frr.git
-            dockerfile: docker/alpine/Dockerfile
diff --git a/doc/developer/building-frr-on-centos6.rst b/doc/developer/building-frr-on-centos6.rst
deleted file mode 100644 (file)
index d503765..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-CentOS 6
-========================================
-
-(As an alternative to this installation, you may prefer to create a FRR
-rpm package yourself and install that package instead. See instructions
-in redhat/README.rpm\_build.md on how to build a rpm package)
-
-Instructions are tested with ``CentOS 6.8`` on ``x86_64`` platform
-
-Warning:
---------
-``CentOS 6`` is very old and not fully supported by the FRR community
-anymore. Building FRR takes multiple manual steps to update the build
-system with newer packages than what's available from the archives.
-However, the built packages can still be installed afterwards on
-a standard ``CentOS 6`` without any special packages.
-
-Support for CentOS 6 is now on a best-effort base by the community.
-
-CentOS 6 restrictions:
-----------------------
-
--  PIMd is not supported on ``CentOS 6``. Upgrade to ``CentOS 7`` if
-   PIMd is needed
--  MPLS is not supported on ``CentOS 6``. MPLS requires Linux Kernel 4.5
-   or higher (LDP can be built, but may have limited use without MPLS)
--  Zebra is unable to detect what bridge/vrf an interface is associcated
-   with (IFLA\_INFO\_SLAVE\_KIND does not exist in the kernel headers,
-   you can use a newer kernel + headers to get this functionality)
--  frr\_reload.py will not work, as this requires Python 2.7, and CentOS
-   6 only has 2.6. You can install Python 2.7 via IUS, but it won't work
-   properly unless you compile and install the ipaddr package for it.
--  Building the package requires Sphinx >= 1.1. Only a non-standard
-   package provides a newer sphinx and requires manual installation
-   (see below)
-
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    sudo yum install git autoconf automake libtool make gawk \
-      readline-devel texinfo net-snmp-devel groff pkgconfig \
-      json-c-devel pam-devel flex epel-release perl-XML-LibXML \
-      c-ares-devel
-
-Install newer version of bison (CentOS 6 package source is too old) from
-CentOS 7
-
-::
-
-    sudo yum install rpm-build
-    curl -O http://vault.centos.org/7.0.1406/os/Source/SPackages/bison-2.7-4.el7.src.rpm
-    rpmbuild --rebuild ./bison-2.7-4.el7.src.rpm
-    sudo yum install ./rpmbuild/RPMS/x86_64/bison-2.7-4.el6.x86_64.rpm
-    rm -rf rpmbuild
-
-Install newer version of autoconf and automake (Package versions are too
-old)
-
-::
-
-    curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
-    tar xvf autoconf-2.69.tar.gz
-    cd autoconf-2.69
-    ./configure --prefix=/usr
-    make
-    sudo make install
-    cd ..
-
-    curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz
-    tar xvf automake-1.15.tar.gz
-    cd automake-1.15
-    ./configure --prefix=/usr
-    make
-    sudo make install
-    cd ..
-
-Install ``Python 2.7`` in parallel to default 2.6. Make sure you've
-install EPEL (``epel-release`` as above). Then install current
-``python27``, ``python27-devel`` and ``pytest``
-
-::
-
-    sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
-    sudo rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm
-    sudo yum install python27 python27-pip python27-devel
-    sudo pip2.7 install pytest
-
-Please note that ``CentOS 6`` needs to keep python pointing to version
-2.6 for ``yum`` to keep working, so don't create a symlink for python2.7
-to python
-
-Install newer ``Sphinx-Build`` based on ``Python 2.7``
-
-Create a new repo ``/etc/yum.repos.d/puias6.repo`` with the following contents:
-
-::
-
-    ### Name: RPM Repository for RHEL 6 - PUIAS (used for Sphinx-Build)
-    ### URL: http://springdale.math.ias.edu/data/puias/computational
-    [puias-computational]
-    name = RPM Repository for RHEL 6 - Sphinx-Build
-    baseurl = http://springdale.math.ias.edu/data/puias/computational/$releasever/$basearch
-    #mirrorlist =
-    enabled = 1
-    protect = 0
-    gpgkey =
-    gpgcheck = 0
-
-Update rpm database & Install newer sphinx
-
-::
-
-    sudo yum update
-    sudo yum install python27-sphinx
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-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 \
-      -c "FRR FRRouting suite" -d /var/run/frr frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    ./configure \
-        --bindir=/usr/bin \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --libdir=/usr/lib/frr \
-        --libexecdir=/usr/lib/frr \
-        --localstatedir=/var/run/frr \
-        --with-moduledir=/usr/lib/frr/modules \
-        --disable-pimd \
-        --enable-snmp=agentx \
-        --enable-multipath=64 \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvt \
-        --enable-rtadv \
-        --disable-exampledir \
-        --enable-watchfrr \
-        --disable-ldpd \
-        --enable-fpm \
-        --enable-nhrpd \
-        --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
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /var/log/frr
-    sudo mkdir /etc/frr
-    sudo touch /etc/frr/zebra.conf
-    sudo touch /etc/frr/bgpd.conf
-    sudo touch /etc/frr/ospfd.conf
-    sudo touch /etc/frr/ospf6d.conf
-    sudo touch /etc/frr/isisd.conf
-    sudo touch /etc/frr/ripd.conf
-    sudo touch /etc/frr/ripngd.conf
-    sudo touch /etc/frr/nhrpd.conf
-    sudo touch /etc/frr/eigrpd.conf
-    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 chmod 640 /etc/frr/*.conf
-
-Install daemon config file
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -p -m 644 redhat/daemons /etc/frr/
-    sudo chown frr:frr /etc/frr/daemons
-
-Edit /etc/frr/daemons as needed to select the required daemons
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc.
-Enable the daemons as required by changing the value to ``yes``
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit ``/etc/sysctl.conf`` and set the following values (ignore the other
-settings)
-
-::
-
-    # Controls IP packet forwarding
-    net.ipv4.ip_forward = 1
-    net.ipv6.conf.all.forwarding=1
-
-    # Controls source route verification
-    net.ipv4.conf.default.rp_filter = 0
-
-Load the modifed sysctl's on the system:
-
-::
-
-    sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf
-
-Add init.d startup files
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -p -m 755 redhat/frr.init /etc/init.d/frr
-    sudo chkconfig --add frr
-
-Enable frr daemon at startup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo chkconfig frr on
-
-Start FRR manually (or reboot)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo /etc/init.d/frr start
diff --git a/doc/developer/building-frr-on-centos7.rst b/doc/developer/building-frr-on-centos7.rst
deleted file mode 100644 (file)
index 31cd4dc..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-CentOS 7
-========================================
-
-(As an alternative to this installation, you may prefer to create a FRR
-rpm package yourself and install that package instead. See instructions
-in redhat/README.rpm\_build.md on how to build a rpm package)
-
-CentOS 7 restrictions:
-----------------------
-
--  MPLS is not supported on ``CentOS 7`` with default kernel. MPLS
-   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
-   limited use without MPLS)
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    sudo yum install git autoconf automake libtool make gawk \
-      readline-devel texinfo net-snmp-devel groff pkgconfig \
-      json-c-devel pam-devel bison flex pytest c-ares-devel \
-      perl-XML-LibXML python-devel systemd-devel python-sphinx
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-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 \
-      -c "FRR FRRouting suite" -d /var/run/frr frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    ./configure \
-        --bindir=/usr/bin \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --libdir=/usr/lib/frr \
-        --libexecdir=/usr/lib/frr \
-        --localstatedir=/var/run/frr \
-        --with-moduledir=/usr/lib/frr/modules \
-        --enable-pimd \
-        --enable-snmp=agentx \
-        --enable-multipath=64 \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvt \
-        --enable-rtadv \
-       --enable-systemd=yes \
-        --disable-exampledir \
-        --enable-watchfrr \
-        --disable-ldpd \
-        --enable-fpm \
-        --enable-nhrpd \
-        --enable-eigrpd \
-        --enable-babeld \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    make
-    make check
-    sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /var/log/frr
-    sudo mkdir /etc/frr
-    sudo touch /etc/frr/zebra.conf
-    sudo touch /etc/frr/bgpd.conf
-    sudo touch /etc/frr/ospfd.conf
-    sudo touch /etc/frr/ospf6d.conf
-    sudo touch /etc/frr/isisd.conf
-    sudo touch /etc/frr/ripd.conf
-    sudo touch /etc/frr/ripngd.conf
-    sudo touch /etc/frr/pimd.conf
-    sudo touch /etc/frr/nhrpd.conf
-    sudo touch /etc/frr/eigrpd.conf
-    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 chmod 640 /etc/frr/*.conf
-
-Install daemon config file
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -p -m 644 redhat/daemons /etc/frr/
-    sudo chown frr:frr /etc/frr/daemons
-
-Edit /etc/frr/daemons as needed to select the required daemons
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc.
-Enable the daemons as required by changing the value to ``yes``
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the
-following content:
-
-::
-
-    # Sysctl for routing
-    #
-    # Routing: We need to forward packets
-    net.ipv4.conf.all.forwarding=1
-    net.ipv6.conf.all.forwarding=1
-
-Load the modifed sysctl's on the system:
-
-::
-
-    sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf
-
-Install frr Service and redhat init files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service
-    sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr
-
-Register the systemd files
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo systemctl preset frr.service
-
-Enable required frr at startup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo systemctl enable frr
-
-Reboot or start FRR manually
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo systemctl start frr
diff --git a/doc/developer/building-frr-on-debian8.rst b/doc/developer/building-frr-on-debian8.rst
deleted file mode 100644 (file)
index d1e65a4..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-Debian 8
-========================================
-
-Debian 8 restrictions:
-----------------------
-
--  MPLS is not supported on ``Debian 8`` with default kernel. MPLS
-   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
-   limited use without MPLS)
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    sudo apt-get install git autoconf automake libtool make gawk \
-       libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
-       python-pip libc-ares-dev python3-dev python3-sphinx
-
-Install newer pytest (>3.0) from pip
-
-::
-
-    sudo pip install pytest
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo addgroup --system --gid 92 frr
-    sudo addgroup --system --gid 85 frrvty
-    sudo adduser --system --ingroup frr --home /var/run/frr/ \
-       --gecos "FRR suite" --shell /bin/false frr
-    sudo usermod -a -G frrvty frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    ./configure \
-        --enable-exampledir=/usr/share/doc/frr/examples/ \
-        --localstatedir=/var/run/frr \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --enable-vtysh \
-        --enable-isisd \
-        --enable-pimd \
-        --enable-watchfrr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --enable-ldpd \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    make
-    make check
-    sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 755 -o frr -g frr -d /var/log/frr
-    sudo install -m 775 -o frr -g frrvty -d /etc/frr
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
-    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
-other settings)
-
-::
-
-    # Uncomment the next line to enable packet forwarding for IPv4
-    net.ipv4.ip_forward=1
-
-    # Uncomment the next line to enable packet forwarding for IPv6
-    #  Enabling this option disables Stateless Address Autoconfiguration
-    #  based on Router Advertisements for this host
-    net.ipv6.conf.all.forwarding=1
-
-**Reboot** or use ``sysctl -p`` to apply the same config to the running
-system
-
-Troubleshooting
-^^^^^^^^^^^^^^^
-
-**Local state directory**
-
-The local state directory must exist and have the correct permissions
-applied for the frrouting daemons to start. In the above ./configure
-example the local state directory is set to /var/run/frr
-(--localstatedir=/var/run/frr) Debian considers /var/run/frr to be
-temporary and this is removed after a reboot.
-
-When using a different local state directory you need to create the new
-directory and change the ownership to the frr user, for example:
-
-::
-
-    mkdir /var/opt/frr
-    chown frr /var/opt/frr
-
-**Shared library error**
-
-If you try and start any of the frrouting daemons you may see the below
-error due to the frrouting shared library directory not being found:
-
-::
-
-    ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory
-
-The fix is to add the following line to /etc/ld.so.conf which will
-continue to reference the library directory after the system reboots. To
-load the library directory path immediately run the ldconfig command
-after adding the line to the file eg:
-
-::
-
-    echo include /usr/local/lib >> /etc/ld.so.conf
-    ldconfig
diff --git a/doc/developer/building-frr-on-debian9.rst b/doc/developer/building-frr-on-debian9.rst
deleted file mode 100644 (file)
index 7dad9a7..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-Debian 9
-========================================
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    sudo apt-get install git autoconf automake libtool make \
-      libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
-      python-pip libc-ares-dev python3-dev python-pytest python3-sphinx
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo addgroup --system --gid 92 frr
-    sudo addgroup --system --gid 85 frrvty
-    sudo adduser --system --ingroup frr --home /var/opt/frr/ \
-       --gecos "FRR suite" --shell /bin/false frr
-    sudo usermod -a -G frrvty frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    git checkout stable/3.0
-    ./bootstrap.sh
-    ./configure \
-        --enable-exampledir=/usr/share/doc/frr/examples/ \
-        --localstatedir=/var/opt/frr \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --enable-vtysh \
-        --enable-isisd \
-        --enable-pimd \
-        --enable-watchfrr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --enable-ldpd \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    make
-    make check
-    sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 755 -o frr -g frr -d /var/log/frr
-    sudo install -m 755 -o frr -g frr -d /var/opt/frr
-    sudo install -m 775 -o frr -g frrvty -d /etc/frr
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
-    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
-other settings)
-
-::
-
-    # Uncomment the next line to enable packet forwarding for IPv4
-    net.ipv4.ip_forward=1
-
-    # Uncomment the next line to enable packet forwarding for IPv6
-    #  Enabling this option disables Stateless Address Autoconfiguration
-    #  based on Router Advertisements for this host
-    net.ipv6.conf.all.forwarding=1
-
-**Reboot** or use ``sysctl -p`` to apply the same config to the running
-system
-
-Troubleshooting
----------------
-
-Shared library error
-^^^^^^^^^^^^^^^^^^^^
-
-If you try and start any of the frrouting daemons you may see the below
-error due to the frrouting shared library directory not being found:
-
-::
-
-   ./zebra: error while loading shared libraries: libfrr.so.0: cannot open
-   shared object file: No such file or directory
-
-The fix is to add the following line to /etc/ld.so.conf which will
-continue to reference the library directory after the system reboots. To
-load the library directory path immediately run the ldconfig command
-after adding the line to the file eg:
-
-::
-
-   echo include /usr/local/lib >> /etc/ld.so.conf
-   ldconfig
diff --git a/doc/developer/building-frr-on-fedora24.rst b/doc/developer/building-frr-on-fedora24.rst
deleted file mode 100644 (file)
index 208c580..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-Fedora 24
-=========================================
-
-(As an alternative to this installation, you may prefer to create a FRR
-rpm package yourself and install that package instead. See instructions
-in redhat/README.rpm\_build.md on how to build a rpm package)
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    sudo dnf install git autoconf automake libtool make gawk \
-      readline-devel texinfo net-snmp-devel groff pkgconfig \
-      json-c-devel pam-devel perl-XML-LibXML pytest bison flex \
-      c-ares-devel python3-devel python3-sphinx
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-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 \
-      -c "FRR FRRouting suite" -d /var/run/frr frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    ./configure \
-        --bindir=/usr/bin \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --libdir=/usr/lib/frr \
-        --libexecdir=/usr/lib/frr \
-        --localstatedir=/var/run/frr \
-        --with-moduledir=/usr/lib/frr/modules \
-        --enable-pimd \
-        --enable-snmp=agentx \
-        --enable-multipath=64 \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvt \
-        --enable-rtadv \
-        --disable-exampledir \
-        --enable-watchfrr \
-        --enable-ldpd \
-        --enable-fpm \
-        --enable-nhrpd \
-        --enable-eigrpd \
-        --enable-babeld \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    make
-    make check
-    sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /var/log/frr
-    sudo mkdir /etc/frr
-    sudo touch /etc/frr/zebra.conf
-    sudo touch /etc/frr/bgpd.conf
-    sudo touch /etc/frr/ospfd.conf
-    sudo touch /etc/frr/ospf6d.conf
-    sudo touch /etc/frr/isisd.conf
-    sudo touch /etc/frr/ripd.conf
-    sudo touch /etc/frr/ripngd.conf
-    sudo touch /etc/frr/pimd.conf
-    sudo touch /etc/frr/ldpd.conf
-    sudo touch /etc/frr/nhrpd.conf
-    sudo touch /etc/frr/eigrpd.conf
-    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 chmod 640 /etc/frr/*.conf
-
-Install daemon config file
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -p -m 644 redhat/daemons /etc/frr/
-    sudo chown frr:frr /etc/frr/daemons
-
-Edit /etc/frr/daemons as needed to select the required daemons
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc.
-Enable the daemons as required by changing the value to ``yes``
-
-Enable IP & IPv6 forwarding (and MPLS)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the
-following content: (Please make sure to list all interfaces with
-required MPLS similar to ``net.mpls.conf.eth0.input=1``)
-
-::
-
-    # Sysctl for routing
-    #
-    # Routing: We need to forward packets
-    net.ipv4.conf.all.forwarding=1
-    net.ipv6.conf.all.forwarding=1
-    #
-    # Enable MPLS Label processing on all interfaces
-    net.mpls.conf.eth0.input=1
-    net.mpls.conf.eth1.input=1
-    net.mpls.conf.eth2.input=1
-    net.mpls.platform_labels=100000
-
-Load the modifed sysctl's on the system:
-
-::
-
-    sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf
-
-Create a new file ``/etc/modules-load.d/mpls.conf`` with the following
-content:
-
-::
-
-    # Load MPLS Kernel Modules
-    mpls-router
-    mpls-iptunnel
-
-And load the kernel modules on the running system:
-
-::
-
-    sudo modprobe mpls-router mpls-iptunnel
-
-Install frr Service and redhat init files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service
-    sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr
-
-Enable required frr at startup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo systemctl enable frr
-
-Reboot or start FRR manually
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo systemctl start frr
diff --git a/doc/developer/building-frr-on-freebsd10.rst b/doc/developer/building-frr-on-freebsd10.rst
deleted file mode 100644 (file)
index 5d14db5..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-FreeBSD 10
-==========================================
-
-FreeBSD 10 restrictions:
-------------------------
-
--  MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel
-   (4.5 or higher). LDP can be built, but may have limited use without
-   MPLS
-
-Install required packages
--------------------------
-
-Add packages: (Allow the install of the package managment tool if this
-is first package install and asked)
-
-::
-
-    pkg install git autoconf automake libtool gmake gawk json-c pkgconf \
-        bison flex py27-pytest c-ares python3 py-sphinx
-
-Make sure there is no /usr/bin/flex preinstalled (and use the newly
-installed in /usr/local/bin): (FreeBSD frequently provides a older flex
-as part of the base OS which takes preference in path)
-
-::
-
-    rm -f /usr/bin/flex
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr group and user
-^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    pw groupadd frr -g 101
-    pw groupadd frrvty -g 102
-    pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \
-        -d /usr/local/etc/frr -s /usr/sbin/nologin
-
-(You may prefer different options on configure statement. These are just
-an example)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    export MAKE=gmake
-    export LDFLAGS="-L/usr/local/lib"
-    export CPPFLAGS="-I/usr/local/include"
-    ./configure \
-        --sysconfdir=/usr/local/etc/frr \
-        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
-        --localstatedir=/var/run/frr \
-        --prefix=/usr/local \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    gmake
-    gmake check
-    sudo gmake install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /usr/local/etc/frr
-    sudo touch /usr/local/etc/frr/zebra.conf
-    sudo touch /usr/local/etc/frr/bgpd.conf
-    sudo touch /usr/local/etc/frr/ospfd.conf
-    sudo touch /usr/local/etc/frr/ospf6d.conf
-    sudo touch /usr/local/etc/frr/isisd.conf
-    sudo touch /usr/local/etc/frr/ripd.conf
-    sudo touch /usr/local/etc/frr/ripngd.conf
-    sudo touch /usr/local/etc/frr/pimd.conf
-    sudo chown -R frr:frr /usr/local/etc/frr
-    sudo touch /usr/local/etc/frr/vtysh.conf
-    sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf
-    sudo chmod 640 /usr/local/etc/frr/*.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Add the following lines to the end of ``/etc/sysctl.conf``:
-
-::
-
-    # Routing: We need to forward packets
-    net.inet.ip.forwarding=1
-    net.inet6.ip6.forwarding=1
-
-**Reboot** or use ``sysctl`` to apply the same config to the running
-system
diff --git a/doc/developer/building-frr-on-freebsd11.rst b/doc/developer/building-frr-on-freebsd11.rst
deleted file mode 100644 (file)
index 87fb302..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-FreeBSD 11
-==========================================
-
-FreeBSD 11 restrictions:
-------------------------
-
--  MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel
-   (4.5 or higher). LDP can be built, but may have limited use without
-   MPLS
-
-Install required packages
--------------------------
-
-Add packages: (Allow the install of the package managment tool if this
-is first package install and asked)
-
-::
-
-    pkg install git autoconf automake libtool gmake gawk json-c pkgconf \
-        bison flex py27-pytest c-ares python3 py-sphinx
-
-Make sure there is no /usr/bin/flex preinstalled (and use the newly
-installed in /usr/local/bin): (FreeBSD frequently provides a older flex
-as part of the base OS which takes preference in path)
-
-::
-
-    rm -f /usr/bin/flex
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr group and user
-^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    pw groupadd frr -g 101
-    pw groupadd frrvty -g 102
-    pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \
-        -d /usr/local/etc/frr -s /usr/sbin/nologin
-
-(You may prefer different options on configure statement. These are just
-an example)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    export MAKE=gmake
-    export LDFLAGS="-L/usr/local/lib"
-    export CPPFLAGS="-I/usr/local/include"
-    ./configure \
-        --sysconfdir=/usr/local/etc/frr \
-        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
-        --localstatedir=/var/run/frr \
-        --prefix=/usr/local \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    gmake
-    gmake check
-    sudo gmake install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /usr/local/etc/frr
-    sudo touch /usr/local/etc/frr/zebra.conf
-    sudo touch /usr/local/etc/frr/bgpd.conf
-    sudo touch /usr/local/etc/frr/ospfd.conf
-    sudo touch /usr/local/etc/frr/ospf6d.conf
-    sudo touch /usr/local/etc/frr/isisd.conf
-    sudo touch /usr/local/etc/frr/ripd.conf
-    sudo touch /usr/local/etc/frr/ripngd.conf
-    sudo touch /usr/local/etc/frr/pimd.conf
-    sudo chown -R frr:frr /usr/local/etc/frr
-    sudo touch /usr/local/etc/frr/vtysh.conf
-    sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf
-    sudo chmod 640 /usr/local/etc/frr/*.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Add the following lines to the end of ``/etc/sysctl.conf``:
-
-::
-
-    # Routing: We need to forward packets
-    net.inet.ip.forwarding=1
-    net.inet6.ip6.forwarding=1
-
-**Reboot** or use ``sysctl`` to apply the same config to the running
-system
diff --git a/doc/developer/building-frr-on-freebsd9.rst b/doc/developer/building-frr-on-freebsd9.rst
deleted file mode 100644 (file)
index 02279de..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-FreeBSD 9
-=========================================
-
-FreeBSD 9 restrictions:
------------------------
-
--  MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel
-   (4.5 or higher). LDP can be built, but may have limited use without
-   MPLS
-
-Install required packages
--------------------------
-
-Add packages: (Allow the install of the package managment tool if this
-is first package install and asked)
-
-::
-
-    pkg install -y git autoconf automake libtool gmake gawk \
-        pkgconf texinfo json-c bison flex py27-pytest c-ares \
-        python3 py-sphinx
-
-Make sure there is no /usr/bin/flex preinstalled (and use the newly
-installed in /usr/local/bin): (FreeBSD frequently provides a older flex
-as part of the base OS which takes preference in path)
-
-::
-
-    rm -f /usr/bin/flex
-
-For building with clang (instead of gcc), upgrade clang from 3.4 default
-to 3.6 *This is needed to build FreeBSD packages as well - for packages
-clang is default* (Clang 3.4 as shipped with FreeBSD 9 crashes during
-compile)
-
-::
-
-    pkg install clang36
-    pkg delete clang34
-    mv /usr/bin/clang /usr/bin/clang34
-    ln -s /usr/local/bin/clang36 /usr/bin/clang
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr group and user
-^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    pw groupadd frr -g 101
-    pw groupadd frrvty -g 102
-    pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \
-        -d /usr/local/etc/frr -s /usr/sbin/nologin
-
-(You may prefer different options on configure statement. These are just
-an example)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    export MAKE=gmake
-    export LDFLAGS="-L/usr/local/lib"
-    export CPPFLAGS="-I/usr/local/include"
-    ./configure \
-        --sysconfdir=/usr/local/etc/frr \
-        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
-        --localstatedir=/var/run/frr \
-        --prefix=/usr/local \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    gmake
-    gmake check
-    sudo gmake install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /usr/local/etc/frr
-    sudo touch /usr/local/etc/frr/zebra.conf
-    sudo touch /usr/local/etc/frr/bgpd.conf
-    sudo touch /usr/local/etc/frr/ospfd.conf
-    sudo touch /usr/local/etc/frr/ospf6d.conf
-    sudo touch /usr/local/etc/frr/isisd.conf
-    sudo touch /usr/local/etc/frr/ripd.conf
-    sudo touch /usr/local/etc/frr/ripngd.conf
-    sudo touch /usr/local/etc/frr/pimd.conf
-    sudo chown -R frr:frr /usr/local/etc/frr
-    sudo touch /usr/local/etc/frr/vtysh.conf
-    sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf
-    sudo chmod 640 /usr/local/etc/frr/*.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Add the following lines to the end of ``/etc/sysctl.conf``:
-
-::
-
-    # Routing: We need to forward packets
-    net.inet.ip.forwarding=1
-    net.inet6.ip6.forwarding=1
-
-**Reboot** or use ``sysctl`` to apply the same config to the running
-system
diff --git a/doc/developer/building-frr-on-netbsd6.rst b/doc/developer/building-frr-on-netbsd6.rst
deleted file mode 100644 (file)
index ca0845d..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-NetBSD 6
-========================================
-
-NetBSD 6 restrictions:
-----------------------
-
--  MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel
-   (4.5 or higher). LDP can be built, but may have limited use without
-   MPLS
-
-Install required packages
--------------------------
-
-Configure Package location:
-
-::
-
-    PKG_PATH="ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All"
-    export PKG_PATH
-
-Add packages:
-
-::
-
-    sudo pkg_add git autoconf automake libtool gmake gawk openssl \
-       pkg-config json-c python27 py27-test python35 py-sphinx
-
-Install SSL Root Certificates (for git https access):
-
-::
-
-    sudo pkg_add mozilla-rootcerts
-    sudo touch /etc/openssl/openssl.cnf
-    sudo mozilla-rootcerts install
-
-Select default Python and py.test
-
-::
-
-    sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python
-    sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo groupadd -g 92 frr
-    sudo groupadd -g 93 frrvty
-    sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \
-        -d /nonexistent -s /sbin/nologin frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    MAKE=gmake
-    export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
-    export CPPFLAGS="-I/usr/pkg/include"
-    ./configure \
-        --sysconfdir=/usr/pkg/etc/frr \
-        --enable-exampledir=/usr/pkg/share/examples/frr \
-        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
-        --localstatedir=/var/run/frr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    gmake
-    gmake check
-    sudo gmake install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /var/log/frr
-    sudo mkdir /usr/pkg/etc/frr
-    sudo touch /usr/pkg/etc/frr/zebra.conf
-    sudo touch /usr/pkg/etc/frr/bgpd.conf
-    sudo touch /usr/pkg/etc/frr/ospfd.conf
-    sudo touch /usr/pkg/etc/frr/ospf6d.conf
-    sudo touch /usr/pkg/etc/frr/isisd.conf
-    sudo touch /usr/pkg/etc/frr/ripd.conf
-    sudo touch /usr/pkg/etc/frr/ripngd.conf
-    sudo touch /usr/pkg/etc/frr/pimd.conf
-    sudo chown -R frr:frr /usr/pkg/etc/frr
-    sudo touch /usr/local/etc/frr/vtysh.conf
-    sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf
-    sudo chmod 640 /usr/pkg/etc/frr/*.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Add the following lines to the end of ``/etc/sysctl.conf``:
-
-::
-
-    # Routing: We need to forward packets
-    net.inet.ip.forwarding=1
-    net.inet6.ip6.forwarding=1
-
-**Reboot** or use ``sysctl`` to apply the same config to the running
-system
-
-Install rc.d init files
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    cp pkgsrc/*.sh /etc/rc.d/
-    chmod 555 /etc/rc.d/*.sh
-
-Enable FRR processes
-^^^^^^^^^^^^^^^^^^^^
-
-(Enable the required processes only)
-
-::
-
-    echo "zebra=YES" >> /etc/rc.conf
-    echo "bgpd=YES" >> /etc/rc.conf
-    echo "ospfd=YES" >> /etc/rc.conf
-    echo "ospf6d=YES" >> /etc/rc.conf
-    echo "isisd=YES" >> /etc/rc.conf
-    echo "ripngd=YES" >> /etc/rc.conf
-    echo "ripd=YES" >> /etc/rc.conf
-    echo "pimd=YES" >> /etc/rc.conf
diff --git a/doc/developer/building-frr-on-netbsd7.rst b/doc/developer/building-frr-on-netbsd7.rst
deleted file mode 100644 (file)
index 86242ef..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-NetBSD 7
-========================================
-
-NetBSD 7 restrictions:
-----------------------
-
--  MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel
-   (4.5 or higher). LDP can be built, but may have limited use without
-   MPLS
-
-Install required packages
--------------------------
-
-::
-
-    sudo pkgin install git autoconf automake libtool gmake gawk openssl \
-       pkg-config json-c python27 py27-test python35 py-sphinx
-
-Install SSL Root Certificates (for git https access):
-
-::
-
-    sudo pkgin install mozilla-rootcerts
-    sudo touch /etc/openssl/openssl.cnf
-    sudo mozilla-rootcerts install
-
-Select default Python and py.test
-
-::
-
-    sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python
-    sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo groupadd -g 92 frr
-    sudo groupadd -g 93 frrvty
-    sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \
-        -d /nonexistent -s /sbin/nologin frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    MAKE=gmake
-    export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
-    export CPPFLAGS="-I/usr/pkg/include"
-    ./configure \
-        --sysconfdir=/usr/pkg/etc/frr \
-        --enable-exampledir=/usr/pkg/share/examples/frr \
-        --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
-        --localstatedir=/var/run/frr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    gmake
-    gmake check
-    sudo gmake install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo mkdir /usr/pkg/etc/frr
-    sudo touch /usr/pkg/etc/frr/zebra.conf
-    sudo touch /usr/pkg/etc/frr/bgpd.conf
-    sudo touch /usr/pkg/etc/frr/ospfd.conf
-    sudo touch /usr/pkg/etc/frr/ospf6d.conf
-    sudo touch /usr/pkg/etc/frr/isisd.conf
-    sudo touch /usr/pkg/etc/frr/ripd.conf
-    sudo touch /usr/pkg/etc/frr/ripngd.conf
-    sudo touch /usr/pkg/etc/frr/pimd.conf
-    sudo chown -R frr:frr /usr/pkg/etc/frr
-    sudo touch /usr/local/etc/frr/vtysh.conf
-    sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf
-    sudo chmod 640 /usr/pkg/etc/frr/*.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Add the following lines to the end of ``/etc/sysctl.conf``:
-
-::
-
-    # Routing: We need to forward packets
-    net.inet.ip.forwarding=1
-    net.inet6.ip6.forwarding=1
-
-**Reboot** or use ``sysctl`` to apply the same config to the running
-system
-
-Install rc.d init files
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    cp pkgsrc/*.sh /etc/rc.d/
-    chmod 555 /etc/rc.d/*.sh
-
-Enable FRR processes
-^^^^^^^^^^^^^^^^^^^^
-
-(Enable the required processes only)
-
-::
-
-    echo "zebra=YES" >> /etc/rc.conf
-    echo "bgpd=YES" >> /etc/rc.conf
-    echo "ospfd=YES" >> /etc/rc.conf
-    echo "ospf6d=YES" >> /etc/rc.conf
-    echo "isisd=YES" >> /etc/rc.conf
-    echo "ripngd=YES" >> /etc/rc.conf
-    echo "ripd=YES" >> /etc/rc.conf
-    echo "pimd=YES" >> /etc/rc.conf
diff --git a/doc/developer/building-frr-on-omnios.rst b/doc/developer/building-frr-on-omnios.rst
deleted file mode 100644 (file)
index 03f3845..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-OmniOS (OpenSolaris)
-====================================================
-
-OmniOS restrictions:
---------------------
-
--  MPLS is not supported on ``OmniOS`` or ``Solaris``. MPLS requires a
-   Linux Kernel (4.5 or higher). LDP can be built, but may have limited
-   use without MPLS
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    routeadm -e ipv4-forwarding
-    routeadm -e ipv6-forwarding
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    pkg install \
-      developer/build/autoconf \
-      developer/build/automake \
-      developer/lexer/flex \
-      developer/parser/bison \
-      developer/object-file \
-      developer/linker \
-      developer/library/lint \
-      developer/build/gnu-make \
-      developer/gcc51 \
-      library/idnkit \
-      library/idnkit/header-idnkit \
-      system/header \
-      system/library/math/header-math \
-      git libtool gawk pkg-config
-
-Add additional Solaris packages:
-
-::
-
-    pkgadd -d http://get.opencsw.org/now
-    /opt/csw/bin/pkgutil -U
-    /opt/csw/bin/pkgutil -y -i texinfo
-    /opt/csw/bin/pkgutil -y -i perl
-    /opt/csw/bin/pkgutil -y -i libjson_c_dev
-    /opt/csw/bin/pkgutil -y -i python27 py_pip python27_dev
-
-Add libjson to Solaris equivalent of ld.so.conf
-
-::
-
-    crle -l /opt/csw/lib -u
-
-Add pytest:
-
-::
-
-    pip install pytest
-
-Install Sphinx:::
-
-   pip install sphinx
-
-Select Python 2.7 as default (required for pytest)
-
-::
-
-    rm -f /usr/bin/python
-    ln -s /opt/csw/bin/python2.7 /usr/bin/python
-
-Fix PATH for all users and non-interactive sessions. Edit
-``/etc/default/login`` and add the following default PATH:
-
-::
-
-    PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin
-
-Edit ``~/.profile`` and add the following default PATH:
-
-::
-
-    PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr group and user
-^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo groupadd -g 93 frr
-    sudo groupadd -g 94 frrvty
-    sudo useradd -g 93 -u 93 -G frrvty -c "FRR suite" \
-        -d /nonexistent -s /bin/false frr
-
-(You may prefer different options on configure statement. These are just
-an example)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    export MAKE=gmake
-    export LDFLAGS="-L/opt/csw/lib"
-    export CPPFLAGS="-I/opt/csw/include"
-    export PKG_CONFIG_PATH=/opt/csw/lib/pkgconfig
-    ./configure \
-        --sysconfdir=/etc/frr \
-        --enable-exampledir=/usr/share/doc/frr/examples/ \
-        --localstatedir=/var/run/frr \
-        --sbindir=/usr/lib/frr \
-        --enable-vtysh \
-        --enable-watchfrr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    gmake
-    gmake check
-    sudo gmake install
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    routeadm -e ipv4-forwarding
-    routeadm -e ipv6-forwarding
diff --git a/doc/developer/building-frr-on-openbsd6.rst b/doc/developer/building-frr-on-openbsd6.rst
deleted file mode 100644 (file)
index 46db25a..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-OpenBSD 6
-=========================================
-
-Install required packages
--------------------------
-
-Configure PKG\_PATH
-
-::
-
-    export PKG_PATH=http://ftp5.usa.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(machine -a)/
-
-Add packages:
-
-::
-
-    pkg_add git autoconf-2.69p2 automake-1.15.1 libtool bison
-    pkg_add gmake gawk dejagnu openssl json-c py-test py-sphinx
-
-Select Python2.7 as default (required for pytest)
-
-::
-
-    ln -s /usr/local/bin/python2.7 /usr/local/bin/python
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr group and user
-^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    groupadd -g 525 _frr
-    groupadd -g 526 _frrvty
-    useradd -g 525 -u 525 -c "FRR suite" -G _frrvty \
-        -d /nonexistent -s /sbin/nologin _frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    export AUTOCONF_VERSION="2.69"
-    export AUTOMAKE_VERSION="1.15"
-    ./bootstrap.sh
-    export LDFLAGS="-L/usr/local/lib"
-    export CPPFLAGS="-I/usr/local/include"
-    ./configure \
-        --sysconfdir=/etc/frr \
-        --localstatedir=/var/frr \
-        --enable-pimd \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=_frr \
-        --enable-group=_frr \
-        --enable-vty-group=_frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    gmake
-    gmake check
-    doas gmake install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    doas mkdir /var/frr
-    doas chown _frr:_frr /var/frr
-    doas chmod 755 /var/frr
-    doas mkdir /etc/frr
-    doas touch /etc/frr/zebra.conf
-    doas touch /etc/frr/bgpd.conf
-    doas touch /etc/frr/ospfd.conf
-    doas touch /etc/frr/ospf6d.conf
-    doas touch /etc/frr/isisd.conf
-    doas touch /etc/frr/ripd.conf
-    doas touch /etc/frr/ripngd.conf
-    doas touch /etc/frr/pimd.conf
-    doas touch /etc/frr/ldpd.conf
-    doas touch /etc/frr/nhrpd.conf
-    doas chown -R _frr:_frr /etc/frr
-    doas touch /etc/frr/vtysh.conf
-    doas chown -R _frr:_frrvty /etc/frr/vtysh.conf
-    doas chmod 750 /etc/frr
-    doas chmod 640 /etc/frr/*.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Add the following lines to the end of ``/etc/rc.conf``:
-
-::
-
-    net.inet6.ip6.forwarding=1      # 1=Permit forwarding of IPv6 packets
-    net.inet6.ip6.mforwarding=1     # 1=Permit forwarding of IPv6 multicast packets
-    net.inet6.ip6.multipath=1       # 1=Enable IPv6 multipath routing
-
-**Reboot** to apply the config to the system
-
-Enable MPLS Forwarding
-^^^^^^^^^^^^^^^^^^^^^^
-
-To enable MPLS forwarding on a given interface, use the following
-command:
-
-::
-
-    doas ifconfig em0 mpls
-
-Alternatively, to make MPLS forwarding persistent across reboots, add
-the "mpls" keyword in the hostname.\* files of the desired interfaces.
-Example:
-
-::
-
-    cat /etc/hostname.em0
-    inet 10.0.1.1 255.255.255.0 mpls
-
-Install rc.d init files
-^^^^^^^^^^^^^^^^^^^^^^^
-
-(create them in /etc/rc.d - no example are included at this time with
-FRR source)
-
-Example (for zebra - store as ``/etc/rc.d/frr_zebra.sh``)
-
-::
-
-    #!/bin/sh
-    #
-    # $OpenBSD: frr_zebra.rc,v 1.1 2013/04/18 20:29:08 sthen Exp $
-
-    daemon="/usr/local/sbin/zebra -d"
-
-    . /etc/rc.d/rc.subr
-
-    rc_cmd $1
-
-Enable FRR processes
-^^^^^^^^^^^^^^^^^^^^
-
-(Enable the required processes only)
-
-::
-
-    echo "frr_zebra=YES" >> /etc/rc.conf
-    echo "frr_bgpd=YES" >> /etc/rc.conf
-    echo "frr_ospfd=YES" >> /etc/rc.conf
-    echo "frr_ospf6d=YES" >> /etc/rc.conf
-    echo "frr_isisd=YES" >> /etc/rc.conf
-    echo "frr_ripngd=YES" >> /etc/rc.conf
-    echo "frr_ripd=YES" >> /etc/rc.conf
-    echo "frr_pimd=YES" >> /etc/rc.conf
-    echo "frr_ldpd=YES" >> /etc/rc.conf
diff --git a/doc/developer/building-frr-on-ubuntu1204.rst b/doc/developer/building-frr-on-ubuntu1204.rst
deleted file mode 100644 (file)
index 459d411..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-Ubuntu 12.04LTS
-===============================================
-
--  MPLS is not supported on ``Ubuntu 12.04`` with default kernel. MPLS
-   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
-   limited use without MPLS) For an updated Ubuntu Kernel, see
-   http://kernel.ubuntu.com/~kernel-ppa/mainline/
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    apt-get install \
-       git autoconf automake libtool make gawk libreadline-dev texinfo \
-       dejagnu pkg-config libpam0g-dev libjson0-dev flex python-pip \
-       libc-ares-dev python3-dev python3-sphinx install-info
-
-Install newer bison from 14.04 package source (Ubuntu 12.04 package
-source is too old)
-
-::
-
-    mkdir builddir
-    cd builddir
-    wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.dsc
-    wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg.orig.tar.bz2
-    wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.debian.tar.gz
-    tar -jxvf bison_3.0.2.dfsg.orig.tar.bz2
-    cd bison-3.0.2.dfsg/
-    tar xzf ../bison_3.0.2.dfsg-2.debian.tar.gz
-    sudo apt-get build-dep bison
-    debuild -b -uc -us
-    cd ..
-    sudo dpkg -i ./libbison-dev_3.0.2.dfsg-2_amd64.deb ./bison_3.0.2.dfsg-2_amd64.deb
-    cd ..
-    rm -rf builddir
-
-Install newer version of autoconf and automake:
-
-::
-
-    wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
-    tar xvf autoconf-2.69.tar.gz
-    cd autoconf-2.69
-    ./configure --prefix=/usr
-    make
-    sudo make install
-    cd ..
-
-    wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz
-    tar xvf automake-1.15.tar.gz
-    cd automake-1.15
-    ./configure --prefix=/usr
-    make
-    sudo make install
-    cd ..
-
-Install pytest:
-
-::
-
-    pip install pytest
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo groupadd -r -g 92 frr
-    sudo groupadd -r -g 85 frrvty
-    sudo adduser --system --ingroup frr --home /var/run/frr/ \
-       --gecos "FRR suite" --shell /sbin/nologin frr
-    sudo usermod -a -G frrvty frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    ./configure \
-        --prefix=/usr \
-        --enable-exampledir=/usr/share/doc/frr/examples/ \
-        --localstatedir=/var/run/frr \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --enable-pimd \
-        --enable-watchfrr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    make
-    make check
-    sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 755 -o frr -g frr -d /var/log/frr
-    sudo install -m 775 -o frr -g frrvty -d /etc/frr
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
-    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
-other settings)
-
-::
-
-    # Uncomment the next line to enable packet forwarding for IPv4
-    net.ipv4.ip_forward=1
-
-    # Uncomment the next line to enable packet forwarding for IPv6
-    #  Enabling this option disables Stateless Address Autoconfiguration
-    #  based on Router Advertisements for this host
-    net.ipv6.conf.all.forwarding=1
-
-**Reboot** or use ``sysctl -p`` to apply the same config to the running
-system
-
-Install the init.d service
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 755 tools/frr /etc/init.d/frr
-    sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
-    sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
-
-Enable daemons
-^^^^^^^^^^^^^^
-
-| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for
-  those daemons you want to start by systemd.
-| For example.
-
-::
-
-    zebra=yes
-    bgpd=yes
-    ospfd=yes
-    ospf6d=yes
-    ripd=yes
-    ripngd=yes
-    isisd=yes
-
-Start the init.d service
-^^^^^^^^^^^^^^^^^^^^^^^^
-
--  /etc/init.d/frr start
--  use ``/etc/init.d/frr status`` to check its status.
diff --git a/doc/developer/building-frr-on-ubuntu1404.rst b/doc/developer/building-frr-on-ubuntu1404.rst
deleted file mode 100644 (file)
index 681cc30..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-Ubuntu 14.04LTS
-===============================================
-
--  MPLS is not supported on ``Ubuntu 14.04`` with default kernel. MPLS
-   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
-   limited use without MPLS) For an updated Ubuntu Kernel, see
-   http://kernel.ubuntu.com/~kernel-ppa/mainline/
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    apt-get install \
-       git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \
-       pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
-       libc-ares-dev python3-dev python3-sphinx install-info
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo groupadd -r -g 92 frr
-    sudo groupadd -r -g 85 frrvty
-    sudo adduser --system --ingroup frr --home /var/run/frr/ \
-       --gecos "FRR suite" --shell /sbin/nologin frr
-    sudo usermod -a -G frrvty frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    ./configure \
-        --prefix=/usr \
-        --enable-exampledir=/usr/share/doc/frr/examples/ \
-        --localstatedir=/var/run/frr \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --enable-pimd \
-        --enable-watchfrr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --enable-ldpd \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    make
-    make check
-    sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 755 -o frr -g frr -d /var/log/frr
-    sudo install -m 775 -o frr -g frrvty -d /etc/frr
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
-    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
-
-Enable IP & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
-other settings)
-
-::
-
-    # Uncomment the next line to enable packet forwarding for IPv4
-    net.ipv4.ip_forward=1
-
-    # Uncomment the next line to enable packet forwarding for IPv6
-    #  Enabling this option disables Stateless Address Autoconfiguration
-    #  based on Router Advertisements for this host
-    net.ipv6.conf.all.forwarding=1
-
-**Reboot** or use ``sysctl -p`` to apply the same config to the running
-system
-
-Install the init.d service
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 755 tools/frr /etc/init.d/frr
-    sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
-    sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
-
-Enable daemons
-^^^^^^^^^^^^^^
-
-| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for
-  those daemons you want to start by systemd.
-| For example.
-
-::
-
-    zebra=yes
-    bgpd=yes
-    ospfd=yes
-    ospf6d=yes
-    ripd=yes
-    ripngd=yes
-    isisd=yes
-
-Start the init.d service
-^^^^^^^^^^^^^^^^^^^^^^^^
-
--  /etc/init.d/frr start
--  use ``/etc/init.d/frr status`` to check its status.
diff --git a/doc/developer/building-frr-on-ubuntu1604.rst b/doc/developer/building-frr-on-ubuntu1604.rst
deleted file mode 100644 (file)
index 69c4e44..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-Ubuntu 16.04LTS
-===============================================
-
--  MPLS is not supported on ``Ubuntu 16.04`` with default kernel. MPLS
-   requires Linux Kernel 4.5 or higher (LDP can be built, but may have
-   limited use without MPLS) For an updated Ubuntu Kernel, see
-   http://kernel.ubuntu.com/~kernel-ppa/mainline/
-
-Install required packages
--------------------------
-
-Add packages:
-
-::
-
-    apt-get install \
-       git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \
-       pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
-       libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
-       install-info
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo groupadd -r -g 92 frr
-    sudo groupadd -r -g 85 frrvty
-    sudo adduser --system --ingroup frr --home /var/run/frr/ \
-       --gecos "FRR suite" --shell /sbin/nologin frr
-    sudo usermod -a -G frrvty frr
-
-Download Source, configure and compile it
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(You may prefer different options on configure statement. These are just
-an example.)
-
-::
-
-    git clone https://github.com/frrouting/frr.git frr
-    cd frr
-    ./bootstrap.sh
-    ./configure \
-        --prefix=/usr \
-        --enable-exampledir=/usr/share/doc/frr/examples/ \
-        --localstatedir=/var/run/frr \
-        --sbindir=/usr/lib/frr \
-        --sysconfdir=/etc/frr \
-        --enable-pimd \
-        --enable-watchfrr \
-        --enable-ospfclient=yes \
-        --enable-ospfapi=yes \
-        --enable-multipath=64 \
-        --enable-user=frr \
-        --enable-group=frr \
-        --enable-vty-group=frrvty \
-        --enable-configfile-mask=0640 \
-        --enable-logfile-mask=0640 \
-        --enable-rtadv \
-        --enable-fpm \
-        --enable-systemd=yes \
-        --with-pkg-git-version \
-        --with-pkg-extra-version=-MyOwnFRRVersion
-    make
-    make check
-    sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 755 -o frr -g frr -d /var/log/frr
-    sudo install -m 775 -o frr -g frrvty -d /etc/frr
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
-    sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
-    sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf
-
-Enable IPv4 & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
-other settings)
-
-::
-
-    # Uncomment the next line to enable packet forwarding for IPv4
-    net.ipv4.ip_forward=1
-
-    # Uncomment the next line to enable packet forwarding for IPv6
-    #  Enabling this option disables Stateless Address Autoconfiguration
-    #  based on Router Advertisements for this host
-    net.ipv6.conf.all.forwarding=1
-
-Enable MPLS Forwarding (with Linux Kernel >= 4.5)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit ``/etc/sysctl.conf`` and the following lines. Make sure to add a
-line equal to ``net.mpls.conf.eth0.input`` or each interface used with
-MPLS
-
-::
-
-    # Enable MPLS Label processing on all interfaces
-    net.mpls.conf.eth0.input=1
-    net.mpls.conf.eth1.input=1
-    net.mpls.conf.eth2.input=1
-    net.mpls.platform_labels=100000
-
-Add MPLS kernel modules
-^^^^^^^^^^^^^^^^^^^^^^^
-
-Add the following lines to ``/etc/modules-load.d/modules.conf``:
-
-::
-
-    # Load MPLS Kernel Modules
-    mpls-router
-    mpls-iptunnel
-
-**Reboot** or use ``sysctl -p`` to apply the same config to the running
-system
-
-Install the systemd service (if rebooted from last step, change directory back to frr directory)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-    sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
-    sudo install -m 644 tools/etc/default/frr /etc/default/frr
-    sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-    sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
-    sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
-    sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
-
-Enable daemons
-^^^^^^^^^^^^^^
-
-| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for
-  those daemons you want to start by systemd.
-| For example.
-
-::
-
-    zebra=yes
-    bgpd=yes
-    ospfd=yes
-    ospf6d=yes
-    ripd=yes
-    ripngd=yes
-    isisd=yes
-
-Enable the systemd service
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
--  systemctl enable frr
-
-Start the systemd service
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
--  systemctl start frr
--  use ``systemctl status frr`` to check its status.
diff --git a/doc/developer/building-frr-on-ubuntu1804.rst b/doc/developer/building-frr-on-ubuntu1804.rst
deleted file mode 100644 (file)
index 50e90fc..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-Ubuntu 18.04 LTS
-================
-
-Install dependencies
---------------------
-
-Required packages
-^^^^^^^^^^^^^^^^^
-
-::
-
-   sudo apt-get install \
-      git autoconf automake libtool make gawk libreadline-dev texinfo \
-      pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
-      libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
-      install-info
-
-Optional packages
-^^^^^^^^^^^^^^^^^
-
-Dependencies for additional functionality can be installed as-desired.
-
-Protobuf
-~~~~~~~~
-
-::
-
-   sudo apt-get install \
-       protobuf-c-compiler \
-       libprotobuf-c-dev
-
-ZeroMQ
-~~~~~~
-
-::
-
-   sudo apt-get install \
-       libzmq5 \
-       libzmq3-dev
-
-Get FRR, compile it and install it (from Git)
----------------------------------------------
-
-**This assumes you want to build and install FRR from source and not
-using any packages**
-
-Add frr groups and user
-^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-   sudo groupadd -r -g 92 frr
-   sudo groupadd -r -g 85 frrvty
-   sudo adduser --system --ingroup frr --home /var/run/frr/ \
-      --gecos "FRR suite" --shell /sbin/nologin frr
-   sudo usermod -a -G frrvty frr
-
-Download source
-^^^^^^^^^^^^^^^
-
-::
-
-   git clone https://github.com/frrouting/frr.git frr
-
-Configure
-^^^^^^^^^
-Options below are provided as an example.
-
-.. seealso:: *Installation* section of user guide
-
-.. code-block:: shell
-
-   cd frr
-   ./bootstrap.sh
-   ./configure \
-       --prefix=/usr \
-       --enable-exampledir=/usr/share/doc/frr/examples/ \
-       --localstatedir=/var/run/frr \
-       --sbindir=/usr/lib/frr \
-       --sysconfdir=/etc/frr \
-       --enable-pimd \
-       --enable-watchfrr \
-       --enable-ospfclient=yes \
-       --enable-ospfapi=yes \
-       --enable-multipath=64 \
-       --enable-user=frr \
-       --enable-group=frr \
-       --enable-vty-group=frrvty \
-       --enable-configfile-mask=0640 \
-       --enable-logfile-mask=0640 \
-       --enable-rtadv \
-       --enable-fpm \
-       --enable-systemd=yes \
-       --with-pkg-git-version \
-       --with-pkg-extra-version=-MyOwnFRRVersion
-
-If optional packages were installed, the associated feature may now be
-enabled.
-
-.. option:: --enable-protobuf
-
-Enable support for protobuf transport
-
-.. option:: --enable-zeromq
-
-Enable support for ZeroMQ transport
-
-Compile
-^^^^^^^
-
-::
-
-   make
-   make check
-   sudo make install
-
-Create empty FRR configuration files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Although not strictly necessary, it's good practice to create empty
-configuration files _before_ starting FRR. This assures that the permissions 
-are correct. If the files are not already present, FRR will create them.
-
-It's also important to consider _which_ files to create. FRR supports writing
-configuration to a monolithic file, :file:`/etc/frr/frr.conf`.
-
-.. seealso:: *VTYSH* section of user guide
-
-The presence of :file:`/etc/frr/frr.conf` on startup implicitly configures FRR
-to ignore daemon-specific configuration files.
-
-Daemon-specific configuration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-   sudo install -m 755 -o frr -g frr -d /var/log/frr
-   sudo install -m 775 -o frr -g frrvty -d /etc/frr
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
-
-Monolithic configuration
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-   sudo install -m 755 -o frr -g frr -d /var/log/frr
-   sudo install -m 775 -o frr -g frrvty -d /etc/frr
-   sudo install -m 640 -o frr -g frr /dev/null /etc/frr/frr.conf
-
-Enable IPv4 & IPv6 forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Edit :file:`/etc/sysctl.conf` and uncomment the following values (ignore the
-other settings):
-
-::
-
-   # Uncomment the next line to enable packet forwarding for IPv4
-   net.ipv4.ip_forward=1
-
-   # Uncomment the next line to enable packet forwarding for IPv6
-   #  Enabling this option disables Stateless Address Autoconfiguration
-   #  based on Router Advertisements for this host
-   net.ipv6.conf.all.forwarding=1
-
-Add MPLS kernel modules
-^^^^^^^^^^^^^^^^^^^^^^^
-
-Ubuntu 18.04 ships with kernel 4.15. MPLS modules are present by default.  To
-enable, add the following lines to :file:`/etc/modules-load.d/modules.conf`:
-
-::
-
-   # Load MPLS Kernel Modules
-   mpls_router
-   mpls_iptunnel
-
-Reboot or use ``sysctl -p`` to apply the same config to the running system.
-
-Enable MPLS Forwarding
-^^^^^^^^^^^^^^^^^^^^^^
-
-Edit :file:`/etc/sysctl.conf` and the following lines. Make sure to add a line
-equal to :file:`net.mpls.conf.eth0.input` for each interface used with MPLS.
-
-::
-
-   # Enable MPLS Label processing on all interfaces
-   net.mpls.conf.eth0.input=1
-   net.mpls.conf.eth1.input=1
-   net.mpls.conf.eth2.input=1
-   net.mpls.platform_labels=100000
-
-Install the systemd service
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
-   sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
-   sudo install -m 644 tools/etc/default/frr /etc/default/frr
-   sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
-   sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
-   sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
-   sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
-
-Enable daemons
-^^^^^^^^^^^^^^
-
-Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for those
-daemons you want to start by systemd.  For example:
-
-::
-
-   zebra=yes
-   bgpd=yes
-   ospfd=yes
-   ospf6d=yes
-   ripd=yes
-   ripngd=yes
-   isisd=yes
-
-Enable the systemd service
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Enabling the systemd service causes FRR to be started upon boot. To enable it,
-use the following command:
-
-.. code-block:: shell
-
-   systemctl enable frr
-
-Start the systemd service
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: shell
-
-   systemctl start frr
-
-After starting the service, you can use ``systemctl status frr`` to check its
-status.
index d145849f7f6c5ba3c4a8604c53c44634b8dd531e..4c18445f9d1893b4f4d609884127649665f8535e 100644 (file)
@@ -7,21 +7,21 @@ Building FRR
 .. toctree::
    :maxdepth: 2
 
-   building-frr-on-alpine
-   building-frr-on-centos6
-   building-frr-on-centos7
-   building-frr-on-debian8
-   building-frr-on-debian9
-   building-frr-on-fedora24
-   building-frr-on-freebsd10
-   building-frr-on-freebsd11
-   building-frr-on-freebsd9
-   building-frr-on-netbsd6
-   building-frr-on-netbsd7
-   building-frr-on-omnios
-   building-frr-on-openbsd6
+   building-frr-for-alpine
+   building-frr-for-centos6
+   building-frr-for-centos7
+   building-frr-for-debian8
+   building-frr-for-debian9
+   building-frr-for-fedora24
+   building-frr-for-freebsd10
+   building-frr-for-freebsd11
+   building-frr-for-freebsd9
+   building-frr-for-netbsd6
+   building-frr-for-netbsd7
+   building-frr-for-omnios
+   building-frr-for-openbsd6
    building-frr-for-openwrt
-   building-frr-on-ubuntu1204
-   building-frr-on-ubuntu1404
-   building-frr-on-ubuntu1604
-   building-frr-on-ubuntu1804
+   building-frr-for-ubuntu1204
+   building-frr-for-ubuntu1404
+   building-frr-for-ubuntu1604
+   building-frr-for-ubuntu1804
index 20391c47bcfe52e663be3d1b3d19d5e1caa520d6..c0716a5c9319cf0f7ae3deb89fb28e9e45b66e88 100644 (file)
@@ -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/developer/subdir.am b/doc/developer/subdir.am
new file mode 100644 (file)
index 0000000..43d1290
--- /dev/null
@@ -0,0 +1,72 @@
+#
+# doc/developer
+#
+
+dev_RSTFILES = \
+       doc/developer/bgp-typecodes.rst \
+       doc/developer/bgpd.rst \
+       doc/developer/building-frr-for-openwrt.rst \
+       doc/developer/building-frr-for-alpine.rst \
+       doc/developer/building-frr-for-centos6.rst \
+       doc/developer/building-frr-for-centos7.rst \
+       doc/developer/building-frr-for-debian8.rst \
+       doc/developer/building-frr-for-debian9.rst \
+       doc/developer/building-frr-for-fedora24.rst \
+       doc/developer/building-frr-for-freebsd10.rst \
+       doc/developer/building-frr-for-freebsd11.rst \
+       doc/developer/building-frr-for-freebsd9.rst \
+       doc/developer/building-frr-for-netbsd6.rst \
+       doc/developer/building-frr-for-netbsd7.rst \
+       doc/developer/building-frr-for-omnios.rst \
+       doc/developer/building-frr-for-openbsd6.rst \
+       doc/developer/building-frr-for-ubuntu1204.rst \
+       doc/developer/building-frr-for-ubuntu1404.rst \
+       doc/developer/building-frr-for-ubuntu1604.rst \
+       doc/developer/building-frr-for-ubuntu1804.rst \
+       doc/developer/building.rst \
+       doc/developer/cli.rst \
+       doc/developer/conf.py \
+       doc/developer/hooks.rst \
+       doc/developer/index.rst \
+       doc/developer/library.rst \
+       doc/developer/logging.rst \
+       doc/developer/maintainer-release-build.rst \
+       doc/developer/memtypes.rst \
+       doc/developer/modules.rst \
+       doc/developer/next-hop-tracking.rst \
+       doc/developer/ospf-api.rst \
+       doc/developer/ospf-sr.rst \
+       doc/developer/ospf.rst \
+       doc/developer/workflow.rst \
+       doc/developer/zebra.rst \
+       # end
+
+EXTRA_DIST += \
+       $(dev_RSTFILES) \
+       doc/developer/draft-zebra-00.ms \
+       doc/developer/ldpd-basic-test-setup.md \
+       # end
+
+DEVBUILD = doc/developer/_build
+$(DEVBUILD)/.doctrees/environment.pickle: $(dev_RSTFILES)
+
+#
+# nothing built automatically for "all" target.
+#
+
+#
+# standard targets
+#
+
+developer-info: $(DEVBUILD)/texinfo/frr.info
+developer-html: $(DEVBUILD)/html/.buildinfo
+developer-pdf:  $(DEVBUILD)/latexpdf
+
+#
+# hook-in for clean
+#
+
+.PHONY: clean-devdocs
+clean-local: clean-devdocs
+clean-devdocs:
+       -rm -rf "$(DEVBUILD)"
diff --git a/doc/frr-sphinx.mk b/doc/frr-sphinx.mk
deleted file mode 100644 (file)
index 3e4c67d..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# Sphinx is not designed to be invoked multiple times against the same toctree.
-.NOTPARALLEL:
-
-# You can set these variables from the command line.
-SPHINXOPTS    ?=
-SPHINXBUILD   ?= sphinx-build
-PAPER         ?=
-BUILDDIR      = _build
-
-# This is a custom FRR variable just for this docs subdirectory used to support
-# VPATH builds. Makefiles which include this file should override it to point
-# to the correct sources path.
-SOURCESDIR    ?= .
-
-# User-friendly check for sphinx-build
-ifneq ($(MAKECMDGOALS), clean)
-    ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-        SPHINXBUILD = sphinx-1.0-build
-    endif
-    ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-        $(error "The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/")
-    endif
-endif
-
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCESDIR)
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCESDIR)
-
-.PHONY: help
-help:
-       @echo "Please use \`make <target>' where <target> is one of"
-       @echo "  html       to make standalone HTML files"
-       @echo "  dirhtml    to make HTML files named index.html in directories"
-       @echo "  singlehtml to make a single large HTML file"
-       @echo "  pickle     to make pickle files"
-       @echo "  json       to make JSON files"
-       @echo "  htmlhelp   to make HTML files and a HTML help project"
-       @echo "  qthelp     to make HTML files and a qthelp project"
-       @echo "  applehelp  to make an Apple Help Book"
-       @echo "  devhelp    to make HTML files and a Devhelp project"
-       @echo "  epub       to make an epub"
-       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
-       @echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
-       @echo "  text       to make text files"
-       @echo "  man        to make manual pages"
-       @echo "  texinfo    to make Texinfo files"
-       @echo "  info       to make Texinfo files and run them through makeinfo"
-       @echo "  gettext    to make PO message catalogs"
-       @echo "  changes    to make an overview of all changed/added/deprecated items"
-       @echo "  xml        to make Docutils-native XML files"
-       @echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
-       @echo "  linkcheck  to check all external links for integrity"
-       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
-       @echo "  coverage   to run coverage check of the documentation (if enabled)"
-
-.PHONY: clean
-clean:
-       rm -rf $(BUILDDIR)/*
-
-.PHONY: html
-html:
-       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-       @echo
-       @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-.PHONY: dirhtml
-dirhtml:
-       $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-       @echo
-       @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-.PHONY: singlehtml
-singlehtml:
-       $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
-       @echo
-       @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-.PHONY: pickle
-pickle:
-       $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-       @echo
-       @echo "Build finished; now you can process the pickle files."
-
-.PHONY: json
-json:
-       $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-       @echo
-       @echo "Build finished; now you can process the JSON files."
-
-.PHONY: htmlhelp
-htmlhelp:
-       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-       @echo
-       @echo "Build finished; now you can run HTML Help Workshop with the" \
-             ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-.PHONY: qthelp
-qthelp:
-       $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-       @echo
-       @echo "Build finished; now you can run "qcollectiongenerator" with the" \
-             ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-       @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FRR.qhcp"
-       @echo "To view the help file:"
-       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FRR.qhc"
-
-.PHONY: applehelp
-applehelp:
-       $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
-       @echo
-       @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
-       @echo "N.B. You won't be able to view it unless you put it in" \
-             "~/Library/Documentation/Help or install it in your application" \
-             "bundle."
-
-.PHONY: devhelp
-devhelp:
-       $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
-       @echo
-       @echo "Build finished."
-       @echo "To view the help file:"
-       @echo "# mkdir -p $$HOME/.local/share/devhelp/FRR"
-       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FRR"
-       @echo "# devhelp"
-
-.PHONY: epub
-epub:
-       $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
-       @echo
-       @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-.PHONY: latex
-latex:
-       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-       @echo
-       @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-       @echo "Run \`make' in that directory to run these through (pdf)latex" \
-             "(use \`make latexpdf' here to do that automatically)."
-
-.PHONY: latexpdf
-latexpdf:
-       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-       @echo "Running LaTeX files through pdflatex..."
-       $(MAKE) -C $(BUILDDIR)/latex all-pdf
-       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-.PHONY: latexpdfja
-latexpdfja:
-       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-       @echo "Running LaTeX files through platex and dvipdfmx..."
-       $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
-       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-.PHONY: text
-text:
-       $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
-       @echo
-       @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-.PHONY: man
-man:
-       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
-       @echo
-       @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-.PHONY: texinfo
-texinfo:
-       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-       @echo
-       @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
-       @echo "Run \`make' in that directory to run these through makeinfo" \
-             "(use \`make info' here to do that automatically)."
-
-.PHONY: info
-info:
-       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-       @echo "Running Texinfo files through makeinfo..."
-       $(MAKE) -C $(BUILDDIR)/texinfo info
-       @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-.PHONY: gettext
-gettext:
-       $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
-       @echo
-       @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-.PHONY: changes
-changes:
-       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-       @echo
-       @echo "The overview file is in $(BUILDDIR)/changes."
-
-.PHONY: linkcheck
-linkcheck:
-       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-       @echo
-       @echo "Link check complete; look for any errors in the above output " \
-             "or in $(BUILDDIR)/linkcheck/output.txt."
-
-.PHONY: doctest
-doctest:
-       $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-       @echo "Testing of doctests in the sources finished, look at the " \
-             "results in $(BUILDDIR)/doctest/output.txt."
-
-.PHONY: coverage
-coverage:
-       $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
-       @echo "Testing of coverage in the sources finished, look at the " \
-             "results in $(BUILDDIR)/coverage/python.txt."
-
-.PHONY: xml
-xml:
-       $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
-       @echo
-       @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
-
-.PHONY: pseudoxml
-pseudoxml:
-       $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
-       @echo
-       @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/doc/manpages/Makefile b/doc/manpages/Makefile
new file mode 100644 (file)
index 0000000..7cccfa2
--- /dev/null
@@ -0,0 +1,12 @@
+all: ALWAYS
+       @$(MAKE) -s -C ../.. doc/manpages/man.stamp
+help: ALWAYS
+       @$(MAKE) -s -C ../.. doc/help
+%: ALWAYS
+       @$(MAKE) -s -C ../.. doc/manpages/_build/$@
+
+Makefile:
+       #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
deleted file mode 100644 (file)
index 009c723..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-# This is necessary to support VPATH builds.
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-# This variable is used as the documentation source location in frr-sphinx.mk
-SOURCESDIR = @srcdir@
-
-include @srcdir@/../frr-sphinx.mk
-
-# -----------------------------------------------------------------------------
-# Automake requires that 3rd-party Makefiles recognize these targets.
-# -----------------------------------------------------------------------------
-# install
-# install-data
-# install-exec
-# uninstall
-# install-dvi
-# install-html
-# install-info
-# install-ps
-# install-pdf
-# installdirs
-# check
-# installcheck
-# mostlyclean
-# clean
-# distclean
-# maintainer-clean
-# dvi
-# pdf
-# ps
-# info
-# html
-# tags
-# ctags
-
-# These targets are automatically generated by Sphinx but conflict with
-# implicitly defined Automake rules, so we manually override them to nothing.
-# The other option is deleting the Sphinx-generated rules, which suppresses the
-# warning but kinda screws up the symmetry between Makefiles.
-info: ;
-html: ;
-
-all: man
-
-install-data: man
-
-install: install-data
index 5fff6fca6651cd6014b6ca42da0b745ce1357269..74d3eb7bbdccb605e79cf65151c4e08cbc11a5f2 100644 (file)
@@ -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.
 
index e540d236ea147d42331c0b0cdbda6cda4d8f75b0..f57bc1d27868eecc379211746d44bad55e19ef32 100644 (file)
@@ -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 (file)
index 0000000..c14c076
--- /dev/null
@@ -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
+
index c62835c7701f3588a63902459e0d92b0f775e5ce..053555c4e4274205a4d41aa02e6f21e83d522989 100644 (file)
@@ -10,6 +10,7 @@
    bgpd
    eigrpd
    isisd
+   fabricd
    ldpd
    nhrpd
    ospf6d
diff --git a/doc/manpages/subdir.am b/doc/manpages/subdir.am
new file mode 100644 (file)
index 0000000..4a9aa4d
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# doc/manpages
+#
+
+man_RSTFILES = \
+       doc/manpages/bgpd.rst \
+       doc/manpages/common-options.rst \
+       doc/manpages/conf.py \
+       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 \
+       doc/manpages/ldpd.rst \
+       doc/manpages/mtracebis.rst \
+       doc/manpages/nhrpd.rst \
+       doc/manpages/ospf6d.rst \
+       doc/manpages/ospfclient.rst \
+       doc/manpages/ospfd.rst \
+       doc/manpages/pimd.rst \
+       doc/manpages/ripd.rst \
+       doc/manpages/pbrd.rst \
+       doc/manpages/ripngd.rst \
+       doc/manpages/sharpd.rst \
+       doc/manpages/staticd.rst \
+       doc/manpages/vtysh.rst \
+       doc/manpages/watchfrr.rst \
+       doc/manpages/zebra.rst \
+       doc/manpages/bfdd.rst \
+       doc/manpages/bfd-options.rst \
+       # end
+
+EXTRA_DIST += $(man_RSTFILES)
+
+MANBUILD = doc/manpages/_build/man
+doc/manpages/_build/.doctrees/environment.pickle: $(man_RSTFILES)
+
+#
+# automake integration
+#
+
+rstman1dir = $(mandir)/man1
+rstman8dir = $(mandir)/man8
+
+rstman1_DATA =
+rstman8_DATA =
+
+if DOC
+rstman1_DATA += $(man1)
+rstman8_DATA += $(man8)
+endif # DOC
+
+man1 = $(MANBUILD)/frr.1
+man8 =
+
+# dependency
+$(man8) $(man1): $(MANBUILD)/man.stamp
+
+#
+# hook-ins for clean / doc
+# (install is handled by automake _DATA)
+#
+
+clean-local: clean-manpages
+.PHONY: clean-manpages
+clean-manpages:
+       -rm -rf $(MANBUILD)
+
+doc: doc-man
+.PHONY: doc-man
+doc-man: $(rstman8_DATA) $(rstman1_DATA)
diff --git a/doc/mpls/.gitignore b/doc/mpls/.gitignore
deleted file mode 100644 (file)
index b0a4a46..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-.arch-ids
-.arch-inventory
-*~
-*.loT
-
diff --git a/doc/subdir.am b/doc/subdir.am
new file mode 100644 (file)
index 0000000..4170101
--- /dev/null
@@ -0,0 +1,176 @@
+#
+# doc
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+PAPER         ?=
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
+
+###
+
+AM_V_SPHINX = $(am__v_SPHINX_$(V))
+am__v_SPHINX_ = $(am__v_SPHINX_$(AM_DEFAULT_VERBOSITY))
+am__v_SPHINX_0 = @echo "  SPHINX  " $@;
+am__v_SPHINX_1 =
+AM_V_MAKEINFO = $(am__v_MAKEINFO_$(V))
+am__v_MAKEINFO_ = $(am__v_MAKEINFO_$(AM_DEFAULT_VERBOSITY))
+am__v_MAKEINFO_0 = @echo "  MAKEINFO" $@;
+am__v_MAKEINFO_1 =
+
+#
+# real-file sphinx targets that work for dependencies
+#
+
+doc/%/_build/.doctrees/environment.pickle:
+       $(AM_V_SPHINX) ( \
+               subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \
+               $(SPHINXBUILD) -a -q -b text -d "$${subdoc}/_build/.doctrees" \
+                       $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/text" \
+       )
+doc/%/_build/html/.buildinfo: doc/%/_build/.doctrees/environment.pickle
+       $(AM_V_SPHINX) ( \
+               subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \
+               $(SPHINXBUILD) -q -b html -d "$${subdoc}/_build/.doctrees" \
+                       $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/html" \
+       )
+.PRECIOUS: doc/%/_build/texinfo/frr.texi
+doc/%/_build/texinfo/frr.texi: doc/%/_build/.doctrees/environment.pickle
+       $(AM_V_SPHINX) ( \
+               subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \
+               $(SPHINXBUILD) -q -b texinfo -d "$${subdoc}/_build/.doctrees" \
+                       $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/texinfo" \
+       )
+doc/%/_build/texinfo/frr.info: doc/%/_build/texinfo/frr.texi
+       $(AM_V_MAKEINFO)$(MAKEINFO) --no-split -o '$@' '$<'
+doc/%/_build/man/man.stamp: doc/%/_build/.doctrees/environment.pickle
+       $(AM_V_SPHINX) ( \
+               subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \
+               $(MKDIR_P) "$${subdoc}/_build/man"; touch $@.tmp; \
+               $(SPHINXBUILD) -a -q -b man -d "$${subdoc}/_build/.doctrees" \
+                       $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/man" && \
+                       mv $@.tmp $@ \
+       )
+
+#
+# auxiliary sphinx targets (output name = directory,
+# deps will not work very well)
+#
+
+SPHINXTARGETS = \
+         html dirhtml singlehtml pickle json \
+         htmlhelp qthelp applehelp devhelp \
+         epub latex text man texinfo gettext \
+         changes linkcheck doctest coverage \
+         xml pseudoxml \
+         # end
+
+M_SPHINXTARGETS = $(addprefix doc/%/_build/,$(SPHINXTARGETS))
+.PRECIOUS: $(M_SPHINXTARGETS)
+$(M_SPHINXTARGETS): doc/%/_build/.doctrees/environment.pickle
+       $(AM_V_SPHINX) ( \
+               target="$@"; \
+               builder="$${target##*/}"; \
+               subdoc="$${target#doc/}"; subdoc="doc/$${subdoc%%/*}"; \
+               rm -rf "$@"; \
+               $(SPHINXBUILD) -q -b $${builder} -d $${subdoc}/_build/.doctrees \
+                       $(ALLSPHINXOPTS) $(top_srcdir)/$${subdoc} $@ \
+       )
+
+.PHONY: doc/%/_build/latexpdf
+doc/%/_build/latexpdf: doc/%/_build/latex
+       @make -C $< all-pdf
+
+# If you want to build the developer's docs in other formats, try the
+# following:
+#
+# $ cd developer
+# $ make help
+
+# dist tarballs want doc sources
+EXTRA_DIST += \
+       doc/mpls/ChangeLog.opaque.txt \
+       doc/mpls/ospfd.conf \
+       doc/mpls/cli_summary.txt \
+       doc/mpls/opaque_lsa.txt \
+       doc/figures/cligraph.png \
+       doc/figures/cligraph.svg \
+       doc/figures/fig-normal-processing.dia \
+       doc/figures/fig-normal-processing.png \
+       doc/figures/fig-normal-processing.txt \
+       doc/figures/fig-rs-processing.dia \
+       doc/figures/fig-rs-processing.png \
+       doc/figures/fig-rs-processing.txt \
+       doc/figures/fig_topologies_full.dia \
+       doc/figures/fig_topologies_full.png \
+       doc/figures/fig_topologies_full.txt \
+       doc/figures/fig_topologies_rs.dia \
+       doc/figures/fig_topologies_rs.png \
+       doc/figures/fig_topologies_rs.txt \
+       doc/figures/fig-vnc-commercial-route-reflector.dia \
+       doc/figures/fig-vnc-commercial-route-reflector.png \
+       doc/figures/fig-vnc-commercial-route-reflector.txt \
+       doc/figures/fig-vnc-frr-route-reflector.dia \
+       doc/figures/fig-vnc-frr-route-reflector.png \
+       doc/figures/fig-vnc-frr-route-reflector.txt \
+       doc/figures/fig-vnc-gw.dia \
+       doc/figures/fig-vnc-gw.png \
+       doc/figures/fig-vnc-gw-rr.dia \
+       doc/figures/fig-vnc-gw-rr.png \
+       doc/figures/fig-vnc-gw-rr.txt \
+       doc/figures/fig-vnc-gw.txt \
+       doc/figures/fig-vnc-mesh.dia \
+       doc/figures/fig-vnc-mesh.png \
+       doc/figures/fig-vnc-mesh.txt \
+       doc/figures/fig-vnc-redundant-route-reflectors.dia \
+       doc/figures/fig-vnc-redundant-route-reflectors.png \
+       doc/figures/fig-vnc-redundant-route-reflectors.txt \
+       doc/figures/frr-icon.svg \
+       doc/figures/frr-logo-icon.png \
+       doc/figures/frr-logo-medium.png \
+       doc/figures/frr-logo.png \
+       doc/figures/frr-logo-small.png \
+       doc/figures/git_branches.png \
+       doc/figures/git_branches.svg \
+       doc/figures/ospf_api_architecture.png \
+       doc/figures/ospf_api_msghdr.png \
+       doc/figures/ospf_api_msgs1.png \
+       doc/figures/ospf_api_msgs2.png \
+       doc/extra/frrlexer.py \
+       # end
+
+
+.PHONY: doc/help
+doc/help:
+       @echo "Please use \`make doc/{user,manpages,developer}/<target>' where <target> is one of"
+       @echo "  html       to make standalone HTML files"
+       @echo "  dirhtml    to make HTML files named index.html in directories"
+       @echo "  singlehtml to make a single large HTML file"
+       @echo "  pickle     to make pickle files"
+       @echo "  json       to make JSON files"
+       @echo "  htmlhelp   to make HTML files and a HTML help project"
+       @echo "  qthelp     to make HTML files and a qthelp project"
+       @echo "  applehelp  to make an Apple Help Book"
+       @echo "  devhelp    to make HTML files and a Devhelp project"
+       @echo "  epub       to make an epub"
+       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+       @echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+       @echo "  text       to make text files"
+       @echo "  man        to make manual pages"
+       @echo "  texinfo    to make Texinfo files"
+       @echo "  info       to make Texinfo files and run them through makeinfo"
+       @echo "  gettext    to make PO message catalogs"
+       @echo "  changes    to make an overview of all changed/added/deprecated items"
+       @echo "  xml        to make Docutils-native XML files"
+       @echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
+       @echo "  linkcheck  to check all external links for integrity"
+       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+       @echo "  coverage   to run coverage check of the documentation (if enabled)"
diff --git a/doc/user/Makefile b/doc/user/Makefile
new file mode 100644 (file)
index 0000000..840ee5b
--- /dev/null
@@ -0,0 +1,16 @@
+all: ALWAYS
+       @$(MAKE) -s -C ../.. doc-user
+help: ALWAYS
+       @$(MAKE) -s -C ../.. doc/help
+pdf: ALWAYS
+       @$(MAKE) -s -C ../.. doc/user/_build/latexpdf
+info: ALWAYS
+       @$(MAKE) -s -C ../.. doc/user/_build/texinfo/frr.info
+%: ALWAYS
+       @$(MAKE) -s -C ../.. doc/user/_build/$@
+
+Makefile:
+       #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/doc/user/Makefile.am b/doc/user/Makefile.am
deleted file mode 100644 (file)
index 64af2ff..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-# This is necessary to support VPATH builds.
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-# This variable is used as the documentation source location in frr-sphinx.mk
-SOURCESDIR = @srcdir@
-
-include @srcdir@/../frr-sphinx.mk
-
-# -----------------------------------------------------------------------------
-# Automake requires that 3rd-party Makefiles recognize these targets.
-# -----------------------------------------------------------------------------
-# install
-# install-data
-# install-exec
-# uninstall
-# install-dvi
-# install-html
-# install-info
-# install-ps
-# install-pdf
-# installdirs
-# check
-# installcheck
-# mostlyclean
-# clean
-# distclean
-# maintainer-clean
-# dvi
-# pdf
-# ps
-# info
-# html
-# tags
-# ctags
-
-# When building 'all', the logic is that we want to make docs that are easily
-# readable by the person that just built them. Technically the reST source is
-# readable in its own right, but we'll also build info and html because those
-# offer sequentially better reading experiences. PDF is not built by default
-# because it takes quite a while.
-all: info
-
-# info and html already have built-in sphinx rules; pdf goes to latexpdf
-pdf: latexpdf
-
-# install user manual as info file
-install-info: info
-       install -d ${DESTDIR}${infodir}
-       gzip < _build/texinfo/frr.info > ${DESTDIR}${infodir}/frr.info.gz
-       install-info _build/texinfo/frr.info ${DESTDIR}${infodir}/dir
-
-install-data: install-info
-
-install: install-data
index 3143f8bb65300ca05d0657e3d1bdfadfe7dc039a..41fcc66f8d2e4ca69e0efe7709d1462c5a5c57b5 100644 (file)
@@ -19,11 +19,6 @@ table.mark th {
 table.mark td {
     vertical-align: middle;
 }
-table.mark td[colspan="7"] {
-    text-align: center;
-    padding-top: 8pt;
-    padding-bottom: 2pt;
-}
 table.mark cite {
     font-weight: bold;
 }
@@ -32,6 +27,13 @@ table.mark cite {
 td.mark {
     width: 4.5em;
 }
+table.mark strong {
+    display:block;
+    text-align: center;
+    margin:auto;
+    padding-top: 8pt;
+    padding-bottom: 2pt;
+}
 td.mark span {
     display: block;
     padding: 3px 1px;
@@ -39,6 +41,12 @@ td.mark span {
     width: 36pt;
     margin:auto;
 }
+table.mark tr td:first-child {
+    padding-left:1.5em;
+}
+table.mark tr td:first-child cite {
+    margin-left:-1.5em;
+}
 span.mark-y   { background-color: #77ffaa; }
 span.mark-geq { background-color: #aaff77; }
 span.mark-cp  { background-color: #ffbb55; }
diff --git a/doc/user/fabricd.rst b/doc/user/fabricd.rst
new file mode 100644 (file)
index 0000000..cf0f937
--- /dev/null
@@ -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
index 5818551343aecdf6fc4551605b92b300ce2dba07..8190415bf4c335739400baa68493b683a7ec3ae2 100644 (file)
@@ -42,6 +42,7 @@ Protocols
    bfd
    bgp
    babeld
+   fabricd
    ldpd
    eigrpd
    isisd
index 3da5a6cd3037b584755398bc22c433b7edd18633..da431916aec69a513ec14ef731899a44b3a0971f 100644 (file)
@@ -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.
index 54f82f683255836bfccf4bd4e167658aafdb606b..ee681858d1a4bc6f8590039fcf8c9178f6c9282f 100644 (file)
@@ -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
index 51bd6228e3eb227deee6d4bb3dd3bf538035ac46..e90b84b02bc56def407aa8b309be817f17f4cabf 100644 (file)
@@ -166,69 +166,69 @@ features with system dependencies are included here.
    will look somewhat shoddy on other sphinx targets like PDF or info (but
    should still be readable.)
 
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | Daemon / Feature                  | Linux          | OpenBSD      | FreeBSD    | NetBSD     | Solaris    |
-+==+================================+================+==============+============+============+============+
-| FRR Core                                                                                                 |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++===================================+================+==============+============+============+============+
+| **FRR Core**                      |                |              |            |            |            |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `zebra`                           | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | VRF                            | :mark:`≥4.8`   | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | MPLS                           | :mark:`≥4.5`   | :mark:`Y`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    VRF                            | :mark:`≥4.8`   | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    MPLS                           | :mark:`≥4.5`   | :mark:`Y`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `pbrd` (Policy Routing)           | :mark:`Y`      | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-| WAN / Carrier protocols                                                                                  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+| **WAN / Carrier protocols**       |                |              |            |            |            |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `bgpd` (BGP)                      | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | VRF / L3VPN                    | :mark:`≥4.8`   | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
-|  |                                | :mark:`†4.3`   |              |            |            |            |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | EVPN                           | :mark:`≥4.18`  | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
-|  |                                | :mark:`†4.9`   |              |            |            |            |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | VNC (Virtual Network Control)  | :mark:`CP`     | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | Flowspec                       | :mark:`CP`     | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    VRF / L3VPN                    | :mark:`≥4.8`   | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
+|                                   | :mark:`†4.3`   |              |            |            |            |
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    EVPN                           | :mark:`≥4.18`  | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
+|                                   | :mark:`†4.9`   |              |            |            |            |
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    VNC (Virtual Network Control)  | :mark:`CP`     | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    Flowspec                       | :mark:`CP`     | :mark:`CP`   | :mark:`CP` | :mark:`CP` | :mark:`CP` |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `ldpd` (LDP)                      | :mark:`≥4.5`   | :mark:`Y`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | VPWS / PW                      | :mark:`N`      | :mark:`≥5.8` | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | VPLS                           | :mark:`N`      | :mark:`≥5.8` | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    VPWS / PW                      | :mark:`N`      | :mark:`≥5.8` | :mark:`N`  | :mark:`N`  | :mark:`N`  |
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    VPLS                           | :mark:`N`      | :mark:`≥5.8` | :mark:`N`  | :mark:`N`  | :mark:`N`  |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `nhrpd` (NHRP)                    | :mark:`Y`      | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-| Link-State Routing                                                                                       |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+| **Link-State Routing**            |                |              |            |            |            |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `ospfd` (OSPFv2)                  | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | Segment Routing                | :mark:`≥4.12`  | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    Segment Routing                | :mark:`≥4.12`  | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `ospf6d` (OSPFv3)                 | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `isisd` (IS-IS)                   | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-| Distance-Vector Routing                                                                                  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+| **Distance-Vector Routing**       |                |              |            |            |            |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `ripd` (RIPv2)                    | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `ripngd` (RIPng)                  | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `babeld` (BABEL)                  | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `eigrpd` (EIGRP)                  | :mark:`Y`      | :mark:`Y`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-| Multicast Routing                                                                                        |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+| **Multicast Routing**             |                |              |            |            |            |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 | `pimd` (PIM)                      | :mark:`≥4.18`  | :mark:`N`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | SSM (Source Specific)          | :mark:`Y`      | :mark:`N`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
-|  | ASM (Any Source)               | :mark:`Y`      | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
-+--+--------------------------------+----------------+--------------+------------+------------+------------+
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    SSM (Source Specific)          | :mark:`Y`      | :mark:`N`    | :mark:`Y`  | :mark:`Y`  | :mark:`Y`  |
++-----------------------------------+----------------+--------------+------------+------------+------------+
+|    ASM (Any Source)               | :mark:`Y`      | :mark:`N`    | :mark:`N`  | :mark:`N`  | :mark:`N`  |
++-----------------------------------+----------------+--------------+------------+------------+------------+
 
 The indicators have the following semantics:
 
index 68ce14982be90d194418c3600063a5014c2a050a..8a76a61e787a29704603d3b7554e4fb9837a8511 100644 (file)
@@ -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
index e27da63b536f951221e0ff7dd777c2b550140efe..8831c0159b1395ee6112aa8144f0059c7f40dc59 100644 (file)
@@ -33,13 +33,14 @@ All sharp commands are under the enable node and preceeded by the ``sharp``
 keyword. At present, no sharp commands will be preserved in the config.
 
 .. index:: sharp install
-.. clicmd:: sharp install routes A.B.C.D nexthop E.F.G.H (1-1000000)
+.. clicmd:: sharp install routes A.B.C.D nexthop <E.F.G.H|X:X::X:X> (1-1000000)
 
    Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D``
-   with specified nexthop ``E.F.G.H``. The nexthop is a ``NEXTHOP_TYPE_IPV4``
-   and must be reachable to be installed into the kernel. The routes are
-   installed into zebra as ``ZEBRA_ROUTE_SHARP`` and can be used as part of a
-   normal route redistribution. Route installation time is noted in the debug
+   with specified nexthop ``E.F.G.H`` or ``X:X::X:X``. The nexthop is
+   a ``NEXTHOP_TYPE_IPV4`` or ``NEXTHOP_TYPE_IPV6`` and must be reachable
+   to be installed into the kernel. The routes are installed into zebra as
+   ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route
+   redistribution. Route installation time is noted in the debug
    log. When zebra successfully installs a route into the kernel and SHARP
    receives success notifications for all routes this is logged as well.
 
diff --git a/doc/user/subdir.am b/doc/user/subdir.am
new file mode 100644 (file)
index 0000000..53d3605
--- /dev/null
@@ -0,0 +1,111 @@
+#
+# doc/user
+#
+
+user_RSTFILES = \
+       doc/user/babeld.rst \
+       doc/user/ldpd.rst \
+       doc/user/basic.rst \
+       doc/user/bgp.rst \
+       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 \
+       doc/user/installation.rst \
+       doc/user/ipv6.rst \
+       doc/user/isisd.rst \
+       doc/user/kernel.rst \
+       doc/user/nhrpd.rst \
+       doc/user/ospf6d.rst \
+       doc/user/ospfd.rst \
+       doc/user/ospf_fundamentals.rst \
+       doc/user/overview.rst \
+       doc/user/packet-dumps.rst \
+       doc/user/pim.rst \
+       doc/user/ripd.rst \
+       doc/user/pbr.rst \
+       doc/user/ripngd.rst \
+       doc/user/routemap.rst \
+       doc/user/routeserver.rst \
+       doc/user/rpki.rst \
+       doc/user/setup.rst \
+       doc/user/sharp.rst \
+       doc/user/snmp.rst \
+       doc/user/snmptrap.rst \
+       doc/user/static.rst \
+       doc/user/vnc.rst \
+       doc/user/vtysh.rst \
+       doc/user/zebra.rst \
+       doc/user/bfd.rst \
+       doc/user/flowspec.rst \
+       # end
+
+EXTRA_DIST += \
+       $(user_RSTFILES) \
+       doc/user/Useful_Sysctl_Settings.md \
+       # end
+
+USERBUILD = doc/user/_build
+$(USERBUILD)/.doctrees/environment.pickle: $(user_RSTFILES)
+
+#
+# automake integration (things that should be built in "all")
+#
+
+if DOC
+nodist_noinst_DATA += $(USERBUILD)/texinfo/frr.info
+endif
+if DOC_HTML
+nodist_noinst_DATA += $(USERBUILD)/html/.buildinfo
+endif
+
+#
+# standard targets
+#
+
+.PHONY: info html pdf
+info: $(USERBUILD)/texinfo/frr.info
+html: $(USERBUILD)/html/.buildinfo
+pdf:  $(USERBUILD)/latexpdf
+
+#
+# hook-ins for clean / install / doc
+#
+
+.PHONY: clean-userdocs
+clean-local: clean-userdocs
+clean-userdocs:
+       -rm -rf "$(USERBUILD)"
+
+# INSTALL_INFO=install-info
+.PHONY: install-info uninstall-info install-html uninstall-html
+
+install-info: $(USERBUILD)/texinfo/frr.info
+       $(MKDIR_P) "$(DESTDIR)$(infodir)"
+       $(INSTALL_DATA) "$<" "$(DESTDIR)$(infodir)"
+       [ -z "${DESTDIR}" ] && $(INSTALL_INFO) --info-dir="$(DESTDIR)$(infodir)" "$<" || true
+uninstall-info: $(USERBUILD)/texinfo/frr.info
+       -rm -f "$(DESTDIR)$(infodir)/$<"
+       [ -z "${DESTDIR}" ] && $(INSTALL_INFO) --delete --info-dir="$(DESTDIR)$(infodir)" "$<" || true
+
+install-html: $(USERBUILD)/html/.buildinfo
+       $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+       cp -r "$(USERBUILD)/html" "$(DESTDIR)$(htmldir)"
+uninstall-html:
+       -rm -rf "$(DESTDIR)$(htmldir)/html"
+
+.PHONY: install-data-local uninstall-local
+if DOC
+DOC_INFO=info
+install-data-local: install-info
+uninstall-local:  uninstall-info
+endif
+if DOC_HTML
+DOC_HTML=html
+install-data-local: install-html
+uninstall-local:  uninstall-html
+endif
+doc: $(DOC_INFO) $(DOC_HTML)
index 85f2a7af3eff53b2cb70813c309a06776b813762..e3e5d1325a6261a02db9a1fe4c3028104b0b2c75 100644 (file)
@@ -395,8 +395,6 @@ be updated with the new name. To illustrate, if you want to recompile with
 
    ./configure --with-defaultvrfname=global
 
-More information about the option in :ref:`_frr-configuration`.
-
 .. _zebra-mpls:
 
 MPLS Commands
index 5b72399e727f7159c2c86428af808e846bf0a37d..0303c6f0d437709ecc0f3201ab8bda6e9ac5137d 100644 (file)
@@ -1,18 +1,2 @@
-!Makefile
-Makefile.in
-*.o
-*.a
 eigrpd
 eigrpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
index eeefc519688ccce2c37f7298254b46bfa46b91be..d291cab4c0c7566237693ff29d127cb0e2c6b9c4 100644 (file)
@@ -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"
index 190c18777e23139b7447d84feb0d4e505a8f4245..311fbce4ab68170caf0c7d9ade6190990fc90ab8 100644 (file)
@@ -1085,7 +1085,7 @@ DEFUN (eigrp_redistribute_source_metric,
 DEFUN (no_eigrp_redistribute_source_metric,
        no_eigrp_redistribute_source_metric_cmd,
        "no redistribute " FRR_REDIST_STR_EIGRPD
-       " metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)",
+       " [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]",
        "Disable\n"
        REDIST_STR
        FRR_REDIST_HELP_STR_EIGRPD
index 2635d555d9a202e4039b025b77a311c8f16bc4de..bc48173bba11d9b593bf5bd16221eacd59db1443 100644 (file)
@@ -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 (file)
index 17e9044..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-!Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
index 795535596b6fd0a6ec5f4c06a6808059bc73f724..05cec5a5282484ab4b4790c231aadccdd6e1f4cf 100644 (file)
@@ -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 (file)
index 30b4bc9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-.nfs*
-*~
-*.loT
-
index a882bbf675443d4213f538474e8cceb722719a30..b6184ca0f54b515c8f6837d5fedc3c0acd285c0f 100644 (file)
@@ -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 (file)
index 0000000..7951efe
--- /dev/null
@@ -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 (file)
index 0000000..be9e33b
--- /dev/null
@@ -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 (file)
index 0000000..76c182f
--- /dev/null
@@ -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
index 4b3d78421e8cf3a451b6c22feef551d3bd274376..a41d6ff8152267214bb99680de920d8654d6a8c8 100644 (file)
@@ -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);
index 7e8a4a4edaba81502d7ba6ec840a3c2baa431882..28750278b017eee7c198153e7cc2c70bd9017d62 100644 (file)
@@ -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);
index cd4b76139f7455f6603abbbb1cb6ce910beb9209..817a44bafe66fad4e2598c7f30d6d8b360a0559c 100644 (file)
@@ -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;
 }
index 8dbd7ac492b9017cb952b5d15fcf4b4546bc7eb9..ea68767fe0fb35c1bfb5b40ff61631df5918a258 100644 (file)
@@ -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 */
index 66c97ae8974413610db366e68b64c5abdc2cbd45..e8777e9b53a1d6eaab1e706e77058e2771f401f9 100644 (file)
@@ -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);
+       }
+}
index d531cb1576c1e7bf710875d4749c728f7afe219f..4e6379447cf5136de7f28ed31a6d95a34812f33d 100644 (file)
@@ -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 (file)
index c521f42..0000000
+++ /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_lsp_hash.h b/isisd/isis_lsp_hash.h
deleted file mode 100644 (file)
index b50aa09..0000000
+++ /dev/null
@@ -1,34 +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
- */
-#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);
-#endif
index 3b4168adb97fca0597c1420186fb02bbe292c456..4d6a6da5d602b2b883d4b0ba75055a22bf3d70da 100644 (file)
 #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();
index 2155bf584ec13d78aebd0d0d9401a365c3059093..2dfccf9830bdccbeb8a795c68dbe935f7e323a6d 100644 (file)
@@ -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++;
                }
        }
index 5c4e3a35bcb44baf60bd4374df7ff909f4ea97af..88575f531943770c7155aba12fa36757fd96a075 100644 (file)
@@ -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;
 }
index c69bfedeae78603ebcd3c3852d5f5ead79b063ca..3d2420eb036abf340f7459c8e93b2215fd5ad509 100644 (file)
@@ -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);
index cd3ca44379c35aaeff9fbd98b1d8d2377277a073..ab7584ed3e04c5dc9a71ee50de70476593bf8c3c 100644 (file)
@@ -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);
 }
index 341921146bb522858fe6bb004b3bbd439eb0090d..6a7528623c08df603c5315f327f26d737373af95 100644 (file)
 #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"
 #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");
        }
 
index 9a73ca8783dd3b6d766eb2b73b21fe45692773b0..f4db98cfed532af958e56671be8aba600e97ca07 100644 (file)
@@ -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 (file)
index 0000000..af552e0
--- /dev/null
@@ -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
index 44ba64ce26f80f76d3a3064b9241560fa4f41681..08b905c65032fd89ca22169329ac76cc45151d62 100644 (file)
@@ -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;
 }
index a433fcdb41a86f3da769b084d55d8c1dfb12ce56..b22460a0b5402abb914d1a45ea26aec402a114e4 100644 (file)
@@ -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));
+       }
+}
index bd1fa3e6768d3cea582f6b3821393a0bc2b9765a..4144809fa3aeaaf4a55317dfe522679906ae3705 100644 (file)
@@ -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 (file)
index 0000000..3242762
--- /dev/null
@@ -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_tx_queue.h b/isisd/isis_tx_queue.h
new file mode 100644 (file)
index 0000000..ddecdf1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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
+ */
+#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 (file)
index ce2952c..0000000
+++ /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 (file)
index 0000000..2b98a88
--- /dev/null
@@ -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 (file)
index 0000000..b726b4e
--- /dev/null
@@ -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 (file)
index 0000000..95ebe0d
--- /dev/null
@@ -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 (file)
index 0000000..95aaeae
--- /dev/null
@@ -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);
+}
index 9bc0f2ef350f674a896e0a87d802713c2802d615..33d8a0f77172036155ea8a5cb845195137fd9821 100644 (file)
@@ -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;
index a19f287453f463ad817301038bcb5a4a1659be07..e3ff3b8d93e377111a666099048a991ef9212319 100644 (file)
@@ -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();
 }
index ce602e4402b3488fd7f9223333629dbd6b6304c9..864021428aa885dfbf07d3eae33e98dec79f4ed7 100644 (file)
 #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 {                                                                   \
index 7b8be46167cf25144d09be6cd80cf8462fe1cd6e..7571255e59251cc0b22c135da34fd2967b9bd3c0 100644 (file)
@@ -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)
index a2f4b51698ba10405f6d56e3bb5e5919b8bf9e37..ec8a5c40863d9b26c6e84f914bb28a1f03f04a94 100644 (file)
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
 ldpd
 ldpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
index 03b62b482b26076fd10c0162d217dec626c2a6f7..81043988863b1c5ab9a6caad4be78b427ff5e8e5 100644 (file)
@@ -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)
index 906737217c0e0513a7279b6658f9f9dde1e2ca22..a719d0cbb7067e5b5af614655b24bc6e21288be0 100644 (file)
  * 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>
index 2d87be0cda80e7d92279cc76df48f1c3d23e98ec..24e738d6227a0805c5861f40d98e3f65bf3ab7b0 100644 (file)
@@ -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 = \
index 072146dbd54877508bf76f6fa568a0ec95f7ea4a..6176b30f8d2fd8f7f328c920de96758d3bb5e164 100644 (file)
@@ -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/agg_table.c b/lib/agg_table.c
new file mode 100644 (file)
index 0000000..6033fc3
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Aggregate Route
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ *               Donald Sharp
+ *
+ * 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 "agg_table.h"
+
+
+static struct route_node *agg_node_create(route_table_delegate_t *delegate,
+                                         struct route_table *table)
+{
+       struct agg_node *node;
+
+       node = XCALLOC(MTYPE_TMP, sizeof(struct agg_node));
+
+       return agg_node_to_rnode(node);
+}
+
+static void agg_node_destroy(route_table_delegate_t *delegate,
+                            struct route_table *table, struct route_node *node)
+
+{
+       struct agg_node *anode = agg_node_from_rnode(node);
+
+       XFREE(MTYPE_TMP, anode);
+}
+
+route_table_delegate_t agg_table_delegate = {
+       .create_node = agg_node_create,
+       .destroy_node = agg_node_destroy,
+};
+
+struct agg_table *agg_table_init(void)
+{
+       struct agg_table *at;
+
+       at = XCALLOC(MTYPE_TMP, sizeof(struct agg_table));
+
+       at->route_table = route_table_init_with_delegate(&agg_table_delegate);
+       at->route_table->info = at;
+
+       return at;
+}
diff --git a/lib/agg_table.h b/lib/agg_table.h
new file mode 100644 (file)
index 0000000..235f0d3
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * agg_table - Aggregate Table Header
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ *               Donald Sharp
+ *
+ * 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 __AGG_TABLE_H__
+#define __AGG_TABLE_H__
+
+#include "prefix.h"
+#include "table.h"
+
+struct agg_table {
+       struct route_table *route_table;
+
+       void *info;
+};
+
+struct agg_node {
+       /*
+        * Caution these must be the very first fields
+        * @see agg_node_to_rnode
+        * @see agg_node_from_rnode
+        */
+       ROUTE_NODE_FIELDS
+
+       /* Aggregation. */
+       void *aggregate;
+};
+
+static inline struct route_node *agg_node_to_rnode(struct agg_node *node)
+{
+       return (struct route_node *)node;
+}
+
+static inline struct agg_node *agg_node_from_rnode(struct route_node *node)
+{
+       return (struct agg_node *)node;
+}
+
+static inline struct agg_node *agg_lock_node(struct agg_node *node)
+{
+       return (struct agg_node *)route_lock_node(agg_node_to_rnode(node));
+}
+
+static inline void agg_unlock_node(struct agg_node *node)
+{
+       return route_unlock_node(agg_node_to_rnode(node));
+}
+
+static inline void agg_set_table_info(struct agg_table *atable, void *data)
+{
+       atable->info = data;
+}
+
+static inline void *agg_get_table_info(struct agg_table *atable)
+{
+       return atable->info;
+}
+
+static inline struct agg_node *agg_route_top(struct agg_table *table)
+{
+       return agg_node_from_rnode(route_top(table->route_table));
+}
+
+static inline struct agg_node *agg_route_next(struct agg_node *node)
+{
+       return agg_node_from_rnode(route_next(agg_node_to_rnode(node)));
+}
+
+static inline struct agg_node *agg_node_get(struct agg_table *table,
+                                           struct prefix *p)
+{
+       return agg_node_from_rnode(route_node_get(table->route_table, p));
+}
+
+static inline struct agg_node *
+agg_node_lookup(const struct agg_table *const table, struct prefix *p)
+{
+       return agg_node_from_rnode(route_node_lookup(table->route_table, p));
+}
+
+static inline struct agg_node *agg_route_next_until(struct agg_node *node,
+                                                   struct agg_node *limit)
+{
+       struct route_node *rnode;
+
+       rnode = route_next_until(agg_node_to_rnode(node),
+                               agg_node_to_rnode(limit));
+
+       return agg_node_from_rnode(rnode);
+}
+
+static inline struct agg_node *agg_node_match(struct agg_table *table,
+                                             struct prefix *p)
+{
+       return agg_node_from_rnode(route_node_match(table->route_table, p));
+}
+
+static inline struct agg_node *agg_node_parent(struct agg_node *node)
+{
+       struct route_node *rn = agg_node_to_rnode(node);
+
+       return agg_node_from_rnode(rn->parent);
+}
+
+static inline struct agg_node *agg_node_left(struct agg_node *node)
+{
+       struct route_node *rn = agg_node_to_rnode(node);
+
+       return agg_node_from_rnode(rn->l_left);
+}
+
+static inline struct agg_node *agg_node_right(struct agg_node *node)
+{
+       struct route_node *rn = agg_node_to_rnode(node);
+
+       return agg_node_from_rnode(rn->l_right);
+}
+
+extern struct agg_table *agg_table_init(void);
+
+static inline void agg_table_finish(struct agg_table *atable)
+{
+       route_table_finish(atable->route_table);
+       atable->route_table = NULL;
+
+       XFREE(MTYPE_TMP, atable);
+}
+
+static inline struct agg_node *agg_route_table_top(struct agg_node *node)
+{
+       return (struct agg_node *)route_top(node->table);
+}
+
+static inline struct agg_table *agg_get_table(struct agg_node *node)
+{
+       return (struct agg_table *)node->table->info;
+}
+#endif
index 0eddb47514d5e5ea39d104c33650317922f07dc1..1dfe583caf7743744a35c49362e7c5abe6d1015b 100644 (file)
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -342,7 +342,7 @@ static void bfd_last_update(time_t last_update, char *buf, size_t len)
  * bfd_show_param - Show the BFD parameter information.
  */
 void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
-                   int extra_space, uint8_t use_json, json_object *json_obj)
+                   int extra_space, bool use_json, json_object *json_obj)
 {
        json_object *json_bfd = NULL;
 
@@ -378,7 +378,7 @@ void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
  * bfd_show_status - Show the BFD status information.
  */
 static void bfd_show_status(struct vty *vty, struct bfd_info *bfd_info,
-                           int bfd_tag, int extra_space, uint8_t use_json,
+                           int bfd_tag, int extra_space, bool use_json,
                            json_object *json_bfd)
 {
        char time_buf[32];
@@ -402,7 +402,7 @@ static void bfd_show_status(struct vty *vty, struct bfd_info *bfd_info,
  * bfd_show_info - Show the BFD information.
  */
 void bfd_show_info(struct vty *vty, struct bfd_info *bfd_info, int multihop,
-                  int extra_space, uint8_t use_json, json_object *json_obj)
+                  int extra_space, bool use_json, json_object *json_obj)
 {
        json_object *json_bfd = NULL;
 
index f824b0fd9b54aa9802168cfcd6f8a9331510e16c..b1e490a62279a2b95c8112d7ca56a8b861099b25 100644 (file)
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -91,11 +91,11 @@ extern struct interface *bfd_get_peer_info(struct stream *s, struct prefix *dp,
 const char *bfd_get_status_str(int status);
 
 extern void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info,
-                          int bfd_tag, int extra_space, uint8_t use_json,
+                          int bfd_tag, int extra_space, bool use_json,
                           json_object *json_obj);
 
 extern void bfd_show_info(struct vty *vty, struct bfd_info *bfd_info,
-                         int multihop, int extra_space, uint8_t use_json,
+                         int multihop, int extra_space, bool use_json,
                          json_object *json_obj);
 
 extern void bfd_client_sendmsg(struct zclient *zclient, int command);
index 1df644210723a3e7ec47ad382bf79940d08c5d82..26afc762fba20dabc846bd921e41aca305155e62 100644 (file)
@@ -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:
index 75b69507ec7bf153e281b3ca818dacf4ba4cf073..8e51641b88cfab90b2ced915b9f2f052f1caa91c 100644 (file)
@@ -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"
index 0d6e6ee7e5fc60b0ac55918d38acc258face2219..3b18b58a2e9e3dfefdb0fdedc2549c4ff8c901a4 100644 (file)
  * 02111-1307, USA.
  */
 
+%top{
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+}
 %{
 /* ignore flex generated code in static analyzer */
 #ifndef __clang_analyzer__
index ce84783aa6f7570da98027cabbc489a8cf1cd4b6..582106ebd429356cf98b6ff224c0f4e89dc6501a 100644 (file)
--- a/lib/csv.c
+++ b/lib/csv.c
  * 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));
index d901c26a2ed336ad37eefd66984e359b0e0dd246..6c0805a4fa9b4542319eaf82476b35d6bae53698 100644 (file)
@@ -1,4 +1,3 @@
-%{
 /*
  * clippy (CLI preparator in python) C pseudo-lexer
  * Copyright (C) 2016-2017  David Lamparter for NetDEF, Inc.
  * 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"
index 35d0fe4ff420de5e6c7e64684d938e3bcf64a91f..afef196cec4ce3cfac14fdc7af747b28eabc91c0 100644 (file)
  * 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);
index eb6587a35ae6c4473144a66eb583338ed53f32ec..d48b23f38a9a1804831cfa81f1541d03260adc9f 100644 (file)
@@ -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
        }
 
@@ -332,7 +339,7 @@ static void *fpt_run(void *arg)
 
        fpt->master->handle_signals = false;
 
-       if (fpt->os_name)
+       if (fpt->os_name[0])
                frr_pthread_set_name(fpt, NULL, fpt->os_name);
 
        frr_pthread_notify_running(fpt);
index cc4fc74337b940abd82f42ad8d4b78bd8ee6326d..732e2925fef67246b6e2b9a6184b2b223ea59ea5 100644 (file)
@@ -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 */
index 715e67b868c24bbe9adeb945f6aec9986850d3bb..85d968182b042f87a46f7eb33e9802339ca818d3 100644 (file)
  * 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>
index 51e7a3987e00297dcebc1cf9515989df792d4fb6..ef03e85217b4c10d703c2c1e67e7ff6cab5a87e5 100644 (file)
  * 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"
index 264c7c48f00ec6a30d91670bf777c0710efce8a4..c9c942f9bf897a02599dea196ce1dcea5463556a 100644 (file)
  * 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"
 
index 935064f4d2aee42cae984101c987684e2665221c..4fe305f282681009ec462869e75968e6af31fd47 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "memory.h"
 #include "hook.h"
 
index 25da7a8188dd93fa70a54221276a2a681b1e2415..2f2073c0a12acf3435579ea284336d312b722ae9 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -629,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;
index b83f1f76f2a617dae2d4f9eaf21e383fde2b2c5a..c2f4052b8f5ea66be9be7b5f3cfdcba19cc570a7 100644 (file)
@@ -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);
 
index 54241407205d203f0ae3964e784afbf27bc03e7d..935d13772752a2a668fc4d9699793c4addd7845a 100644 (file)
@@ -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);
index 40b6aadaa3ca416bc4ad81f8562535fecf4134bd..4ea20ba178ad5e57b7a44fe0a391c489d086440a 100644 (file)
  * is the *last* keyword on the line no matter
  * what.
  */
-int use_json(const int argc, struct cmd_token *argv[])
+bool use_json(const int argc, struct cmd_token *argv[])
 {
        if (argc == 0)
-               return 0;
+               return false;
 
        if (argv[argc - 1]->arg && strmatch(argv[argc - 1]->text, "json"))
-               return 1;
+               return true;
 
-       return 0;
+       return false;
 }
 
 void json_object_string_add(struct json_object *obj, const char *key,
index 788d1d6efa1d882093d76788df7e839c99489d47..d34916230473447e79f399c29d85dd8b283c6df2 100644 (file)
@@ -52,7 +52,7 @@ extern int json_object_object_get_ex(struct json_object *obj, const char *key,
 
 #include "command.h"
 
-extern int use_json(const int argc, struct cmd_token *argv[]);
+extern bool use_json(const int argc, struct cmd_token *argv[]);
 extern void json_object_string_add(struct json_object *obj, const char *key,
                                   const char *s);
 extern void json_object_int_add(struct json_object *obj, const char *key,
index 332a5b1d453aac833f4811dd1734a177b9f1a98c..2ddc571e688999eab79fa1412066e7379ffa5676 100644 (file)
  * 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 */
index 821c57f37b2d1a9c4e7c09ae2d2bc23dd53d082c..61f5fa70816981987a611550a4a08d33c152321e 100644 (file)
@@ -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;
@@ -589,6 +615,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);
 
index b067018e08de3bdef4b33f9b2b635a3fc0b3833f..521783e4b09887d5434d33b98e36a2314dd0f9e2 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -925,7 +925,6 @@ static const struct zebra_desc_table command_types[] = {
        DESC_ENTRY(ZEBRA_IMPORT_ROUTE_REGISTER),
        DESC_ENTRY(ZEBRA_IMPORT_ROUTE_UNREGISTER),
        DESC_ENTRY(ZEBRA_IMPORT_CHECK_UPDATE),
-       DESC_ENTRY(ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD),
        DESC_ENTRY(ZEBRA_BFD_DEST_REGISTER),
        DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER),
        DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE),
@@ -1075,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"))
@@ -1103,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;
 }
index 87cba69fc51536b579f01997fe6351ad29ee7ff2..fee23a75ac67e1d11463c102b2e68a87444ba1b5 100644 (file)
@@ -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
@@ -36,9 +39,19 @@ DEFINE_MTYPE(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec")
 
 static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr)
 {
+       size_t current;
        size_t oldsize;
 
-       atomic_fetch_add_explicit(&mt->n_alloc, 1, memory_order_relaxed);
+       current = 1 + atomic_fetch_add_explicit(&mt->n_alloc, 1,
+                                               memory_order_relaxed);
+
+       oldsize = atomic_load_explicit(&mt->n_max, memory_order_relaxed);
+       if (current > oldsize)
+               /* note that this may fail, but approximation is sufficient */
+               atomic_compare_exchange_weak_explicit(&mt->n_max, &oldsize,
+                                                     current,
+                                                     memory_order_relaxed,
+                                                     memory_order_relaxed);
 
        oldsize = atomic_load_explicit(&mt->size, memory_order_relaxed);
        if (oldsize == 0)
@@ -51,7 +64,15 @@ static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr)
 #ifdef HAVE_MALLOC_USABLE_SIZE
        size_t mallocsz = malloc_usable_size(ptr);
 
-       atomic_fetch_add_explicit(&mt->total, mallocsz, memory_order_relaxed);
+       current = mallocsz + atomic_fetch_add_explicit(&mt->total, mallocsz,
+                                                      memory_order_relaxed);
+       oldsize = atomic_load_explicit(&mt->max_size, memory_order_relaxed);
+       if (current > oldsize)
+               /* note that this may fail, but approximation is sufficient */
+               atomic_compare_exchange_weak_explicit(&mt->max_size, &oldsize,
+                                                     current,
+                                                     memory_order_relaxed,
+                                                     memory_order_relaxed);
 #endif
 }
 
index c39f34e3a7f8a313f2c3c5d9497b5e18650a4468..2d6c1447786a467d39fc147acb981947380ad996 100644 (file)
@@ -34,9 +34,11 @@ struct memtype {
        struct memtype *next, **ref;
        const char *name;
        _Atomic size_t n_alloc;
+       _Atomic size_t n_max;
        _Atomic size_t size;
 #ifdef HAVE_MALLOC_USABLE_SIZE
        _Atomic size_t total;
+       _Atomic size_t max_size;
 #endif
 };
 
index 9ee2e52ec751cacb33b42209ea6b974e520729ac..5fd9c3b900437c13a5feb6c2f792d7aa96a08c33 100644 (file)
@@ -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"
@@ -73,27 +75,45 @@ static int show_memory_mallinfo(struct vty *vty)
 static int qmem_walker(void *arg, struct memgroup *mg, struct memtype *mt)
 {
        struct vty *vty = arg;
-       if (!mt)
+       if (!mt) {
                vty_out(vty, "--- qmem %s ---\n", mg->name);
-       else {
+               vty_out(vty, "%-30s: %8s %-8s%s %8s %9s\n",
+                       "Type", "Current#", "  Size",
+#ifdef HAVE_MALLOC_USABLE_SIZE
+                       "     Total",
+#else
+                       "",
+#endif
+                       "Max#",
+#ifdef HAVE_MALLOC_USABLE_SIZE
+                       "MaxBytes"
+#else
+                       ""
+#endif
+                       );
+       } else {
                if (mt->n_alloc != 0) {
                        char size[32];
                        snprintf(size, sizeof(size), "%6zu", mt->size);
-
 #ifdef HAVE_MALLOC_USABLE_SIZE
 #define TSTR " %9zu"
 #define TARG , mt->total
+#define TARG2 , mt->max_size
 #else
 #define TSTR ""
 #define TARG
+#define TARG2
 #endif
-                       vty_out(vty, "%-30s: %10zu  %-16s"TSTR"\n", mt->name,
+                       vty_out(vty, "%-30s: %8zu %-8s"TSTR" %8zu"TSTR"\n",
+                               mt->name,
                                mt->n_alloc,
                                mt->size == 0 ? ""
                                              : mt->size == SIZE_VAR
-                                                       ? "(variably sized)"
+                                                       ? "variable"
                                                        : size
-                               TARG);
+                               TARG,
+                               mt->n_max
+                               TARG2);
                }
        }
        return 0;
index 35bfce3a890d73e9cd9acd080bef56c7a2f39ee4..e8d13339b633cf8470628e625f3b68a0ea00eb06 100644 (file)
  * 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>
index 2b666f256fce5037cbb3c8a965e0ea76aa2a48da..57460801279ac5b3c42f17562cabdafb13d79f7b 100644 (file)
@@ -396,7 +396,7 @@ static int64_t prefix_new_seq_get(struct prefix_list *plist)
 
        newseq = ((maxseq / 5) * 5) + 5;
 
-       return newseq;
+       return (newseq > UINT_MAX) ? UINT_MAX : newseq;
 }
 
 /* Return prefix list entry which has same seq number. */
@@ -1900,7 +1900,7 @@ void prefix_bgp_orf_remove_all(afi_t afi, char *name)
 
 /* return prefix count */
 int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
-                               uint8_t use_json)
+                               bool use_json)
 {
        struct prefix_list *plist;
        struct prefix_list_entry *pentry;
index fecbe0e2ce6813a2fd8e7b99f60865df0f7bfb61..8a4fa8d3ce6cf4c60e47c66ed82ceada80970961 100644 (file)
@@ -72,6 +72,7 @@ extern struct stream *prefix_bgp_orf_entry(struct stream *,
                                           uint8_t, uint8_t);
 extern int prefix_bgp_orf_set(char *, afi_t, struct orf_prefix *, int, int);
 extern void prefix_bgp_orf_remove_all(afi_t, char *);
-extern int prefix_bgp_show_prefix_list(struct vty *, afi_t, char *, uint8_t);
+extern int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
+                                      bool use_json);
 
 #endif /* _QUAGGA_PLIST_H */
index 69fd61e2a06998ea914551f4b02b3aeb71e43c24..7f868beda419048aef5a788c7e05af2c59b9919d 100644 (file)
  * 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>
index 04fbeee7004c98ab159eb714a9968dfd8eda94f1..11e28b4c912554caf2c9cae8adebb407a46ce0fb 100644 (file)
 #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 */
index 72f59a1b78608d84e436baa6e6835e2bf20b1a7e..c5eff44ca7f07271310c26bd08ee4c29df183b07 100644 (file)
@@ -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"
index 4125bb53aee6c5a7413f8d248ae88dd13017dfb5..e5613c2081530e701b9dbeeb87b21693ce7cdf5e 100644 (file)
@@ -891,6 +891,14 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map)
        }
 }
 
+static int sort_route_map(const void **map1, const void **map2)
+{
+       const struct route_map *m1 = *map1;
+       const struct route_map *m2 = *map2;
+
+       return strcmp(m1->name, m2->name);
+}
+
 static int vty_show_route_map(struct vty *vty, const char *name)
 {
        struct route_map *map;
@@ -907,9 +915,19 @@ static int vty_show_route_map(struct vty *vty, const char *name)
                        return CMD_SUCCESS;
                }
        } else {
+
+               struct list *maplist = list_new();
+               struct listnode *ln;
+
                for (map = route_map_master.head; map; map = map->next)
-                       if (!map->deleted)
-                               vty_show_route_map_entry(vty, map);
+                       listnode_add(maplist, map);
+
+               list_sort(maplist, sort_route_map);
+
+               for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
+                       vty_show_route_map_entry(vty, map);
+
+               list_delete_and_null(&maplist);
        }
        return CMD_SUCCESS;
 }
index a36bf47139c307ceacc85629427a747dec394939..585cf859e5742b1a952a0ba935e6c9f1c6b19d56 100644 (file)
@@ -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;
index 55e7f6435826118df2c8735f12a3832ea7912191..589a2292568281580c8690dd2e7e453a20a272e9 100644 (file)
@@ -270,7 +270,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);
 
@@ -299,7 +299,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);
 
@@ -344,7 +344,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);
 
@@ -465,7 +465,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);
 
index be211f82a8e527a8ec8e1dda6cc47e14559460ee..39773d9ac89ef7cfe022cc444266eea243b9eee5 100644 (file)
 /* 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
 
index b0c33ca7f42baeac4acd8dce8b9163fc5974b639..71ee9f1a5452740f3f585df1d81048b04d8a72b1 100644 (file)
 /* 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
index 50cfd70a571ff4e6071ea5a6d7f5cf51e90859a4..499bb94920d6c7039b0c29f66985866a4edcf057 100644 (file)
@@ -6,6 +6,7 @@ lib_libfrr_la_LDFLAGS = -version-info 0:0:0
 lib_libfrr_la_LIBADD = @LIBCAP@
 
 lib_libfrr_la_SOURCES = \
+       lib/agg_table.c \
        lib/bfd.c \
        lib/buffer.c \
        lib/checksum.c \
@@ -83,12 +84,29 @@ 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)
 lib/nexthop_group.lo: lib/nexthop_group_clippy.c
 
 pkginclude_HEADERS += \
+       lib/agg_table.h \
        lib/bfd.h \
        lib/bitfield.h \
        lib/buffer.h \
@@ -150,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 \
@@ -235,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 \
@@ -250,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
@@ -291,7 +331,7 @@ if GIT_VERSION
 # (even if gitversion.h's file timestamp doesn't change, make will think it
 # did, because of .PHONY...)
 
-.PHONY: lib/gitversion.h.tmp
+PHONY_GITVERSION=lib/gitversion.h.tmp
 .SILENT: lib/gitversion.h lib/gitversion.h.tmp
 GITH=lib/gitversion.h
 lib/gitversion.h.tmp: $(top_srcdir)/.git
@@ -300,7 +340,8 @@ lib/gitversion.h: lib/gitversion.h.tmp
        { test -f ${GITH} && diff -s -q ${GITH}.tmp ${GITH}; } || cp ${GITH}.tmp ${GITH}
 
 else
-.PHONY: lib/gitversion.h
+PHONY_GITVERSION=lib/gitversion.h
 lib/gitversion.h:
        true
 endif
+.PHONY: $(PHONY_GITVERSION)
index 8304abe59b38ec5b3b349b1848a412ccf266a9a3..711ace111ec15a39d9ee9d611908f3718bc665f4 100644 (file)
@@ -126,9 +126,6 @@ struct route_table {
                                                                                \
        /* Each node of route. */                                              \
        void *info;                                                            \
-                                                                               \
-       /* Aggregation. */                                                     \
-       void *aggregate;
 
 
 /* Each routing entry. */
index 748c14f675c35d5159d025fe128360e048ecfc22..480137a7a956f4853567d442313b5efcaa022b4b 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -811,6 +811,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:
@@ -1210,6 +1211,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:
index b8ff85e80ff584f954f990abcc695d0d15d45c70..cab734ae5e0d73f96ffc232d0523895fba803015 100644 (file)
@@ -91,7 +91,6 @@ typedef enum {
        ZEBRA_IMPORT_ROUTE_REGISTER,
        ZEBRA_IMPORT_ROUTE_UNREGISTER,
        ZEBRA_IMPORT_CHECK_UPDATE,
-       ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
        ZEBRA_BFD_DEST_REGISTER,
        ZEBRA_BFD_DEST_DEREGISTER,
        ZEBRA_BFD_DEST_UPDATE,
index b12f6616bae9d4c96f1b4ad290b676cfcbf79e8a..d80aa06935500d11e032fea227ea8dcb2006bcb0 100644 (file)
@@ -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 */
 
index 798188b0b93d284c066bf7845fd74f23040fde0d..357e65588dce38a2ed99904d332d81c69ad8f752 100644 (file)
@@ -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
index c5b26b52e6cdb5891332f7e87addae9306ba7107..a8dcd17c418797a506574e0867a95e8ff0efac29 100644 (file)
--- 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])
index 3f47381278fd22c0ae9acb294ad226e47d1ca878..3d4d56d58937167938c270128e28ab6c83749cd1 100644 (file)
@@ -1,2 +1 @@
-!Makefile
 nhrpd
index 46a327b59f21265aa2bac727c951cb18a89a4ebf..85e941e7bacd1d63fed3300fe7e708df39c4f420 100644 (file)
@@ -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>
index af78b3d9ee6a74f560ed13dcce6aa4279c4ac1d7..4c6827cb3d63536e4976426e02c373d95b397006 100644 (file)
@@ -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>
index 75ecaa70c124cf84756fc6094fe9ef3278161cd0..3fdfa9c31307d14af5121c7d182295d30141357c 100644 (file)
@@ -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>
index 7ca9731765d2d1c6691d0d869e2a1eb67f24ef85..9301c2d515eba9084658e6f8167414d956361ca0 100644 (file)
@@ -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>
index 3a42712748cd3b768820f0f0ca7d60df4c39cc96..ccca100db57940b038501c5a08b44cccd3958e20 100644 (file)
@@ -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"
index 737e70103e553e125c512ddc31a36b79e926c913..f99e566399b571f4a59faa195b31bbfdaf1f1006 100644 (file)
@@ -7,6 +7,10 @@
  * (at your option) any later version.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <unistd.h>
 
 #include "zebra.h"
index e62ee1ef72206a17924c031a0d4281d85ce92c51..a983aa71bca91997184b3fe268e0768fee8b8868 100644 (file)
@@ -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"
index 44271d68ac7930697598e388b784d4a0aa51bc6d..e051830f8524681ea0ab0daa848dac472dd403ad 100644 (file)
@@ -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"
index 044529a5cab4c53a74a62172cd5f46d363aa5f51..e7b187f3b607eeac0f747fcdca6a29c118923d85 100644 (file)
@@ -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"
index 9ed2517069372b784a6afb1ab432abd8fb5d4a7b..84053b4b5d68ee8c31551297c5a322f50292376f 100644 (file)
@@ -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"
index dfa5dc3df0537fb8bbc9f4a52c73a76a596cfbfa..f017d974dfd5adf1358b69b088f68fb2aab38f20 100644 (file)
@@ -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>
 
index d66e96822417658ee574b05cede67ba54a3ff1f2..758c22e2be87d62a406082d1688416df8fb4ab07 100644 (file)
@@ -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@
index 7cd703414ac9aee81c0c77e2d9b4fdc44a2d5f89..c1a99685f39d6e34c61c57cd59c08b68b3aca277 100644 (file)
@@ -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>
index 6e7cad8aec2c5940fbfc538d8c5b910187db04f6..c662295083e79063f814c14bfeecdde45fd03880 100644 (file)
@@ -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>
index 01b2f433af8b6128a56be47a116d103c22b23af8..6030987a1bdf25bb802d7068440628228a9482dd 100644 (file)
@@ -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>
index 744af2d5ce70a847a0b2e9303dd73f9f9e04f4d6..e398b1ca58644440c2d1e60af60fbb8e50ee51e9 100644 (file)
@@ -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
index 5af88defeba69dc6a65251900ff33c61567a5db1..dc7a3f6d45766c8f8b848b45273fbdcab741a6da 100644 (file)
@@ -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)) {
index 8b720b6d844ae0e98cea494cd3a89b0736d70fbf..40b3522c3d7c94f033cdda8495544912623e79b1 100644 (file)
@@ -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));
        }
index e88d10ad7e594b129821334929b94b5ea4f72981..d871a8842ecb3969fe8b0eea28433db9e6fdebdb 100644 (file)
@@ -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)                                                  \
index 0cc7294d67995cae0bb0037da7edda552c15fbf0..4c24f47131893ff1ea8b463088900a7ccb08fa58 100644 (file)
@@ -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);
                }
        }
 
index a099eead49bab5bf718a24ec3901b28f5f6a9bdc..021e825ae33dc82a27de356081d523d06f2b3cee 100644 (file)
@@ -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);
index fde47c74fef9e8a148ee522de1d24f734af5cb00..ca1a65ff0b293e7833dcb91bdafc6bdea71a2e49 100644 (file)
@@ -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);
index 8a6c4a5ccfd3437e9a1910068307ea1d2c0fee64..d9c29f2651b9e028996f72367ea2c1ff23386ef3 100644 (file)
@@ -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 = \
index 1740b04fbcbcb940b11d52f195b2c471989249bb..9be70451f001d86fa42e383ae12510f61d2efbec 100644 (file)
@@ -1,16 +1 @@
-!Makefile
-Makefile.in
-*.o
 ospfclient
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-refix
index 834d4aaba77e64e00102d52bbf7d12b4f0f6a97a..df7d85a1f5d810ed637f425fa9d9bee6f0494f32 100644 (file)
@@ -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
index 752c875a622136a8e523968d0e02b27e4c44b0bf..fc65db33ee539c245d548a15d8d92f82675cbd26 100644 (file)
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
 ospfd
 ospfd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
index df41897660acbfca66067a897d43c613aa5115aa..594735a08f8021919240b920308d250e1ff82bcd 100644 (file)
@@ -312,7 +312,7 @@ void ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params)
  * ospf_bfd_show_info - Show BFD info structure
  */
 void ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
-                       uint8_t use_json, int param_only)
+                       bool use_json, int param_only)
 {
        if (param_only)
                bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json,
@@ -326,7 +326,7 @@ void ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
  * ospf_bfd_interface_show - Show the interface BFD configuration.
  */
 void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp,
-                            json_object *json_interface_sub, uint8_t use_json)
+                            json_object *json_interface_sub, bool use_json)
 {
        struct ospf_if_params *params;
 
index 6d7caf4217e5d25e05e5967d1c6597787dfaa60d..74385d326852f3d02c3460f5bc17fd084f8e3a5a 100644 (file)
@@ -35,13 +35,13 @@ extern void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state,
 
 extern void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp,
                                    json_object *json_interface_sub,
-                                   uint8_t use_json);
+                                   bool use_json);
 
 extern void ospf_bfd_info_nbr_create(struct ospf_interface *oi,
                                     struct ospf_neighbor *nbr);
 
 extern void ospf_bfd_show_info(struct vty *vty, void *bfd_info,
-                              json_object *json_obj, uint8_t use_json,
+                              json_object *json_obj, bool use_json,
                               int param_only);
 
 extern void ospf_bfd_info_free(void **bfd_info);
index 19d2e6a95251f4fb1de862a5c56bda0105842370..755634a2f166c5d2d9935351a016a71a7b1b3cc1 100644 (file)
@@ -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;
                        }
index 23dae6b087486b401903cd9adc840f57ecbfccfd..220de3234d2097fb9b0943d1e86a01394725d317 100644 (file)
  * 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>
@@ -2311,7 +2315,7 @@ DEFUN (show_ip_opsf_srdb,
        int idx = 0;
        struct in_addr rid;
        struct sr_node *srn;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL, *json_node_array = NULL;
 
        if (!OspfSR.enabled) {
index 39f14a00c3acf850a49ae12bc0c85820624a22c8..aa877903fc07f20d6468082a8620d5b7be782838 100644 (file)
@@ -2623,7 +2623,7 @@ const char *ospf_abr_type_descr_str[] = {"Unknown", "Standard (RFC2328)",
 const char *ospf_shortcut_mode_descr_str[] = {"Default", "Enabled", "Disabled"};
 
 static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area,
-                             json_object *json_areas, uint8_t use_json)
+                             json_object *json_areas, bool use_json)
 {
        json_object *json_area = NULL;
 
@@ -3243,7 +3243,7 @@ DEFUN (show_ip_ospf,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        char *vrf_name = NULL;
        bool all_vrf = FALSE;
@@ -3263,11 +3263,15 @@ DEFUN (show_ip_ospf,
 
        /* vrf input is provided could be all or specific vrf*/
        if (vrf_name) {
+               bool ospf_output = FALSE;
+
                use_vrf = 1;
+
                if (all_vrf) {
                        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                                if (!ospf->oi_running)
                                        continue;
+                               ospf_output = TRUE;
                                ret = show_ip_ospf_common(vty, ospf, json,
                                                          use_vrf);
                        }
@@ -3276,21 +3280,34 @@ DEFUN (show_ip_ospf,
                                        json_object_to_json_string_ext(
                                                json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
-                       }
+                       } else if (!ospf_output)
+                               vty_out(vty, "%% OSPF instance not found\n");
                        return ret;
                }
                ospf = ospf_lookup_by_inst_name(inst, vrf_name);
                if ((ospf == NULL) || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
        } else {
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                /* Display default ospf (instance 0) info */
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
        }
@@ -3321,7 +3338,7 @@ DEFUN (show_ip_ospf_instance,
        int idx_number = 3;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        int ret = CMD_SUCCESS;
        json_object *json = NULL;
 
@@ -3350,7 +3367,7 @@ DEFUN (show_ip_ospf_instance,
 static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
                                       struct interface *ifp,
                                       json_object *json_interface_sub,
-                                      uint8_t use_json)
+                                      bool use_json)
 {
        int is_up;
        struct ospf_neighbor *nbr;
@@ -3667,7 +3684,7 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
 
 static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
                                         char *intf_name, uint8_t use_vrf,
-                                        json_object *json, uint8_t use_json)
+                                        json_object *json, bool use_json)
 {
        struct interface *ifp;
        struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
@@ -3760,7 +3777,7 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
 static void show_ip_ospf_interface_traffic_sub(struct vty *vty,
                                               struct ospf_interface *oi,
                                               json_object *json_interface_sub,
-                                              uint8_t use_json)
+                                              bool use_json)
 {
        if (use_json) {
                json_object_int_add(json_interface_sub, "ifIndex",
@@ -3798,7 +3815,7 @@ static void show_ip_ospf_interface_traffic_sub(struct vty *vty,
 /* OSPFv2 Packet Counters */
 static int show_ip_ospf_interface_traffic_common(
        struct vty *vty, struct ospf *ospf, char *intf_name, json_object *json,
-       int display_once, uint8_t use_vrf, uint8_t use_json)
+       int display_once, uint8_t use_vrf, bool use_json)
 {
        struct vrf *vrf = NULL;
        struct interface *ifp = NULL;
@@ -3916,7 +3933,7 @@ DEFUN (show_ip_ospf_interface,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        char *vrf_name = NULL, *intf_name = NULL;
        bool all_vrf = FALSE;
@@ -3951,14 +3968,21 @@ DEFUN (show_ip_ospf_interface,
                                        json_object_to_json_string_ext(
                                                json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
-                       }
+                       } else if (!ospf)
+                               vty_out(vty, "%% OSPF instance not found\n");
 
                        return ret;
                }
                ospf = ospf_lookup_by_inst_name(inst, vrf_name);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
                ret = show_ip_ospf_interface_common(vty, ospf, intf_name,
@@ -3968,8 +3992,14 @@ DEFUN (show_ip_ospf_interface,
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
                ret = show_ip_ospf_interface_common(vty, ospf, intf_name,
@@ -4000,7 +4030,7 @@ DEFUN (show_ip_ospf_instance_interface,
        int idx_intf = 0;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        char *intf_name = NULL;
        int ret = CMD_SUCCESS;
        json_object *json = NULL;
@@ -4049,7 +4079,7 @@ DEFUN (show_ip_ospf_interface_traffic,
        bool all_vrf = FALSE;
        int inst = 0;
        int idx_vrf = 0, idx_intf = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        int ret = CMD_SUCCESS;
        int display_once = 0;
@@ -4125,7 +4155,7 @@ static void show_ip_ospf_neighbour_header(struct vty *vty)
 
 static void show_ip_ospf_neighbor_sub(struct vty *vty,
                                      struct ospf_interface *oi,
-                                     json_object *json, uint8_t use_json)
+                                     json_object *json, bool use_json)
 {
        struct route_node *rn;
        struct ospf_neighbor *nbr, *prev_nbr = NULL;
@@ -4236,7 +4266,7 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty,
 }
 
 static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
-                                       json_object *json, uint8_t use_json,
+                                       json_object *json, bool use_json,
                                        uint8_t use_vrf)
 {
        struct ospf_interface *oi;
@@ -4298,7 +4328,7 @@ DEFUN (show_ip_ospf_neighbor,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        char *vrf_name = NULL;
        bool all_vrf = FALSE;
@@ -4329,23 +4359,36 @@ DEFUN (show_ip_ospf_neighbor,
                                        json_object_to_json_string_ext(
                                                json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
-                       }
+                       } else if (!ospf)
+                               vty_out(vty, "OSPF instance not found\n");
 
                        return ret;
                }
 
                ospf = ospf_lookup_by_inst_name(inst, vrf_name);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
        } else {
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
        }
@@ -4381,7 +4424,7 @@ DEFUN (show_ip_ospf_instance_neighbor,
        int idx_number = 3;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        int ret = CMD_SUCCESS;
 
@@ -4408,7 +4451,7 @@ DEFUN (show_ip_ospf_instance_neighbor,
 }
 
 static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
-                                           json_object *json, uint8_t use_json,
+                                           json_object *json, bool use_json,
                                            uint8_t use_vrf)
 {
        struct listnode *node;
@@ -4511,7 +4554,7 @@ DEFUN (show_ip_ospf_neighbor_all,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        char *vrf_name = NULL;
        bool all_vrf = FALSE;
@@ -4593,7 +4636,7 @@ DEFUN (show_ip_ospf_instance_neighbor_all,
        int idx_number = 3;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        int ret = CMD_SUCCESS;
 
@@ -4621,7 +4664,7 @@ DEFUN (show_ip_ospf_instance_neighbor_all,
 static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
                                            int arg_base,
                                            struct cmd_token **argv,
-                                           uint8_t use_json, uint8_t use_vrf)
+                                           bool use_json, uint8_t use_vrf)
 {
        struct interface *ifp;
        struct route_node *rn;
@@ -4680,7 +4723,7 @@ DEFUN (show_ip_ospf_neighbor_int,
 {
        struct ospf *ospf;
        int idx_ifname = 4;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        int ret = CMD_SUCCESS;
        struct interface *ifp = NULL;
@@ -4716,7 +4759,7 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
        int idx_ifname = 5;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!uj)
                show_ip_ospf_neighbour_header(vty);
@@ -4739,8 +4782,7 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
 static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
                                             struct ospf_interface *oi,
                                             struct ospf_nbr_nbma *nbr_nbma,
-                                            uint8_t use_json,
-                                            json_object *json)
+                                            bool use_json, json_object *json)
 {
        char timebuf[OSPF_TIME_DUMP_SIZE];
        json_object *json_sub = NULL;
@@ -4820,8 +4862,7 @@ static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
 static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
                                             struct ospf_interface *oi,
                                             struct ospf_neighbor *nbr,
-                                            json_object *json,
-                                            uint8_t use_json)
+                                            json_object *json, bool use_json)
 {
        char timebuf[OSPF_TIME_DUMP_SIZE];
        json_object *json_sub = NULL;
@@ -5037,7 +5078,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
 static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
                                           int arg_base,
                                           struct cmd_token **argv,
-                                          uint8_t use_json, uint8_t use_vrf)
+                                          bool use_json, uint8_t use_vrf)
 {
        struct listnode *node;
        struct ospf_neighbor *nbr;
@@ -5098,7 +5139,7 @@ DEFUN (show_ip_ospf_neighbor_id,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        int ret = CMD_SUCCESS;
 
@@ -5127,7 +5168,7 @@ DEFUN (show_ip_ospf_instance_neighbor_id,
        int idx_router_id = 5;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        instance = strtoul(argv[idx_number]->arg, NULL, 10);
        ospf = ospf_lookup_instance(instance);
@@ -5143,8 +5184,7 @@ DEFUN (show_ip_ospf_instance_neighbor_id,
 
 static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
                                               struct ospf *ospf,
-                                              json_object *json,
-                                              uint8_t use_json,
+                                              json_object *json, bool use_json,
                                               uint8_t use_vrf)
 {
        struct ospf_interface *oi;
@@ -5212,7 +5252,7 @@ DEFUN (show_ip_ospf_neighbor_detail,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        char *vrf_name = NULL;
        bool all_vrf = FALSE;
@@ -5292,7 +5332,7 @@ DEFUN (show_ip_ospf_instance_neighbor_detail,
        int idx_number = 3;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        int ret = CMD_SUCCESS;
 
@@ -5321,7 +5361,7 @@ DEFUN (show_ip_ospf_instance_neighbor_detail,
 static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
                                                   struct ospf *ospf,
                                                   json_object *json,
-                                                  uint8_t use_json,
+                                                  bool use_json,
                                                   uint8_t use_vrf)
 {
        struct listnode *node;
@@ -5401,7 +5441,7 @@ DEFUN (show_ip_ospf_neighbor_detail_all,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        char *vrf_name = NULL;
        bool all_vrf = FALSE;
@@ -5483,7 +5523,7 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all,
        int idx_number = 3;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        int ret = CMD_SUCCESS;
 
@@ -5513,7 +5553,7 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
                                                   struct ospf *ospf,
                                                   int arg_base,
                                                   struct cmd_token **argv,
-                                                  uint8_t use_json)
+                                                  bool use_json)
 {
        struct ospf_interface *oi;
        struct interface *ifp;
@@ -5581,17 +5621,22 @@ DEFUN (show_ip_ospf_neighbor_int_detail,
        JSON_STR)
 {
        struct ospf *ospf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        int ret = CMD_SUCCESS;
+       bool ospf_output = FALSE;
 
        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                if (!ospf->oi_running)
                        continue;
+               ospf_output = TRUE;
                ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0,
                                                              argv, uj);
        }
 
+       if (!ospf_output)
+               vty_out(vty, "%% OSPF instance not found\n");
+
        return ret;
 }
 
@@ -5611,7 +5656,7 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail,
        int idx_ifname = 5;
        struct ospf *ospf;
        unsigned short instance = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        instance = strtoul(argv[idx_number]->arg, NULL, 10);
        ospf = ospf_lookup_instance(instance);
@@ -6296,19 +6341,28 @@ DEFUN (show_ip_ospf_database_max,
        OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
        if (vrf_name) {
+               bool ospf_output = FALSE;
+
                use_vrf = 1;
+
                if (all_vrf) {
                        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                                if (!ospf->oi_running)
                                        continue;
+                               ospf_output = TRUE;
                                ret = show_ip_ospf_database_common(
                                        vty, ospf, idx_vrf ? 2 : 0, argc, argv,
                                        use_vrf);
                        }
+
+                       if (!ospf_output)
+                               vty_out(vty, "%% OSPF instance not found\n");
                } else {
                        ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-                       if (ospf == NULL || !ospf->oi_running)
+                       if (ospf == NULL || !ospf->oi_running) {
+                               vty_out(vty, "%% OSPF instance not found\n");
                                return CMD_SUCCESS;
+                       }
                        ret = (show_ip_ospf_database_common(
                                vty, ospf, idx_vrf ? 2 : 0, argc, argv,
                                use_vrf));
@@ -6316,8 +6370,11 @@ DEFUN (show_ip_ospf_database_max,
        } else {
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
-               if (ospf == NULL || !ospf->oi_running)
+               if (ospf == NULL || !ospf->oi_running) {
+                       vty_out(vty, "%% OSPF instance not found\n");
                        return CMD_SUCCESS;
+               }
+
                ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv,
                                                   use_vrf);
        }
@@ -6377,16 +6434,22 @@ DEFUN (show_ip_ospf_instance_database,
                        }
                } else {
                        ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-                       if ((ospf == NULL) || !ospf->oi_running)
+                       if ((ospf == NULL) || !ospf->oi_running) {
+                               vty_out(vty, "%% OSPF instance not found\n");
                                return CMD_SUCCESS;
+                       }
+
                        ret = (show_ip_ospf_database_common(
                                vty, ospf, idx ? 2 : 0, argc, argv, use_vrf));
                }
        } else {
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
-               if (ospf == NULL || !ospf->oi_running)
+               if (ospf == NULL || !ospf->oi_running) {
+                       vty_out(vty, "%% OSPF instance not found\n");
                        return CMD_SUCCESS;
+               }
+
                ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv,
                                                    use_vrf));
        }
@@ -6415,8 +6478,10 @@ DEFUN (show_ip_ospf_instance_database_max,
        if (ospf == NULL)
                return CMD_NOT_MY_INSTANCE;
 
-       if (!ospf->oi_running)
+       if (!ospf->oi_running) {
+               vty_out(vty, "%% OSPF instance not found\n");
                return CMD_SUCCESS;
+       }
 
        return show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0);
 }
@@ -6505,8 +6570,11 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
                ospf = ospf_lookup_instance(instance);
                if (ospf == NULL)
                        return CMD_NOT_MY_INSTANCE;
-               if (!ospf->oi_running)
+               if (!ospf->oi_running) {
+                       vty_out(vty, "%% OSPF instance not found\n");
                        return CMD_SUCCESS;
+               }
+
                return (show_ip_ospf_database_type_adv_router_common(
                        vty, ospf, idx ? 1 : 0, argc, argv, use_vrf));
        }
@@ -6514,27 +6582,39 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
        OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
        if (vrf_name) {
+               bool ospf_output = FALSE;
+
                use_vrf = 1;
+
                if (all_vrf) {
                        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                                if (!ospf->oi_running)
                                        continue;
+                               ospf_output = TRUE;
                                ret = show_ip_ospf_database_type_adv_router_common(
                                        vty, ospf, idx ? 1 : 0, argc, argv,
                                        use_vrf);
                        }
+                       if (!ospf_output)
+                               vty_out(vty, "%% OSPF instance not found\n");
                } else {
                        ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-                       if ((ospf == NULL) || !ospf->oi_running)
+                       if ((ospf == NULL) || !ospf->oi_running) {
+                               vty_out(vty, "%% OSPF instance not found\n");
                                return CMD_SUCCESS;
+                       }
+
                        ret = show_ip_ospf_database_type_adv_router_common(
                                vty, ospf, idx ? 1 : 0, argc, argv, use_vrf);
                }
        } else {
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
-               if (ospf == NULL || !ospf->oi_running)
+               if (ospf == NULL || !ospf->oi_running) {
+                       vty_out(vty, "%% OSPF instance not found\n");
                        return CMD_SUCCESS;
+               }
+
                ret = show_ip_ospf_database_type_adv_router_common(
                        vty, ospf, idx ? 1 : 0, argc, argv, use_vrf);
        }
@@ -9271,19 +9351,28 @@ DEFUN (show_ip_ospf_border_routers,
        OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
        if (vrf_name) {
+               bool ospf_output = FALSE;
+
                use_vrf = 1;
+
                if (all_vrf) {
                        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                                if (!ospf->oi_running)
                                        continue;
 
+                               ospf_output = TRUE;
                                ret = show_ip_ospf_border_routers_common(
                                        vty, ospf, use_vrf);
                        }
+
+                       if (!ospf_output)
+                               vty_out(vty, "%% OSPF instance not found\n");
                } else {
                        ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-                       if (ospf == NULL || !ospf->oi_running)
+                       if (ospf == NULL || !ospf->oi_running) {
+                               vty_out(vty, "%% OSPF instance not found\n");
                                return CMD_SUCCESS;
+                       }
 
                        ret = show_ip_ospf_border_routers_common(vty, ospf,
                                                                 use_vrf);
@@ -9291,8 +9380,11 @@ DEFUN (show_ip_ospf_border_routers,
        } else {
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
-               if (ospf == NULL || !ospf->oi_running)
+               if (ospf == NULL || !ospf->oi_running) {
+                       vty_out(vty, "%% OSPF instance not found\n");
                        return CMD_SUCCESS;
+               }
+
                ret = show_ip_ospf_border_routers_common(vty, ospf, use_vrf);
        }
 
@@ -9393,7 +9485,7 @@ DEFUN (show_ip_ospf_route,
        int inst = 0;
        int idx_vrf = 0;
        uint8_t use_vrf = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
 
        if (uj)
@@ -9403,11 +9495,15 @@ DEFUN (show_ip_ospf_route,
 
        /* vrf input is provided could be all or specific vrf*/
        if (vrf_name) {
+               bool ospf_output = FALSE;
+
                use_vrf = 1;
+
                if (all_vrf) {
                        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                                if (!ospf->oi_running)
                                        continue;
+                               ospf_output = TRUE;
                                ret = show_ip_ospf_route_common(vty, ospf, json,
                                                                use_vrf);
                        }
@@ -9417,22 +9513,35 @@ DEFUN (show_ip_ospf_route,
                                vty_out(vty, "%s\n",
                                        json_object_to_json_string(json));
                                json_object_free(json);
-                       }
+                       } else if (!ospf_output)
+                               vty_out(vty, "%% OSPF instance not found\n");
 
                        return ret;
                }
                ospf = ospf_lookup_by_inst_name(inst, vrf_name);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
        } else {
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
                                json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
                        return CMD_SUCCESS;
                }
        }
@@ -9484,7 +9593,7 @@ DEFUN (show_ip_ospf_vrfs,
        "Show OSPF VRFs \n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        json_object *json_vrfs = NULL;
        struct ospf *ospf = NULL;
index cd659a9bc92592448beb1de28040a1b992df6d9b..83074b5ac018f8c8f2d6a0c152b3cde4e0671bdd 100644 (file)
@@ -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 = \
index ff95d885276f568677fb67c1c4c38b14213d6502..86622ea1741650b27941db46ae0338cd8d19f111 100644 (file)
@@ -1,15 +1 @@
-!Makefile
-Makefile.in
-libpbr.a
 pbrd
-tags
-TAGS
-.deps
-*.o
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
index 42ab393218ff8c6f47260b00bf7b18961b00e4f1..79475590345dd8ac9d7e8476fb47e7e5eadca393 100644 (file)
@@ -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 = \
index 1f56cfaecdabd2dac7344f859ef8710ce6b03079..b1780df7584697357283efef27fb41449690cccc 100644 (file)
@@ -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
index c0d95aeed9e3799542ee7097f3d982b899a8e98e..65c495eff04502a6f0ca35e74be2d362f4d0aa30 100644 (file)
  * 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"
index b4bf6bada34b256c4ef2eab050cdce6c1a05fbd9..30ee8f24abd7fb26a165818a84a6999ff5ed21ab 100644 (file)
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifdef __linux__
 
 #include <stdio.h>
index 8c1cd8d96303b03995347409b10db6ddd3960986..8d974403ac631e8e100a5fba4c989f992bd6854a 100644 (file)
  * 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>
index f7a217b514f492d1bfb1aee0ee1b9877aed88313..466cc60643aca3bbb2d5a6a97c5cb4446e14db34 100644 (file)
@@ -64,7 +64,7 @@ void pim_bfd_write_config(struct vty *vty, struct interface *ifp)
  * pim_bfd_show_info - Show BFD info structure
  */
 void pim_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
-                      uint8_t use_json, int param_only)
+                      bool use_json, int param_only)
 {
        if (param_only)
                bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json,
index 83def93b6674130cdb6a5f35cd740477feb5581a..962b727f88f3ea0b8bb53c4d969fbda9256ea38a 100644 (file)
@@ -28,7 +28,7 @@
 void pim_bfd_init(void);
 void pim_bfd_write_config(struct vty *vty, struct interface *ifp);
 void pim_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
-                      uint8_t use_json, int param_only);
+                      bool use_json, int param_only);
 void pim_bfd_if_param_set(struct interface *ifp, uint32_t min_rx,
                          uint32_t min_tx, uint8_t detect_mult, int defaults);
 int pim_bfd_reg_dereg_all_nbr(struct interface *ifp, int command);
index 611d8d36811af5b631300f324e955add2458234a..8ef8f87d153e23b2ee4522af73a09384cb0f49d3 100644 (file)
@@ -432,7 +432,7 @@ static void pim_show_membership_helper(struct vty *vty,
        json_object_object_add(json_iface, ch_grp_str, json_row);
 }
 static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
-                               uint8_t uj)
+                               bool uj)
 {
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
@@ -549,7 +549,7 @@ static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp,
 }
 
 static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
-                                uint8_t uj)
+                                bool uj)
 {
        struct interface *ifp;
        time_t now;
@@ -634,7 +634,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
 
 static void igmp_show_interfaces_single(struct pim_instance *pim,
                                        struct vty *vty, const char *ifname,
-                                       uint8_t uj)
+                                       bool uj)
 {
        struct igmp_sock *igmp;
        struct interface *ifp;
@@ -894,7 +894,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
 
 static void pim_show_interfaces_single(struct pim_instance *pim,
                                       struct vty *vty, const char *ifname,
-                                      uint8_t uj)
+                                      bool uj)
 {
        struct in_addr ifaddr;
        struct interface *ifp;
@@ -1295,7 +1295,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
 }
 
 static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
-                                const char *ifname, uint8_t uj)
+                                const char *ifname, bool uj)
 {
        struct interface *ifp;
        struct igmp_stats rx_stats;
@@ -1365,7 +1365,7 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
 }
 
 static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
-                               uint8_t uj)
+                               bool uj)
 {
        struct interface *ifp;
        struct listnode *upnode;
@@ -1458,7 +1458,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
 }
 
 static void pim_show_interface_traffic(struct pim_instance *pim,
-                                      struct vty *vty, uint8_t uj)
+                                      struct vty *vty, bool uj)
 {
        struct interface *ifp = NULL;
        struct pim_interface *pim_ifp = NULL;
@@ -1538,7 +1538,7 @@ static void pim_show_interface_traffic(struct pim_instance *pim,
 
 static void pim_show_interface_traffic_single(struct pim_instance *pim,
                                              struct vty *vty,
-                                             const char *ifname, uint8_t uj)
+                                             const char *ifname, bool uj)
 {
        struct interface *ifp = NULL;
        struct pim_interface *pim_ifp = NULL;
@@ -1627,7 +1627,7 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim,
 
 static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
                                 struct pim_ifchannel *ch, json_object *json,
-                                time_t now, uint8_t uj)
+                                time_t now, bool uj)
 {
        char ch_src_str[INET_ADDRSTRLEN];
        char ch_grp_str[INET_ADDRSTRLEN];
@@ -1690,7 +1690,7 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
        }
 }
 
-static void pim_show_join(struct pim_instance *pim, struct vty *vty, uint8_t uj)
+static void pim_show_join(struct pim_instance *pim, struct vty *vty, bool uj)
 {
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
@@ -1724,7 +1724,7 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, uint8_t uj)
 }
 
 static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
-                                     const char *neighbor, uint8_t uj)
+                                     const char *neighbor, bool uj)
 {
        struct listnode *neighnode;
        struct interface *ifp;
@@ -1933,8 +1933,7 @@ static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
 }
 
 static void pim_show_state(struct pim_instance *pim, struct vty *vty,
-                          const char *src_or_group, const char *group,
-                          uint8_t uj)
+                          const char *src_or_group, const char *group, bool uj)
 {
        struct channel_oil *c_oil;
        struct listnode *node;
@@ -2135,7 +2134,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
 }
 
 static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
-                              uint8_t uj)
+                              bool uj)
 {
        struct listnode *neighnode;
        struct interface *ifp;
@@ -2331,7 +2330,7 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
 }
 
 static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
-                             uint8_t uj)
+                             bool uj)
 {
        struct listnode *upnode;
        struct pim_upstream *up;
@@ -2476,7 +2475,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim,
                                         struct vty *vty,
                                         struct pim_interface *pim_ifp,
                                         struct pim_ifchannel *ch,
-                                        json_object *json, uint8_t uj)
+                                        json_object *json, bool uj)
 {
        struct pim_upstream *up = ch->upstream;
        json_object *json_group = NULL;
@@ -2532,7 +2531,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim,
 }
 
 static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
-                                 uint8_t uj)
+                                 bool uj)
 {
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
@@ -2568,7 +2567,7 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
 }
 
 static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
-                                 uint8_t uj)
+                                 bool uj)
 {
        struct listnode *upnode;
        struct pim_upstream *up;
@@ -2701,7 +2700,7 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
                uptime_mroute_del, (long long)pim->mroute_del_events);
 }
 
-static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, uint8_t uj)
+static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
 {
        struct listnode *up_node;
        struct pim_upstream *up;
@@ -2821,8 +2820,7 @@ static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
        hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
 }
 
-static void igmp_show_groups(struct pim_instance *pim, struct vty *vty,
-                            uint8_t uj)
+static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
 {
        struct interface *ifp;
        time_t now;
@@ -3373,7 +3371,7 @@ DEFUN (show_ip_igmp_interface,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3400,7 +3398,7 @@ DEFUN (show_ip_igmp_interface_vrf_all,
        JSON_STR)
 {
        int idx = 2;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -3456,7 +3454,7 @@ DEFUN (show_ip_igmp_join_vrf_all,
        VRF_CMD_HELP_STR
        "IGMP static join information\n")
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -3490,7 +3488,7 @@ DEFUN (show_ip_igmp_groups,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3510,7 +3508,7 @@ DEFUN (show_ip_igmp_groups_vrf_all,
        IGMP_GROUP_STR
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -3608,7 +3606,7 @@ DEFUN (show_ip_igmp_statistics,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3715,7 +3713,7 @@ DEFUN (show_ip_pim_interface,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3742,7 +3740,7 @@ DEFUN (show_ip_pim_interface_vrf_all,
        JSON_STR)
 {
        int idx = 6;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -3781,7 +3779,7 @@ DEFUN (show_ip_pim_join,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3801,7 +3799,7 @@ DEFUN (show_ip_pim_join_vrf_all,
        "PIM interface join information\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -3835,7 +3833,7 @@ DEFUN (show_ip_pim_local_membership,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3859,7 +3857,7 @@ DEFUN (show_ip_pim_neighbor,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3886,7 +3884,7 @@ DEFUN (show_ip_pim_neighbor_vrf_all,
        JSON_STR)
 {
        int idx = 2;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -3949,7 +3947,7 @@ DEFUN (show_ip_pim_state,
        const char *group = NULL;
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -3983,7 +3981,7 @@ DEFUN (show_ip_pim_state_vrf_all,
        const char *src_or_group = NULL;
        const char *group = NULL;
        int idx = 2;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -4026,7 +4024,7 @@ DEFUN (show_ip_pim_upstream,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -4046,7 +4044,7 @@ DEFUN (show_ip_pim_upstream_vrf_all,
        "PIM upstream information\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -4078,7 +4076,7 @@ DEFUN (show_ip_pim_upstream_join_desired,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -4100,7 +4098,7 @@ DEFUN (show_ip_pim_upstream_rpf,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -4122,7 +4120,7 @@ DEFUN (show_ip_pim_rp,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -4142,7 +4140,7 @@ DEFUN (show_ip_pim_rp_vrf_all,
        "PIM RP information\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -4176,7 +4174,7 @@ DEFUN (show_ip_pim_rpf,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -4196,7 +4194,7 @@ DEFUN (show_ip_pim_rpf_vrf_all,
        "PIM cached source rpf information\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -4349,7 +4347,7 @@ DEFUN (show_ip_pim_interface_traffic,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -4473,7 +4471,7 @@ DEFUN (show_ip_multicast_vrf_all,
        VRF_CMD_HELP_STR
        "Multicast global information\n")
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -4496,7 +4494,7 @@ DEFUN (show_ip_multicast_vrf_all,
 }
 
 static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
-                       uint8_t uj)
+                       bool uj)
 {
        struct listnode *node;
        struct channel_oil *c_oil;
@@ -4830,7 +4828,7 @@ DEFUN (show_ip_mroute,
        "Fill in Assumed data\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        bool fill = false;
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
@@ -4855,7 +4853,7 @@ DEFUN (show_ip_mroute_vrf_all,
        "Fill in Assumed data\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        int idx = 4;
        struct vrf *vrf;
        bool first = true;
@@ -4963,7 +4961,7 @@ DEFUN (show_ip_mroute_count_vrf_all,
        VRF_CMD_HELP_STR
        "Route and packet count data\n")
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -5549,7 +5547,7 @@ DEFUN (no_ip_pim_ssm_prefix_list_name,
 }
 
 static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
-                                       struct vty *vty, uint8_t uj)
+                                       struct vty *vty, bool uj)
 {
        struct pim_ssm *ssm = pim->ssm_info;
        const char *range_str =
@@ -5578,7 +5576,7 @@ DEFUN (show_ip_pim_ssm_range,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -5589,7 +5587,7 @@ DEFUN (show_ip_pim_ssm_range,
 }
 
 static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
-                                      struct vty *vty, uint8_t uj,
+                                      struct vty *vty, bool uj,
                                       const char *group)
 {
        struct in_addr group_addr;
@@ -5631,7 +5629,7 @@ DEFUN (show_ip_pim_group_type,
 {
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!vrf)
                return CMD_WARNING;
@@ -5642,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]",
@@ -6433,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;
@@ -6455,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;
@@ -6480,6 +6472,17 @@ static int pim_cmd_interface_delete(struct interface *ifp)
        return 1;
 }
 
+static int interface_no_ip_pim_helper(struct vty *vty)
+{
+        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 CMD_SUCCESS;
+}
+
 DEFUN_HIDDEN (interface_no_ip_pim_ssm,
        interface_no_ip_pim_ssm_cmd,
        "no ip pim ssm",
@@ -6488,16 +6491,10 @@ DEFUN_HIDDEN (interface_no_ip_pim_ssm,
        PIM_STR
        IFACE_PIM_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 CMD_SUCCESS;
+       return interface_no_ip_pim_helper(vty);
 }
 
-DEFUN (interface_no_ip_pim_sm,
+DEFUN_HIDDEN (interface_no_ip_pim_sm,
        interface_no_ip_pim_sm_cmd,
        "no ip pim sm",
        NO_STR
@@ -6505,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 */
@@ -7468,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")
 {
@@ -7480,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")
 {
@@ -7908,7 +7909,7 @@ static void print_empty_json_obj(struct vty *vty)
 }
 
 static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
-                                   uint8_t uj)
+                                   bool uj)
 {
        struct listnode *mbrnode;
        struct pim_msdp_mg_mbr *mbr;
@@ -7985,7 +7986,7 @@ DEFUN (show_ip_msdp_mesh_group,
        "MSDP mesh-group information\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
 
@@ -8007,7 +8008,7 @@ DEFUN (show_ip_msdp_mesh_group_vrf_all,
        "MSDP mesh-group information\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -8030,7 +8031,7 @@ DEFUN (show_ip_msdp_mesh_group_vrf_all,
 }
 
 static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
-                              uint8_t uj)
+                              bool uj)
 {
        struct listnode *mpnode;
        struct pim_msdp_peer *mp;
@@ -8084,7 +8085,7 @@ static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
 }
 
 static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
-                                     const char *peer, uint8_t uj)
+                                     const char *peer, bool uj)
 {
        struct listnode *mpnode;
        struct pim_msdp_peer *mp;
@@ -8200,7 +8201,7 @@ DEFUN (show_ip_msdp_peer_detail,
        "peer ip address\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
 
@@ -8235,7 +8236,7 @@ DEFUN (show_ip_msdp_peer_detail_vrf_all,
        JSON_STR)
 {
        int idx = 2;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -8262,8 +8263,7 @@ DEFUN (show_ip_msdp_peer_detail_vrf_all,
        return CMD_SUCCESS;
 }
 
-static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty,
-                           uint8_t uj)
+static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
 {
        struct listnode *sanode;
        struct pim_msdp_sa *sa;
@@ -8340,7 +8340,7 @@ static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty,
 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
                                         const char *src_str,
                                         const char *grp_str, struct vty *vty,
-                                        uint8_t uj, json_object *json)
+                                        bool uj, json_object *json)
 {
        char rp_str[INET_ADDRSTRLEN];
        char peer_str[INET_ADDRSTRLEN];
@@ -8404,7 +8404,7 @@ static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
 }
 
 static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
-                                  uint8_t uj)
+                                  bool uj)
 {
        struct listnode *sanode;
        struct pim_msdp_sa *sa;
@@ -8441,7 +8441,7 @@ DEFUN (show_ip_msdp_sa_detail,
        "Detailed output\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
 
@@ -8464,7 +8464,7 @@ DEFUN (show_ip_msdp_sa_detail_vrf_all,
        "Detailed output\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
 
@@ -8487,7 +8487,7 @@ DEFUN (show_ip_msdp_sa_detail_vrf_all,
 }
 
 static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
-                                const char *addr, uint8_t uj)
+                                const char *addr, bool uj)
 {
        struct listnode *sanode;
        struct pim_msdp_sa *sa;
@@ -8516,7 +8516,7 @@ static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
 }
 
 static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
-                              const char *src, const char *grp, uint8_t uj)
+                              const char *src, const char *grp, bool uj)
 {
        struct listnode *sanode;
        struct pim_msdp_sa *sa;
@@ -8556,7 +8556,7 @@ DEFUN (show_ip_msdp_sa_sg,
        "group ip\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        int idx = 2;
 
@@ -8593,7 +8593,7 @@ DEFUN (show_ip_msdp_sa_sg_vrf_all,
        "group ip\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        struct vrf *vrf;
        bool first = true;
        int idx = 2;
@@ -8637,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);
@@ -8724,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);
index 95d0278a34317a789275e5357ee9dab41b33e310..1fb624a6a0bde85f6542697ed8312eef70020c1f 100644 (file)
@@ -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;
index 428816e1f095d6d7a02b400e7d0d0a5ce0c26c60..40851a45299a356f05b7706b099c870c23158874 100644 (file)
  * 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)
index 3db5015e73819eab712120e8ea71745e03ee5ec0..031e527eb34fb6fa53312f8cb54d5937edadf992 100644 (file)
@@ -951,8 +951,7 @@ int pim_rp_check_is_my_ip_address(struct pim_instance *pim,
        return 0;
 }
 
-void pim_rp_show_information(struct pim_instance *pim, struct vty *vty,
-                            uint8_t uj)
+void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
 {
        struct rp_info *rp_info;
        struct rp_info *prev_rp_info = NULL;
index e0631b27bed0d38199cf1cebf7165d50fe22c070..672a69631907c0d12ae4375e2b4d36eca7d8deb7 100644 (file)
@@ -68,7 +68,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group);
 #define RP(P, G)       pim_rp_g ((P), (G))
 
 void pim_rp_show_information(struct pim_instance *pim, struct vty *vty,
-                            uint8_t uj);
+                            bool uj);
 void pim_resolve_rp_nh(struct pim_instance *pim);
 int pim_rp_list_cmp(void *v1, void *v2);
 #endif
index 88be195beec7fba8afa4cb963cea1b13036afd6d..a4aec710e9a6cb2e461c741bc7e0504ea96cf41d 100644 (file)
@@ -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;
                                }
 
index 55d56ece976255f88fee56472fdcda0b3c2c8e88..fef8e36577fe9f5116cafe43222d2d3b871a785f 100644 (file)
@@ -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 = \
index 63e9a66d8f76434ac50c56ae9c3424fd5f133b78..c97f963b3da62e7caf32879f88e2759488a93afd 100644 (file)
@@ -1,8 +1 @@
-Makefile
-Makefile.in
 *.sh
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
diff --git a/ports/.gitignore b/ports/.gitignore
deleted file mode 100644 (file)
index dd5bf7c..0000000
+++ /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 (file)
index dd5bf7c..0000000
+++ /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 (file)
index dd5bf7c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-
index 2e5590964715b3db3c24b8211a9d1462db96c624..a140ce3d5454404312181bb02dee46f542b311b7 100644 (file)
@@ -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 *'
@@ -277,4 +277,4 @@ if __name__ == '__main__':
     process_file(args.cfile, ofd, dumpfd, args.all_defun)
 
     if args.o is not None:
-        clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__)])
+        clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable])
diff --git a/qpb/.gitignore b/qpb/.gitignore
deleted file mode 100644 (file)
index 17e9044..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-!Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
index 7e5ba5b0ce40fb9e56edfe8f521674d25d05b053..aca611ba1952cef41179e371eccbfff443045bda 100644 (file)
  * 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"
index 3c006fd221b5fddc1eef351a6dd9263af492fe3b..75a733f8fcfeba54682d169d492814cac42cf40c 100644 (file)
@@ -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
index a38f1c06e32ab01ec2f0ecce0dcef1dce1f6808f..15804cea0fa7e831c48361adf4bcb17c2ee80263 100644 (file)
@@ -1,10 +1,2 @@
 zebra.spec
 frr.spec
-Makefile
-Makefile.in
-.nfs*
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
index c461e543d238b4cd23d78ae8bbe1b7b58e63b88e..a3f095786d817f11cdc93450982dd0ffadcca0e3 100644 (file)
@@ -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
index de708cf4fd7e313f6866c97543641cec8527bdd3..c301a1c23a5de4d8f9fa85eb5ae1f6704fb26595 100644 (file)
@@ -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
index 2e33aee1730c84c70afef20d9e4f83315c6ecfe0..47a92eed32cc67fb651ad610d81968abbb2ce82f 100755 (executable)
@@ -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
 
index 654d355fd7ea94cbeb6e79a9620c96d0b2a34afe..df7c5da54e5896262ecfcb2601ca4bb23d5b9887 100644 (file)
     /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
+}
index 25b48506a6ed7b22d5660b2f19642e08c5fe1441..bff0b405151344571be6a87080cb0bf9e4b6113d 100644 (file)
@@ -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
index 177250ca6108989feb9094b2374f9a956e85ba15..f149501d61b42b4b7bc6cb4edd303c419ea14df6 100644 (file)
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
 ripd
 ripd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
index 612db1a7abc5646f8d44800c91c53f587d02eee5..0d06e7e653c0f7d00db57b434000902cfcbde20f 100644 (file)
@@ -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 = \
index 213384d139312c317649d738960bfb0a02e7c51e..e6a8ee6be2d47dacb5e014945076a4371142a1d6 100644 (file)
@@ -1,17 +1,2 @@
-!Makefile
-Makefile.in
-*.o
 ripngd
 ripngd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
index ef324b001a734629deaa026eb2f7b957bf8782c3..d7d3d245d6afe80bc98b114a2f4d03d8b29eba81 100644 (file)
@@ -31,7 +31,7 @@
 #include "stream.h"
 #include "zclient.h"
 #include "command.h"
-#include "table.h"
+#include "agg_table.h"
 #include "thread.h"
 #include "privs.h"
 #include "vrf.h"
@@ -159,14 +159,15 @@ static int ripng_if_ipv6_lladdress_check(struct interface *ifp)
 
 static int ripng_if_down(struct interface *ifp)
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct ripng_interface *ri;
        struct list *list = NULL;
        struct listnode *listnode = NULL, *nextnode = NULL;
 
        if (ripng)
-               for (rp = route_top(ripng->table); rp; rp = route_next(rp))
+               for (rp = agg_route_top(ripng->table); rp;
+                    rp = agg_route_next(rp))
                        if ((list = rp->info) != NULL)
                                for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
                                                       rinfo))
@@ -479,7 +480,7 @@ int ripng_interface_address_delete(int command, struct zclient *zclient,
 vector ripng_enable_if;
 
 /* RIPng enable network table. */
-struct route_table *ripng_enable_network;
+struct agg_table *ripng_enable_network;
 
 /* Lookup RIPng enable network. */
 /* Check wether the interface has at least a connected prefix that
@@ -492,7 +493,7 @@ static int ripng_enable_network_lookup_if(struct interface *ifp)
 
        for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
                struct prefix *p;
-               struct route_node *n;
+               struct agg_node *n;
 
                p = connected->address;
 
@@ -501,10 +502,10 @@ static int ripng_enable_network_lookup_if(struct interface *ifp)
                        address.prefix = p->u.prefix6;
                        address.prefixlen = IPV6_MAX_BITLEN;
 
-                       n = route_node_match(ripng_enable_network,
-                                            (struct prefix *)&address);
+                       n = agg_node_match(ripng_enable_network,
+                                          (struct prefix *)&address);
                        if (n) {
-                               route_unlock_node(n);
+                               agg_unlock_node(n);
                                return 1;
                        }
                }
@@ -521,7 +522,7 @@ static int ripng_enable_network_lookup2(struct connected *connected)
        p = connected->address;
 
        if (p->family == AF_INET6) {
-               struct route_node *node;
+               struct agg_node *node;
 
                address.family = p->family;
                address.prefix = p->u.prefix6;
@@ -529,11 +530,11 @@ static int ripng_enable_network_lookup2(struct connected *connected)
 
                /* LPM on p->family, p->u.prefix6/IPV6_MAX_BITLEN within
                 * ripng_enable_network */
-               node = route_node_match(ripng_enable_network,
-                                       (struct prefix *)&address);
+               node = agg_node_match(ripng_enable_network,
+                                     (struct prefix *)&address);
 
                if (node) {
-                       route_unlock_node(node);
+                       agg_unlock_node(node);
                        return 1;
                }
        }
@@ -544,12 +545,12 @@ static int ripng_enable_network_lookup2(struct connected *connected)
 /* Add RIPng enable network. */
 static int ripng_enable_network_add(struct prefix *p)
 {
-       struct route_node *node;
+       struct agg_node *node;
 
-       node = route_node_get(ripng_enable_network, p);
+       node = agg_node_get(ripng_enable_network, p);
 
        if (node->info) {
-               route_unlock_node(node);
+               agg_unlock_node(node);
                return -1;
        } else
                node->info = (void *)1;
@@ -563,17 +564,17 @@ static int ripng_enable_network_add(struct prefix *p)
 /* Delete RIPng enable network. */
 static int ripng_enable_network_delete(struct prefix *p)
 {
-       struct route_node *node;
+       struct agg_node *node;
 
-       node = route_node_lookup(ripng_enable_network, p);
+       node = agg_node_lookup(ripng_enable_network, p);
        if (node) {
                node->info = NULL;
 
                /* Unlock info lock. */
-               route_unlock_node(node);
+               agg_unlock_node(node);
 
                /* Unlock lookup lock. */
-               route_unlock_node(node);
+               agg_unlock_node(node);
 
                return 1;
        }
@@ -771,13 +772,14 @@ void ripng_clean_network()
 {
        unsigned int i;
        char *str;
-       struct route_node *rn;
+       struct agg_node *rn;
 
        /* ripng_enable_network */
-       for (rn = route_top(ripng_enable_network); rn; rn = route_next(rn))
+       for (rn = agg_route_top(ripng_enable_network); rn;
+            rn = agg_route_next(rn))
                if (rn->info) {
                        rn->info = NULL;
-                       route_unlock_node(rn);
+                       agg_unlock_node(rn);
                }
 
        /* ripng_enable_if */
@@ -877,12 +879,12 @@ int ripng_network_write(struct vty *vty, int config_mode)
 {
        unsigned int i;
        const char *ifname;
-       struct route_node *node;
+       struct agg_node *node;
        char buf[BUFSIZ];
 
        /* Write enable network. */
-       for (node = route_top(ripng_enable_network); node;
-            node = route_next(node))
+       for (node = agg_route_top(ripng_enable_network); node;
+            node = agg_route_next(node))
                if (node->info) {
                        struct prefix *p = &node->p;
                        vty_out(vty, "%s%s/%d\n",
@@ -1124,7 +1126,7 @@ void ripng_if_init()
        hook_register_prio(if_del, 0, ripng_if_delete_hook);
 
        /* RIPng enable network init. */
-       ripng_enable_network = route_table_init();
+       ripng_enable_network = agg_table_init();
 
        /* RIPng enable interface init. */
        ripng_enable_if = vector_init(1);
index 83cb59c8b897d1f0ca5d5b7264745e5ac9972fed..f66a0b95272b48fb3b85e579abf1f67c59cb3a84 100644 (file)
@@ -22,7 +22,7 @@
 #include <zebra.h>
 
 #include "prefix.h"
-#include "table.h"
+#include "agg_table.h"
 #include "memory.h"
 #include "if.h"
 #include "vty.h"
@@ -44,13 +44,12 @@ void ripng_aggregate_free(struct ripng_aggregate *aggregate)
 }
 
 /* Aggregate count increment check. */
-void ripng_aggregate_increment(struct route_node *child,
-                              struct ripng_info *rinfo)
+void ripng_aggregate_increment(struct agg_node *child, struct ripng_info *rinfo)
 {
-       struct route_node *np;
+       struct agg_node *np;
        struct ripng_aggregate *aggregate;
 
-       for (np = child; np; np = np->parent)
+       for (np = child; np; np = agg_node_parent(np))
                if ((aggregate = np->aggregate) != NULL) {
                        aggregate->count++;
                        rinfo->suppress++;
@@ -58,13 +57,12 @@ void ripng_aggregate_increment(struct route_node *child,
 }
 
 /* Aggregate count decrement check. */
-void ripng_aggregate_decrement(struct route_node *child,
-                              struct ripng_info *rinfo)
+void ripng_aggregate_decrement(struct agg_node *child, struct ripng_info *rinfo)
 {
-       struct route_node *np;
+       struct agg_node *np;
        struct ripng_aggregate *aggregate;
 
-       for (np = child; np; np = np->parent)
+       for (np = child; np; np = agg_node_parent(np))
                if ((aggregate = np->aggregate) != NULL) {
                        aggregate->count--;
                        rinfo->suppress--;
@@ -72,14 +70,14 @@ void ripng_aggregate_decrement(struct route_node *child,
 }
 
 /* Aggregate count decrement check for a list. */
-void ripng_aggregate_decrement_list(struct route_node *child, struct list *list)
+void ripng_aggregate_decrement_list(struct agg_node *child, struct list *list)
 {
-       struct route_node *np;
+       struct agg_node *np;
        struct ripng_aggregate *aggregate;
        struct ripng_info *rinfo = NULL;
        struct listnode *node = NULL;
 
-       for (np = child; np; np = np->parent)
+       for (np = child; np; np = agg_node_parent(np))
                if ((aggregate = np->aggregate) != NULL)
                        aggregate->count -= listcount(list);
 
@@ -90,8 +88,8 @@ void ripng_aggregate_decrement_list(struct route_node *child, struct list *list)
 /* RIPng routes treatment. */
 int ripng_aggregate_add(struct prefix *p)
 {
-       struct route_node *top;
-       struct route_node *rp;
+       struct agg_node *top;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct ripng_aggregate *aggregate;
        struct ripng_aggregate *sub;
@@ -99,7 +97,7 @@ int ripng_aggregate_add(struct prefix *p)
        struct listnode *node = NULL;
 
        /* Get top node for aggregation. */
-       top = route_node_get(ripng->table, p);
+       top = agg_node_get(ripng->table, p);
 
        /* Allocate new aggregate. */
        aggregate = ripng_aggregate_new();
@@ -108,7 +106,7 @@ int ripng_aggregate_add(struct prefix *p)
        top->aggregate = aggregate;
 
        /* Suppress routes match to the aggregate. */
-       for (rp = route_lock_node(top); rp; rp = route_next_until(rp, top)) {
+       for (rp = agg_lock_node(top); rp; rp = agg_route_next_until(rp, top)) {
                /* Suppress normal route. */
                if ((list = rp->info) != NULL)
                        for (ALL_LIST_ELEMENTS_RO(list, node, rinfo)) {
@@ -128,8 +126,8 @@ int ripng_aggregate_add(struct prefix *p)
 /* Delete RIPng static route. */
 int ripng_aggregate_delete(struct prefix *p)
 {
-       struct route_node *top;
-       struct route_node *rp;
+       struct agg_node *top;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct ripng_aggregate *aggregate;
        struct ripng_aggregate *sub;
@@ -137,13 +135,13 @@ int ripng_aggregate_delete(struct prefix *p)
        struct listnode *node = NULL;
 
        /* Get top node for aggregation. */
-       top = route_node_get(ripng->table, p);
+       top = agg_node_get(ripng->table, p);
 
        /* Allocate new aggregate. */
        aggregate = top->aggregate;
 
        /* Suppress routes match to the aggregate. */
-       for (rp = route_lock_node(top); rp; rp = route_next_until(rp, top)) {
+       for (rp = agg_lock_node(top); rp; rp = agg_route_next_until(rp, top)) {
                /* Suppress normal route. */
                if ((list = rp->info) != NULL)
                        for (ALL_LIST_ELEMENTS_RO(list, node, rinfo)) {
@@ -160,8 +158,8 @@ int ripng_aggregate_delete(struct prefix *p)
        top->aggregate = NULL;
        ripng_aggregate_free(aggregate);
 
-       route_unlock_node(top);
-       route_unlock_node(top);
+       agg_unlock_node(top);
+       agg_unlock_node(top);
 
        return 0;
 }
index dc7d422d1e0fba47dc3e4b805850af39c8ad15a9..e402f4a66c850a7016eb097cadb30ec64ea4049b 100644 (file)
@@ -42,11 +42,11 @@ struct ripng_aggregate {
        uint16_t tag_out;
 };
 
-extern void ripng_aggregate_increment(struct route_node *rp,
+extern void ripng_aggregate_increment(struct agg_node *rp,
                                      struct ripng_info *rinfo);
-extern void ripng_aggregate_decrement(struct route_node *rp,
+extern void ripng_aggregate_decrement(struct agg_node *rp,
                                      struct ripng_info *rinfo);
-extern void ripng_aggregate_decrement_list(struct route_node *rp,
+extern void ripng_aggregate_decrement_list(struct agg_node *rp,
                                           struct list *list);
 extern int ripng_aggregate_add(struct prefix *p);
 extern int ripng_aggregate_delete(struct prefix *p);
index 6830e0e926a0c4adaacc981c196fbfa6ea65fc9d..a8cc9ee128b4977288fb71bf13c597b4455bb9b9 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "command.h"
 #include "prefix.h"
-#include "table.h"
+#include "agg_table.h"
 #include "stream.h"
 #include "memory.h"
 #include "routemap.h"
@@ -37,7 +37,7 @@
 struct zclient *zclient = NULL;
 
 /* Send ECMP routes to zebra. */
-static void ripng_zebra_ipv6_send(struct route_node *rp, uint8_t cmd)
+static void ripng_zebra_ipv6_send(struct agg_node *rp, uint8_t cmd)
 {
        struct list *list = (struct list *)rp->info;
        struct zapi_route api;
@@ -100,13 +100,13 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, uint8_t cmd)
 }
 
 /* Add/update ECMP routes to zebra. */
-void ripng_zebra_ipv6_add(struct route_node *rp)
+void ripng_zebra_ipv6_add(struct agg_node *rp)
 {
        ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_ADD);
 }
 
 /* Delete ECMP routes from zebra. */
-void ripng_zebra_ipv6_delete(struct route_node *rp)
+void ripng_zebra_ipv6_delete(struct agg_node *rp)
 {
        ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_DELETE);
 }
index 934a87b0751f502c2e6b8b90ea94e18842c70128..d1341d67b7493713f2ea231b0145f1b38f335f18 100644 (file)
@@ -27,7 +27,7 @@
 #include "memory.h"
 #include "if.h"
 #include "stream.h"
-#include "table.h"
+#include "agg_table.h"
 #include "command.h"
 #include "sockopt.h"
 #include "distribute.h"
@@ -394,7 +394,7 @@ static int ripng_lladdr_check(struct interface *ifp, struct in6_addr *addr)
 static int ripng_garbage_collect(struct thread *t)
 {
        struct ripng_info *rinfo;
-       struct route_node *rp;
+       struct agg_node *rp;
 
        rinfo = THREAD_ARG(t);
        rinfo->t_garbage_collect = NULL;
@@ -409,7 +409,7 @@ static int ripng_garbage_collect(struct thread *t)
        listnode_delete(rp->info, rinfo);
        if (list_isempty((struct list *)rp->info)) {
                list_delete_and_null((struct list **)&rp->info);
-               route_unlock_node(rp);
+               agg_unlock_node(rp);
        }
 
        /* Free RIPng routing information. */
@@ -426,7 +426,7 @@ static void ripng_timeout_update(struct ripng_info *rinfo);
  */
 struct ripng_info *ripng_ecmp_add(struct ripng_info *rinfo_new)
 {
-       struct route_node *rp = rinfo_new->rp;
+       struct agg_node *rp = rinfo_new->rp;
        struct ripng_info *rinfo = NULL;
        struct list *list = NULL;
 
@@ -465,7 +465,7 @@ struct ripng_info *ripng_ecmp_add(struct ripng_info *rinfo_new)
  */
 struct ripng_info *ripng_ecmp_replace(struct ripng_info *rinfo_new)
 {
-       struct route_node *rp = rinfo_new->rp;
+       struct agg_node *rp = rinfo_new->rp;
        struct list *list = (struct list *)rp->info;
        struct ripng_info *rinfo = NULL, *tmp_rinfo = NULL;
        struct listnode *node = NULL, *nextnode = NULL;
@@ -522,7 +522,7 @@ struct ripng_info *ripng_ecmp_replace(struct ripng_info *rinfo_new)
  */
 struct ripng_info *ripng_ecmp_delete(struct ripng_info *rinfo)
 {
-       struct route_node *rp = rinfo->rp;
+       struct agg_node *rp = rinfo->rp;
        struct list *list = (struct list *)rp->info;
 
        RIPNG_TIMER_OFF(rinfo->t_timeout);
@@ -664,7 +664,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
 {
        int ret;
        struct prefix_ipv6 p;
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo = NULL, newinfo;
        struct ripng_interface *ri;
        struct in6_addr *nexthop;
@@ -773,7 +773,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
                nexthop = &from->sin6_addr;
 
        /* Lookup RIPng routing table. */
-       rp = route_node_get(ripng->table, (struct prefix *)&p);
+       rp = agg_node_get(ripng->table, (struct prefix *)&p);
 
        newinfo.rp = rp;
        newinfo.nexthop = *nexthop;
@@ -798,7 +798,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
                                if (rte->metric > rinfo->metric) {
                                        /* New route has a greater metric.
                                         * Discard it. */
-                                       route_unlock_node(rp);
+                                       agg_unlock_node(rp);
                                        return;
                                }
 
@@ -821,7 +821,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
                /* Redistributed route check. */
                if (rinfo->type != ZEBRA_ROUTE_RIPNG
                    && rinfo->metric != RIPNG_METRIC_INFINITY) {
-                       route_unlock_node(rp);
+                       agg_unlock_node(rp);
                        return;
                }
 
@@ -830,7 +830,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
                    && ((rinfo->sub_type == RIPNG_ROUTE_STATIC)
                        || (rinfo->sub_type == RIPNG_ROUTE_DEFAULT))
                    && rinfo->metric != RIPNG_METRIC_INFINITY) {
-                       route_unlock_node(rp);
+                       agg_unlock_node(rp);
                        return;
                }
        }
@@ -844,7 +844,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
                if (rte->metric != RIPNG_METRIC_INFINITY)
                        ripng_ecmp_add(&newinfo);
                else
-                       route_unlock_node(rp);
+                       agg_unlock_node(rp);
        } else {
                /* If there is an existing route, compare the next hop address
                   to the address of the router from which the datagram came.
@@ -890,7 +890,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
                        ripng_timeout_update(rinfo);
 
                /* Unlock tempolary lock of the route. */
-               route_unlock_node(rp);
+               agg_unlock_node(rp);
        }
 }
 
@@ -899,7 +899,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p,
                            ifindex_t ifindex, struct in6_addr *nexthop,
                            route_tag_t tag)
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo = NULL, newinfo;
        struct list *list = NULL;
 
@@ -909,7 +909,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p,
        if (IN6_IS_ADDR_LOOPBACK(&p->prefix))
                return;
 
-       rp = route_node_get(ripng->table, (struct prefix *)p);
+       rp = agg_node_get(ripng->table, (struct prefix *)p);
 
        memset(&newinfo, 0, sizeof(struct ripng_info));
        newinfo.type = type;
@@ -928,7 +928,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p,
                if (rinfo->type == ZEBRA_ROUTE_CONNECT
                    && rinfo->sub_type == RIPNG_ROUTE_INTERFACE
                    && rinfo->metric != RIPNG_METRIC_INFINITY) {
-                       route_unlock_node(rp);
+                       agg_unlock_node(rp);
                        return;
                }
 
@@ -941,13 +941,13 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p,
                        if (type != ZEBRA_ROUTE_RIPNG
                            || ((sub_type != RIPNG_ROUTE_STATIC)
                                && (sub_type != RIPNG_ROUTE_DEFAULT))) {
-                               route_unlock_node(rp);
+                               agg_unlock_node(rp);
                                return;
                        }
                }
 
                ripng_ecmp_replace(&newinfo);
-               route_unlock_node(rp);
+               agg_unlock_node(rp);
        } else
                ripng_ecmp_add(&newinfo);
 
@@ -972,7 +972,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p,
 void ripng_redistribute_delete(int type, int sub_type, struct prefix_ipv6 *p,
                               ifindex_t ifindex)
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
 
        if (IN6_IS_ADDR_LINKLOCAL(&p->prefix))
@@ -980,7 +980,7 @@ void ripng_redistribute_delete(int type, int sub_type, struct prefix_ipv6 *p,
        if (IN6_IS_ADDR_LOOPBACK(&p->prefix))
                return;
 
-       rp = route_node_lookup(ripng->table, (struct prefix *)p);
+       rp = agg_node_lookup(ripng->table, (struct prefix *)p);
 
        if (rp) {
                struct list *list = rp->info;
@@ -1014,21 +1014,21 @@ void ripng_redistribute_delete(int type, int sub_type, struct prefix_ipv6 *p,
                                ripng_event(RIPNG_TRIGGERED_UPDATE, 0);
                        }
                }
-               route_unlock_node(rp);
+               agg_unlock_node(rp);
        }
 }
 
 /* Withdraw redistributed route. */
 void ripng_redistribute_withdraw(int type)
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo = NULL;
        struct list *list = NULL;
 
        if (!ripng)
                return;
 
-       for (rp = route_top(ripng->table); rp; rp = route_next(rp))
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp))
                if ((list = rp->info) != NULL) {
                        rinfo = listgetdata(listhead(list));
                        if ((rinfo->type == type)
@@ -1199,7 +1199,7 @@ static void ripng_request_process(struct ripng_packet *packet, int size,
        caddr_t lim;
        struct rte *rte;
        struct prefix_ipv6 p;
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct ripng_interface *ri;
 
@@ -1255,14 +1255,13 @@ static void ripng_request_process(struct ripng_packet *packet, int size,
                        p.prefixlen = rte->prefixlen;
                        apply_mask_ipv6(&p);
 
-                       rp = route_node_lookup(ripng->table,
-                                              (struct prefix *)&p);
+                       rp = agg_node_lookup(ripng->table, (struct prefix *)&p);
 
                        if (rp) {
                                rinfo = listgetdata(
                                        listhead((struct list *)rp->info));
                                rte->metric = rinfo->metric;
-                               route_unlock_node(rp);
+                               agg_unlock_node(rp);
                        } else
                                rte->metric = RIPNG_METRIC_INFINITY;
                }
@@ -1361,12 +1360,12 @@ static int ripng_read(struct thread *thread)
 /* Walk down the RIPng routing table then clear changed flag. */
 static void ripng_clear_changed_flag(void)
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo = NULL;
        struct list *list = NULL;
        struct listnode *listnode = NULL;
 
-       for (rp = route_top(ripng->table); rp; rp = route_next(rp))
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp))
                if ((list = rp->info) != NULL)
                        for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
                                UNSET_FLAG(rinfo->flags, RIPNG_RTF_CHANGED);
@@ -1535,7 +1534,7 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
                          int route_type)
 {
        int ret;
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct ripng_interface *ri;
        struct ripng_aggregate *aggregate;
@@ -1558,7 +1557,7 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
 
        ripng_rte_list = ripng_rte_new();
 
-       for (rp = route_top(ripng->table); rp; rp = route_next(rp)) {
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) {
                if ((list = rp->info) != NULL
                    && (rinfo = listgetdata(listhead(list))) != NULL
                    && rinfo->suppress == 0) {
@@ -1807,9 +1806,9 @@ static int ripng_create(void)
        ripng->obuf = stream_new(RIPNG_MAX_PACKET_SIZE);
 
        /* Initialize RIPng routig table. */
-       ripng->table = route_table_init();
-       ripng->route = route_table_init();
-       ripng->aggregate = route_table_init();
+       ripng->table = agg_table_init();
+       ripng->route = agg_table_init();
+       ripng->aggregate = agg_table_init();
 
        /* Make socket. */
        ripng->sock = ripng_make_socket();
@@ -1952,7 +1951,7 @@ DEFUN (show_ipv6_ripng,
        IPV6_STR
        "Show RIPng routes\n")
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct ripng_aggregate *aggregate;
        struct prefix_ipv6 *p;
@@ -1971,7 +1970,7 @@ DEFUN (show_ipv6_ripng,
                "      (i) - interface, (a/S) - aggregated/Suppressed\n\n"
                "   Network      Next Hop                      Via     Metric Tag Time\n");
 
-       for (rp = route_top(ripng->table); rp; rp = route_next(rp)) {
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) {
                if ((aggregate = rp->aggregate) != NULL) {
                        p = (struct prefix_ipv6 *)&rp->p;
 
@@ -2125,13 +2124,13 @@ DEFUN (clear_ipv6_rip,
        IPV6_STR
        "Clear IPv6 RIP database\n")
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct list *list;
        struct listnode *listnode;
 
        /* Clear received RIPng routes */
-       for (rp = route_top(ripng->table); rp; rp = route_next(rp)) {
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) {
                list = rp->info;
                if (list == NULL)
                        continue;
@@ -2155,7 +2154,7 @@ DEFUN (clear_ipv6_rip,
                if (list_isempty(list)) {
                        list_delete_and_null(&list);
                        rp->info = NULL;
-                       route_unlock_node(rp);
+                       agg_unlock_node(rp);
                }
        }
 
@@ -2206,7 +2205,7 @@ DEFUN (ripng_route,
        int idx_ipv6addr = 1;
        int ret;
        struct prefix_ipv6 p;
-       struct route_node *rp;
+       struct agg_node *rp;
 
        ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg,
                              (struct prefix_ipv6 *)&p);
@@ -2216,10 +2215,10 @@ DEFUN (ripng_route,
        }
        apply_mask_ipv6(&p);
 
-       rp = route_node_get(ripng->route, (struct prefix *)&p);
+       rp = agg_node_get(ripng->route, (struct prefix *)&p);
        if (rp->info) {
                vty_out(vty, "There is already same static route.\n");
-               route_unlock_node(rp);
+               agg_unlock_node(rp);
                return CMD_WARNING;
        }
        rp->info = (void *)1;
@@ -2240,7 +2239,7 @@ DEFUN (no_ripng_route,
        int idx_ipv6addr = 2;
        int ret;
        struct prefix_ipv6 p;
-       struct route_node *rp;
+       struct agg_node *rp;
 
        ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg,
                              (struct prefix_ipv6 *)&p);
@@ -2250,17 +2249,17 @@ DEFUN (no_ripng_route,
        }
        apply_mask_ipv6(&p);
 
-       rp = route_node_lookup(ripng->route, (struct prefix *)&p);
+       rp = agg_node_lookup(ripng->route, (struct prefix *)&p);
        if (!rp) {
                vty_out(vty, "Can't find static route.\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
 
        ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0);
-       route_unlock_node(rp);
+       agg_unlock_node(rp);
 
        rp->info = NULL;
-       route_unlock_node(rp);
+       agg_unlock_node(rp);
 
        return CMD_SUCCESS;
 }
@@ -2274,7 +2273,7 @@ DEFUN (ripng_aggregate_address,
        int idx_ipv6_prefixlen = 1;
        int ret;
        struct prefix p;
-       struct route_node *node;
+       struct agg_node *node;
 
        ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg,
                              (struct prefix_ipv6 *)&p);
@@ -2284,10 +2283,10 @@ DEFUN (ripng_aggregate_address,
        }
 
        /* Check aggregate alredy exist or not. */
-       node = route_node_get(ripng->aggregate, &p);
+       node = agg_node_get(ripng->aggregate, &p);
        if (node->info) {
                vty_out(vty, "There is already same aggregate route.\n");
-               route_unlock_node(node);
+               agg_unlock_node(node);
                return CMD_WARNING;
        }
        node->info = (void *)1;
@@ -2307,7 +2306,7 @@ DEFUN (no_ripng_aggregate_address,
        int idx_ipv6_prefixlen = 2;
        int ret;
        struct prefix p;
-       struct route_node *rn;
+       struct agg_node *rn;
 
        ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg,
                              (struct prefix_ipv6 *)&p);
@@ -2316,14 +2315,14 @@ DEFUN (no_ripng_aggregate_address,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       rn = route_node_lookup(ripng->aggregate, &p);
+       rn = agg_node_lookup(ripng->aggregate, &p);
        if (!rn) {
                vty_out(vty, "Can't find aggregate route.\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
-       route_unlock_node(rn);
+       agg_unlock_node(rn);
        rn->info = NULL;
-       route_unlock_node(rn);
+       agg_unlock_node(rn);
 
        ripng_aggregate_delete(&p);
 
@@ -2582,7 +2581,7 @@ DEFUN (no_ripng_default_information_originate,
 /* Update ECMP routes to zebra when ECMP is disabled. */
 static void ripng_ecmp_disable(void)
 {
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo, *tmp_rinfo;
        struct list *list;
        struct listnode *node, *nextnode;
@@ -2590,7 +2589,7 @@ static void ripng_ecmp_disable(void)
        if (!ripng)
                return;
 
-       for (rp = route_top(ripng->table); rp; rp = route_next(rp))
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp))
                if ((list = rp->info) != NULL && listcount(list) > 1) {
                        rinfo = listgetdata(listhead(list));
                        if (!ripng_route_rte(rinfo))
@@ -2655,7 +2654,7 @@ static int ripng_config_write(struct vty *vty)
        int ripng_network_write(struct vty *, int);
        void ripng_redistribute_write(struct vty *, int);
        int write = 0;
-       struct route_node *rp;
+       struct agg_node *rp;
 
        if (ripng) {
 
@@ -2678,7 +2677,8 @@ static int ripng_config_write(struct vty *vty)
                config_write_ripng_offset_list(vty);
 
                /* RIPng aggregate routes. */
-               for (rp = route_top(ripng->aggregate); rp; rp = route_next(rp))
+               for (rp = agg_route_top(ripng->aggregate); rp;
+                    rp = agg_route_next(rp))
                        if (rp->info != NULL)
                                vty_out(vty, " aggregate-address %s/%d\n",
                                        inet6_ntoa(rp->p.u.prefix6),
@@ -2689,7 +2689,8 @@ static int ripng_config_write(struct vty *vty)
                        vty_out(vty, " allow-ecmp\n");
 
                /* RIPng static routes. */
-               for (rp = route_top(ripng->route); rp; rp = route_next(rp))
+               for (rp = agg_route_top(ripng->route); rp;
+                    rp = agg_route_next(rp))
                        if (rp->info != NULL)
                                vty_out(vty, " route %s/%d\n",
                                        inet6_ntoa(rp->p.u.prefix6),
@@ -2811,7 +2812,7 @@ static void ripng_distribute_update_all_wrapper(struct access_list *notused)
 void ripng_clean()
 {
        int i;
-       struct route_node *rp;
+       struct agg_node *rp;
        struct ripng_info *rinfo;
        struct ripng_aggregate *aggregate;
        struct list *list = NULL;
@@ -2819,7 +2820,8 @@ void ripng_clean()
 
        if (ripng) {
                /* Clear RIPng routes */
-               for (rp = route_top(ripng->table); rp; rp = route_next(rp)) {
+               for (rp = agg_route_top(ripng->table); rp;
+                    rp = agg_route_next(rp)) {
                        if ((list = rp->info) != NULL) {
                                rinfo = listgetdata(listhead(list));
                                if (ripng_route_rte(rinfo))
@@ -2834,13 +2836,13 @@ void ripng_clean()
                                }
                                list_delete_and_null(&list);
                                rp->info = NULL;
-                               route_unlock_node(rp);
+                               agg_unlock_node(rp);
                        }
 
                        if ((aggregate = rp->aggregate) != NULL) {
                                ripng_aggregate_free(aggregate);
                                rp->aggregate = NULL;
-                               route_unlock_node(rp);
+                               agg_unlock_node(rp);
                        }
                }
 
@@ -2862,17 +2864,19 @@ void ripng_clean()
                }
 
                /* Static RIPng route configuration. */
-               for (rp = route_top(ripng->route); rp; rp = route_next(rp))
+               for (rp = agg_route_top(ripng->route); rp;
+                    rp = agg_route_next(rp))
                        if (rp->info) {
                                rp->info = NULL;
-                               route_unlock_node(rp);
+                               agg_unlock_node(rp);
                        }
 
                /* RIPng aggregated prefixes */
-               for (rp = route_top(ripng->aggregate); rp; rp = route_next(rp))
+               for (rp = agg_route_top(ripng->aggregate); rp;
+                    rp = agg_route_next(rp))
                        if (rp->info) {
                                rp->info = NULL;
-                               route_unlock_node(rp);
+                               agg_unlock_node(rp);
                        }
 
                for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
index 534905d895973636e5d33a3ee5648951750d289a..1095a33494e71d49946be5581df0f11fa37f8480 100644 (file)
@@ -109,13 +109,13 @@ struct ripng {
        struct stream *obuf;
 
        /* RIPng routing information base. */
-       struct route_table *table;
+       struct agg_table *table;
 
        /* RIPng only static route information. */
-       struct route_table *route;
+       struct agg_table *route;
 
        /* RIPng aggregate route information. */
-       struct route_table *aggregate;
+       struct agg_table *aggregate;
 
        /* RIPng threads. */
        struct thread *t_read;
@@ -198,7 +198,7 @@ struct ripng_info {
        uint8_t metric_out;
        uint16_t tag_out;
 
-       struct route_node *rp;
+       struct agg_node *rp;
 };
 
 #ifdef notyet
@@ -377,8 +377,8 @@ extern void ripng_redistribute_withdraw(int type);
 extern void ripng_distribute_update_interface(struct interface *);
 extern void ripng_if_rmap_update_interface(struct interface *);
 
-extern void ripng_zebra_ipv6_add(struct route_node *);
-extern void ripng_zebra_ipv6_delete(struct route_node *);
+extern void ripng_zebra_ipv6_add(struct agg_node *node);
+extern void ripng_zebra_ipv6_delete(struct agg_node *node);
 
 extern void ripng_redistribute_clean(void);
 extern int ripng_redistribute_check(int);
index 1f7ff09d6edc52005e4e3b362b593d4eeb6e211c..8f834a1d297d5200fd4b711a90b7264d6fbf5bc2 100644 (file)
@@ -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 = \
index cc33cfc188ae9f31827264419d4d39f7caed902d..91b9f2e902f83bab903573cbd30f0339a1bfb7a9 100644 (file)
@@ -1,17 +1,2 @@
-Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
 sharpd
 sharpd.conf
index 956da9d4edd44baa4b13a4bcae40432346d0f987..797e336c2d2de814d91a6a5e3437d34e9146a9a0 100644 (file)
@@ -81,13 +81,14 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
 
 DEFPY (install_routes,
        install_routes_cmd,
-       "sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes [instance (0-255)$instance]",
+       "sharp install routes A.B.C.D$start nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6> (1-1000000)$routes [instance (0-255)$instance]",
        "Sharp routing Protocol\n"
        "install some routes\n"
        "Routes to install\n"
        "Address to start /32 generation at\n"
-       "Nexthop to use\n"
-       "Nexthop address\n"
+       "Nexthop to use(Can be an IPv4 or IPv6 address)\n"
+       "V4 Nexthop address to use\n"
+       "V6 Nexthop address to use\n"
        "How many to create\n"
        "Instance to use\n"
        "Instance\n")
@@ -107,8 +108,13 @@ DEFPY (install_routes,
        p.prefixlen = 32;
        p.u.prefix4 = start;
 
-       nhop.gate.ipv4 = nexthop;
-       nhop.type = NEXTHOP_TYPE_IPV4;
+       if (nexthop4.s_addr != INADDR_ANY) {
+               nhop.gate.ipv4 = nexthop4;
+               nhop.type = NEXTHOP_TYPE_IPV4;
+       } else {
+               memcpy(&nhop.gate.ipv6, &nexthop6, IPV6_MAX_BYTELEN);
+               nhop.type = NEXTHOP_TYPE_IPV6;
+       }
 
        zlog_debug("Inserting %ld routes", routes);
 
@@ -185,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);
@@ -192,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;
 }
index fcb555170b8870d94c6422da6b370456d5a59db5..286f320874ca3a80727eec1770f0ad8593203348 100644 (file)
@@ -193,7 +193,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh)
 
        api_nh = &api.nexthops[0];
        api_nh->vrf_id = VRF_DEFAULT;
-       api_nh->gate.ipv4 = nh->gate.ipv4;
+       api_nh->gate = nh->gate;
        api_nh->type = nh->type;
        api_nh->ifindex = nh->ifindex;
        api.nexthop_num = 1;
index 490a2ba787ebc3c1c936c4bc4a2364f735d99a0b..2a34aecfb3eff05f495b85f1222d594cb5cba3dc 100644 (file)
@@ -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 = \
index ac7860290b9e3dd2ade4fa1155075c96da6c4916..a4796fd730c03f239528114f8942d9315ff481f9 100644 (file)
@@ -3,4 +3,3 @@ parts
 prime
 stage
 frr*.snap
-!*/Makefile
index a2c7946e71ef2edef4e6d597126417d55bc442cb..3f1a0385a4261c3b3e3112a234654d352b6ce8ab 100644 (file)
@@ -1,5 +1,5 @@
 Makefile
-Makefile.in
+!Makefile.in
 ?.manifest
 *.xml
 pkginfo.*.full
@@ -17,6 +17,3 @@ depend.smf
 frr.init
 *.pkg
 *.pkg.gz
-*~
-*.loT
-*.a
\ No newline at end of file
diff --git a/solaris/Makefile.am b/solaris/Makefile.am
deleted file mode 100644 (file)
index 5633991..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-# Solaris packages automake file
-
-# XXX This file uses GNU make extensions.
-
-.PHONY: packages
-
-# the names of the various subpackages, and some convenient 
-# derived variables.
-pkg_names = daemons dev doc libs smf
-pkg_frr_daemons = zebra bgpd ospfd ospf6d ripd ripngd
-pkg_name_rev = @PACKAGE_VERSION@-@CONFDATE@-@target_os@-@target_cpu@
-pkg_depends = $(pkg_names:%=depend.%)
-pkg_packages = $(pkg_names:%=@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg)
-pkg_pkginfos = $(pkg_names:%=pkginfo.%.full)
-pkg_prototypes = $(pkg_names:%=prototype.%)
-pkg_manifests = frr.xml
-
-# pkgmk variable substitutions wont grok ${variable} in prototype
-# file, so we cant let autoconf generate the file sadly
-# wish automake would just provide a template for this
-edit = $(SED) \
-       -e 's,@prefix\@,$(prefix),g' \
-       -e 's,@exec_prefix,$(exec_prefix),g' \
-       -e 's,@bindir\@,$(bindir),g' \
-       -e 's,@sbindir\@,$(sbindir),g' \
-       -e 's,@libexecdir\@,$(libexecdir),g' \
-       -e 's,@datadir\@,$(datadir),g' \
-       -e 's,@sysconfdir\@,$(sysconfdir),g' \
-       -e 's,@sharedstatedir\@,$(sharedstatedir),g' \
-       -e 's,@localstatedir\@,$(localstatedir),g' \
-       -e 's,@libdir\@,$(libdir),g' \
-       -e 's,@includedir\@,$(includedir),g' \
-       -e 's,@infodir\@,$(infodir),g' \
-       -e 's,@mandir\@,$(mandir),g' \
-       -e 's,@enable_user\@,$(enable_user),g' \
-       -e 's,@enable_group\@,$(enable_group),g' \
-       -e 's,@enable_vty_group\@,$(enable_vty_group),g' \
-       -e 's,@frr_statedir\@,$(frr_statedir),g' \
-       -e 's,[@]PACKAGE_NAME[@],@PACKAGE_NAME@,g' \
-       -e 's,[@]PACKAGE_TARNAME[@],@PACKAGE_TARNAME@,g' \
-       -e 's,[@]PACKAGE_VERSION[@],@PACKAGE_VERSION@,g' \
-       -e 's,[@]PACKAGE_BUGREPORT[@],@PACKAGE_BUGREPORT@,g' \
-       -e 's,[@]CONFDATE[@],@CONFDATE@,g' \
-       -e 's,[@]target_cpu[@],$(target_cpu),g' \
-       -e 's,[@]target_host[@],$(target_host),g' \
-       -e 's,[@]target_os[@],$(target_os),g'
-
-# common options for pkgmk
-pkg_make_vars = exec_prefix=@exec_prefix@ prefix=@prefix@ \
-       builddir=@builddir@ srcdir=@srcdir@ \
-       top_builddir=@top_builddir@ top_srcdir=@top_srcdir@ \
-       abs_builddir=@abs_builddir@ abs_srcdir=@abs_srcdir@ \
-       abs_top_builddir=@abs_top_builddir@ abs_top_srcdir=@abs_top_srcdir@
-
-# pkgmk: write the package to spool in build dir, to avoid root dependencies
-pkg_make = pkgmk -o -d @abs_builddir@ \
-       -f $< DESTDIR="$(DESTDIR)/" $(pkg_make_vars)
-
-# pkgtrans: write a pkg file stream, shame we cant pipe directly to it from
-# pkgmk..
-pkg_trans = pkgtrans -s @abs_builddir@ "@abs_builddir@/$@"
-
-# pkgmk can only cope with a single pkginfo, cant 'stack' various 
-# pkginfo template files and a package specific pkginfo file in the prototype
-# Create the package specific template here, and create the full pkginfo
-# by cating this and the common pkginfo.tmpl together.
-pkginfo.tmpl: $(srcdir)/pkginfo.tmpl.in Makefile
-       rm -f $@
-       $(edit) $< > $@
-
-pkginfo.%.tmpl: $(srcdir)/pkginfo.%.tmpl.in Makefile
-       rm -f $@
-       $(edit) $< > $@
-
-pkginfo.%.full: pkginfo.%.tmpl pkginfo.tmpl Makefile
-       cat pkginfo.tmpl pkginfo.$*.tmpl > $@
-
-# use 'edit' above to transform prototype.in to pkgmk acceptable prototype
-prototype.%: $(srcdir)/prototype.%.in Makefile
-       rm -f $@
-       $(edit) $< > $@
-
-# use edit to construct the SMF manifest files
-%.xml: $(srcdir)/%.xml.in Makefile
-       rm -f $@
-       $(edit) $< > $@
-# use edit to construct the depend files
-depend.%: $(srcdir)/depend.%.in Makefile
-       rm -f $@
-       $(edit) $< > $@
-
-# method file (bit like init script)
-frr.init: $(srcdir)/frr.init.in Makefile
-       rm -f $@
-       $(edit) $< > $@
-
-# construct the pkg
-@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg: prototype.% \
-               depend.% frr.init pkginfo.%.full
-       ($(pkg_make) && \
-       $(pkg_trans) "FRR$*")
-
-%.pkg.gz : %.pkg
-       (gzip -c $< > $@)
-
-# pkginfo.package and prototype.package are all built sources
-#BUILT_SOURCES = pkginfo.daemons pkginfo.dev pkginfo.doc pkginfo.libs \
-#      prototype.daemons prototype.dev prototype.doc prototype.libs
-BUILT_SOURCES = $(pkg_pkginfos) pkginfo.tmpl $(pkg_prototypes) \
-       $(pkg_manifests) $(pkg_depends) frr.init
-
-CLEANFILES = $(BUILT_SOURCES) $(pkg_packages)
-
-EXTRA_DIST = $(pkg_manifests:%=%.in) $(pkg_prototypes:%=%.in) \
-       $(pkg_names:%=pkginfo.%.tmpl.in) $(srcdir)/pkginfo.tmpl.in \
-       $(pkg_depends:%=%.in) frr.init.in README.txt
-
-pkg-root-install:
-       (cd $(top_builddir) && \
-        $(MAKE) DESTDIR=$(abs_builddir)/frr-root install)
-
-packages: $(pkg_packages)
-
-#nodist_pkgdata_DATA = $(pkg_packages)
diff --git a/solaris/Makefile.in b/solaris/Makefile.in
new file mode 100644 (file)
index 0000000..df9122a
--- /dev/null
@@ -0,0 +1,155 @@
+# Solaris packages automake file
+
+# XXX This file uses GNU make extensions.
+
+.PHONY: packages all all-files
+
+all: all-files
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+includedir = @includedir@
+infodir = @infodir@
+mandir = @mandir@
+frr_statedir = @frr_statedir@
+
+builddir = @builddir@
+srcdir = @srcdir@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+
+enable_user = @enable_user@
+enable_group = @enable_group@
+enable_vty_group = @enable_vty_group@
+
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+CONFDATE = @CONFDATE@
+
+host_cpu = @host_cpu@
+host_os = @host_os@
+
+SED = @SED@
+MAKE = @MAKE@
+
+# the names of the various subpackages, and some convenient 
+# derived variables.
+pkg_names = daemons dev doc libs smf
+pkg_frr_daemons = zebra bgpd ospfd ospf6d ripd ripngd
+pkg_name_rev = $(PACKAGE_VERSION)-$(CONFDATE)-$(host_os)-$(host_cpu)
+pkg_depends = $(pkg_names:%=depend.%)
+pkg_packages = $(pkg_names:%=@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg)
+pkg_pkginfos = $(pkg_names:%=pkginfo.%.full)
+pkg_prototypes = $(pkg_names:%=prototype.%)
+pkg_manifests = frr.xml
+
+# pkgmk variable substitutions wont grok ${variable} in prototype
+# file, so we cant let autoconf generate the file sadly
+# wish automake would just provide a template for this
+edit = $(SED) \
+       -e 's,@prefix\@,$(prefix),g' \
+       -e 's,@exec_prefix,$(exec_prefix),g' \
+       -e 's,@bindir\@,$(bindir),g' \
+       -e 's,@sbindir\@,$(sbindir),g' \
+       -e 's,@libexecdir\@,$(libexecdir),g' \
+       -e 's,@datadir\@,$(datadir),g' \
+       -e 's,@sysconfdir\@,$(sysconfdir),g' \
+       -e 's,@sharedstatedir\@,$(sharedstatedir),g' \
+       -e 's,@localstatedir\@,$(localstatedir),g' \
+       -e 's,@libdir\@,$(libdir),g' \
+       -e 's,@includedir\@,$(includedir),g' \
+       -e 's,@infodir\@,$(infodir),g' \
+       -e 's,@mandir\@,$(mandir),g' \
+       -e 's,@enable_user\@,$(enable_user),g' \
+       -e 's,@enable_group\@,$(enable_group),g' \
+       -e 's,@enable_vty_group\@,$(enable_vty_group),g' \
+       -e 's,@frr_statedir\@,$(frr_statedir),g' \
+       -e 's,[@]PACKAGE_NAME[@],$(PACKAGE_NAME),g' \
+       -e 's,[@]PACKAGE_TARNAME[@],$(PACKAGE_TARNAME),g' \
+       -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
+       -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
+       -e 's,[@]CONFDATE[@],$(CONFDATE),g' \
+       -e 's,[@]host_cpu[@],$(host_cpu),g' \
+       -e 's,[@]host_os[@],$(host_os),g'
+
+# common options for pkgmk
+pkg_make_vars = exec_prefix=$(exec_prefix) prefix=$(prefix) \
+       builddir=$(builddir) srcdir=$(srcdir) \
+       top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \
+       abs_builddir=$(abs_builddir) abs_srcdir=$(abs_srcdir) \
+       abs_top_builddir=$(abs_top_builddir) abs_top_srcdir=$(abs_top_srcdir)
+
+# pkgmk: write the package to spool in build dir, to avoid root dependencies
+pkg_make = pkgmk -o -d $(abs_builddir) \
+       -f $< DESTDIR="$(DESTDIR)/" $(pkg_make_vars)
+
+# pkgtrans: write a pkg file stream, shame we cant pipe directly to it from
+# pkgmk..
+pkg_trans = pkgtrans -s $(abs_builddir) "$(abs_builddir)/$@"
+
+# pkgmk can only cope with a single pkginfo, cant 'stack' various 
+# pkginfo template files and a package specific pkginfo file in the prototype
+# Create the package specific template here, and create the full pkginfo
+# by cating this and the common pkginfo.tmpl together.
+pkginfo.tmpl: $(srcdir)/pkginfo.tmpl.in Makefile
+       rm -f $@
+       $(edit) $< > $@
+
+pkginfo.%.tmpl: $(srcdir)/pkginfo.%.tmpl.in Makefile
+       rm -f $@
+       $(edit) $< > $@
+
+pkginfo.%.full: pkginfo.%.tmpl pkginfo.tmpl Makefile
+       cat pkginfo.tmpl pkginfo.$*.tmpl > $@
+
+# use 'edit' above to transform prototype.in to pkgmk acceptable prototype
+prototype.%: $(srcdir)/prototype.%.in Makefile
+       rm -f $@
+       $(edit) $< > $@
+
+# use edit to construct the SMF manifest files
+%.xml: $(srcdir)/%.xml.in Makefile
+       rm -f $@
+       $(edit) $< > $@
+# use edit to construct the depend files
+depend.%: $(srcdir)/depend.%.in Makefile
+       rm -f $@
+       $(edit) $< > $@
+
+# method file (bit like init script)
+frr.init: $(srcdir)/frr.init.in Makefile
+       rm -f $@
+       $(edit) $< > $@
+
+# construct the pkg
+$(PACKAGE_TARNAME)-%-$(pkg_name_rev).pkg: prototype.% \
+               depend.% frr.init pkginfo.%.full
+       ($(pkg_make) && \
+       $(pkg_trans) "FRR$*")
+
+%.pkg.gz : %.pkg
+       (gzip -c $< > $@)
+
+pkg-root-install:
+       (cd $(top_builddir) && \
+        $(MAKE) DESTDIR=$(abs_builddir)/frr-root install)
+
+packages: $(pkg_packages)
+
+all-files: $(pkg_pkginfos) pkginfo.tmpl $(pkg_prototypes) \
+       $(pkg_manifests) $(pkg_depends) frr.init
index 89a281ceb6824cc33c637792d8aaa72877e108fd..ffbf9b9cef650050362a91942ba7c2e10d8b33e1 100644 (file)
@@ -1,4 +1,4 @@
-ARCH="@target_cpu@"
+ARCH="@host_cpu@"
 CATEGORY="system"
 VERSION="@PACKAGE_VERSION@,REV=@CONFDATE@"
 VENDOR="http://www.frrouting.org/"
diff --git a/solaris/subdir.am b/solaris/subdir.am
new file mode 100644 (file)
index 0000000..1d19d56
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# solaris
+#
+
+.PHONY: solaris/all
+if SOLARIS
+all: solaris/all
+solaris/all:
+       @make -s -C solaris all
+endif
+
+CLEANFILES += \
+       solaris/frr.xml \
+       solaris/frr.init \
+       solaris/pkginfo.tmpl \
+       solaris/prototype.daemons \
+       solaris/prototype.dev \
+       solaris/prototype.doc \
+       solaris/prototype.libs \
+       solaris/prototype.smf \
+       solaris/pkginfo.daemons.tmpl \
+       solaris/pkginfo.dev.tmpl \
+       solaris/pkginfo.doc.tmpl \
+       solaris/pkginfo.libs.tmpl \
+       solaris/pkginfo.smf.tmpl \
+       solaris/depend.daemons \
+       solaris/depend.dev \
+       solaris/depend.doc \
+       solaris/depend.libs \
+       solaris/depend.smf \
+       # end
+
+EXTRA_DIST += \
+       solaris/frr.xml.in \
+       solaris/frr.init.in \
+       solaris/pkginfo.tmpl.in \
+       solaris/prototype.daemons.in \
+       solaris/prototype.dev.in \
+       solaris/prototype.doc.in \
+       solaris/prototype.libs.in \
+       solaris/prototype.smf.in \
+       solaris/pkginfo.daemons.tmpl.in \
+       solaris/pkginfo.dev.tmpl.in \
+       solaris/pkginfo.doc.tmpl.in \
+       solaris/pkginfo.libs.tmpl.in \
+       solaris/pkginfo.smf.tmpl.in \
+       solaris/depend.daemons.in \
+       solaris/depend.dev.in \
+       solaris/depend.doc.in \
+       solaris/depend.libs.in \
+       solaris/depend.smf.in \
+       solaris/README.txt \
+       # end
index c6e4587b6aafa1691cffb49082a7c12c73b1fea9..44f7fb79da8d45eb6fba677a93078d1d9cb6941e 100644 (file)
@@ -29,8 +29,8 @@
 #include "static_zebra.h"
 #include "static_nht.h"
 
-void static_nht_update(struct prefix *p, uint32_t nh_num,
-                      afi_t afi, vrf_id_t vrf_id)
+void static_nht_update(struct prefix *p, uint32_t nh_num, afi_t afi,
+                      vrf_id_t nh_vrf_id)
 {
        struct route_table *stable;
        struct static_route *si;
@@ -40,41 +40,47 @@ void static_nht_update(struct prefix *p, uint32_t nh_num,
        bool orig;
        bool reinstall;
 
-       vrf = vrf_lookup_by_id(vrf_id);
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+               svrf = vrf->info;
+               if (!svrf)
+                       continue;
 
-       if (!vrf || !vrf->info)
-               return;
+               stable = static_vrf_static_table(afi, SAFI_UNICAST, svrf);
+               if (!stable)
+                       continue;
 
-       svrf = vrf->info;
-       stable = static_vrf_static_table(afi, SAFI_UNICAST, svrf);
-       if (!stable)
-               return;
+               for (rn = route_top(stable); rn; rn = route_next(rn)) {
+                       reinstall = false;
+                       for (si = rn->info; si; si = si->next) {
+                               if (si->nh_vrf_id != nh_vrf_id)
+                                       continue;
 
-       for (rn = route_top(stable); rn; rn = route_next(rn)) {
-               reinstall = false;
-               for (si = rn->info; si; si = si->next) {
-                       if (si->type != STATIC_IPV4_GATEWAY &&
-                           si->type != STATIC_IPV4_GATEWAY_IFNAME &&
-                           si->type != STATIC_IPV6_GATEWAY &&
-                           si->type != STATIC_IPV6_GATEWAY_IFNAME)
-                               continue;
+                               if (si->type != STATIC_IPV4_GATEWAY
+                                   && si->type != STATIC_IPV4_GATEWAY_IFNAME
+                                   && si->type != STATIC_IPV6_GATEWAY
+                                   && si->type != STATIC_IPV6_GATEWAY_IFNAME)
+                                       continue;
 
-                       orig = si->nh_valid;
-                       if (p->family == AF_INET &&
-                           p->u.prefix4.s_addr == si->addr.ipv4.s_addr)
-                               si->nh_valid = !!nh_num;
+                               orig = si->nh_valid;
+                               if (p->family == AF_INET
+                                   && p->u.prefix4.s_addr
+                                              == si->addr.ipv4.s_addr)
+                                       si->nh_valid = !!nh_num;
 
-                       if (p->family == AF_INET6 &&
-                           memcmp(&p->u.prefix6, &si->addr.ipv6, 16) == 0)
-                               si->nh_valid = !!nh_num;
+                               if (p->family == AF_INET6
+                                   && memcmp(&p->u.prefix6, &si->addr.ipv6, 16)
+                                              == 0)
+                                       si->nh_valid = !!nh_num;
 
-                       if (orig != si->nh_valid)
-                               reinstall = true;
+                               if (orig != si->nh_valid)
+                                       reinstall = true;
 
-                       if (reinstall) {
-                               static_zebra_route_add(rn, si, vrf_id,
-                                                      SAFI_UNICAST, true);
-                               reinstall = false;
+                               if (reinstall) {
+                                       static_zebra_route_add(
+                                               rn, si, vrf->vrf_id,
+                                               SAFI_UNICAST, true);
+                                       reinstall = false;
+                               }
                        }
                }
        }
index d33c1539c8142cb4fc21350e02067b05ad99db6a..ad143209ee0bb70c72147db96ca756fdb738cd3e 100644 (file)
@@ -153,12 +153,18 @@ static int static_vrf_config_write(struct vty *vty)
        struct vrf *vrf;
 
        RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+               if (vrf->vrf_id != VRF_DEFAULT)
+                       vty_frame(vty, "vrf %s\n", vrf->name);
+
                static_config(vty, vrf->info, AFI_IP,
                              SAFI_UNICAST, "ip route");
                static_config(vty, vrf->info, AFI_IP,
                              SAFI_MULTICAST, "ip mroute");
                static_config(vty, vrf->info, AFI_IP6,
                              SAFI_UNICAST, "ipv6 route");
+
+               if (vrf->vrf_id != VRF_DEFAULT)
+                       vty_endframe(vty, "!\n");
        }
 
        return 0;
index 771d8d1de37a5c0cbe445ca122b54c90c97eca0e..f697969a7227d34faae573098b5a67d706124d84 100644 (file)
@@ -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;
index a87dc074dfc07e2d5f1bfcd41adae3917dc2dde2..4692dc00d7143a9c988a69748e06b31fcb339139 100644 (file)
@@ -35,6 +35,7 @@
 #include "nexthop.h"
 #include "nexthop_group.h"
 #include "hash.h"
+#include "jhash.h"
 
 #include "static_vrf.h"
 #include "static_routes.h"
@@ -180,6 +181,9 @@ static void zebra_connected(struct zclient *zclient)
 
 struct static_nht_data {
        struct prefix *nh;
+
+       vrf_id_t nh_vrf_id;
+
        uint32_t refcount;
        uint8_t nh_num;
 };
@@ -201,13 +205,18 @@ static int static_zebra_nexthop_update(int command, struct zclient *zclient,
 
        memset(&lookup, 0, sizeof(lookup));
        lookup.nh = &nhr.prefix;
+       lookup.nh_vrf_id = vrf_id;
 
        nhtd = hash_lookup(static_nht_hash, &lookup);
-       if (nhtd)
+
+       if (nhtd) {
                nhtd->nh_num = nhr.nexthop_num;
 
+               static_nht_update(&nhr.prefix, nhr.nexthop_num, afi,
+                                 nhtd->nh_vrf_id);
+       } else
+               zlog_err("No nhtd?");
 
-       static_nht_update(&nhr.prefix, nhr.nexthop_num, afi, vrf_id);
        return 1;
 }
 
@@ -219,8 +228,10 @@ static void static_zebra_capabilities(struct zclient_capabilities *cap)
 static unsigned int static_nht_hash_key(void *data)
 {
        struct static_nht_data *nhtd = data;
+       unsigned int key = 0;
 
-       return prefix_hash_key(nhtd->nh);
+       key = prefix_hash_key(nhtd->nh);
+       return jhash_1word(nhtd->nh_vrf_id, key);
 }
 
 static int static_nht_hash_cmp(const void *d1, const void *d2)
@@ -228,6 +239,9 @@ static int static_nht_hash_cmp(const void *d1, const void *d2)
        const struct static_nht_data *nhtd1 = d1;
        const struct static_nht_data *nhtd2 = d2;
 
+       if (nhtd1->nh_vrf_id != nhtd2->nh_vrf_id)
+               return 0;
+
        return prefix_same(nhtd1->nh, nhtd2->nh);
 }
 
@@ -242,6 +256,7 @@ static void *static_nht_hash_alloc(void *data)
        prefix_copy(new->nh, copy->nh);
        new->refcount = 0;
        new->nh_num = 0;
+       new->nh_vrf_id = copy->nh_vrf_id;
 
        return new;
 }
@@ -293,6 +308,7 @@ void static_zebra_nht_register(struct static_route *si, bool reg)
 
        memset(&lookup, 0, sizeof(lookup));
        lookup.nh = &p;
+       lookup.nh_vrf_id = si->nh_vrf_id;
 
        si->nh_registered = reg;
 
index 3b06a92e22a85f9cc6a9c010cdfd6fde264c0b9f..33cc0e20505ea1d37b149595a3bcd034b294f27b 100644 (file)
@@ -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 = \
index c8368b39b613985f3c0ed8d99b28e32fdedd72d1..37cd245de08c0c7453057e2931b2d83ab91fe258 100644 (file)
@@ -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 (file)
index 0000000..dd4594f
--- /dev/null
@@ -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 (file)
index a7dec67..0000000
+++ /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
index da9e447fc0a78929d6672f5cce701ddf2172bd16..60bee5c88c710a458cb02b8f81184e9a2beaf0e7 100644 (file)
@@ -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):
index 67a1593500b96ef92e41aef9cfcdf5948909dc47..b75c1002d43034613d71ad7437f33b30d59696f8 100644 (file)
@@ -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);
index 4abbe81499be693f39a91cf6581bde569ebd3da8..4a89bda84eac865059ab1755ffddc96497bc9691 100644 (file)
Binary files a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz and b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz differ
index 3e31b833511d2ded04ba55ce053d4ab5cfa6b3ad..869dd732eb9dcf6b3ba98156e427d1ade530685f 100644 (file)
@@ -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++;
 };
index 4cc15ba23fd8db5e466948071abdfe79c3108771..8f062d8b5efdf916f3ae90160641bfc692f165d3 100644 (file)
@@ -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}",
index e3c31c2d91fb4d78b8b97d165c63081b3b7fcf56..7371db283ac3a3d3a2bd7aae01d287044e54f349 100644 (file)
@@ -2,3 +2,4 @@ import frrtest
 
 class TestCli(frrtest.TestRefOut):
     program = './test_cli'
+    built_refout = True
index ec0835c7191258667c93f5e8d7be7a66214f86c7..24821febe6be0ef4065efcc16f7cf87b3d430154 100644 (file)
@@ -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 (file)
index 0000000..739a0e8
--- /dev/null
@@ -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
index c751c0b12d03bf04d4260c77352279dc084c0338..652d7618a8665809411983ad4bbe438200550833 100644 (file)
  * 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"
 
index 7bf3be9dbf6f85a59246d3ec3aeffa308d42049d..d400dfe8fa573f5d2837f1e635c1b3cd16de4b5d 100644 (file)
@@ -1,10 +1,2 @@
-!Makefile
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-.libs
-*.o
 /permutations
 /ssd
index 4c6968ac2765bede04b79465ea70c8d277bfd559..bbb358fc6c5b4176415daf5eac0fdfbe84c3226c 100644 (file)
@@ -11,3 +11,4 @@
 194  sharp
 195  pbr
 196  static
+197  openfabric
index 0b170d33fd62f386728a177aea0946741113abb7..9c8a8e90433f0bed598553ea5b20dc5d97046d61 100755 (executable)
--- 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
index 80441753e7a2b907e0da0f3cf522c0be87be05d3..c5109dc3e8823b626d82f3d676bfc38d3a0ae14d 100644 (file)
  * 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"
index de58e0a20e2b75756bc168828a9563872ad033da..cc0315c1307de1c0166af7821c752bd56388f8eb 100644 (file)
  *   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();
index 5856eac25352641ae5e513b7fe35c10b4654e47f..c1a39b8a12a41a08e65eae250cc9f6be9392da2b 100644 (file)
@@ -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 (file)
index 0000000..07e093b
--- /dev/null
@@ -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 (file)
index 936640c..0000000
+++ /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
index 92b5686a945a1a26f2ca6a0207b5142784647aed..0f68e58d62ea5cb9640b4d07714fcaec4d083536 100755 (executable)
@@ -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 (file)
index 0000000..932429a
--- /dev/null
@@ -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
index c249115fd372d8468cb2e5f887c98f6ddc70912b..6a92b9081377f32f5ad3bff15e39fb91abb722af 100644 (file)
@@ -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);
index c8e4c025e035b77bec851b517a6dd88fed7d7050..ee980d5128d30dfbc1c35ce3aaa3715e73ce66dc 100644 (file)
@@ -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,11 +50,11 @@ 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
+#define VTYSH_VRF        VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD
 
 enum vtysh_write_integrated {
        WRITE_INTEGRATED_UNSPECIFIED,
index 42f08342c0b299017a9fb396e08706c6adf08586..9f6e20f2be65090e5f984d89849100f049b6df0a 100644 (file)
@@ -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)
index 86fa62f474a44ef13ed536208d27b0e263468745..7e979f2c8f39a5dd9fd0fdec8b7f87d5b7344f73 100644 (file)
 #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"
index b8c020c04cbe153a7624c1683e74cf385866c6df..b3f5a6cd91414ec0f453af0a8ae6a6cf18fa3ed4 100644 (file)
@@ -1,16 +1 @@
-!Makefile
-Makefile.in
-*.o
 watchfrr
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
index 931f11ef63a5e42155b4a7a52556d0e61c17e885..f0b49c9a8482101ea6386329abf9ce756b122541 100644 (file)
@@ -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 += \
index 4a06756a2d56d9574a1ea99c12b05606b8bce18d..41a86e7d753aa49cd75695e8ec263b18a8407303 100644 (file)
@@ -1,15 +1,3 @@
-!Makefile
-Makefile.in
-*.o
 zebra
 zebra.conf
 client
-tags
-TAGS
-.deps
-.nfs*
-.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
index 5a58fe1751cbc54bbbb131aaf1ccc4007db85284..7ec73ea111cd9b55bbf2d8f7bc0f14d00a3ca28c 100644 (file)
@@ -39,6 +39,7 @@
 #include "zebra/interface.h"
 #include "zebra/ioctl_solaris.h"
 #include "zebra/rib.h"
+#include "zebra/rt.h"
 
 static int if_get_addr(struct interface *, struct sockaddr *, const char *);
 static void interface_info_ioctl(struct interface *);
@@ -55,7 +56,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;
 
@@ -76,13 +76,11 @@ calculate_lifc_len:
                lifn.lifn_flags = LIFC_NOXMIT;
                /* we want NOXMIT interfaces too */
                ret = ioctl(sock, SIOCGLIFNUM, &lifn);
-               save_errno = errno;
-
        }
 
        if (ret < 0) {
                zlog_warn("interface_list_ioctl: SIOCGLIFNUM failed %s",
-                         safe_strerror(save_errno));
+                         safe_strerror(errno));
                close(sock);
                return -1;
        }
index 1fc3e61a3b685ce6fe88d00be741e24028812601..3d67e3378f356ba3bffda520d719317275fc28bc 100644 (file)
@@ -259,6 +259,8 @@ static void netlink_determine_zebra_iftype(char *kind, zebra_iftype_t *zif_type)
                *zif_type = ZEBRA_IF_VXLAN;
        else if (strcmp(kind, "macvlan") == 0)
                *zif_type = ZEBRA_IF_MACVLAN;
+       else if (strcmp(kind, "veth") == 0)
+               *zif_type = ZEBRA_IF_VETH;
 }
 
 #define parse_rtattr_nested(tb, max, rta)                                      \
@@ -675,7 +677,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
 
        /* Update link. */
-       zebra_if_update_link(ifp, link_ifindex);
+       zebra_if_update_link(ifp, link_ifindex, ns_id);
 
        /* Hardware type and address. */
        ifp->ll_type = netlink_to_zebra_link_type(ifi->ifi_type);
@@ -1201,7 +1203,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                         ZEBRA_INTERFACE_VRF_LOOPBACK);
 
                        /* Update link. */
-                       zebra_if_update_link(ifp, link_ifindex);
+                       zebra_if_update_link(ifp, link_ifindex, ns_id);
 
                        netlink_interface_update_hw_addr(tb, ifp);
 
index 48adfd5a3d2e5b26abcc06b428ceac1a7b15d6ea..0c9e21d06893f4011ef40677bb98ea03087a47be 100644 (file)
@@ -981,13 +981,16 @@ void if_refresh(struct interface *ifp)
        if_get_flags(ifp);
 }
 
-void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex)
+void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
+                         ns_id_t ns_id)
 {
        struct zebra_if *zif;
 
+       if (IS_ZEBRA_IF_VETH(ifp))
+               return;
        zif = (struct zebra_if *)ifp->info;
        zif->link_ifindex = link_ifindex;
-       zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
+       zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
                                              link_ifindex);
 }
 
@@ -1072,6 +1075,10 @@ static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
                return "VRF";
                break;
 
+       case ZEBRA_IF_VETH:
+               return "VETH";
+               break;
+
        default:
                return "Unknown";
                break;
index 2add0a2de6b845cec53c6555762c88805b3f1fb9..02a05e6146399c5b53412baad44241dcf24d3b5c 100644 (file)
@@ -191,6 +191,7 @@ typedef enum {
        ZEBRA_IF_BRIDGE,    /* bridge device */
        ZEBRA_IF_VLAN,      /* VLAN sub-interface */
        ZEBRA_IF_MACVLAN,   /* MAC VLAN interface*/
+       ZEBRA_IF_VETH,      /* VETH interface*/
 } zebra_iftype_t;
 
 /* Zebra "slave" interface type */
@@ -312,7 +313,10 @@ static inline void zebra_if_set_ziftype(struct interface *ifp,
 #define IS_ZEBRA_IF_MACVLAN(ifp)                                               \
        (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_MACVLAN)
 
-#define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)                                          \
+#define IS_ZEBRA_IF_VETH(ifp)                                               \
+       (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_VETH)
+
+#define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)                                  \
        (((struct zebra_if *)(ifp->info))->zif_slave_type                      \
         == ZEBRA_IF_SLAVE_BRIDGE)
 
@@ -342,7 +346,8 @@ extern int if_subnet_add(struct interface *, struct connected *);
 extern int if_subnet_delete(struct interface *, struct connected *);
 extern int ipv6_address_configured(struct interface *ifp);
 extern void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id);
-extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex);
+extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
+                                ns_id_t ns_id);
 
 extern void vrf_add_update(struct vrf *vrfp);
 
index 3683596b41394b9ed3d2a331ad835fafd9a2b98a..8e2cd2e418c303e0bca3a630280363b0f3c0fab7 100644 (file)
@@ -99,7 +99,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;
        }
 
@@ -146,6 +146,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
@@ -203,6 +206,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
index c4f21d1504ebfc57d09ab9d790d808ed95e9f45c..cefd1996a96ab782fecc8a9e5ddefe7f2015d86e 100644 (file)
@@ -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);
 
index b3aeaf2f76c123e065b98c5d71daec003172acf7..8e5d7fbdbee5d5d6dfc16c669bf0d97f5377e23c 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "zebra/rib.h"
 #include "zebra/rt.h"
+#include "zebra/zebra_pbr.h"
 
 /* Thank you, Solaris, for polluting application symbol namespace. */
 #undef hook_register
index 5dc3750315b14b4ac789700120b9f65cb152f476..a87fcec41f0eda8200fd518d2fb63bc9de51a1c8 100644 (file)
@@ -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
index ebd632270c7d004b855799e55fcd3c2776a3dcd7..be0f6a23be74224f4a83756306b5b30e784d4323 100644 (file)
@@ -129,6 +129,7 @@ static inline int add_nexthop(qpb_allocator_t *allocator, Fpm__AddRoute *msg,
        }
 
        // TODO: Use src.
+       (void)src;
 
        return 1;
 }
index f7283aed36af7403731b5d71a9331146bf444a8b..8f48cc5191f6b2aa353f8037ff7176914859120a 100644 (file)
@@ -2698,7 +2698,7 @@ void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf)
  * (VTY command handler).
  */
 void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf,
-                         mpls_label_t label, uint8_t use_json)
+                         mpls_label_t label, bool use_json)
 {
        struct hash *lsp_table;
        zebra_lsp_t *lsp;
@@ -2729,7 +2729,7 @@ void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf,
  * Display MPLS label forwarding table (VTY command handler).
  */
 void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
-                               uint8_t use_json)
+                               bool use_json)
 {
        char buf[BUFSIZ];
        json_object *json = NULL;
index 65204a67dc8c9b9e14a97c4061097a469d60822e..86bee129cfe51c68a89cc47a4ac5569e70399bdf 100644 (file)
@@ -349,13 +349,13 @@ void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf);
  * (VTY command handler).
  */
 void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf,
-                         mpls_label_t label, uint8_t use_json);
+                         mpls_label_t label, bool use_json);
 
 /*
  * Display MPLS label forwarding table (VTY command handler).
  */
 void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
-                               uint8_t use_json);
+                               bool use_json);
 
 /*
  * Display MPLS LSP configuration of all static LSPs (VTY command handler).
index 2e02b12311e6399151aed2961018785a4fa04f2f..796aa3f6661044de1f364883fe8386851a9057f3 100644 (file)
@@ -339,7 +339,7 @@ DEFUN (show_mpls_table,
        JSON_STR)
 {
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
        zebra_mpls_print_lsp_table(vty, zvrf, uj);
@@ -357,7 +357,7 @@ DEFUN (show_mpls_table_lsp,
 {
        uint32_t label;
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
        label = atoi(argv[3]->arg);
index ab07549ec26d13054dde6d5368ebdb2db3a02e74..2c8fa77c32d91a84c3753ea4560ed96b990c1b6d 100644 (file)
@@ -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? */
@@ -2209,7 +2254,6 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
                       union prefixconstptr src_pp,
                       const struct route_entry *re)
 {
-       const struct prefix *p = pp.p;
        const struct prefix *src_p = src_pp.p;
        bool is_srcdst = src_p && src_p->prefixlen;
        char straddr[PREFIX_STRLEN];
@@ -2232,10 +2276,34 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
                   re->nexthop_num, re->nexthop_active_num);
 
        for (ALL_NEXTHOPS(re->ng, nexthop)) {
-               inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
-               zlog_debug("%s: %s %s[%u] vrf %u with flags %s%s%s", func,
+               struct interface *ifp;
+               struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
+
+               switch (nexthop->type) {
+               case NEXTHOP_TYPE_BLACKHOLE:
+                       sprintf(straddr, "Blackhole");
+                       break;
+               case NEXTHOP_TYPE_IFINDEX:
+                       ifp = if_lookup_by_index(nexthop->ifindex,
+                                                nexthop->vrf_id);
+                       sprintf(straddr, "%s", ifp ? ifp->name : "Unknown");
+                       break;
+               case NEXTHOP_TYPE_IPV4:
+                       /* fallthrough */
+               case NEXTHOP_TYPE_IPV4_IFINDEX:
+                       inet_ntop(AF_INET, &nexthop->gate, straddr,
+                                 INET6_ADDRSTRLEN);
+                       break;
+               case NEXTHOP_TYPE_IPV6:
+               case NEXTHOP_TYPE_IPV6_IFINDEX:
+                       inet_ntop(AF_INET6, &nexthop->gate, straddr,
+                                 INET6_ADDRSTRLEN);
+                       break;
+               }
+               zlog_debug("%s: %s %s[%u] vrf %s(%u) with flags %s%s%s", func,
                           (nexthop->rparent ? "  NH" : "NH"), straddr,
-                          nexthop->ifindex, nexthop->vrf_id,
+                          nexthop->ifindex, vrf ? vrf->name : "Unknown",
+                          nexthop->vrf_id,
                           (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
                                    ? "ACTIVE "
                                    : ""),
index 4f1d5cf6d584054e8eca6af1d6c125e9a8d02431..de08e323af115b61de3b345260be056775f8e7d2 100644 (file)
@@ -55,7 +55,7 @@
 extern int allow_delete;
 
 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
-                           safi_t safi, bool use_fib, uint8_t use_json,
+                           safi_t safi, bool use_fib, bool use_json,
                            route_tag_t tag,
                            const struct prefix *longer_prefix_p,
                            bool supernets_only, int type,
@@ -135,7 +135,7 @@ DEFUN (show_ip_rpf,
        "Display RPF information for multicast source\n"
        JSON_STR)
 {
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
                                false, uj, 0, NULL, false, 0, 0);
 }
@@ -760,8 +760,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
                                 bool use_fib, route_tag_t tag,
                                 const struct prefix *longer_prefix_p,
                                 bool supernets_only, int type,
-                                unsigned short ospf_instance_id,
-                                uint8_t use_json)
+                                unsigned short ospf_instance_id, bool use_json)
 {
        struct route_node *rn;
        struct route_entry *re;
@@ -850,7 +849,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
 }
 
 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
-                           safi_t safi, bool use_fib, uint8_t use_json,
+                           safi_t safi, bool use_fib, bool use_json,
                            route_tag_t tag,
                            const struct prefix *longer_prefix_p,
                            bool supernets_only, int type,
@@ -1723,7 +1722,7 @@ DEFUN (show_vrf_vni,
        struct zebra_vrf *zvrf;
        json_object *json = NULL;
        json_object *json_vrfs = NULL;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (uj) {
                json = json_object_new_object();
@@ -1759,7 +1758,7 @@ DEFUN (show_evpn_global,
        "EVPN\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zebra_vxlan_print_evpn(vty, uj);
        return CMD_SUCCESS;
@@ -1774,7 +1773,7 @@ DEFUN (show_evpn_vni,
        JSON_STR)
 {
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
        zebra_vxlan_print_vnis(vty, zvrf, uj);
@@ -1792,7 +1791,7 @@ DEFUN (show_evpn_vni_vni,
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[3]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -1814,7 +1813,7 @@ DEFUN (show_evpn_rmac_vni_mac,
 {
        vni_t l3vni = 0;
        struct ethaddr mac;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        if (!prefix_str2mac(argv[6]->arg, &mac)) {
@@ -1836,7 +1835,7 @@ DEFUN (show_evpn_rmac_vni,
        JSON_STR)
 {
        vni_t l3vni = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
@@ -1854,7 +1853,7 @@ DEFUN (show_evpn_rmac_vni_all,
        "All VNIs\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
 
@@ -1875,7 +1874,7 @@ DEFUN (show_evpn_nh_vni_ip,
 {
        vni_t l3vni;
        struct ipaddr ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        if (str2ipaddr(argv[6]->arg, &ip) != 0) {
@@ -1899,7 +1898,7 @@ DEFUN (show_evpn_nh_vni,
        JSON_STR)
 {
        vni_t l3vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
@@ -1917,7 +1916,7 @@ DEFUN (show_evpn_nh_vni_all,
        "All VNIs\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zebra_vxlan_print_nh_all_l3vni(vty, uj);
 
@@ -1936,7 +1935,7 @@ DEFUN (show_evpn_mac_vni,
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -1955,7 +1954,7 @@ DEFUN (show_evpn_mac_vni_all,
        JSON_STR)
 {
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
        zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
@@ -1976,7 +1975,7 @@ DEFUN (show_evpn_mac_vni_all_vtep,
 {
        struct zebra_vrf *zvrf;
        struct in_addr vtep_ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
                if (!uj)
@@ -2030,7 +2029,7 @@ DEFUN (show_evpn_mac_vni_vtep,
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct in_addr vtep_ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
@@ -2056,7 +2055,7 @@ DEFUN (show_evpn_neigh_vni,
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -2075,7 +2074,7 @@ DEFUN (show_evpn_neigh_vni_all,
        JSON_STR)
 {
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
        zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
@@ -2097,7 +2096,7 @@ DEFUN (show_evpn_neigh_vni_neigh,
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct ipaddr ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (str2ipaddr(argv[6]->arg, &ip) != 0) {
@@ -2125,7 +2124,7 @@ DEFUN (show_evpn_neigh_vni_vtep,
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct in_addr vtep_ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
index b0fc0a39bd85663da4bee0ee5ecf0acc88e5e75e..eb1b07170129c495c17f0ea86f5917d4abe3dad7 100644 (file)
@@ -79,7 +79,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
 
 static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
                                         struct ipaddr *ip, uint8_t flags,
-                                        uint16_t cmd);
+                                        uint32_t seq, uint16_t cmd);
 static unsigned int neigh_hash_keymake(void *p);
 static int neigh_cmp(const void *p1, const void *p2);
 static void *zvni_neigh_alloc(void *p);
@@ -93,7 +93,7 @@ static void zvni_neigh_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip);
 static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
                                         struct ethaddr *macaddr,
-                                        uint8_t flags);
+                                        uint8_t flags, uint32_t seq);
 static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
                                         struct ethaddr *macaddr,
                                         uint8_t flags);
@@ -147,7 +147,7 @@ static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
                             uint32_t flags);
 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
 static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
-                                      uint8_t flags);
+                                      uint8_t flags, uint32_t seq);
 static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
                                       uint8_t flags);
 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
@@ -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_warn("%s: Unexpected family type: %d", __PRETTY_FUNCTION__,
                          hle1->p.family);
@@ -296,47 +299,60 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
        struct vty *vty;
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
+       const char *type_str;
+       const char *state_str;
+       bool flags_present = false;
 
        ipaddr2str(&n->ip, buf2, sizeof(buf2));
        prefix_mac2str(&n->emac, buf1, sizeof(buf1));
+       type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ?
+                                               "local" : "remote";
+       state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
        vty = (struct vty *)ctxt;
        if (json == NULL) {
                vty_out(vty, "IP: %s\n",
                        ipaddr2str(&n->ip, buf2, sizeof(buf2)));
-               vty_out(vty, " MAC: %s",
+               vty_out(vty, " Type: %s\n", type_str);
+               vty_out(vty, " State: %s\n", state_str);
+               vty_out(vty, " MAC: %s\n",
                        prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
        } else {
                json_object_string_add(json, "ip", buf2);
+               json_object_string_add(json, "type", type_str);
+               json_object_string_add(json, "state", state_str);
                json_object_string_add(json, "mac", buf1);
        }
        if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
                if (json == NULL) {
-                       vty_out(vty, " Remote VTEP: %s",
+                       vty_out(vty, " Remote VTEP: %s\n",
                                inet_ntoa(n->r_vtep_ip));
                } else
                        json_object_string_add(json, "remoteVtep",
                                               inet_ntoa(n->r_vtep_ip));
        }
-       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
-               if (!json) {
-                       vty_out(vty, "\n");
-                       vty_out(vty, " State: %s",
-                               IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active"
-                                                        : "Inactive");
-               }
-       }
        if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
-               if (!json)
-                       vty_out(vty, " Default-gateway");
-               else
+               if (!json) {
+                       vty_out(vty, " Flags: Default-gateway");
+                       flags_present = true;
+               } else
                        json_object_boolean_true_add(json, "defaultGateway");
        }
        if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
-               if (!json)
-                       vty_out(vty, " Router");
+               if (!json) {
+                       vty_out(vty,
+                               flags_present ? " ,Router" : " Flags: Router");
+                       flags_present = true;
+               }
+       }
+       if (json == NULL) {
+               if (flags_present)
+                       vty_out(vty, "\n");
+               vty_out(vty, " Local Seq: %u Remote Seq: %u\n",
+                       n->loc_seq, n->rem_seq);
+       } else {
+               json_object_int_add(json, "localSequence", n->loc_seq);
+               json_object_int_add(json, "remoteSequence", n->rem_seq);
        }
-       if (json == NULL)
-               vty_out(vty, "\n");
 }
 
 /*
@@ -350,6 +366,7 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
        struct neigh_walk_ctx *wctx = ctxt;
+       const char *state_str;
 
        vty = wctx->vty;
        json_vni = wctx->json;
@@ -360,55 +377,58 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
 
        prefix_mac2str(&n->emac, buf1, sizeof(buf1));
        ipaddr2str(&n->ip, buf2, sizeof(buf2));
-       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
-           && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) {
+       state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive";
+       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
+               if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
+                       return;
+
                if (json_vni == NULL) {
-                       vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width,
-                               buf2, "local", buf1);
+                       vty_out(vty, "%*s %-6s %-8s %-17s\n",
+                               -wctx->addr_width, buf2, "local",
+                               state_str, buf1);
                } else {
                        json_object_string_add(json_row, "type", "local");
+                       json_object_string_add(json_row, "state", state_str);
                        json_object_string_add(json_row, "mac", buf1);
+                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
+                               json_object_boolean_true_add(
+                                               json_row, "defaultGateway");
+                       json_object_int_add(json_row, "localSequence",
+                                           n->loc_seq);
+                       json_object_int_add(json_row, "remoteSequence",
+                                           n->rem_seq);
                }
                wctx->count++;
-       } else {
-               if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) {
-                       if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) {
-                               if (json_vni == NULL) {
-                                       if (wctx->count == 0)
-                                               vty_out(vty,
-                                                       "%*s %-6s %-17s %-21s\n",
-                                                       -wctx->addr_width,
-                                                       "Neighbor", "Type",
-                                                       "MAC", "Remote VTEP");
-                                       vty_out(vty, "%*s %-6s %-17s %-21s\n",
-                                               -wctx->addr_width, buf2,
-                                               "remote", buf1,
-                                               inet_ntoa(n->r_vtep_ip));
-                               } else {
-                                       json_object_string_add(json_row, "type",
-                                                              "remote");
-                                       json_object_string_add(json_row, "mac",
-                                                              buf1);
-                                       json_object_string_add(
-                                               json_row, "remoteVtep",
-                                               inet_ntoa(n->r_vtep_ip));
-                               }
-                               wctx->count++;
-                       }
+       } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
+               if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
+                   !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
+                       return;
+
+               if (json_vni == NULL) {
+                       if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
+                           (wctx->count == 0))
+                               vty_out(vty,
+                                       "%*s %-6s %-8s %-17s %-21s\n",
+                                       -wctx->addr_width, "Neighbor", "Type",
+                                       "State", "MAC", "Remote VTEP");
+                       vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
+                               -wctx->addr_width, buf2, "remote", state_str,
+                               buf1, inet_ntoa(n->r_vtep_ip));
                } else {
-                       if (json_vni == NULL) {
-                               vty_out(vty, "%*s %-6s %-17s %-21s\n",
-                                       -wctx->addr_width, buf2, "remote", buf1,
-                                       inet_ntoa(n->r_vtep_ip));
-                       } else {
-                               json_object_string_add(json_row, "type",
-                                                      "remote");
-                               json_object_string_add(json_row, "mac", buf1);
-                               json_object_string_add(json_row, "remoteVtep",
-                                                      inet_ntoa(n->r_vtep_ip));
-                       }
-                       wctx->count++;
+                       json_object_string_add(json_row, "type", "remote");
+                       json_object_string_add(json_row, "state", state_str);
+                       json_object_string_add(json_row, "mac", buf1);
+                       json_object_string_add(json_row, "remoteVtep",
+                                              inet_ntoa(n->r_vtep_ip));
+                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
+                               json_object_boolean_true_add(json_row,
+                                                            "defaultGateway");
+                       json_object_int_add(json_row, "localSequence",
+                                           n->loc_seq);
+                       json_object_int_add(json_row, "remoteSequence",
+                                           n->rem_seq);
                }
+               wctx->count++;
        }
 
        if (json_vni)
@@ -461,8 +481,9 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
        hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
 
        if (json == NULL) {
-               vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
-                       "Type", "MAC", "Remote VTEP");
+               vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
+                       -wctx.addr_width, "IP", "Type",
+                       "State", "MAC", "Remote VTEP");
        }
        hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
 
@@ -535,6 +556,8 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
                                       inet_ntoa(zrmac->fwd_info.r_vtep_ip));
                json_object_int_add(json, "refCount",
                                    rb_host_count(&zrmac->host_rb));
+               json_object_int_add(json, "localSequence", zrmac->loc_seq);
+               json_object_int_add(json, "remoteSequence", zrmac->rem_seq);
                RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
                        json_object_array_add(
                                json_hosts,
@@ -588,6 +611,10 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
                vty_out(vty, " Remote-gateway Mac ");
 
        vty_out(vty, "\n");
+       vty_out(vty, " Local Seq: %u Remote Seq: %u",
+               mac->loc_seq, mac->rem_seq);
+       vty_out(vty, "\n");
+
        /* print all the associated neigh */
        vty_out(vty, " Neighbors:\n");
        if (!listcount(mac->neigh_list))
@@ -596,11 +623,8 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
                for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
                        vty_out(vty, "    %s %s\n",
                                ipaddr2str(&n->ip, buf2, sizeof(buf2)),
-                               CHECK_FLAG(n->flags, ZEBRA_MAC_LOCAL)
-                                       ? (IS_ZEBRA_NEIGH_ACTIVE(n)
-                                                  ? "Active"
-                                                  : "Inactive")
-                                       : "");
+                               (IS_ZEBRA_NEIGH_ACTIVE(n)
+                                          ? "Active" : "Inactive"));
                }
        }
 
@@ -627,13 +651,15 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
        if (json_mac_hdr)
                json_mac = json_object_new_object();
 
-       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
-           && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) {
+       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
                struct zebra_ns *zns;
                ifindex_t ifindex;
                struct interface *ifp;
                vlanid_t vid;
 
+               if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)
+                       return;
+
                zns = zebra_ns_lookup(NS_DEFAULT);
                ifindex = mac->fwd_info.local.ifindex;
                ifp = if_lookup_by_index_per_ns(zns, ifindex);
@@ -653,59 +679,46 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
                        else
                                json_object_int_add(json_mac, "vlan", vid);
                }
-               if (json_mac_hdr == NULL)
+               if (json_mac_hdr == NULL) {
                        vty_out(vty, "\n");
-               else
+               } else {
+                       json_object_int_add(json_mac, "localSequence",
+                                           mac->loc_seq);
+                       json_object_int_add(json_mac, "remoteSequence",
+                                           mac->rem_seq);
                        json_object_object_add(json_mac_hdr, buf1, json_mac);
+               }
+
                wctx->count++;
+
        } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
-               if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) {
-                       if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
-                                          &wctx->r_vtep_ip)) {
-                               if (wctx->count == 0) {
-                                       if (json_mac_hdr == NULL) {
-                                               vty_out(vty, "\nVNI %u\n\n",
-                                                       wctx->zvni->vni);
-                                               vty_out(vty,
-                                                       "%-17s %-6s %-21s %-5s\n",
-                                                       "MAC", "Type",
-                                                       "Intf/Remote VTEP",
-                                                       "VLAN");
-                                       }
-                               }
-                               if (json_mac_hdr == NULL)
-                                       vty_out(vty, "%-17s %-6s %-21s\n", buf1,
-                                               "remote",
-                                               inet_ntoa(mac->fwd_info
-                                                                 .r_vtep_ip));
-                               else {
-                                       json_object_string_add(json_mac, "type",
-                                                              "remote");
-                                       json_object_string_add(
-                                               json_mac, "remoteVtep",
-                                               inet_ntoa(mac->fwd_info
-                                                                 .r_vtep_ip));
-                                       json_object_object_add(json_mac_hdr,
-                                                              buf1, json_mac);
-                               }
-                               wctx->count++;
+
+               if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
+                   !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
+                                   &wctx->r_vtep_ip))
+                       return;
+
+               if (json_mac_hdr == NULL) {
+                       if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) &&
+                           (wctx->count == 0)) {
+                               vty_out(vty, "\nVNI %u\n\n", wctx->zvni->vni);
+                               vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC",
+                                       "Type", "Intf/Remote VTEP", "VLAN");
                        }
+                       vty_out(vty, "%-17s %-6s %-21s\n", buf1, "remote",
+                               inet_ntoa(mac->fwd_info.r_vtep_ip));
                } else {
-                       if (json_mac_hdr == NULL)
-                               vty_out(vty, "%-17s %-6s %-21s\n", buf1,
-                                       "remote",
-                                       inet_ntoa(mac->fwd_info.r_vtep_ip));
-                       else {
-                               json_object_string_add(json_mac, "type",
-                                                      "remote");
-                               json_object_string_add(
-                                       json_mac, "remoteVtep",
+                       json_object_string_add(json_mac, "type", "remote");
+                       json_object_string_add(json_mac, "remoteVtep",
                                        inet_ntoa(mac->fwd_info.r_vtep_ip));
-                               json_object_object_add(json_mac_hdr, buf1,
-                                                      json_mac);
-                       }
-                       wctx->count++;
+                       json_object_object_add(json_mac_hdr, buf1, json_mac);
+                       json_object_int_add(json_mac, "localSequence",
+                                           mac->loc_seq);
+                       json_object_int_add(json_mac, "remoteSequence",
+                                           mac->rem_seq);
                }
+
+               wctx->count++;
        }
 }
 
@@ -1166,7 +1179,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
  */
 static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
                                         struct ipaddr *ip, uint8_t flags,
-                                        uint16_t cmd)
+                                        uint32_t seq, uint16_t cmd)
 {
        char buf[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
@@ -1197,7 +1210,10 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
        } else
                stream_putl(s, 0); /* Just MAC. */
 
-       stream_putc(s, flags); /* sticky mac/gateway mac */
+       if (cmd == ZEBRA_MACIP_ADD) {
+               stream_putc(s, flags); /* sticky mac/gateway mac */
+               stream_putl(s, seq); /* sequence number */
+       }
 
 
        /* Write packet size. */
@@ -1205,10 +1221,10 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
 
        if (IS_ZEBRA_DEBUG_VXLAN)
                zlog_debug(
-                       "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
+                       "Send MACIP %s flags 0x%x MAC %s IP %s seq %u L2-VNI %u to %s",
                        (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags,
                        prefix_mac2str(macaddr, buf, sizeof(buf)),
-                       ipaddr2str(ip, buf2, sizeof(buf2)), vni,
+                       ipaddr2str(ip, buf2, sizeof(buf2)), seq, vni,
                        zebra_route_string(client->proto));
 
        if (cmd == ZEBRA_MACIP_ADD)
@@ -1393,106 +1409,100 @@ static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip)
        return n;
 }
 
-/* Process all neigh associated to a mac upon local mac add event */
-static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni,
-                                               zebra_mac_t *zmac)
+/*
+ * Process all neighbors associated with a MAC upon the MAC being learnt
+ * locally or undergoing any other change (such as sequence number).
+ */
+static void zvni_process_neigh_on_local_mac_change(zebra_vni_t *zvni,
+                                                  zebra_mac_t *zmac,
+                                                  bool seq_change)
 {
        zebra_neigh_t *n = NULL;
        struct listnode *node = NULL;
        char buf[ETHER_ADDR_STRLEN];
-       char buf2[INET6_ADDRSTRLEN];
 
+       if (IS_ZEBRA_DEBUG_VXLAN)
+               zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
+                          prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
+                          seq_change ? "CHANGE" : "ADD", zvni->vni);
+
+       /* Walk all neighbors and mark any inactive local neighbors as
+        * active and/or update sequence number upon a move, and inform BGP.
+        * The action for remote neighbors is TBD.
+        * NOTE: We can't simply uninstall remote neighbors as the kernel may
+        * accidentally end up deleting a just-learnt local neighbor.
+        */
        for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
                if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
-                       /* MAC is learnt locally, program all inactive neigh
-                        * pointing to this mac */
-                       if (IS_ZEBRA_NEIGH_INACTIVE(n)) {
-                               if (IS_ZEBRA_DEBUG_VXLAN)
-                                       zlog_debug(
-                                               "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
-                                               ipaddr2str(&n->ip, buf2,
-                                                          sizeof(buf2)),
-                                               prefix_mac2str(&n->emac, buf,
-                                                              sizeof(buf)),
-                                               zvni->vni);
-
+                       if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change) {
                                ZEBRA_NEIGH_SET_ACTIVE(n);
+                               n->loc_seq = zmac->loc_seq;
                                zvni_neigh_send_add_to_client(
-                                       zvni->vni, &n->ip, &n->emac, n->flags);
-                       } else {
-                               if (IS_ZEBRA_DEBUG_VXLAN)
-                                       zlog_debug(
-                                               "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
-                                               ipaddr2str(&n->ip, buf2,
-                                                          sizeof(buf2)),
-                                               prefix_mac2str(&n->emac, buf,
-                                                              sizeof(buf)),
-                                               zvni->vni);
+                                       zvni->vni, &n->ip, &n->emac,
+                                       n->flags, n->loc_seq);
                        }
-               } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
-                       /* TODO: assume the neigh has moved too ?? */
                }
        }
 }
 
-/* Process all neigh associated to a mac upon local mac del event */
+/*
+ * Process all neighbors associated with a local MAC upon the MAC being
+ * deleted.
+ */
 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni,
                                                zebra_mac_t *zmac)
 {
        zebra_neigh_t *n = NULL;
        struct listnode *node = NULL;
        char buf[ETHER_ADDR_STRLEN];
-       char buf2[INET6_ADDRSTRLEN];
 
+       if (IS_ZEBRA_DEBUG_VXLAN)
+               zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u",
+                          prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
+                          zvni->vni);
+
+       /* Walk all local neighbors and mark as inactive and inform
+        * BGP, if needed.
+        * TBD: There is currently no handling for remote neighbors. We
+        * don't expect them to exist, if they do, do we install the MAC
+        * as a remote MAC and the neighbor as remote?
+        */
        for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
                if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
                        if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
-                               if (IS_ZEBRA_DEBUG_VXLAN)
-                                       zlog_debug(
-                                               "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
-                                               ipaddr2str(&n->ip, buf2,
-                                                          sizeof(buf2)),
-                                               prefix_mac2str(&n->emac, buf,
-                                                              sizeof(buf)),
-                                               zvni->vni);
-
                                ZEBRA_NEIGH_SET_INACTIVE(n);
+                               n->loc_seq = 0;
                                zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
                                                              &n->emac, 0);
                        }
-               } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
-                          && IS_ZEBRA_DEBUG_VXLAN) {
-                       zlog_debug(
-                               "local MAC %s getting deleted on VNI %u has remote neigh %s",
-                               prefix_mac2str(&n->emac, buf, sizeof(buf)),
-                               zvni->vni,
-                               ipaddr2str(&n->ip, buf2, sizeof(buf2)));
                }
        }
 }
 
-/* process all neigh associated to a mac entry upon remote mac add */
+/*
+ * Process all neighbors associated with a MAC upon the MAC being remotely
+ * learnt.
+ */
 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni,
                                                 zebra_mac_t *zmac)
 {
        zebra_neigh_t *n = NULL;
        struct listnode *node = NULL;
        char buf[ETHER_ADDR_STRLEN];
-       char buf2[INET6_ADDRSTRLEN];
 
+       if (IS_ZEBRA_DEBUG_VXLAN)
+               zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u",
+                          prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)),
+                          zvni->vni);
+
+       /* Walk all local neighbors and mark as inactive and inform
+        * BGP, if needed.
+        */
        for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
                if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
                        if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
-                               if (IS_ZEBRA_DEBUG_VXLAN)
-                                       zlog_debug(
-                                               "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
-                                               ipaddr2str(&n->ip, buf2,
-                                                          sizeof(buf2)),
-                                               prefix_mac2str(&n->emac, buf,
-                                                              sizeof(buf)),
-                                               zvni->vni);
-
                                ZEBRA_NEIGH_SET_INACTIVE(n);
+                               n->loc_seq = 0;
                                zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
                                                              &n->emac, 0);
                        }
@@ -1500,25 +1510,14 @@ static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni,
        }
 }
 
-/* process all neigh associated to mac entry upon remote mac del */
+/*
+ * Process all neighbors associated with a remote MAC upon the MAC being
+ * deleted.
+ */
 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
                                                 zebra_mac_t *zmac)
 {
-       zebra_neigh_t *n = NULL;
-       struct listnode *node = NULL;
-       char buf[ETHER_ADDR_STRLEN];
-       char buf2[INET6_ADDRSTRLEN];
-
-       for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
-               if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
-                   && IS_ZEBRA_DEBUG_VXLAN) {
-                       zlog_debug(
-                               "remote MAC %s getting deleted on VNI %u has local neigh %s",
-                               prefix_mac2str(&n->emac, buf, sizeof(buf)),
-                               zvni->vni,
-                               ipaddr2str(&n->ip, buf2, sizeof(buf2)));
-               }
-       }
+       /* NOTE: Currently a NO-OP. */
 }
 
 /*
@@ -1526,7 +1525,8 @@ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
  */
 static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
                                         struct ethaddr *macaddr,
-                                        uint8_t neigh_flags)
+                                        uint8_t neigh_flags,
+                                        uint32_t seq)
 {
        uint8_t flags = 0;
 
@@ -1537,7 +1537,7 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
                SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
 
        return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
-                                            ZEBRA_MACIP_ADD);
+                                            seq, ZEBRA_MACIP_ADD);
 }
 
 /*
@@ -1547,7 +1547,7 @@ static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
                                         struct ethaddr *macaddr, uint8_t flags)
 {
        return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
-                                            ZEBRA_MACIP_DEL);
+                                            0, ZEBRA_MACIP_DEL);
 }
 
 /*
@@ -1578,6 +1578,7 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
        flags = NTF_EXT_LEARNED;
        if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
                flags |= NTF_ROUTER;
+       ZEBRA_NEIGH_SET_ACTIVE(n);
        ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags);
 #endif
        return ret;
@@ -1609,6 +1610,8 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
        if (!vlan_if)
                return -1;
 
+       ZEBRA_NEIGH_SET_INACTIVE(n);
+       n->loc_seq = 0;
        return kernel_del_neigh(vlan_if, &n->ip);
 }
 
@@ -1802,6 +1805,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
        /* Set "local" forwarding info. */
        SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
        SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
+       ZEBRA_NEIGH_SET_ACTIVE(n);
        /* Set Router flag (R-bit) */
        if (ip->ipa_type == IPADDR_V6)
                SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
@@ -1819,7 +1823,8 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
                        prefix_mac2str(macaddr, buf, sizeof(buf)),
                        ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
 
-       zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
+       zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
+                                     n->flags, n->loc_seq);
 
        return 0;
 }
@@ -1963,11 +1968,15 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
        char buf2[INET6_ADDRSTRLEN];
        zebra_neigh_t *n = NULL;
        zebra_mac_t *zmac = NULL, *old_zmac = NULL;
+       uint32_t old_mac_seq = 0, mac_new_seq = 0;
+       bool upd_mac_seq = false;
+       bool neigh_mac_change = false;
        bool check_rbit = false;
 
-       /* create a dummy MAC if the MAC is not already present */
+       /* Check if the MAC exists. */
        zmac = zvni_mac_lookup(zvni, macaddr);
        if (!zmac) {
+               /* create a dummy MAC if the MAC is not already present */
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
                                "AUTO MAC %s created for neigh %s on VNI %u",
@@ -1985,15 +1994,40 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
                memset(&zmac->flags, 0, sizeof(uint32_t));
                SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
+       } else {
+               if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
+                       /*
+                        * We don't change the MAC to local upon a neighbor
+                        * learn event, we wait for the explicit local MAC
+                        * learn. However, we have to compute its sequence
+                        * number in preparation for when it actually turns
+                        * local.
+                        */
+                       upd_mac_seq = true;
+               }
        }
 
-       /* If same entry already exists, it might be a change or it might be a
-        * move from remote to local.
-        */
+       /* Check if the neighbor exists. */
        n = zvni_neigh_lookup(zvni, ip);
-       if (n) {
+       if (!n) {
+               /* New neighbor - create */
+               n = zvni_neigh_add(zvni, ip, macaddr);
+               if (!n) {
+                       flog_err(
+                               ZEBRA_ERR_MAC_ADD_FAILED,
+                               "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
+                               ipaddr2str(ip, buf2, sizeof(buf2)),
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               ifp->name, ifp->ifindex, zvni->vni);
+                       return -1;
+               }
+               /* Set "local" forwarding info. */
+               SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
+               n->ifindex = ifp->ifindex;
+               check_rbit = true;
+       } else {
                if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
-
+                       /* If there is no MAC change, BGP isn't interested. */
                        if (router_flag !=
                            (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
                                        ? 1 : 0))
@@ -2007,16 +2041,26 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                                n->ifindex = ifp->ifindex;
                        } else {
 
-                               /* If the MAC has changed,
-                                * need to issue a delete first
-                                * as this means a different MACIP route.
-                                * Also, need to do some unlinking/relinking.
+                               /* If the MAC has changed, need to issue a
+                                * delete first as this means a different
+                                * MACIP route. Also, need to do some
+                                * unlinking/relinking. We also need to
+                                * update the MAC's sequence number
+                                * in different situations.
                                 */
-                               zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
-                                                     &n->emac, 0);
+                               if (IS_ZEBRA_NEIGH_ACTIVE(n))
+                                       zvni_neigh_send_del_to_client(
+                                               zvni->vni, &n->ip, &n->emac, 0);
                                old_zmac = zvni_mac_lookup(zvni, &n->emac);
                                if (old_zmac) {
-                                       listnode_delete(old_zmac->neigh_list, n);
+                                       old_mac_seq =
+                                               CHECK_FLAG(old_zmac->flags,
+                                                          ZEBRA_MAC_REMOTE) ?
+                                                       old_zmac->rem_seq :
+                                                       old_zmac->loc_seq;
+                                       neigh_mac_change = upd_mac_seq = true;
+                                       listnode_delete(
+                                               old_zmac->neigh_list, n);
                                        zvni_deref_ip2mac(zvni, old_zmac, 0);
                                }
 
@@ -2028,14 +2072,21 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                                listnode_add_sort(zmac->neigh_list, n);
                        }
 
-               } else
-               /* Neighbor has moved from remote to local. */
-               {
-                       /* If MAC has changed, do the unlink/link */
+               } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
+                       /*
+                        * Neighbor has moved from remote to local. Its
+                        * MAC could have also changed as part of the move.
+                        */
                        if (memcmp(n->emac.octet, macaddr->octet,
                                   ETH_ALEN) != 0) {
                                old_zmac = zvni_mac_lookup(zvni, &n->emac);
                                if (old_zmac) {
+                                       old_mac_seq = CHECK_FLAG(
+                                                       old_zmac->flags,
+                                                       ZEBRA_MAC_REMOTE) ?
+                                                       old_zmac->rem_seq :
+                                                       old_zmac->loc_seq;
+                                       neigh_mac_change = upd_mac_seq = true;
                                        listnode_delete(old_zmac->neigh_list,
                                                        n);
                                        zvni_deref_ip2mac(zvni, old_zmac, 0);
@@ -2053,22 +2104,19 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                        n->ifindex = ifp->ifindex;
                        check_rbit = true;
                }
-       } else {
-               /* New neighbor - create */
-               n = zvni_neigh_add(zvni, ip, macaddr);
-               if (!n) {
-                       flog_err(
-                               ZEBRA_ERR_MAC_ADD_FAILED,
-                               "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
-                               ipaddr2str(ip, buf2, sizeof(buf2)),
-                               prefix_mac2str(macaddr, buf, sizeof(buf)),
-                               ifp->name, ifp->ifindex, zvni->vni);
-                       return -1;
-               }
-               /* Set "local" forwarding info. */
-               SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
-               n->ifindex = ifp->ifindex;
-               check_rbit = true;
+       }
+
+       /* If MAC was previously remote, or the neighbor had a different
+        * MAC earlier, recompute the sequence number.
+        */
+       if (upd_mac_seq) {
+               uint32_t seq1, seq2;
+
+               seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE) ?
+                      zmac->rem_seq + 1 : zmac->loc_seq;
+               seq2 = neigh_mac_change ? old_mac_seq + 1 : 0;
+               mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ?
+                             MAX(seq1, seq2) : zmac->loc_seq;
        }
 
        /*Mark Router flag (R-bit) */
@@ -2078,38 +2126,40 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
 
        /* Before we program this in BGP, we need to check if MAC is locally
-        * learnt as well
+        * learnt. If not, force neighbor to be inactive and reset its seq.
         */
        if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
-               if (IS_ZEBRA_DEBUG_VXLAN)
-                       zlog_debug(
-                               "Skipping neigh %s add to client as MAC %s is not local on VNI %u with flags 0x%x",
-                               ipaddr2str(ip, buf2, sizeof(buf2)),
-                               prefix_mac2str(macaddr, buf, sizeof(buf)),
-                               zvni->vni, n->flags);
-
+               ZEBRA_NEIGH_SET_INACTIVE(n);
+               n->loc_seq = 0;
+               zmac->loc_seq = mac_new_seq;
                return 0;
        }
 
-       if (!check_rbit) {
+       if (!check_rbit)
+               return 0;
+
+       /* If the MAC's sequence number has changed, inform the MAC and all
+        * neighbors associated with the MAC to BGP, else just inform this
+        * neighbor.
+        */
+       if (upd_mac_seq && zmac->loc_seq != mac_new_seq) {
                if (IS_ZEBRA_DEBUG_VXLAN)
-                       zlog_debug(
-                               "Skipping neigh %s with MAC %s on VNI %u add to client as router flag is not set.",
-                               ipaddr2str(ip, buf2, sizeof(buf2)),
-                               prefix_mac2str(macaddr, buf, sizeof(buf)),
-                               zvni->vni);
+                       zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u",
+                                  prefix_mac2str(macaddr, buf, sizeof(buf)),
+                                  zvni->vni, zmac->loc_seq, mac_new_seq);
+               zmac->loc_seq = mac_new_seq;
+               if (zvni_mac_send_add_to_client(zvni->vni, macaddr,
+                                               zmac->flags, zmac->loc_seq))
+                       return -1;
+               zvni_process_neigh_on_local_mac_change(zvni, zmac, 1);
                return 0;
        }
 
-       /* Inform BGP. */
-       if (IS_ZEBRA_DEBUG_VXLAN)
-               zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u with flags 0x%x",
-                          ipaddr2str(ip, buf2, sizeof(buf2)),
-                          prefix_mac2str(macaddr, buf, sizeof(buf)),
-                          zvni->vni, n->flags);
        ZEBRA_NEIGH_SET_ACTIVE(n);
+       n->loc_seq = zmac->loc_seq;
 
-       return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
+       return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
+                                            n->flags, n->loc_seq);
 }
 
 static int zvni_remote_neigh_update(zebra_vni_t *zvni,
@@ -2325,7 +2375,7 @@ static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
  * Inform BGP about local MAC addition.
  */
 static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
-                                      uint8_t mac_flags)
+                                      uint8_t mac_flags, uint32_t seq)
 {
        uint8_t flags = 0;
 
@@ -2335,7 +2385,7 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
                SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
 
        return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
-                                            ZEBRA_MACIP_ADD);
+                                            seq, ZEBRA_MACIP_ADD);
 }
 
 /*
@@ -2352,7 +2402,7 @@ static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
                SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
 
        return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
-                                            ZEBRA_MACIP_DEL);
+                                            0, ZEBRA_MACIP_DEL);
 }
 
 /*
@@ -3976,69 +4026,442 @@ static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni,
        return 0;
 }
 
-/* Public functions */
-
-int is_l3vni_for_prefix_routes_only(vni_t vni)
+/* Process a remote MACIP add from BGP. */
+static void process_remote_macip_add(vni_t vni,
+                                    struct ethaddr *macaddr,
+                                    uint16_t ipa_len,
+                                    struct ipaddr *ipaddr,
+                                    uint8_t flags,
+                                    uint32_t seq,
+                                    struct in_addr vtep_ip)
 {
-       zebra_l3vni_t *zl3vni = NULL;
-
-       zl3vni = zl3vni_lookup(vni);
-       if (!zl3vni)
-               return 0;
-
-       return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
-}
+       zebra_vni_t *zvni;
+       zebra_vtep_t *zvtep;
+       zebra_mac_t *mac, *old_mac;
+       zebra_neigh_t *n = NULL;
+       int update_mac = 0, update_neigh = 0;
+       char buf[ETHER_ADDR_STRLEN];
+       char buf1[INET6_ADDRSTRLEN];
+       struct interface *ifp = NULL;
+       struct zebra_if *zif = NULL;
+       uint32_t tmp_seq;
+       uint8_t sticky = 0;
+       uint8_t remote_gw = 0;
+       uint8_t router_flag = 0;
 
-/* handle evpn route in vrf table */
-void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac,
-                                   struct ipaddr *vtep_ip,
-                                   struct prefix *host_prefix)
-{
-       zebra_l3vni_t *zl3vni = NULL;
-       struct ipaddr ipv4_vtep;
+       /* Locate VNI hash entry - expected to exist. */
+       zvni = zvni_lookup(vni);
+       if (!zvni) {
+               zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni);
+               return;
+       }
 
-       zl3vni = zl3vni_from_vrf(vrf_id);
-       if (!zl3vni || !is_l3vni_oper_up(zl3vni))
+       ifp = zvni->vxlan_if;
+       if (ifp)
+               zif = ifp->info;
+       if (!ifp ||
+           !if_is_operative(ifp) ||
+           !zif ||
+           !zif->brslave_info.br_if) {
+               zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
+                         vni);
                return;
+       }
 
-       /*
-        * add the next hop neighbor -
-        * neigh to be installed is the ipv6 nexthop neigh
+       /* The remote VTEP specified should normally exist, but it is
+        * possible that when peering comes up, peer may advertise MACIP
+        * routes before advertising type-3 routes.
         */
-       zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
+       zvtep = zvni_vtep_find(zvni, &vtep_ip);
+       if (!zvtep) {
+               if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
+                       flog_err(
+                               ZEBRA_ERR_VTEP_ADD_FAILED,
+                               "Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
+                               vni, zvni);
+                       return;
+               }
 
-       /*
-        * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
-        * address. Rmac is programmed against the ipv4 vtep because we only
-        * support ipv4 tunnels in the h/w right now
-        */
-       memset(&ipv4_vtep, 0, sizeof(struct ipaddr));
-       ipv4_vtep.ipa_type = IPADDR_V4;
-       if (vtep_ip->ipa_type == IPADDR_V6)
-               ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
-                                        &(ipv4_vtep.ipaddr_v4));
-       else
-               memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
-                      sizeof(struct in_addr));
+               zvni_vtep_install(zvni, &vtep_ip);
+       }
 
-       /*
-        * add the rmac - remote rmac to be installed is against the ipv4
-        * nexthop address
-        */
-       zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix);
-}
+       sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+       remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+       router_flag = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
 
-/* handle evpn vrf route delete */
-void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
-                                   struct ipaddr *vtep_ip,
-                                   struct prefix *host_prefix)
-{
-       zebra_l3vni_t *zl3vni = NULL;
-       zebra_neigh_t *nh = NULL;
-       zebra_mac_t *zrmac = NULL;
+       mac = zvni_mac_lookup(zvni, macaddr);
 
-       zl3vni = zl3vni_from_vrf(vrf_id);
-       if (!zl3vni)
+       /* Ignore if the mac is already present as a gateway mac */
+       if (mac &&
+           CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) &&
+           CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
+                                  vni,
+                                  prefix_mac2str(macaddr, buf, sizeof(buf)),
+                                  ipa_len ? " IP " : "",
+                                  ipa_len ?
+                                  ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
+               return;
+       }
+
+       /* check if the remote MAC is unknown or has a change.
+        * If so, that needs to be updated first. Note that client could
+        * install MAC and MACIP separately or just install the latter.
+        */
+       if (!mac
+           || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
+           || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0) != sticky
+           || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0)
+               != remote_gw
+           || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)
+           || seq != mac->rem_seq)
+               update_mac = 1;
+
+       if (update_mac) {
+               if (!mac) {
+                       mac = zvni_mac_add(zvni, macaddr);
+                       if (!mac) {
+                               zlog_warn(
+                                       "Failed to add MAC %s VNI %u Remote VTEP %s",
+                                       prefix_mac2str(macaddr, buf,
+                                                      sizeof(buf)),
+                                       vni, inet_ntoa(vtep_ip));
+                               return;
+                       }
+
+                       /* Is this MAC created for a MACIP? */
+                       if (ipa_len)
+                               SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
+               } else {
+                       const char *mac_type;
+
+                       /* When host moves but changes its (MAC,IP)
+                        * binding, BGP may install a MACIP entry that
+                        * corresponds to "older" location of the host
+                        * in transient situations (because {IP1,M1}
+                        * is a different route from {IP1,M2}). Check
+                        * the sequence number and ignore this update
+                        * if appropriate.
+                        */
+                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
+                               tmp_seq = mac->loc_seq;
+                               mac_type = "local";
+                       } else {
+                               tmp_seq = mac->rem_seq;
+                               mac_type = "remote";
+                       }
+                       if (seq < tmp_seq) {
+                               if (IS_ZEBRA_DEBUG_VXLAN)
+                                       zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u",
+                                       vni,
+                                       prefix_mac2str(macaddr,
+                                                      buf, sizeof(buf)),
+                                       ipa_len ? " IP " : "",
+                                       ipa_len ?
+                                       ipaddr2str(ipaddr,
+                                                  buf1, sizeof(buf1)) : "",
+                                       mac_type,
+                                       tmp_seq);
+                               return;
+                       }
+               }
+
+               /* Set "auto" and "remote" forwarding info. */
+               UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
+               memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
+               SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
+               mac->fwd_info.r_vtep_ip = vtep_ip;
+
+               if (sticky)
+                       SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+               else
+                       UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+
+               if (remote_gw)
+                       SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
+               else
+                       UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
+
+               zvni_process_neigh_on_remote_mac_add(zvni, mac);
+
+               /* Install the entry. */
+               zvni_mac_install(zvni, mac);
+       }
+
+       /* Update seq number. */
+       mac->rem_seq = seq;
+
+       /* If there is no IP, return after clearing AUTO flag of MAC. */
+       if (!ipa_len) {
+               UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
+               return;
+       }
+
+       /* Check if the remote neighbor itself is unknown or has a
+        * change. If so, create or update and then install the entry.
+        */
+       n = zvni_neigh_lookup(zvni, ipaddr);
+       if (!n
+           || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
+           || (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0)
+           || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip)
+           || ((CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0)
+               != router_flag)
+           || seq != n->rem_seq)
+               update_neigh = 1;
+
+       if (update_neigh) {
+               if (!n) {
+                       n = zvni_neigh_add(zvni, ipaddr, macaddr);
+                       if (!n) {
+                               zlog_warn(
+                                       "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
+                                       ipaddr2str(ipaddr, buf1,
+                                                  sizeof(buf1)),
+                                       prefix_mac2str(macaddr, buf,
+                                                      sizeof(buf)),
+                                       vni, inet_ntoa(vtep_ip));
+                               return;
+                       }
+
+               } else {
+                       const char *n_type;
+
+                       /* When host moves but changes its (MAC,IP)
+                        * binding, BGP may install a MACIP entry that
+                        * corresponds to "older" location of the host
+                        * in transient situations (because {IP1,M1}
+                        * is a different route from {IP1,M2}). Check
+                        * the sequence number and ignore this update
+                        * if appropriate.
+                        */
+                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
+                               tmp_seq = n->loc_seq;
+                               n_type = "local";
+                       } else {
+                               tmp_seq = n->rem_seq;
+                               n_type = "remote";
+                       }
+                       if (seq < tmp_seq) {
+                               if (IS_ZEBRA_DEBUG_VXLAN)
+                                       zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
+                                       vni,
+                                       prefix_mac2str(macaddr,
+                                                      buf, sizeof(buf)),
+                                       ipa_len ? " IP " : "",
+                                       ipa_len ?
+                                       ipaddr2str(ipaddr,
+                                                  buf1, sizeof(buf1)) : "",
+                                       n_type,
+                                       tmp_seq);
+                               return;
+                       }
+                       if (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) {
+                               /* MAC change, send a delete for old
+                                * neigh if learnt locally.
+                                */
+                               if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) &&
+                                   IS_ZEBRA_NEIGH_ACTIVE(n))
+                                       zvni_neigh_send_del_to_client(
+                                               zvni->vni, &n->ip,
+                                               &n->emac, 0);
+
+                               /* update neigh list for macs */
+                               old_mac = zvni_mac_lookup(zvni, &n->emac);
+                               if (old_mac) {
+                                       listnode_delete(old_mac->neigh_list, n);
+                                       zvni_deref_ip2mac(zvni, old_mac, 1);
+                               }
+                               listnode_add_sort(mac->neigh_list, n);
+                               memcpy(&n->emac, macaddr, ETH_ALEN);
+                       }
+               }
+
+               /* Set "remote" forwarding info. */
+               UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
+               n->r_vtep_ip = vtep_ip;
+               SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
+
+               /* Set router flag (R-bit) to this Neighbor entry */
+               if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
+                       SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+               else
+                       UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+
+               /* Install the entry. */
+               zvni_neigh_install(zvni, n);
+       }
+
+       /* Update seq number. */
+       n->rem_seq = seq;
+}
+
+/* Process a remote MACIP delete from BGP. */
+static void process_remote_macip_del(vni_t vni,
+                                    struct ethaddr *macaddr,
+                                    uint16_t ipa_len,
+                                    struct ipaddr *ipaddr,
+                                    struct in_addr vtep_ip)
+{
+       zebra_vni_t *zvni;
+       zebra_mac_t *mac = NULL;
+       zebra_neigh_t *n = NULL;
+       struct interface *ifp = NULL;
+       struct zebra_if *zif = NULL;
+       char buf[ETHER_ADDR_STRLEN];
+       char buf1[INET6_ADDRSTRLEN];
+
+       /* Locate VNI hash entry - expected to exist. */
+       zvni = zvni_lookup(vni);
+       if (!zvni) {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni);
+               return;
+       }
+
+       ifp = zvni->vxlan_if;
+       if (ifp)
+               zif = ifp->info;
+       if (!ifp ||
+           !if_is_operative(ifp) ||
+           !zif ||
+           !zif->brslave_info.br_if) {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
+                                  vni);
+               return;
+       }
+
+       /* The remote VTEP specified is normally expected to exist, but
+        * it is possible that the peer may delete the VTEP before deleting
+        * any MACs referring to the VTEP, in which case the handler (see
+        * remote_vtep_del) would have already deleted the MACs.
+        */
+       if (!zvni_vtep_find(zvni, &vtep_ip))
+               return;
+
+       mac = zvni_mac_lookup(zvni, macaddr);
+       if (ipa_len)
+               n = zvni_neigh_lookup(zvni, ipaddr);
+
+       if (n && !mac) {
+               zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL",
+                         prefix_mac2str(macaddr, buf, sizeof(buf)),
+                         ipaddr2str(ipaddr, buf1, sizeof(buf1)), vni);
+               return;
+       }
+
+       /* If the remote mac or neighbor doesn't exist there is nothing
+        * more to do. Otherwise, uninstall the entry and then remove it.
+        */
+       if (!mac && !n)
+               return;
+
+       /* Ignore the delete if this mac is a gateway mac-ip */
+       if (mac
+           && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
+           && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
+               zlog_warn(
+                       "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC",
+                       vni,
+                       prefix_mac2str(macaddr, buf, sizeof(buf)),
+                       ipa_len ? " IP " : "",
+                       ipa_len ?
+                       ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
+               return;
+       }
+
+       /* Uninstall remote neighbor or MAC. */
+       if (n) {
+               /* When the MAC changes for an IP, it is possible the
+                * client may update the new MAC before trying to delete the
+                * "old" neighbor (as these are two different MACIP routes).
+                * Do the delete only if the MAC matches.
+                */
+               if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
+                   && (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0)) {
+                       zvni_neigh_uninstall(zvni, n);
+                       zvni_neigh_del(zvni, n);
+                       zvni_deref_ip2mac(zvni, mac, 1);
+               }
+       } else {
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
+                       zvni_process_neigh_on_remote_mac_del(zvni, mac);
+
+                       if (list_isempty(mac->neigh_list)) {
+                               zvni_mac_uninstall(zvni, mac, 0);
+                               zvni_mac_del(zvni, mac);
+                       } else
+                               SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
+               }
+       }
+}
+
+
+/* Public functions */
+
+int is_l3vni_for_prefix_routes_only(vni_t vni)
+{
+       zebra_l3vni_t *zl3vni = NULL;
+
+       zl3vni = zl3vni_lookup(vni);
+       if (!zl3vni)
+               return 0;
+
+       return CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? 1 : 0;
+}
+
+/* handle evpn route in vrf table */
+void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac,
+                                   struct ipaddr *vtep_ip,
+                                   struct prefix *host_prefix)
+{
+       zebra_l3vni_t *zl3vni = NULL;
+       struct ipaddr ipv4_vtep;
+
+       zl3vni = zl3vni_from_vrf(vrf_id);
+       if (!zl3vni || !is_l3vni_oper_up(zl3vni))
+               return;
+
+       /*
+        * add the next hop neighbor -
+        * neigh to be installed is the ipv6 nexthop neigh
+        */
+       zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
+
+       /*
+        * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
+        * address. Rmac is programmed against the ipv4 vtep because we only
+        * support ipv4 tunnels in the h/w right now
+        */
+       memset(&ipv4_vtep, 0, sizeof(struct ipaddr));
+       ipv4_vtep.ipa_type = IPADDR_V4;
+       if (vtep_ip->ipa_type == IPADDR_V6)
+               ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
+                                        &(ipv4_vtep.ipaddr_v4));
+       else
+               memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
+                      sizeof(struct in_addr));
+
+       /*
+        * add the rmac - remote rmac to be installed is against the ipv4
+        * nexthop address
+        */
+       zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix);
+}
+
+/* handle evpn vrf route delete */
+void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
+                                   struct ipaddr *vtep_ip,
+                                   struct prefix *host_prefix)
+{
+       zebra_l3vni_t *zl3vni = NULL;
+       zebra_neigh_t *nh = NULL;
+       zebra_mac_t *zrmac = NULL;
+
+       zl3vni = zl3vni_from_vrf(vrf_id);
+       if (!zl3vni)
                return;
 
        /* find the next hop entry and rmac entry */
@@ -4057,8 +4480,7 @@ void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
 }
 
 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
-                                          struct ethaddr *rmac,
-                                          uint8_t use_json)
+                                          struct ethaddr *rmac, bool use_json)
 {
        zebra_l3vni_t *zl3vni = NULL;
        zebra_mac_t *zrmac = NULL;
@@ -4102,8 +4524,7 @@ void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
        }
 }
 
-void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni,
-                                  uint8_t use_json)
+void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
 {
        zebra_l3vni_t *zl3vni;
        uint32_t num_rmacs;
@@ -4147,7 +4568,7 @@ void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni,
        }
 }
 
-void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, uint8_t use_json)
+void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json)
 {
        struct zebra_ns *zns = NULL;
        json_object *json = NULL;
@@ -4184,7 +4605,7 @@ void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, uint8_t use_json)
 }
 
 void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
-                                        struct ipaddr *ip, uint8_t use_json)
+                                        struct ipaddr *ip, bool use_json)
 {
        zebra_l3vni_t *zl3vni = NULL;
        zebra_neigh_t *n = NULL;
@@ -4228,7 +4649,7 @@ void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
        }
 }
 
-void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, uint8_t use_json)
+void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json)
 {
        uint32_t num_nh;
        struct nh_walk_ctx wctx;
@@ -4272,7 +4693,7 @@ void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, uint8_t use_json)
        }
 }
 
-void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, uint8_t use_json)
+void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json)
 {
        struct zebra_ns *zns = NULL;
        json_object *json = NULL;
@@ -4303,13 +4724,12 @@ void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, uint8_t use_json)
                                             json, JSON_C_TO_STRING_PRETTY));
                json_object_free(json);
        }
-       return;
 }
 
 /*
  * Display L3 VNI information (VTY command handler).
  */
-void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, uint8_t use_json)
+void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json)
 {
        void *args[2];
        json_object *json = NULL;
@@ -4362,6 +4782,7 @@ void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
                        zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
        } else {
                json_object *json_vrf = NULL;
+
                json_vrf = json_object_new_object();
                json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf));
                json_object_int_add(json_vrf, "vni", zl3vni->vni);
@@ -4382,7 +4803,7 @@ void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
  * Display Neighbors for a VNI (VTY command handler).
  */
 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                vni_t vni, uint8_t use_json)
+                                vni_t vni, bool use_json)
 {
        zebra_vni_t *zvni;
        uint32_t num_neigh;
@@ -4421,8 +4842,9 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
                vty_out(vty,
                        "Number of ARPs (local and remote) known for this VNI: %u\n",
                        num_neigh);
-               vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
-                       "Type", "MAC", "Remote VTEP");
+               vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
+                       -wctx.addr_width, "IP", "Type",
+                       "State", "MAC", "Remote VTEP");
        } else
                json_object_int_add(json, "numArpNd", num_neigh);
 
@@ -4438,7 +4860,7 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
  * Display neighbors across all VNIs (VTY command handler).
  */
 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                    uint8_t use_json)
+                                    bool use_json)
 {
        json_object *json = NULL;
        void *args[2];
@@ -4467,7 +4889,7 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
  */
 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
                                          struct zebra_vrf *zvrf, vni_t vni,
-                                         struct ipaddr *ip, uint8_t use_json)
+                                         struct ipaddr *ip, bool use_json)
 {
        zebra_vni_t *zvni;
        zebra_neigh_t *n;
@@ -4509,7 +4931,7 @@ void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
  */
 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
                                      vni_t vni, struct in_addr vtep_ip,
-                                     uint8_t use_json)
+                                     bool use_json)
 {
        zebra_vni_t *zvni;
        uint32_t num_neigh;
@@ -4551,7 +4973,7 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
  * Display MACs for a VNI (VTY command handler).
  */
 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                               vni_t vni, uint8_t use_json)
+                               vni_t vni, bool use_json)
 {
        zebra_vni_t *zvni;
        uint32_t num_macs;
@@ -4606,7 +5028,7 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
  * Display MACs for all VNIs (VTY command handler).
  */
 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                   uint8_t use_json)
+                                   bool use_json)
 {
        struct mac_walk_ctx wctx;
        json_object *json = NULL;
@@ -4636,8 +5058,7 @@ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
  */
 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
                                         struct zebra_vrf *zvrf,
-                                        struct in_addr vtep_ip,
-                                        uint8_t use_json)
+                                        struct in_addr vtep_ip, bool use_json)
 {
        struct mac_walk_ctx wctx;
        json_object *json = NULL;
@@ -4693,7 +5114,7 @@ void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
  */
 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
                                     vni_t vni, struct in_addr vtep_ip,
-                                    uint8_t use_json)
+                                    bool use_json)
 {
        zebra_vni_t *zvni;
        uint32_t num_macs;
@@ -4743,7 +5164,7 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
  * Display VNI information (VTY command handler).
  */
 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
-                          uint8_t use_json)
+                          bool use_json)
 {
        json_object *json = NULL;
        void *args[2];
@@ -4782,7 +5203,7 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
 }
 
 /* Display all global details for EVPN */
-void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj)
+void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
 {
        int num_l2vnis = 0;
        int num_l3vnis = 0;
@@ -4831,7 +5252,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj)
  * Display VNI hash table (VTY command handler).
  */
 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
-                           uint8_t use_json)
+                           bool use_json)
 {
        json_object *json = NULL;
        struct zebra_ns *zns = NULL;
@@ -5016,14 +5437,9 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
        struct ethaddr macaddr;
        struct ipaddr ip;
        struct in_addr vtep_ip;
-       zebra_vni_t *zvni;
-       zebra_mac_t *mac;
-       zebra_neigh_t *n;
-       unsigned short l = 0, ipa_len;
+       uint16_t l = 0, ipa_len;
        char buf[ETHER_ADDR_STRLEN];
        char buf1[INET6_ADDRSTRLEN];
-       struct interface *ifp = NULL;
-       struct zebra_if *zif = NULL;
 
        memset(&macaddr, 0, sizeof(struct ethaddr));
        memset(&ip, 0, sizeof(struct ipaddr));
@@ -5036,8 +5452,6 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
                /* Message contains VNI, followed by MAC followed by IP (if any)
                 * followed by remote VTEP IP.
                 */
-               mac = NULL;
-               n = NULL;
                memset(&ip, 0, sizeof(ip));
                STREAM_GETL(s, vni);
                STREAM_GET(&macaddr.octet, s, ETH_ALEN);
@@ -5053,103 +5467,17 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
 
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
-                               "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
+                               "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
+                               vni,
                                prefix_mac2str(&macaddr, buf, sizeof(buf)),
-                               ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
+                               ipa_len ? " IP " : "",
+                               ipa_len ?
+                               ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
                                inet_ntoa(vtep_ip),
                                zebra_route_string(client->proto));
 
-               /* Locate VNI hash entry - expected to exist. */
-               zvni = zvni_lookup(vni);
-               if (!zvni) {
-                       if (IS_ZEBRA_DEBUG_VXLAN)
-                               zlog_debug(
-                                       "Failed to locate VNI hash upon remote MACIP DEL, "
-                                       "VNI %u",
-                                       vni);
-                       continue;
-               }
-               ifp = zvni->vxlan_if;
-               if (!ifp) {
-                       zlog_warn(
-                               "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
-                               vni, zvni);
-                       continue;
-               }
-               zif = ifp->info;
-
-               /* If down or not mapped to a bridge, we're done. */
-               if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
-                       continue;
-
-               /* The remote VTEP specified is normally expected to exist, but
-                * it is
-                * possible that the peer may delete the VTEP before deleting
-                * any MACs
-                * referring to the VTEP, in which case the handler (see
-                * remote_vtep_del)
-                * would have already deleted the MACs.
-                */
-               if (!zvni_vtep_find(zvni, &vtep_ip))
-                       continue;
+               process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
 
-               mac = zvni_mac_lookup(zvni, &macaddr);
-               if (ipa_len)
-                       n = zvni_neigh_lookup(zvni, &ip);
-
-               if (n && !mac) {
-                       zlog_warn("Failed to locate MAC %s for neigh %s VNI %u",
-                                 prefix_mac2str(&macaddr, buf, sizeof(buf)),
-                                 ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
-                       continue;
-               }
-
-               /* If the remote mac or neighbor doesn't exist there is nothing
-                * more
-                * to do. Otherwise, uninstall the entry and then remove it.
-                */
-               if (!mac && !n)
-                       continue;
-
-               /* Ignore the delete if this mac is a gateway mac-ip */
-               if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
-                   && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
-                       zlog_warn(
-                               "%u: Ignore Del for  MAC %s neigh %s on VNI %u as it is configured as a default gateway",
-                               zvrf_id(zvrf),
-                               prefix_mac2str(&macaddr, buf, sizeof(buf)),
-                               ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
-                       continue;
-               }
-
-               /* Uninstall remote neighbor or MAC. */
-               if (n) {
-                       /* When the MAC changes for an IP, it is possible the
-                        * client may
-                        * update the new MAC before trying to delete the "old"
-                        * neighbor
-                        * (as these are two different MACIP routes). Do the
-                        * delete only
-                        * if the MAC matches.
-                        */
-                       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
-                           && (memcmp(n->emac.octet, macaddr.octet, ETH_ALEN)
-                               == 0)) {
-                               zvni_neigh_uninstall(zvni, n);
-                               zvni_neigh_del(zvni, n);
-                               zvni_deref_ip2mac(zvni, mac, 1);
-                       }
-               } else {
-                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
-                               zvni_process_neigh_on_remote_mac_del(zvni, mac);
-
-                               if (list_isempty(mac->neigh_list)) {
-                                       zvni_mac_uninstall(zvni, mac, 0);
-                                       zvni_mac_del(zvni, mac);
-                               } else
-                                       SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
-                       }
-               }
        }
 
 stream_failure:
@@ -5168,29 +5496,18 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
        struct ethaddr macaddr;
        struct ipaddr ip;
        struct in_addr vtep_ip;
-       zebra_vni_t *zvni;
-       zebra_vtep_t *zvtep;
-       zebra_mac_t *mac, *old_mac;
-       zebra_neigh_t *n;
-       unsigned short l = 0, ipa_len;
-       int update_mac = 0, update_neigh = 0;
+       uint16_t l = 0, ipa_len;
+       uint8_t flags = 0;
+       uint32_t seq;
        char buf[ETHER_ADDR_STRLEN];
        char buf1[INET6_ADDRSTRLEN];
-       uint8_t sticky = 0;
-       uint8_t remote_gw = 0;
-       uint8_t router_flag = 0;
-       uint8_t flags = 0;
-       struct interface *ifp = NULL;
-       struct zebra_if *zif = NULL;
 
        memset(&macaddr, 0, sizeof(struct ethaddr));
        memset(&ip, 0, sizeof(struct ipaddr));
        memset(&vtep_ip, 0, sizeof(struct in_addr));
 
        if (!EVPN_ENABLED(zvrf)) {
-               zlog_warn(
-                       "%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
-                       __PRETTY_FUNCTION__);
+               zlog_warn("EVPN not enabled, ignoring remote MACIP ADD");
                return;
        }
 
@@ -5201,9 +5518,6 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                /* Message contains VNI, followed by MAC followed by IP (if any)
                 * followed by remote VTEP IP.
                 */
-               update_mac = update_neigh = 0;
-               mac = NULL;
-               n = NULL;
                memset(&ip, 0, sizeof(ip));
                STREAM_GETL(s, vni);
                STREAM_GET(&macaddr.octet, s, ETH_ALEN);
@@ -5219,188 +5533,23 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
 
                /* Get flags - sticky mac and/or gateway mac */
                STREAM_GETC(s, flags);
-               sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
-               remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
-               router_flag = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
                l++;
+               STREAM_GETL(s, seq);
+               l += 4;
 
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
-                               "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s",
+                               "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",
+                               vni,
                                prefix_mac2str(&macaddr, buf, sizeof(buf)),
-                               ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
-                               inet_ntoa(vtep_ip), flags,
+                               ipa_len ? " IP " : "",
+                               ipa_len ?
+                               ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
+                               flags, seq, inet_ntoa(vtep_ip),
                                zebra_route_string(client->proto));
 
-               /* Locate VNI hash entry - expected to exist. */
-               zvni = zvni_lookup(vni);
-               if (!zvni) {
-                       zlog_warn(
-                               "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
-                               vni);
-                       continue;
-               }
-               ifp = zvni->vxlan_if;
-               if (!ifp) {
-                       zlog_warn(
-                               "VNI %u hash %p doesn't have intf upon remote MACIP add",
-                               vni, zvni);
-                       continue;
-               }
-               zif = ifp->info;
-
-               /* If down or not mapped to a bridge, we're done. */
-               if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
-                       continue;
-
-               /* The remote VTEP specified should normally exist, but it is
-                * possible
-                * that when peering comes up, peer may advertise MACIP routes
-                * before
-                * advertising type-3 routes.
-                */
-               zvtep = zvni_vtep_find(zvni, &vtep_ip);
-               if (!zvtep) {
-                       if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
-                               flog_err(
-                                       ZEBRA_ERR_VTEP_ADD_FAILED,
-                                       "Failed to add remote VTEP, VNI %u zvni %p",
-                                       vni, zvni);
-                               continue;
-                       }
-
-                       zvni_vtep_install(zvni, &vtep_ip);
-               }
-
-               mac = zvni_mac_lookup(zvni, &macaddr);
-
-               /* Ignore the update if the mac is already present
-                  as a gateway mac */
-               if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)
-                   && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
-                       if (IS_ZEBRA_DEBUG_VXLAN)
-                               zlog_debug(
-                                       "%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac",
-                                       zvrf_id(zvrf),
-                                       prefix_mac2str(&macaddr, buf,
-                                                      sizeof(buf)),
-                                       ipaddr2str(&ip, buf1, sizeof(buf1)),
-                                       vni);
-                       continue;
-               }
-
-               /* check if the remote MAC is unknown or has a change.
-                * If so, that needs to be updated first. Note that client could
-                * install MAC and MACIP separately or just install the latter.
-                */
-               if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
-                   || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
-                              != sticky
-                   || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0)
-                              != remote_gw
-                   || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
-                       update_mac = 1;
-
-               if (update_mac) {
-                       if (!mac) {
-                               mac = zvni_mac_add(zvni, &macaddr);
-                               if (!mac) {
-                                       zlog_warn(
-                                               "Failed to add MAC %s VNI %u Remote VTEP %s",
-                                               prefix_mac2str(&macaddr, buf,
-                                                              sizeof(buf)),
-                                               vni, inet_ntoa(vtep_ip));
-                                       return;
-                               }
-
-                               /* Is this MAC created for a MACIP? */
-                               if (ipa_len)
-                                       SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
-                       }
-
-                       /* Set "auto" and "remote" forwarding info. */
-                       UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
-                       memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
-                       SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
-                       mac->fwd_info.r_vtep_ip = vtep_ip;
-
-                       if (sticky)
-                               SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
-                       else
-                               UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
-
-                       if (remote_gw)
-                               SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
-                       else
-                               UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
-
-                       zvni_process_neigh_on_remote_mac_add(zvni, mac);
-
-                       /* Install the entry. */
-                       zvni_mac_install(zvni, mac);
-               }
-
-               /* If there is no IP, continue - after clearing AUTO flag of
-                * MAC. */
-               if (!ipa_len) {
-                       UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
-                       continue;
-               }
-
-               /* Check if the remote neighbor itself is unknown or has a
-                * change.
-                * If so, create or update and then install the entry.
-                */
-               n = zvni_neigh_lookup(zvni, &ip);
-               if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
-                   || ((CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0)
-                       != router_flag)
-                   || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
-                   || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
-                       update_neigh = 1;
-
-               if (update_neigh) {
-                       if (!n) {
-                               n = zvni_neigh_add(zvni, &ip, &macaddr);
-                               if (!n) {
-                                       zlog_warn(
-                                               "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
-                                               ipaddr2str(&ip, buf1,
-                                                          sizeof(buf1)),
-                                               prefix_mac2str(&macaddr, buf,
-                                                              sizeof(buf)),
-                                               vni, inet_ntoa(vtep_ip));
-                                       return;
-                               }
-
-                       } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
-                                  != 0) {
-                               /* MAC change, update neigh list for old and new
-                                * mac */
-                               old_mac = zvni_mac_lookup(zvni, &n->emac);
-                               if (old_mac) {
-                                       listnode_delete(old_mac->neigh_list, n);
-                                       zvni_deref_ip2mac(zvni, old_mac, 1);
-                               }
-                               listnode_add_sort(mac->neigh_list, n);
-                               memcpy(&n->emac, &macaddr, ETH_ALEN);
-                       }
-
-                       /* Set "remote" forwarding info. */
-                       UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
-                       /* TODO: Handle MAC change. */
-                       n->r_vtep_ip = vtep_ip;
-                       SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
-
-                       /* Set router flag (R-bit) to this Neighbor entry */
-                       if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
-                               SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
-                       else
-                               UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
-
-                       /* Install the entry. */
-                       zvni_neigh_install(zvni, n);
-               }
+               process_remote_macip_add(vni, &macaddr, ipa_len, &ip,
+                                        flags, seq, vtep_ip);
        }
 
 stream_failure:
@@ -5546,7 +5695,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
        }
 
        if (IS_ZEBRA_DEBUG_VXLAN)
-               zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
+               zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u",
                           prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
                           ifp->ifindex, vid, zvni->vni);
 
@@ -5559,12 +5708,12 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
        if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
                return 0;
 
-       /* Remove MAC from BGP. */
-       zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
-
        /* Update all the neigh entries associated with this mac */
        zvni_process_neigh_on_local_mac_del(zvni, mac);
 
+       /* Remove MAC from BGP. */
+       zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
+
        /*
         * If there are no neigh associated with the mac delete the mac
         * else mark it as AUTO for forward reference
@@ -5590,8 +5739,9 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
        zebra_vni_t *zvni;
        zebra_mac_t *mac;
        char buf[ETHER_ADDR_STRLEN];
-       int add = 1;
-       uint8_t mac_sticky;
+       bool mac_sticky = false;
+       bool inform_client = false;
+       bool upd_neigh = false;
 
        /* We are interested in MACs only on ports or (port, VLAN) that
         * map to a VNI.
@@ -5613,26 +5763,48 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
                return -1;
        }
 
-       if (IS_ZEBRA_DEBUG_VXLAN)
-               zlog_debug("Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
-                          sticky ? "sticky " : "",
-                          prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
-                          ifp->ifindex, vid, zvni->vni);
-
-       /* If same entry already exists, nothing to do. */
+       /* Check if we need to create or update or it is a NO-OP. */
        mac = zvni_mac_lookup(zvni, macaddr);
-       if (mac) {
-               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
-                       mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
-                                            ? 1
-                                            : 0;
+       if (!mac) {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug(
+                               "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u",
+                               sticky ? "sticky " : "",
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               ifp->name, ifp->ifindex, vid, zvni->vni);
 
+               mac = zvni_mac_add(zvni, macaddr);
+               if (!mac) {
+                       flog_err(
+                               ZEBRA_ERR_MAC_ADD_FAILED,
+                               "Failed to add MAC %s intf %s(%u) VID %u VNI %u",
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               ifp->name, ifp->ifindex, vid, zvni->vni);
+                       return -1;
+               }
+               SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
+               mac->fwd_info.local.ifindex = ifp->ifindex;
+               mac->fwd_info.local.vid = vid;
+               if (sticky)
+                       SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+               inform_client = true;
+
+       } else {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug(
+                               "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x",
+                               sticky ? "sticky " : "",
+                               prefix_mac2str(macaddr, buf, sizeof(buf)),
+                               ifp->name, ifp->ifindex, vid, zvni->vni,
+                               mac->flags);
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
+                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
+                               mac_sticky = true;
 
                        /*
-                        * return if nothing has changed.
-                        * inform bgp if sticky flag has changed
-                        * update locally and do not inform bgp if local
-                        * parameters like interface has changed
+                        * Update any changes and if changes are relevant to
+                        * BGP, note it.
                         */
                        if (mac_sticky == sticky
                            && mac->fwd_info.local.ifindex == ifp->ifindex
@@ -5647,61 +5819,74 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
                                                ifp->name, ifp->ifindex, vid,
                                                zvni->vni);
                                return 0;
-                       } else if (mac_sticky != sticky) {
-                               add = 1;
-                       } else {
-                               add = 0; /* This is an update of local
-                                           interface. */
                        }
-               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
+                       if (mac_sticky != sticky) {
+                               if (sticky)
+                                       SET_FLAG(mac->flags,
+                                                ZEBRA_MAC_STICKY);
+                               else
+                                       UNSET_FLAG(mac->flags,
+                                                  ZEBRA_MAC_STICKY);
+                               inform_client = true;
+                       }
+
+                       memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
+                       mac->fwd_info.local.ifindex = ifp->ifindex;
+                       mac->fwd_info.local.vid = vid;
+
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ||
+                          CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
+
                        /*
-                        * If we have already learned the MAC as a remote sticky
-                        * MAC,
-                        * this is a operator error and we must log a warning
+                        * MAC has either moved or was "internally" created due
+                        * to a neighbor learn and is now actually learnt. If
+                        * it was learnt as a remote sticky MAC, this is an
+                        * operator error.
                         */
                        if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
                                zlog_warn(
-                                       "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
+                                       "MAC %s already learnt as remote sticky behind VTEP %s VNI %u",
                                        prefix_mac2str(macaddr, buf,
                                                       sizeof(buf)),
                                        inet_ntoa(mac->fwd_info.r_vtep_ip),
                                        zvni->vni);
                                return 0;
                        }
-               }
-       }
 
-       if (!mac) {
-               mac = zvni_mac_add(zvni, macaddr);
-               if (!mac) {
-                       flog_err(ZEBRA_ERR_MAC_ADD_FAILED,
-                                 "Failed to add MAC %s intf %s(%u) VID %u",
-                                 prefix_mac2str(macaddr, buf, sizeof(buf)),
-                                 ifp->name, ifp->ifindex, vid);
-                       return -1;
+                       /* If an actual move, compute MAC's seq number */
+                       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
+                               mac->loc_seq = MAX(mac->rem_seq + 1,
+                                                  mac->loc_seq);
+                       UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
+                       UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
+                       SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
+                       memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
+                       mac->fwd_info.local.ifindex = ifp->ifindex;
+                       mac->fwd_info.local.vid = vid;
+                       if (sticky)
+                               SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+                       else
+                               UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
+                       /*
+                        * We have to inform BGP of this MAC as well as process
+                        * all neighbors.
+                        */
+                       inform_client = true;
+                       upd_neigh = true;
                }
        }
 
-       /* Set "local" forwarding info. */
-       UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
-       UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
-       SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
-       memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
-       mac->fwd_info.local.ifindex = ifp->ifindex;
-       mac->fwd_info.local.vid = vid;
-
-       if (sticky)
-               SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
-       else
-               UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
-
        /* Inform BGP if required. */
-       if (add) {
-               zvni_process_neigh_on_local_mac_add(zvni, mac);
-               return zvni_mac_send_add_to_client(zvni->vni, macaddr,
-                                                  mac->flags);
+       if (inform_client) {
+               if (zvni_mac_send_add_to_client(zvni->vni, macaddr,
+                                               mac->flags, mac->loc_seq))
+                       return -1;
        }
 
+       /* Process all neighbors associated with this MAC, if required. */
+       if (upd_neigh)
+               zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
+
        return 0;
 }
 
index 2732ef72edfd9e8408af0b0b532a81388102cb43..5097757b1dd82f93067474a5a75e9af825a95f6c 100644 (file)
@@ -68,53 +68,51 @@ extern int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf);
 extern int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf);
 extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf);
 extern void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni,
-                                               struct ipaddr *ip, uint8_t uj);
-extern void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj);
+                                               struct ipaddr *ip, bool uj);
+extern void zebra_vxlan_print_evpn(struct vty *vty, bool uj);
 extern void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
                                                  struct ethaddr *rmac,
-                                                 uint8_t use_json);
+                                                 bool use_json);
 extern void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                      vni_t vni, uint8_t use_json);
+                                      vni_t vni, bool use_json);
 extern void zebra_vxlan_print_macs_all_vni(struct vty *vty,
                                           struct zebra_vrf *zvrf,
-                                          uint8_t use_json);
+                                          bool use_json);
 extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
                                                struct zebra_vrf *zvrf,
                                                struct in_addr vtep_ip,
-                                               uint8_t use_json);
+                                               bool use_json);
 extern void zebra_vxlan_print_specific_mac_vni(struct vty *vty,
                                               struct zebra_vrf *zvrf,
                                               vni_t vni, struct ethaddr *mac);
 extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty,
                                            struct zebra_vrf *zvrf, vni_t vni,
                                            struct in_addr vtep_ip,
-                                           uint8_t use_json);
+                                           bool use_json);
 extern void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                       vni_t vni, uint8_t use_json);
+                                       vni_t vni, bool use_json);
 extern void zebra_vxlan_print_neigh_all_vni(struct vty *vty,
                                            struct zebra_vrf *zvrf,
-                                           uint8_t use_json);
+                                           bool use_json);
 extern void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
                                                 struct zebra_vrf *zvrf,
                                                 vni_t vni, struct ipaddr *ip,
-                                                uint8_t use_json);
+                                                bool use_json);
 extern void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty,
                                             struct zebra_vrf *zvrf, vni_t vni,
                                             struct in_addr vtep_ip,
-                                            uint8_t use_json);
+                                            bool use_json);
 extern void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                 vni_t vni, uint8_t use_json);
+                                 vni_t vni, bool use_json);
 extern void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
-                                  uint8_t use_json);
+                                  bool use_json);
 extern void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t vni,
-                                         uint8_t use_json);
-extern void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty,
-                                             uint8_t use_json);
+                                         bool use_json);
+extern void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json);
 extern void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t vni,
-                                      uint8_t use_json);
-extern void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, uint8_t use_json);
-extern void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni,
-                                   uint8_t use_json);
+                                      bool use_json);
+extern void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json);
+extern void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json);
 extern void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
                                      json_object *json_vrfs);
 extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
index afc59774c91dd4bad06097548f015654dd75b68d..00c849a3d01b40287c8e7e3fbb7b7f9c9c2fe39c 100644 (file)
@@ -83,7 +83,7 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf)
 {
 }
 
-void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj)
+void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
 {
 }
 
index e86967041b2e6daeb72466182093d7c2b0e74da7..44163eb331b6eae20de1a72405a971e49da41096 100644 (file)
@@ -260,6 +260,10 @@ struct zebra_mac_t_ {
                struct in_addr r_vtep_ip;
        } fwd_info;
 
+       /* Mobility sequence numbers associated with this entry. */
+       uint32_t rem_seq;
+       uint32_t loc_seq;
+
        /* List of neigh associated with this mac */
        struct list *neigh_list;
 
@@ -338,6 +342,16 @@ struct zebra_neigh_t_ {
        /* Remote VTEP IP - applicable only for remote neighbors. */
        struct in_addr r_vtep_ip;
 
+       /*
+        * Mobility sequence numbers associated with this entry. The rem_seq
+        * represents the sequence number from the client (BGP) for the most
+        * recent add or update of this entry while the loc_seq represents
+        * the sequence number informed (or to be informed) by zebra to BGP
+        * for this entry.
+        */
+       uint32_t rem_seq;
+       uint32_t loc_seq;
+
        /* list of hosts pointing to this remote NH entry */
        struct host_rb_tree_entry host_rb;
 };