-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
+++ /dev/null
-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>
+++ /dev/null
-ChangeLog information for FRRouting is for now recorded in source-code
-management system. Please see:
-
- http://www.frrouting.org/
## 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@
nodist_pkginclude_HEADERS =
dist_examples_DATA =
man_MANS =
+vtysh_scan =
## libtool, the self-made GNU scourge
## ... this should fix relinking
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
include staticd/subdir.am
include bfdd/subdir.am
-SUBDIRS = . @LIBRFP@ @RFPTEST@ \
- @BGPD@ \
- @VTYSH@ \
- tests
-
-DIST_SUBDIRS = . bgpd \
- vtysh tests \
- bgpd/rfp-example/librfp \
- bgpd/rfp-example/rfptest \
- # end
+include vtysh/subdir.am
+include tests/subdir.am
if PKGSRC
rcdir=@pkgsrcrcdir@
EXTRA_DIST += \
aclocal.m4 \
+ README.md \
m4/README.txt \
\
python/clidef.py \
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:
+++ /dev/null
-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:
+++ /dev/null
-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
--- /dev/null
+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
+```
/* clang-format off */
static struct log_ref ferr_babel_err[] = {
{
- .code = BABEL_ERR_MEMORY,
+ .code = EC_BABEL_MEMORY,
.title = "BABEL Memory Errors",
.description = "Babel has failed to allocate memory, the system is about to run out of memory",
.suggestion = "Find the process that is causing memory shortages, remediate that process and restart FRR"
},
{
- .code = BABEL_ERR_PACKET,
+ .code = EC_BABEL_PACKET,
.title = "BABEL Packet Error",
.description = "Babel has detected a packet encode/decode problem",
.suggestion = "Collect relevant log files and file an Issue"
},
{
- .code = BABEL_ERR_CONFIG,
+ .code = EC_BABEL_CONFIG,
.title = "BABEL Configuration Error",
.description = "Babel has detected a configuration error of some sort",
.suggestion = "Ensure that the configuration is correct"
},
{
- .code = BABEL_ERR_ROUTE,
+ .code = EC_BABEL_ROUTE,
.title = "BABEL Route Error",
.description = "Babel has detected a routing error and has an inconsistent state",
.suggestion = "Gather data for filing an Issue and then restart FRR"
#include "lib/ferr.h"
enum babel_log_refs {
- BABEL_ERR_MEMORY = BABEL_FERR_START,
- BABEL_ERR_PACKET,
- BABEL_ERR_CONFIG,
- BABEL_ERR_ROUTE,
+ EC_BABEL_MEMORY = BABEL_FERR_START,
+ EC_BABEL_PACKET,
+ EC_BABEL_CONFIG,
+ EC_BABEL_ROUTE,
};
extern void babel_error_init(void);
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "babel_filter.h"
#include "vty.h"
#include "filter.h"
if (babel_ifp->ipv4 == NULL) {
babel_ifp->ipv4 = malloc(4);
if (babel_ifp->ipv4 == NULL) {
- flog_err(BABEL_ERR_MEMORY, "not enough memory");
+ flog_err(EC_BABEL_MEMORY, "not enough memory");
} else {
memcpy(babel_ifp->ipv4, &prefix->u.prefix4, 4);
}
tmp = babel_ifp->sendbuf;
babel_ifp->sendbuf = realloc(babel_ifp->sendbuf, babel_ifp->bufsize);
if(babel_ifp->sendbuf == NULL) {
- flog_err(BABEL_ERR_MEMORY, "Couldn't reallocate sendbuf.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't reallocate sendbuf.");
free(tmp);
babel_ifp->bufsize = 0;
return -1;
rc = setsockopt(protocol_socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
(char*)&mreq, sizeof(mreq));
if(rc < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
ifp->name, safe_strerror(errno));
/* This is probably due to a missing link-local address,
rc = setsockopt(protocol_socket, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
(char*)&mreq, sizeof(mreq));
if(rc < 0)
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
ifp->name, safe_strerror(errno));
}
}
route_stream_done(routes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
xroutes = xroute_stream();
if(xroutes) {
}
xroute_stream_done(xroutes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
return CMD_SUCCESS;
}
}
route_stream_done(routes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
xroutes = xroute_stream();
if(xroutes) {
}
xroute_stream_done(xroutes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
return CMD_SUCCESS;
}
}
route_stream_done(routes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
xroutes = xroute_stream();
if(xroutes) {
}
xroute_stream_done(xroutes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
return CMD_SUCCESS;
}
}
route_stream_done(routes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
xroutes = xroute_stream();
if(xroutes) {
}
xroute_stream_done(xroutes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
return CMD_SUCCESS;
}
rc = read_random_bytes(&seed, sizeof(seed));
if(rc < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "read(random): %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "read(random): %s",
safe_strerror(errno));
seed = 42;
}
fd_null = open("/dev/null", O_RDONLY);
if(fd_null < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "open(null): %s", safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "open(null): %s", safe_strerror(errno));
exit(1);
}
rc = dup2(fd_null, fd);
if(rc < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "dup2(null, 0): %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "dup2(null, 0): %s",
safe_strerror(errno));
exit(1);
}
fd = open(state_file, O_RDONLY);
if(fd < 0 && errno != ENOENT)
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "open(babel-state: %s)",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "open(babel-state: %s)",
safe_strerror(errno));
rc = unlink(state_file);
if(fd >= 0 && rc < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "unlink(babel-state): %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "unlink(babel-state): %s",
safe_strerror(errno));
/* If we couldn't unlink it, it's probably stale. */
goto fini;
long t;
rc = read(fd, buf, 99);
if(rc < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "read(babel-state): %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "read(babel-state): %s",
safe_strerror(errno));
} else {
buf[rc] = '\0';
unsigned char sid[8];
rc = parse_eui64(buf2, sid);
if(rc < 0) {
- flog_err(BABEL_ERR_CONFIG, "Couldn't parse babel-state.");
+ flog_err(EC_BABEL_CONFIG, "Couldn't parse babel-state.");
} else {
struct timeval realnow;
debugf(BABEL_DEBUG_COMMON,
if(memcmp(sid, myid, 8) == 0)
myseqno = seqno_plus(s, 1);
else
- flog_err(BABEL_ERR_CONFIG,
+ flog_err(EC_BABEL_CONFIG,
"ID mismatch in babel-state. id=%s; old=%s",
format_eui64(myid),
format_eui64(sid));
}
} else {
- flog_err(BABEL_ERR_CONFIG, "Couldn't parse babel-state.");
+ flog_err(EC_BABEL_CONFIG, "Couldn't parse babel-state.");
}
}
goto fini;
debugf(BABEL_DEBUG_COMMON, "Save state file.");
fd = open(state_file, O_WRONLY | O_TRUNC | O_CREAT, 0644);
if(fd < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "creat(babel-state): %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "creat(babel-state): %s",
safe_strerror(errno));
unlink(state_file);
} else {
format_eui64(myid), (int)myseqno,
(long)realnow.tv_sec);
if(rc < 0 || rc >= 100) {
- flog_err(BABEL_ERR_CONFIG, "write(babel-state): overflow.");
+ flog_err(EC_BABEL_CONFIG, "write(babel-state): overflow.");
unlink(state_file);
} else {
rc = write(fd, buf, rc);
if(rc < 0) {
- flog_err(BABEL_ERR_CONFIG, "write(babel-state): %s",
+ flog_err(EC_BABEL_CONFIG, "write(babel-state): %s",
safe_strerror(errno));
unlink(state_file);
}
/* Make socket for Babel protocol. */
protocol_socket = babel_socket(protocol_port);
if (protocol_socket < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "Couldn't create link local socket: %s",
+ flog_err_sys(EC_LIB_SOCKET, "Couldn't create link local socket: %s",
safe_strerror(errno));
goto fail;
}
(struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0) {
if(errno != EAGAIN && errno != EINTR) {
- flog_err_sys(LIB_ERR_SOCKET, "recv: %s", safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "recv: %s", safe_strerror(errno));
}
} else {
FOR_ALL_INTERFACES(vrf, ifp) {
return;
}
- flog_err(BABEL_ERR_CONFIG,
+ flog_err(EC_BABEL_CONFIG,
"Warning: couldn't find router id -- using random value.");
rc = read_random_bytes(myid, 8);
if(rc < 0) {
- flog_err(BABEL_ERR_CONFIG, "read(random): %s (cannot assign an ID)",
+ flog_err(EC_BABEL_CONFIG, "read(random): %s (cannot assign an ID)",
safe_strerror(errno));
exit(1);
}
if(receive_buffer == NULL) {
receive_buffer = malloc(size);
if(receive_buffer == NULL) {
- flog_err(BABEL_ERR_MEMORY, "malloc(receive_buffer): %s",
+ flog_err(EC_BABEL_MEMORY, "malloc(receive_buffer): %s",
safe_strerror(errno));
return -1;
}
unsigned char *new;
new = realloc(receive_buffer, size);
if(new == NULL) {
- flog_err(BABEL_ERR_MEMORY, "realloc(receive_buffer): %s",
+ flog_err(EC_BABEL_MEMORY, "realloc(receive_buffer): %s",
safe_strerror(errno));
return -1;
}
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/time.h>
#include <sys/param.h>
#include <time.h>
}
if(i + 1 > alen) {
- flog_err(BABEL_ERR_PACKET, "Received truncated attributes.");
+ flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
return;
}
len = a[i + 1];
if(i + len > alen) {
- flog_err(BABEL_ERR_PACKET, "Received truncated attributes.");
+ flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
return;
}
/* Nothing. */
} else if(type == SUBTLV_DIVERSITY) {
if(len > DIVERSITY_HOPS) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received overlong channel information (%d > %d).n",
len, DIVERSITY_HOPS);
len = DIVERSITY_HOPS;
}
if(memchr(a + i + 2, 0, len) != NULL) {
/* 0 is reserved. */
- flog_err(BABEL_ERR_PACKET, "Channel information contains 0!");
+ flog_err(EC_BABEL_PACKET, "Channel information contains 0!");
return;
}
memset(channels, 0, DIVERSITY_HOPS);
}
if(i + 1 > alen) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received truncated sub-TLV on Hello message.");
return -1;
}
len = a[i + 1];
if(i + len > alen) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received truncated sub-TLV on Hello message.");
return -1;
}
DO_NTOHL(*hello_send_us, a + i + 2);
ret = 1;
} else {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received incorrect RTT sub-TLV on Hello message.");
}
} else {
}
if(i + 1 > alen) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received truncated sub-TLV on IHU message.");
return -1;
}
len = a[i + 1];
if(i + len > alen) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received truncated sub-TLV on IHU message.");
return -1;
}
ret = 1;
}
else {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received incorrect RTT sub-TLV on IHU message.");
}
} else {
}
if(!linklocal(from)) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received packet from non-local address %s.",
format_address(from));
return;
}
if (babel_packet_examin (packet, packetlen)) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received malformed packet on %s from %s.",
ifp->name, format_address(from));
return;
neigh = find_neighbour(from, ifp);
if(neigh == NULL) {
- flog_err(BABEL_ERR_PACKET, "Couldn't allocate neighbour.");
+ flog_err(EC_BABEL_PACKET, "Couldn't allocate neighbour.");
return;
}
DO_NTOHS(bodylen, packet + 2);
if(bodylen + 4 > packetlen) {
- flog_err(BABEL_ERR_PACKET, "Received truncated packet (%d + 4 > %d).",
+ flog_err(EC_BABEL_PACKET, "Received truncated packet (%d + 4 > %d).",
bodylen, packetlen);
bodylen = packetlen - 4;
}
have_router_id = 1;
}
if(!have_router_id && message[2] != 0) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received prefix with no router id.");
goto fail;
}
if(message[2] == 0) {
if(metric < 0xFFFF) {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Received wildcard update with finite metric.");
goto done;
}
continue;
fail:
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Couldn't parse packet (%d, %d) from %s on %s.",
message[0], message[1], format_address(from), ifp->name);
goto done;
DO_HTONL(babel_ifp->sendbuf + babel_ifp->buffered_hello + 10, time);
return 1;
} else {
- flog_err(BABEL_ERR_PACKET, "No space left for timestamp sub-TLV "
+ flog_err(EC_BABEL_PACKET, "No space left for timestamp sub-TLV "
"(this shouldn't happen)");
return -1;
}
babel_ifp->sendbuf, babel_ifp->buffered,
(struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0)
- flog_err(BABEL_ERR_PACKET, "send: %s", safe_strerror(errno));
+ flog_err(EC_BABEL_PACKET, "send: %s", safe_strerror(errno));
} else {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Warning: bucket full, dropping packet to %s.",
ifp->name);
}
if(!unicast_buffer)
unicast_buffer = malloc(UNICAST_BUFSIZE);
if(!unicast_buffer) {
- flog_err(BABEL_ERR_MEMORY, "malloc(unicast_buffer): %s",
+ flog_err(EC_BABEL_MEMORY, "malloc(unicast_buffer): %s",
safe_strerror(errno));
return -1;
}
unicast_buffer, unicast_buffered,
(struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0)
- flog_err(BABEL_ERR_PACKET, "send(unicast): %s",
+ flog_err(EC_BABEL_PACKET, "send(unicast): %s",
safe_strerror(errno));
} else {
- flog_err(BABEL_ERR_PACKET,
+ flog_err(EC_BABEL_PACKET,
"Warning: bucket full, dropping unicast packet to %s if %s.",
format_address(unicast_neighbour->address),
unicast_neighbour->ifp->name);
again:
babel_ifp->buffered_updates = malloc(n *sizeof(struct buffered_update));
if(babel_ifp->buffered_updates == NULL) {
- flog_err(BABEL_ERR_MEMORY, "malloc(buffered_updates): %s",
+ flog_err(EC_BABEL_MEMORY, "malloc(buffered_updates): %s",
safe_strerror(errno));
if(n > 4) {
/* Try again with a tiny buffer. */
}
route_stream_done(routes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate route stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
}
set_timeout(&babel_ifp->update_timeout, babel_ifp->update_interval);
babel_ifp->last_update_time = babel_now.tv_sec;
}
xroute_stream_done(xroutes);
} else {
- flog_err(BABEL_ERR_MEMORY, "Couldn't allocate xroute stream.");
+ flog_err(EC_BABEL_MEMORY, "Couldn't allocate xroute stream.");
}
}
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
neigh = malloc(sizeof(struct neighbour));
if(neigh == NULL) {
- flog_err(BABEL_ERR_MEMORY, "malloc(neighbour): %s",
+ flog_err(EC_BABEL_MEMORY, "malloc(neighbour): %s",
safe_strerror(errno));
return NULL;
}
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/time.h>
#include <time.h>
#include <string.h>
return;
if(!route_feasible(route))
- flog_err(BABEL_ERR_ROUTE, "WARNING: installing unfeasible route "
+ flog_err(EC_BABEL_ROUTE, "WARNING: installing unfeasible route "
"(this shouldn't happen).");
i = find_route_slot(route->src->prefix, route->src->plen, NULL);
assert(i >= 0 && i < route_slots);
if(routes[i] != route && routes[i]->installed) {
- flog_err(BABEL_ERR_ROUTE,
+ flog_err(EC_BABEL_ROUTE,
"WARNING: attempting to install duplicate route "
"(this shouldn't happen).");
return;
metric_to_kernel(route_metric(route)), NULL, 0, 0);
if(rc < 0) {
int save = errno;
- flog_err(BABEL_ERR_ROUTE, "kernel_route(ADD): %s",
+ flog_err(EC_BABEL_ROUTE, "kernel_route(ADD): %s",
safe_strerror(errno));
if(save != EEXIST)
return;
route->neigh->ifp->ifindex,
metric_to_kernel(route_metric(route)), NULL, 0, 0);
if(rc < 0)
- flog_err(BABEL_ERR_ROUTE, "kernel_route(FLUSH): %s",
+ flog_err(EC_BABEL_ROUTE, "kernel_route(FLUSH): %s",
safe_strerror(errno));
route->installed = 0;
return;
if(!route_feasible(new))
- flog_err(BABEL_ERR_ROUTE, "WARNING: switching to unfeasible route "
+ flog_err(EC_BABEL_ROUTE, "WARNING: switching to unfeasible route "
"(this shouldn't happen).");
rc = kernel_route(ROUTE_MODIFY, old->src->prefix, old->src->plen,
new->nexthop, new->neigh->ifp->ifindex,
metric_to_kernel(route_metric(new)));
if(rc < 0) {
- flog_err(BABEL_ERR_ROUTE, "kernel_route(MODIFY): %s",
+ flog_err(EC_BABEL_ROUTE, "kernel_route(MODIFY): %s",
safe_strerror(errno));
return;
}
route->nexthop, route->neigh->ifp->ifindex,
new);
if(rc < 0) {
- flog_err(BABEL_ERR_ROUTE, "kernel_route(MODIFY metric): %s",
+ flog_err(EC_BABEL_ROUTE, "kernel_route(MODIFY metric): %s",
safe_strerror(errno));
return;
}
return NULL;
if(martian_prefix(prefix, plen)) {
- flog_err(BABEL_ERR_ROUTE, "Rejecting martian route to %s through %s.",
+ flog_err(EC_BABEL_ROUTE, "Rejecting martian route to %s through %s.",
format_prefix(prefix, plen), format_address(nexthop));
return NULL;
}
route->next = NULL;
new_route = insert_route(route);
if(new_route == NULL) {
- flog_err(BABEL_ERR_ROUTE, "Couldn't insert route.");
+ flog_err(EC_BABEL_ROUTE, "Couldn't insert route.");
free(route);
return NULL;
}
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
src = malloc(sizeof(struct source));
if(src == NULL) {
- flog_err(BABEL_ERR_MEMORY, "malloc(source): %s", safe_strerror(errno));
+ flog_err(EC_BABEL_MEMORY, "malloc(source): %s", safe_strerror(errno));
return NULL;
}
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 = \
THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
# ignore binary files
-*.a
bfdd
struct iovec iov[1];
uint8_t cmsgbuf[255];
+ port[0] = '\0';
+
/* Prepare the recvmsg params. */
iov[0].iov_base = msgbuf;
iov[0].iov_len = msgbuflen;
{
uint32_t pid;
uint8_t ttl __attribute__((unused));
- uint8_t ifnamelen;
+ size_t ifnamelen;
/*
* Register/Deregister/Update Message format:
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 = \
-Makefile
-Makefile.in
-*.o
bgpd
bgp_btoa
bgpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
--- /dev/null
+all: ALWAYS
+ @$(MAKE) -s -C .. bgpd/bgpd
+%: ALWAYS
+ @$(MAKE) -s -C .. bgpd/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
+++ /dev/null
-## 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
-
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_errors.h"
/* Attr. Flags and Attr. Type Code. */
-#define AS_HEADER_SIZE 2
+#define AS_HEADER_SIZE 2
/* Now FOUR octets are used for AS value. */
#define AS_VALUE_SIZE sizeof (as_t)
if (hops < 0) {
if (BGP_DEBUG(as4, AS4))
- zlog_warn(
+ flog_warn(
+ EC_BGP_ASPATH_FEWER_HOPS,
"[AS4] Fewer hops in AS_PATH than NEW_AS_PATH");
/* Something's gone wrong. The RFC says we should now ignore
* AS4_PATH,
*
* This algorithm could be made faster if needed
*/
-static int encap_same(struct bgp_attr_encap_subtlv *h1,
- struct bgp_attr_encap_subtlv *h2)
+static int encap_same(const struct bgp_attr_encap_subtlv *h1,
+ const struct bgp_attr_encap_subtlv *h2)
{
- struct bgp_attr_encap_subtlv *p;
- struct bgp_attr_encap_subtlv *q;
+ const struct bgp_attr_encap_subtlv *p;
+ const struct bgp_attr_encap_subtlv *q;
if (h1 == h2)
return 1;
static int encap_hash_cmp(const void *p1, const void *p2)
{
- return encap_same((struct bgp_attr_encap_subtlv *)p1,
- (struct bgp_attr_encap_subtlv *)p2);
+ return encap_same((const struct bgp_attr_encap_subtlv *)p1,
+ (const struct bgp_attr_encap_subtlv *)p2);
}
static void encap_init(void)
for (i = 0; i <= 2; i++) /* O,T,P, but not E */
if (CHECK_FLAG(desired_flags, attr_flag_str[i].key)
!= CHECK_FLAG(real_flags, attr_flag_str[i].key)) {
- flog_err(
- BGP_ERR_ATTR_FLAG,
- "%s attribute must%s be flagged as \"%s\"",
- lookup_msg(attr_str, attr_code, NULL),
- CHECK_FLAG(desired_flags, attr_flag_str[i].key)
- ? ""
- : " not",
- attr_flag_str[i].str);
+ flog_err(EC_BGP_ATTR_FLAG,
+ "%s attribute must%s be flagged as \"%s\"",
+ lookup_msg(attr_str, attr_code, NULL),
+ CHECK_FLAG(desired_flags, attr_flag_str[i].key)
+ ? ""
+ : " not",
+ attr_flag_str[i].str);
seen = 1;
}
if (!seen) {
if (!CHECK_FLAG(BGP_ATTR_FLAG_OPTIONAL, flags)
&& !CHECK_FLAG(BGP_ATTR_FLAG_TRANS, flags)) {
flog_err(
- BGP_ERR_ATTR_FLAG,
+ EC_BGP_ATTR_FLAG,
"%s well-known attributes must have transitive flag set (%x)",
lookup_msg(attr_str, attr_code, NULL), flags);
return 1;
*/
if (CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL)) {
if (!CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)) {
- flog_err(BGP_ERR_ATTR_FLAG,
- "%s well-known attribute "
- "must NOT have the partial flag set (%x)",
- lookup_msg(attr_str, attr_code, NULL), flags);
+ flog_err(EC_BGP_ATTR_FLAG,
+ "%s well-known attribute "
+ "must NOT have the partial flag set (%x)",
+ lookup_msg(attr_str, attr_code, NULL), flags);
return 1;
}
if (CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
&& !CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS)) {
- flog_err(BGP_ERR_ATTR_FLAG,
- "%s optional + transitive attribute "
- "must NOT have the partial flag set (%x)",
- lookup_msg(attr_str, attr_code, NULL), flags);
+ flog_err(EC_BGP_ATTR_FLAG,
+ "%s optional + transitive attribute "
+ "must NOT have the partial flag set (%x)",
+ lookup_msg(attr_str, attr_code, NULL), flags);
return 1;
}
}
field contains the erroneous attribute (type, length and
value). */
if (length != 1) {
- flog_err(BGP_ERR_ATTR_LEN,
- "Origin attribute length is not one %d", length);
+ flog_err(EC_BGP_ATTR_LEN,
+ "Origin attribute length is not one %d", length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}
contains the unrecognized attribute (type, length and value). */
if ((attr->origin != BGP_ORIGIN_IGP) && (attr->origin != BGP_ORIGIN_EGP)
&& (attr->origin != BGP_ORIGIN_INCOMPLETE)) {
- flog_err(BGP_ERR_ATTR_ORIGIN,
- "Origin attribute value is invalid %d", attr->origin);
+ flog_err(EC_BGP_ATTR_ORIGIN,
+ "Origin attribute value is invalid %d", attr->origin);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_INVAL_ORIGIN,
args->total);
}
/* In case of IBGP, length will be zero. */
if (!attr->aspath) {
- flog_err(BGP_ERR_ATTR_MAL_AS_PATH,
- "Malformed AS path from %s, length is %d", peer->host,
- length);
+ flog_err(EC_BGP_ATTR_MAL_AS_PATH,
+ "Malformed AS path from %s, length is %d", peer->host,
+ length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
0);
}
&& !aspath_left_confed_check(attr->aspath))
|| (peer->sort == BGP_PEER_EBGP
&& aspath_confed_check(attr->aspath))) {
- flog_err(BGP_ERR_ATTR_MAL_AS_PATH, "Malformed AS path from %s",
- peer->host);
+ flog_err(EC_BGP_ATTR_MAL_AS_PATH, "Malformed AS path from %s",
+ peer->host);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_AS_PATH);
return BGP_ATTR_PARSE_ERROR;
if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) {
if (peer->sort == BGP_PEER_EBGP
&& !aspath_firstas_check(attr->aspath, peer->as)) {
- flog_err(BGP_ERR_ATTR_FIRST_AS,
- "%s incorrect first AS (must be %u)",
- peer->host, peer->as);
+ flog_err(EC_BGP_ATTR_FIRST_AS,
+ "%s incorrect first AS (must be %u)",
+ peer->host, peer->as);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_AS_PATH);
return BGP_ATTR_PARSE_ERROR;
/* In case of IBGP, length will be zero. */
if (!*as4_path) {
- flog_err(BGP_ERR_ATTR_MAL_AS_PATH,
- "Malformed AS4 path from %s, length is %d",
- peer->host, length);
+ flog_err(EC_BGP_ATTR_MAL_AS_PATH,
+ "Malformed AS4 path from %s, length is %d", peer->host,
+ length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
0);
}
/* Check nexthop attribute length. */
if (length != 4) {
- flog_err(BGP_ERR_ATTR_LEN,
- "Nexthop attribute length isn't four [%d]", length);
+ flog_err(EC_BGP_ATTR_LEN,
+ "Nexthop attribute length isn't four [%d]", length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
{
char buf[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN);
- flog_err(BGP_ERR_ATTR_MARTIAN_NH, "Martian nexthop %s", buf);
+ flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %s", buf);
return bgp_attr_malformed(
args, BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, args->total);
}
/* Length check. */
if (length != 4) {
- flog_err(BGP_ERR_ATTR_LEN,
- "MED attribute length isn't four [%d]", length);
+ flog_err(EC_BGP_ATTR_LEN,
+ "MED attribute length isn't four [%d]", length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
/* Length check. */
if (length != 4) {
- flog_err(BGP_ERR_ATTR_LEN,
- "LOCAL_PREF attribute length isn't 4 [%u]", length);
+ flog_err(EC_BGP_ATTR_LEN,
+ "LOCAL_PREF attribute length isn't 4 [%u]", length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}
/* Length check. */
if (length != 0) {
- flog_err(BGP_ERR_ATTR_LEN,
- "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
- length);
+ flog_err(EC_BGP_ATTR_LEN,
+ "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
+ length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}
wantedlen = 8;
if (length != wantedlen) {
- flog_err(BGP_ERR_ATTR_LEN,
- "AGGREGATOR attribute length isn't %u [%u]",
- wantedlen, length);
+ flog_err(EC_BGP_ATTR_LEN,
+ "AGGREGATOR attribute length isn't %u [%u]", wantedlen,
+ length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}
const bgp_size_t length = args->length;
if (length != 8) {
- flog_err(BGP_ERR_ATTR_LEN,
- "New Aggregator length is not 8 [%d]", length);
+ flog_err(EC_BGP_ATTR_LEN, "New Aggregator length is not 8 [%d]",
+ length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
0);
}
/* Length check. */
if (length != 4) {
- flog_err(BGP_ERR_ATTR_LEN, "Bad originator ID length %d",
- length);
+ flog_err(EC_BGP_ATTR_LEN, "Bad originator ID length %d",
+ length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
/* Check length. */
if (length % 4) {
- flog_err(BGP_ERR_ATTR_LEN, "Bad cluster list length %d",
- length);
+ flog_err(EC_BGP_ATTR_LEN, "Bad cluster list length %d", length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
stream_getl(s); /* RD low */
}
stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
- if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
+ if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
+ if (!peer->nexthop.ifp) {
+ zlog_warn("%s: interface not set appropriately to handle some attributes",
+ peer->host);
+ return BGP_ATTR_PARSE_WITHDRAW;
+ }
attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+ }
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
stream_getl(s); /* RD low */
}
stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
- if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
+ if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
+ if (!peer->nexthop.ifp) {
+ zlog_warn("%s: interface not set appropriately to handle some attributes",
+ peer->host);
+ return BGP_ATTR_PARSE_WITHDRAW;
+ }
attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+ }
if (attr->mp_nexthop_len
== BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
stream_getl(s); /* RD high */
attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
}
+ if (!peer->nexthop.ifp) {
+ zlog_warn("%s: Interface not set appropriately to handle this some attributes",
+ peer->host);
+ return BGP_ATTR_PARSE_WITHDRAW;
+ }
attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex;
break;
default:
{
uint8_t val;
if ((val = stream_getc(s)))
- zlog_warn(
+ flog_warn(
+ EC_BGP_DEFUNCT_SNPA_LEN,
"%s sent non-zero value, %u, for defunct SNPA-length field",
peer->host, val);
}
if (type == BGP_PREFIX_SID_LABEL_INDEX) {
if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
flog_err(
- BGP_ERR_ATTR_LEN,
+ EC_BGP_ATTR_LEN,
"Prefix SID label index length is %d instead of %d",
length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
return bgp_attr_malformed(args,
/* Placeholder code for the IPv6 SID type */
else if (type == BGP_PREFIX_SID_IPV6) {
if (length != BGP_PREFIX_SID_IPV6_LENGTH) {
- flog_err(BGP_ERR_ATTR_LEN,
- "Prefix SID IPv6 length is %d instead of %d",
- length, BGP_PREFIX_SID_IPV6_LENGTH);
+ flog_err(EC_BGP_ATTR_LEN,
+ "Prefix SID IPv6 length is %d instead of %d",
+ length, BGP_PREFIX_SID_IPV6_LENGTH);
return bgp_attr_malformed(args,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH) {
flog_err(
- BGP_ERR_ATTR_LEN,
+ EC_BGP_ATTR_LEN,
"Prefix SID Originator SRGB length is %d, it must be a multiple of %d ",
length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
return bgp_attr_malformed(
if (tlength < 0) {
flog_err(
- BGP_ERR_ATTR_LEN,
+ EC_BGP_ATTR_LEN,
"Prefix SID internal length %d causes us to read beyond the total Prefix SID length",
length);
return bgp_attr_malformed(args,
* can only support that.
*/
if (length < 2) {
- flog_err(BGP_ERR_ATTR_LEN,
- "Bad PMSI tunnel attribute length %d", length);
+ flog_err(EC_BGP_ATTR_LEN, "Bad PMSI tunnel attribute length %d",
+ length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}
stream_getc(peer->curr); /* Flags */
tnl_type = stream_getc(peer->curr);
if (tnl_type > PMSI_TNLTYPE_MAX) {
- flog_err(BGP_ERR_ATTR_PMSI_TYPE,
- "Invalid PMSI tunnel attribute type %d", tnl_type);
+ flog_err(EC_BGP_ATTR_PMSI_TYPE,
+ "Invalid PMSI tunnel attribute type %d", tnl_type);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
}
if (tnl_type == PMSI_TNLTYPE_INGR_REPL) {
if (length != 9) {
- flog_err(BGP_ERR_ATTR_PMSI_LEN,
- "Bad PMSI tunnel attribute length %d for IR",
- length);
+ flog_err(EC_BGP_ATTR_PMSI_LEN,
+ "Bad PMSI tunnel attribute length %d for IR",
+ length);
return bgp_attr_malformed(
args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
type = BGP_ATTR_LOCAL_PREF;
if (type) {
- zlog_warn("%s Missing well-known attribute %s.", peer->host,
+ flog_warn(EC_BGP_MISSING_ATTRIBUTE,
+ "%s Missing well-known attribute %s.", peer->host,
lookup_msg(attr_str, type, NULL));
bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MISS_ATTR, &type,
bgp_size_t size, struct bgp_nlri *mp_update,
struct bgp_nlri *mp_withdraw)
{
- int ret;
+ bgp_attr_parse_ret_t ret;
uint8_t flag = 0;
uint8_t type = 0;
bgp_size_t length;
/* Check remaining length check.*/
if (endp - BGP_INPUT_PNT(peer) < BGP_ATTR_MIN_LEN) {
/* XXX warning: long int format, int arg (arg 5) */
- zlog_warn(
+ flog_warn(
+ EC_BGP_ATTRIBUTE_TOO_SMALL,
"%s: error BGP attribute length %lu is smaller than min len",
peer->host,
(unsigned long)(endp
/* Check whether Extended-Length applies and is in bounds */
if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN)
&& ((endp - startp) < (BGP_ATTR_MIN_LEN + 1))) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
"%s: Extended length set, but just %lu bytes of attr header",
peer->host,
(unsigned long)(endp
List. */
if (CHECK_BITMAP(seen, type)) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_ATTRIBUTE_REPEATED,
"%s: error BGP attribute type %d appears twice in a message",
peer->host, type);
attr_endp = BGP_INPUT_PNT(peer) + length;
if (attr_endp > endp) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_ATTRIBUTE_TOO_LARGE,
"%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p",
peer->host, type, length, size, attr_endp,
endp);
Attribute Flags Error. The Data field contains the erroneous
attribute (type, length and value). */
if (bgp_attr_flag_invalid(&attr_args)) {
- bgp_attr_parse_ret_t ret;
ret = bgp_attr_malformed(
&attr_args, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
attr_args.total);
/* If hard error occured immediately return to the caller. */
if (ret == BGP_ATTR_PARSE_ERROR) {
- zlog_warn("%s: Attribute %s, parse error", peer->host,
+ flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
+ "%s: Attribute %s, parse error", peer->host,
lookup_msg(attr_str, type, NULL));
if (as4_path)
aspath_unintern(&as4_path);
}
if (ret == BGP_ATTR_PARSE_WITHDRAW) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_ATTRIBUTE_PARSE_WITHDRAW,
"%s: Attribute %s, parse error - treating as withdrawal",
peer->host, lookup_msg(attr_str, type, NULL));
if (as4_path)
/* Check the fetched length. */
if (BGP_INPUT_PNT(peer) != attr_endp) {
- zlog_warn("%s: BGP attribute %s, fetch error",
+ flog_warn(EC_BGP_ATTRIBUTE_FETCH_ERROR,
+ "%s: BGP attribute %s, fetch error",
peer->host, lookup_msg(attr_str, type, NULL));
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
/* Check final read pointer is same as end pointer. */
if (BGP_INPUT_PNT(peer) != endp) {
- zlog_warn("%s: BGP attribute %s, length mismatch", peer->host,
+ flog_warn(EC_BGP_ATTRIBUTES_MISMATCH,
+ "%s: BGP attribute %s, length mismatch", peer->host,
lookup_msg(attr_str, type, NULL));
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
}
/* Check all mandatory well-known attributes are present */
- {
- bgp_attr_parse_ret_t ret;
- if ((ret = bgp_attr_check(peer, attr)) < 0) {
- if (as4_path)
- aspath_unintern(&as4_path);
- return ret;
- }
+ if ((ret = bgp_attr_check(peer, attr)) < 0) {
+ if (as4_path)
+ aspath_unintern(&as4_path);
+ return ret;
}
/*
default:
if (safi != SAFI_FLOWSPEC)
flog_err(
- BGP_ERR_ATTR_NH_SEND_LEN,
+ EC_BGP_ATTR_NH_SEND_LEN,
"Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d",
peer->host, afi, safi, attr->mp_nexthop_len);
break;
{
time_t t_now;
struct bgp_damp_info *bdi = NULL;
- double last_penalty = 0;
+ unsigned int last_penalty = 0;
t_now = bgp_clock();
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_dump.h"
+#include "bgpd/bgp_errors.h"
enum bgp_dump_type {
BGP_DUMP_ALL,
ret = strftime(realpath, MAXPATHLEN, bgp_dump->filename, tm);
if (ret == 0) {
- zlog_warn("bgp_dump_open_file: strftime error");
+ flog_warn(EC_BGP_DUMP, "bgp_dump_open_file: strftime error");
return NULL;
}
bgp_dump->fp = fopen(realpath, "w");
if (bgp_dump->fp == NULL) {
- zlog_warn("bgp_dump_open_file: %s: %s", realpath,
+ flog_warn(EC_BGP_DUMP, "bgp_dump_open_file: %s: %s", realpath,
strerror(errno));
umask(oldumask);
return NULL;
#include "bgp_errors.h"
/* clang-format off */
+static struct log_ref ferr_bgp_warn[] = {
+ {
+ .code = EC_BGP_ASPATH_FEWER_HOPS,
+ .title = "BGP AS-path conversion has failed",
+ .description = "BGP has attempted to convert a AS2 to AS4 path and has failed",
+ .suggestion = "Open an Issue with all relevant log files and restart FRR"
+ },
+ {
+ .code = EC_BGP_DEFUNCT_SNPA_LEN,
+ .title = "BGP has received a value in a reserved field",
+ .description = "BGP has received a non-zero value in a reserved field that was used for SNPA-length at one point in time",
+ .suggestion = "BGP has peered with either a router that is attempting to send SNPA data or it has received a corrupted packet. If we are peering with a SNPA aware router(unlikely) upgrade that router, else open an Issue after gathering relevant log files",
+ },
+ {
+ .code = EC_BGP_MISSING_ATTRIBUTE,
+ .title = "BGP has received an update with missing a missing attribute",
+ .description = "BGP received update packets must have some minimum attribute information within them",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_ATTRIBUTE_TOO_SMALL,
+ .title = "BGP udate packet with attribute data that is too small",
+ .description = "BGP has received an update packet that is too small to parse a given attribute. This typically means that something has gone wrong between us and the remote peer",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
+ .title = "BGP udate packet with extended attribute data that is too small",
+ .description = "BGP has received an update packet that is too small to parse a given extended attribute. This typically means that something has gone wrong between us and the remote peer",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_ATTRIBUTE_REPEATED,
+ .title = "BGP update packet received with a repeated attribute",
+ .description = "BGP has received an update packet with a attribute that is repeated more than one time for a particular route. This typically means that something has gone wrong between us and the remote peer",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_ATTRIBUTE_TOO_LARGE,
+ .title = "BGP udate packet with attribute data that is too large",
+ .description = "BGP has received an update packet that has too much data in a particular attribute. This typically means that something has gone wrong between us and the remote peer",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_ATTRIBUTE_PARSE_ERROR,
+ .title = "BGP update packet with attribute data has a parse error, specific to the attribute",
+ .description = "BGP has received an update packet with an attribute that when parsed does not make sense in some manner",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_ATTRIBUTE_PARSE_WITHDRAW,
+ .title = "BGP update packet with a broken optional attribute has caused a withdraw of associated routes",
+ .description = "BGP has received a update packet with optional attributes that did not parse correctly, instead of resetting the peer, withdraw associated routes and note that this has happened",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_ATTRIBUTE_FETCH_ERROR,
+ .title = "BGP update packet with a broken length",
+ .description = "BGP has received a update packet with an attribute that has an incorrect length",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_ATTRIBUTES_MISMATCH,
+ .title = "BGP update packet with a length different than attribute data length",
+ .description = "BGP has received a update packet with attributes that when parsed do not correctly add up to packet data length",
+ .suggestion = "Gather log data from this and remote peer and open an Issue with this data",
+ },
+ {
+ .code = EC_BGP_DUMP,
+ .title = "BGP MRT dump subsystem has encountered an issue",
+ .description = "BGP has found that the attempted write of MRT data to a dump file has failed",
+ .suggestion = "Ensure BGP has permissions to write the specified file",
+ },
+ {
+ .code = EC_BGP_UPDATE_PACKET_SHORT,
+ .title = "BGP Update Packet is to Small",
+ .description = "The update packet received from a peer is to small",
+ .suggestion = "Determine the source of the update packet and examine that peer for what has gone wrong",
+ },
+ {
+ .code = EC_BGP_UPDATE_PACKET_LONG,
+ .title = "BGP Update Packet is to large",
+ .description = "The update packet received from a peer is to large",
+ .suggestion = "Determine the source of the update packet and examine that peer for what has gone wrong",
+ },
+ {
+ .code = EC_BGP_UNRECOGNIZED_CAPABILITY,
+ .title = "Unknown BGP Capability Received",
+ .description = "The negotiation of capabilities has received a capability that we do not know what to do with",
+ .suggestion = "Determine the source of the capability and remove the capability from what is sent",
+ },
+ {
+ .code = EC_BGP_NO_TCP_MD5,
+ .title = "Unable to set TCP MD5 option on socket",
+ .description = "BGP attempted to setup TCP MD5 configuration on the socket as per configuration but was unable to",
+ .suggestion = "Please collect log files and open Issue",
+ },
+ {
+ .code = EC_BGP_NO_SOCKOPT_MARK,
+ .title = "Unable to set socket MARK option",
+ .description = "BGP attempted to set the SO_MARK option for a socket and was unable to do so",
+ .suggestion = "Please collect log files and open Issue",
+ },
+ {
+ .code = EC_BGP_EVPN_PMSI_PRESENT,
+ .title = "BGP Received a EVPN NLRI with PMSI included",
+ .description = "BGP has received a type-3 NLRI with PMSI information. At this time FRR is not capable of properly handling this NLRI type",
+ .suggestion = "Setup peer to not send this type of data to FRR"
+ },
+ {
+ .code = EC_BGP_EVPN_VPN_VNI,
+ .title = "BGP has received a local macip and cannot properly handle it",
+ .description = "BGP has received a local macip from zebra and has no way to properly handle the macip because the vni is not setup properly",
+ .suggestion = "Ensure proper setup of BGP EVPN",
+ },
+ {
+ .code = EC_BGP_EVPN_ESI,
+ .title = "BGP has received a local ESI for deletion",
+ .description = "BGP has received a local ESI for deletion but when attempting to find the stored data internally was unable to find the information for deletion",
+ .suggestion = "Gather logging and open an Issue",
+ },
+ {
+ .code = EC_BGP_INVALID_LABEL_STACK,
+ .title = "BGP has received a label stack in a NLRI that does not have the BOS marked",
+ .description = "BGP when it receives a NLRI with a label stack should have the BOS marked, this received packet does not have this",
+ .suggestion = "Gather log information from here and remote peer and open an Issue",
+ },
+ {
+ .code = EC_BGP_ZEBRA_SEND,
+ .title = "BGP has attempted to send data to zebra and has failed to do so",
+ .description = "BGP has attempted to send data to zebra but has been unable to do so",
+ .suggestion = "Gather log data, open an Issue and restart FRR"
+ },
+ {
+ .code = EC_BGP_CAPABILITY_INVALID_LENGTH,
+ .title = "BGP has received a capability with an invalid length",
+ .description = "BGP has received a capability from it's peer who's size is wrong",
+ .suggestion = "Gather log files from here and from peer and open an Issue",
+ },
+ {
+ .code = EC_BGP_CAPABILITY_INVALID_DATA,
+ .title = "BGP has received capability data with invalid information",
+ .description = "BGP has noticed that during processing of capability information that data was wrong",
+ .suggestion = "Gather log files from here and from peer and open an Issue",
+ },
+ {
+ .code = EC_BGP_CAPABILITY_VENDOR,
+ .title = "BGP has recieved capability data specific to a particular vendor",
+ .description = "BGP has received a capability that is vendor specific and as such we have no knowledge of how to use this capability in FRR",
+ .suggestion = "On peer turn off this feature"
+ },
+ {
+ .code = EC_BGP_CAPABILITY_UNKNOWN,
+ .title = "BGP has received capability data for a unknown capability",
+ .description = "BGP has received a capability that it does not know how to decode. This may be due to a new feature that has not been coded into FRR or it may be a bug in the remote peer",
+ .suggestion = "Gather log files from here and from peer and open an Issue",
+ },
+ {
+ .code = EC_BGP_INVALID_NEXTHOP_LENGTH,
+ .title = "BGP is attempting to write an invalid nexthop length value",
+ .description = "BGP is in the process of building NLRI information for a peer and has discovered an inconsistent internal state",
+ .suggestion = "Gather log files and open an Issue, restart FRR",
+ },
+ {
+ .code = END_FERR,
+ }
+};
+
static struct log_ref ferr_bgp_err[] = {
{
- .code = BGP_ERR_ATTR_FLAG,
+ .code = EC_BGP_ATTR_FLAG,
.title = "BGP attribute flag is incorrect",
.description = "BGP attribute flag is set to the wrong value (Optional/Transitive/Partial)",
.suggestion = "Determine the soure of the attribute and determine why the attribute flag has been set incorrectly"
},
{
- .code = BGP_ERR_ATTR_LEN,
+ .code = EC_BGP_ATTR_LEN,
.title = "BGP attribute length is incorrect",
.description = "BGP attribute length is incorrect",
.suggestion = "Determine the soure of the attribute and determine why the attribute length has been set incorrectly"
},
{
- .code = BGP_ERR_ATTR_ORIGIN,
+ .code = EC_BGP_ATTR_ORIGIN,
.title = "BGP attribute origin value invalid",
.description = "BGP attribute origin value is invalid",
.suggestion = "Determine the soure of the attribute and determine why the origin attribute has been set incorrectly"
},
{
- .code = BGP_ERR_ATTR_MAL_AS_PATH,
+ .code = EC_BGP_ATTR_MAL_AS_PATH,
.title = "BGP as path is invalid",
.description = "BGP as path has been malformed",
.suggestion = "Determine the soure of the update and determine why the as path has been set incorrectly"
},
{
- .code = BGP_ERR_ATTR_FIRST_AS,
+ .code = EC_BGP_ATTR_FIRST_AS,
.title = "BGP as path first as is invalid",
.description = "BGP update has invalid first as in as path",
.suggestion = "Determine the soure of the update and determine why the as path first as value has been set incorrectly"
},
{
- .code = BGP_ERR_ATTR_PMSI_TYPE,
+ .code = EC_BGP_ATTR_PMSI_TYPE,
.title = "BGP PMSI tunnel attribute type is invalid",
.description = "BGP update has invalid type for PMSI tunnel",
.suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute type has been set incorrectly"
},
{
- .code = BGP_ERR_ATTR_PMSI_LEN,
+ .code = EC_BGP_ATTR_PMSI_LEN,
.title = "BGP PMSI tunnel attribute length is invalid",
.description = "BGP update has invalid length for PMSI tunnel",
.suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute length has been set incorrectly"
},
{
- .code = BGP_ERR_PEER_GROUP,
+ .code = EC_BGP_PEER_GROUP,
.title = "BGP peergroup operated on in error",
.description = "BGP operating on peer-group instead of peers included",
.suggestion = "Ensure the config doesn't contain peergroups contained within peergroups"
},
{
- .code = BGP_ERR_PEER_DELETE,
+ .code = EC_BGP_PEER_DELETE,
.title = "BGP failed to delete peer structure",
.description = "BGP was unable to delete peer structure when address-family removed",
.suggestion = "Determine if all expected peers are removed and restart FRR if not. Most likely a bug"
},
{
- .code = BGP_ERR_TABLE_CHUNK,
+ .code = EC_BGP_TABLE_CHUNK,
.title = "BGP failed to get table chunk memory",
.description = "BGP unable to get chunk memory for table manager",
.suggestion = "Ensure there is adequate memory on the device to support the table requirements"
},
{
- .code = BGP_ERR_MACIP_LEN,
+ .code = EC_BGP_MACIP_LEN,
.title = "BGP received MACIP with invalid IP addr len",
.description = "BGP received MACIP with invalid IP addr len from Zebra",
.suggestion = "Verify MACIP entries inserted in Zebra are correct. Most likely a bug"
},
{
- .code = BGP_ERR_LM_ERROR,
+ .code = EC_BGP_LM_ERROR,
.title = "BGP received invalid label manager message",
.description = "BGP received invalid label manager message from label manager",
.suggestion = "Label manager sent invalid essage to BGP for wrong protocol, instance, etc. Most likely a bug"
},
{
- .code = BGP_ERR_JSON_MEM_ERROR,
+ .code = EC_BGP_JSON_MEM_ERROR,
.title = "BGP unable to allocate memory for JSON output",
.description = "BGP attempted to generate JSON output and was unable to allocate the memory required",
.suggestion = "Ensure that the device has adequate memory to suport the required functions"
},
{
- .code = BGP_ERR_UPDGRP_ATTR_LEN,
+ .code = EC_BGP_UPDGRP_ATTR_LEN,
.title = "BGP update had attributes too long to send",
.description = "BGP attempted to send an update but the attributes were too long to fit",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_UPDGRP_CREATE,
+ .code = EC_BGP_UPDGRP_CREATE,
.title = "BGP update group creation failed",
.description = "BGP attempted to create an update group but was unable to",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_UPDATE_SND,
+ .code = EC_BGP_UPDATE_SND,
.title = "BGP error creating update packet",
.description = "BGP attempted to create an update packet but was unable to",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_PKT_OPEN,
+ .code = EC_BGP_PKT_OPEN,
.title = "BGP error receiving open packet",
.description = "BGP received an open from a peer that was invalid",
.suggestion = "Determine the sending peer and correct his invalid open packet"
},
{
- .code = BGP_ERR_SND_FAIL,
+ .code = EC_BGP_SND_FAIL,
.title = "BGP error sending to peer",
.description = "BGP attempted to respond to open from a peer and failed",
.suggestion = "BGP attempted to respond to an open and could not sene the packet. Check local IP address for source"
},
{
- .code = BGP_ERR_INVALID_STATUS,
+ .code = EC_BGP_INVALID_STATUS,
.title = "BGP error receiving from peer",
.description = "BGP received an update from a peer but status was incorrect",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_UPDATE_RCV,
+ .code = EC_BGP_UPDATE_RCV,
.title = "BGP error receiving update packet",
.description = "BGP received an invalid update packet",
.suggestion = "Determine the source of the update and resolve the invalid update being sent"
},
{
- .code = BGP_ERR_NO_CAP,
+ .code = EC_BGP_NO_CAP,
.title = "BGP error due to capability not enabled",
.description = "BGP attempted a function that did not have the capability enabled",
.suggestion = "Enable the capability if this functionality is desired"
},
{
- .code = BGP_ERR_NOTIFY_RCV,
+ .code = EC_BGP_NOTIFY_RCV,
.title = "BGP error receiving notify message",
.description = "BGP unable to process notification message",
.suggestion = "BGP notify received while in stopped state. If the problem persists, report for troubleshooting"
},
{
- .code = BGP_ERR_KEEP_RCV,
+ .code = EC_BGP_KEEP_RCV,
.title = "BGP error receiving keepalive packet",
.description = "BGP unable to process keepalive packet",
.suggestion = "BGP keepalive received while in stopped state. If the problem persists, report for troubleshooting"
},
{
- .code = BGP_ERR_RFSH_RCV,
+ .code = EC_BGP_RFSH_RCV,
.title = "BGP error receiving route refresh message",
.description = "BGP unable to process route refresh message",
.suggestion = "BGP route refresh received while in stopped state. If the problem persists, report for troubleshooting"},
{
- .code = BGP_ERR_CAP_RCV,
+ .code = EC_BGP_CAP_RCV,
.title = "BGP error capability message",
.description = "BGP unable to process received capability",
.suggestion = "BGP capability message received while in stopped state. If the problem persists, report for troubleshooting"
},
{
- .code = BGP_ERR_NH_UPD,
+ .code = EC_BGP_NH_UPD,
.title = "BGP error with nexthopo update",
.description = "BGP unable to process nexthop update",
.suggestion = "BGP received nexthop update but nexthop is not reachable in this bgp instance. Report for troubleshooting"
},
{
- .code = BGP_ERR_LABEL,
+ .code = EC_BGP_LABEL,
.title = "Failure to apply label",
.description = "BGP attempted to attempted to apply a label but could not",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_MULTIPATH,
+ .code = EC_BGP_MULTIPATH,
.title = "Multipath specified is invalid",
.description = "BGP was started with an invalid ecmp/multipath value",
.suggestion = "Correct the ecmp/multipath value supplied when starting the BGP daemon"
},
{
- .code = BGP_ERR_PKT_PROCESS,
+ .code = EC_BGP_PKT_PROCESS,
.title = "Failure to process a packet",
.description = "BGP attempted to process a received packet but could not",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_CONNECT,
+ .code = EC_BGP_CONNECT,
.title = "Failure to connect to peer",
.description = "BGP attempted to send open to peer but couldn't connect",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_FSM,
+ .code = EC_BGP_FSM,
.title = "BGP FSM issue",
.description = "BGP neighbor transition problem",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_VNI,
+ .code = EC_BGP_VNI,
.title = "BGP VNI creation issue",
.description = "BGP could not create a new VNI",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_NO_DFLT,
+ .code = EC_BGP_NO_DFLT,
.title = "BGP default instance missing",
.description = "BGP could not find default instance",
.suggestion = "Define a default instance of BGP since some feature requires it's existence"
},
{
- .code = BGP_ERR_VTEP_INVALID,
+ .code = EC_BGP_VTEP_INVALID,
.title = "BGP remote VTEP invalid",
.description = "BGP remote VTEP is invalid and cannot be used",
.suggestion = "Correct remote VTEP configuration or resolve the source of the problem"
},
{
- .code = BGP_ERR_ES_INVALID,
+ .code = EC_BGP_ES_INVALID,
.title = "BGP ES route error",
.description = "BGP ES route incorrect, learned both local and remote",
.suggestion = "Correct configuration or addressing so that same not learned both local and remote"
},
{
- .code = BGP_ERR_EVPN_ROUTE_DELETE,
+ .code = EC_BGP_EVPN_ROUTE_DELETE,
.title = "BGP EVPN route delete error",
.description = "BGP attempted to delete an EVPN route and failed",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_EVPN_FAIL,
+ .code = EC_BGP_EVPN_FAIL,
.title = "BGP EVPN install/uninstall error",
.description = "BGP attempted to install or uninstall an EVPN prefix and failed",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_EVPN_ROUTE_INVALID,
+ .code = EC_BGP_EVPN_ROUTE_INVALID,
.title = "BGP EVPN route received with invalid contents",
.description = "BGP received an EVPN route with invalid contents",
.suggestion = "Determine the source of the EVPN route and resolve whatever is causing invalid contents"
},
{
- .code = BGP_ERR_EVPN_ROUTE_CREATE,
+ .code = EC_BGP_EVPN_ROUTE_CREATE,
.title = "BGP EVPN route create error",
.description = "BGP attempted to create an EVPN route and failed",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_ES_CREATE,
+ .code = EC_BGP_ES_CREATE,
.title = "BGP EVPN ES entry create error",
.description = "BGP attempted to create an EVPN ES entry and failed",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = BGP_ERR_MULTI_INSTANCE,
+ .code = EC_BGP_MULTI_INSTANCE,
.title = "BGP config multi-instance issue",
.description = "BGP configuration attempting multiple instances without enabling the feature",
.suggestion = "Correct the configuration so that bgp multiple-instance is enabled if desired"
},
{
- .code = BGP_ERR_EVPN_AS_MISMATCH,
+ .code = EC_BGP_EVPN_AS_MISMATCH,
.title = "BGP AS configuration issue",
.description = "BGP configuration attempted for a different AS than currently configured",
.suggestion = "Correct the configuration so that the correct BGP AS number is used"
},
{
- .code = BGP_ERR_EVPN_INSTANCE_MISMATCH,
+ .code = EC_BGP_EVPN_INSTANCE_MISMATCH,
.title = "BGP EVPN AS and process name mismatch",
.description = "BGP configuration has AS and process name mismatch",
.suggestion = "Correct the configuration so that the BGP AS number and instance name are consistent"
},
{
- .code = BGP_ERR_FLOWSPEC_PACKET,
+ .code = EC_BGP_FLOWSPEC_PACKET,
.title = "BGP Flowspec packet processing error",
.description = "The BGP flowspec subsystem has detected a error in the send or receive of a packet",
.suggestion = "Gather log files from both sides of the peering relationship and open an issue"
},
{
- .code = BGP_ERR_FLOWSPEC_INSTALLATION,
+ .code = EC_BGP_FLOWSPEC_INSTALLATION,
.title = "BGP Flowspec Installation/removal Error",
.description = "The BGP flowspec subsystem has detected that there was a failure for installation/removal/modification of Flowspec from the dataplane",
.suggestion = "Gather log files from the router and open an issue, Restart FRR"
void bgp_error_init(void)
{
log_ref_add(ferr_bgp_err);
+ log_ref_add(ferr_bgp_warn);
}
enum bgp_log_refs {
- BGP_ERR_ATTR_FLAG = BGP_FERR_START,
- BGP_ERR_ATTR_LEN,
- BGP_ERR_ATTR_ORIGIN,
- BGP_ERR_ATTR_MAL_AS_PATH,
- BGP_ERR_ATTR_FIRST_AS,
- BGP_ERR_ATTR_MARTIAN_NH,
- BGP_ERR_ATTR_PMSI_TYPE,
- BGP_ERR_ATTR_PMSI_LEN,
- BGP_ERR_ATTR_NH_SEND_LEN,
- BGP_ERR_PEER_GROUP,
- BGP_ERR_PEER_DELETE,
- BGP_ERR_TABLE_CHUNK,
- BGP_ERR_MACIP_LEN,
- BGP_ERR_LM_ERROR,
- BGP_ERR_JSON_MEM_ERROR,
- BGP_ERR_UPDGRP_ATTR_LEN,
- BGP_ERR_UPDGRP_CREATE,
- BGP_ERR_UPDATE_SND,
- BGP_ERR_PKT_OPEN,
- BGP_ERR_SND_FAIL,
- BGP_ERR_INVALID_STATUS,
- BGP_ERR_UPDATE_RCV,
- BGP_ERR_NO_CAP,
- BGP_ERR_NOTIFY_RCV,
- BGP_ERR_KEEP_RCV,
- BGP_ERR_RFSH_RCV,
- BGP_ERR_CAP_RCV,
- BGP_ERR_NH_UPD,
- BGP_ERR_LABEL,
- BGP_ERR_MULTIPATH,
- BGP_ERR_PKT_PROCESS,
- BGP_ERR_CONNECT,
- BGP_ERR_FSM,
- BGP_ERR_VNI,
- BGP_ERR_NO_DFLT,
- BGP_ERR_VTEP_INVALID,
- BGP_ERR_ES_INVALID,
- BGP_ERR_EVPN_ROUTE_DELETE,
- BGP_ERR_EVPN_FAIL,
- BGP_ERR_EVPN_ROUTE_INVALID,
- BGP_ERR_EVPN_ROUTE_CREATE,
- BGP_ERR_ES_CREATE,
- BGP_ERR_MULTI_INSTANCE,
- BGP_ERR_EVPN_AS_MISMATCH,
- BGP_ERR_EVPN_INSTANCE_MISMATCH,
- BGP_ERR_FLOWSPEC_PACKET,
- BGP_ERR_FLOWSPEC_INSTALLATION,
+ EC_BGP_ATTR_FLAG = BGP_FERR_START,
+ EC_BGP_ATTR_LEN,
+ EC_BGP_ATTR_ORIGIN,
+ EC_BGP_ATTR_MAL_AS_PATH,
+ EC_BGP_ATTR_FIRST_AS,
+ EC_BGP_ATTR_MARTIAN_NH,
+ EC_BGP_ATTR_PMSI_TYPE,
+ EC_BGP_ATTR_PMSI_LEN,
+ EC_BGP_ATTR_NH_SEND_LEN,
+ EC_BGP_PEER_GROUP,
+ EC_BGP_PEER_DELETE,
+ EC_BGP_TABLE_CHUNK,
+ EC_BGP_MACIP_LEN,
+ EC_BGP_LM_ERROR,
+ EC_BGP_JSON_MEM_ERROR,
+ EC_BGP_UPDGRP_ATTR_LEN,
+ EC_BGP_UPDGRP_CREATE,
+ EC_BGP_UPDATE_SND,
+ EC_BGP_PKT_OPEN,
+ EC_BGP_SND_FAIL,
+ EC_BGP_INVALID_STATUS,
+ EC_BGP_UPDATE_RCV,
+ EC_BGP_NO_CAP,
+ EC_BGP_NOTIFY_RCV,
+ EC_BGP_KEEP_RCV,
+ EC_BGP_RFSH_RCV,
+ EC_BGP_CAP_RCV,
+ EC_BGP_NH_UPD,
+ EC_BGP_LABEL,
+ EC_BGP_MULTIPATH,
+ EC_BGP_PKT_PROCESS,
+ EC_BGP_CONNECT,
+ EC_BGP_FSM,
+ EC_BGP_VNI,
+ EC_BGP_NO_DFLT,
+ EC_BGP_VTEP_INVALID,
+ EC_BGP_ES_INVALID,
+ EC_BGP_EVPN_ROUTE_DELETE,
+ EC_BGP_EVPN_FAIL,
+ EC_BGP_EVPN_ROUTE_INVALID,
+ EC_BGP_EVPN_ROUTE_CREATE,
+ EC_BGP_ES_CREATE,
+ EC_BGP_MULTI_INSTANCE,
+ EC_BGP_EVPN_AS_MISMATCH,
+ EC_BGP_EVPN_INSTANCE_MISMATCH,
+ EC_BGP_FLOWSPEC_PACKET,
+ EC_BGP_FLOWSPEC_INSTALLATION,
+ EC_BGP_ASPATH_FEWER_HOPS,
+ EC_BGP_DEFUNCT_SNPA_LEN,
+ EC_BGP_MISSING_ATTRIBUTE,
+ EC_BGP_ATTRIBUTE_TOO_SMALL,
+ EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
+ EC_BGP_ATTRIBUTE_REPEATED,
+ EC_BGP_ATTRIBUTE_TOO_LARGE,
+ EC_BGP_ATTRIBUTE_PARSE_ERROR,
+ EC_BGP_ATTRIBUTE_PARSE_WITHDRAW,
+ EC_BGP_ATTRIBUTE_FETCH_ERROR,
+ EC_BGP_ATTRIBUTES_MISMATCH,
+ EC_BGP_DUMP,
+ EC_BGP_UPDATE_PACKET_SHORT,
+ EC_BGP_UPDATE_PACKET_LONG,
+ EC_BGP_UNRECOGNIZED_CAPABILITY,
+ EC_BGP_NO_TCP_MD5,
+ EC_BGP_NO_SOCKOPT_MARK,
+ EC_BGP_EVPN_PMSI_PRESENT,
+ EC_BGP_EVPN_VPN_VNI,
+ EC_BGP_EVPN_ESI,
+ EC_BGP_INVALID_LABEL_STACK,
+ EC_BGP_ZEBRA_SEND,
+ EC_BGP_CAPABILITY_INVALID_LENGTH,
+ EC_BGP_CAPABILITY_INVALID_DATA,
+ EC_BGP_CAPABILITY_VENDOR,
+ EC_BGP_CAPABILITY_UNKNOWN,
+ EC_BGP_INVALID_NEXTHOP_LENGTH,
};
extern void bgp_error_init(void);
bgp_def = bgp_get_default();
if (!bgp_def) {
- flog_err(BGP_ERR_NO_DFLT,
- "vrf import rt new - def instance not created yet");
+ flog_err(EC_BGP_NO_DFLT,
+ "vrf import rt new - def instance not created yet");
return NULL;
}
bgp_def = bgp_get_default();
if (!bgp_def) {
- flog_err(BGP_ERR_NO_DFLT,
- "vrf import rt free - def instance not created yet");
+ flog_err(EC_BGP_NO_DFLT,
+ "vrf import rt free - def instance not created yet");
return;
}
bgp_def = bgp_get_default();
if (!bgp_def) {
- flog_err(
- BGP_ERR_NO_DFLT,
- "vrf import rt lookup - def instance not created yet");
+ flog_err(EC_BGP_NO_DFLT,
+ "vrf import rt lookup - def instance not created yet");
return NULL;
}
stream_put_in_addr(s, &p->prefix.imet_addr.ip.ipaddr_v4);
else if (is_evpn_prefix_ipaddr_v6(p)) {
flog_err(
- BGP_ERR_VTEP_INVALID,
+ EC_BGP_VTEP_INVALID,
"Bad remote IP when trying to %s remote VTEP for VNI %u",
add ? "ADD" : "DEL", vpn->vni);
return -1;
*/
if (remote_ri) {
flog_err(
- BGP_ERR_ES_INVALID,
+ EC_BGP_ES_INVALID,
"%u ERROR: local es route for ESI: %s Vtep %s also learnt from remote",
bgp->vrf_id,
esi_to_str(&evp->prefix.es_addr.esi, buf, sizeof(buf)),
&attr, 1, &ri,
&route_changed);
if (ret != 0) {
- flog_err(
- BGP_ERR_ES_INVALID,
- "%u ERROR: Failed to updated ES route ESI: %s VTEP %s",
- bgp->vrf_id,
- esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)),
- ipaddr2str(&es->originator_ip, buf1, sizeof(buf1)));
+ flog_err(EC_BGP_ES_INVALID,
+ "%u ERROR: Failed to updated ES route ESI: %s VTEP %s",
+ bgp->vrf_id,
+ esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)),
+ ipaddr2str(&es->originator_ip, buf1, sizeof(buf1)));
}
assert(ri);
build_evpn_type4_prefix(&p, &es->esi, es->originator_ip.ipaddr_v4);
ret = delete_evpn_type4_route(bgp, es, &p);
if (ret) {
- flog_err(BGP_ERR_EVPN_ROUTE_DELETE,
- "%u failed to delete type-4 route for ESI %s",
- bgp->vrf_id, esi_to_str(&es->esi, buf, sizeof(buf)));
+ flog_err(EC_BGP_EVPN_ROUTE_DELETE,
+ "%u failed to delete type-4 route for ESI %s",
+ bgp->vrf_id, esi_to_str(&es->esi, buf, sizeof(buf)));
}
/* Delete all routes from per ES table */
if (ret) {
flog_err(
- BGP_ERR_EVPN_FAIL,
+ EC_BGP_EVPN_FAIL,
"Failed to %s EVPN %s route in ESI %s",
install ? "install"
: "uninstall",
if (ret) {
flog_err(
- BGP_ERR_EVPN_FAIL,
+ EC_BGP_EVPN_FAIL,
"Failed to %s EVPN %s route in VRF %s",
install ? "install"
: "uninstall",
if (ret) {
flog_err(
- BGP_ERR_EVPN_FAIL,
+ EC_BGP_EVPN_FAIL,
"%u: Failed to %s EVPN %s route in VNI %u",
bgp->vrf_id,
install ? "install"
if (ret) {
flog_err(
- BGP_ERR_EVPN_FAIL,
+ EC_BGP_EVPN_FAIL,
"%u: Failed to %s EVPN %s route in ESI %s", bgp->vrf_id,
install ? "install" : "uninstall", "ES",
esi_to_str(&evp->prefix.es_addr.esi, buf, sizeof(buf)));
ri);
if (ret) {
- flog_err(BGP_ERR_EVPN_FAIL,
- "%u: Failed to %s prefix %s in VRF %s",
- bgp_def->vrf_id,
- install ? "install" : "uninstall",
- prefix2str(evp, buf, sizeof(buf)),
- vrf_id_to_name(bgp_vrf->vrf_id));
+ flog_err(EC_BGP_EVPN_FAIL,
+ "%u: Failed to %s prefix %s in VRF %s",
+ bgp_def->vrf_id,
+ install ? "install" : "uninstall",
+ prefix2str(evp, buf, sizeof(buf)),
+ vrf_id_to_name(bgp_vrf->vrf_id));
return ret;
}
}
ret = uninstall_evpn_route_entry(bgp, vpn, evp, ri);
if (ret) {
- flog_err(
- BGP_ERR_EVPN_FAIL,
- "%u: Failed to %s EVPN %s route in VNI %u",
- bgp->vrf_id, install ? "install" : "uninstall",
- evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
- ? "MACIP"
- : "IMET",
- vpn->vni);
+ flog_err(EC_BGP_EVPN_FAIL,
+ "%u: Failed to %s EVPN %s route in VNI %u",
+ bgp->vrf_id, install ? "install" : "uninstall",
+ evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
+ ? "MACIP"
+ : "IMET",
+ vpn->vni);
return ret;
}
}
*/
if (psize != 33 && psize != 37 && psize != 49 && psize != 36
&& psize != 40 && psize != 52) {
- flog_err(BGP_ERR_EVPN_ROUTE_INVALID,
- "%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
- peer->bgp->vrf_id, peer->host, psize);
+ flog_err(EC_BGP_EVPN_ROUTE_INVALID,
+ "%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
+ peer->bgp->vrf_id, peer->host, psize);
return -1;
}
pfx += ETH_ALEN;
} else {
flog_err(
- BGP_ERR_EVPN_ROUTE_INVALID,
+ EC_BGP_EVPN_ROUTE_INVALID,
"%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
peer->bgp->vrf_id, peer->host, macaddr_len);
return -1;
if (ipaddr_len != 0 && ipaddr_len != IPV4_MAX_BITLEN
&& ipaddr_len != IPV6_MAX_BITLEN) {
flog_err(
- BGP_ERR_EVPN_ROUTE_INVALID,
+ EC_BGP_EVPN_ROUTE_INVALID,
"%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
peer->bgp->vrf_id, peer->host, ipaddr_len);
return -1;
* IP len (1) and IP (4 or 16).
*/
if (psize != 17 && psize != 29) {
- flog_err(BGP_ERR_EVPN_ROUTE_INVALID,
- "%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
- peer->bgp->vrf_id, peer->host, psize);
+ flog_err(EC_BGP_EVPN_ROUTE_INVALID,
+ "%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
+ peer->bgp->vrf_id, peer->host, psize);
return -1;
}
if (attr &&
(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL) {
- zlog_warn("%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
- peer->bgp->vrf_id, peer->host,
- attr->pmsi_tnl_type);
+ flog_warn(
+ EC_BGP_EVPN_PMSI_PRESENT,
+ "%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
+ peer->bgp->vrf_id, peer->host,
+ attr->pmsi_tnl_type);
}
}
memcpy(&p.prefix.imet_addr.ip.ip.addr, pfx, IPV4_MAX_BYTELEN);
} else {
flog_err(
- BGP_ERR_EVPN_ROUTE_INVALID,
+ EC_BGP_EVPN_ROUTE_INVALID,
"%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
peer->bgp->vrf_id, peer->host, ipaddr_len);
return -1;
* RD (8), ESI (10), ip-len (1), ip (4 or 16)
*/
if (psize != 23 && psize != 35) {
- flog_err(BGP_ERR_EVPN_ROUTE_INVALID,
- "%u:%s - Rx EVPN Type-4 NLRI with invalid length %d",
- peer->bgp->vrf_id, peer->host, psize);
+ flog_err(EC_BGP_EVPN_ROUTE_INVALID,
+ "%u:%s - Rx EVPN Type-4 NLRI with invalid length %d",
+ peer->bgp->vrf_id, peer->host, psize);
return -1;
}
memcpy(&vtep_ip, pfx, IPV4_MAX_BYTELEN);
} else {
flog_err(
- BGP_ERR_EVPN_ROUTE_INVALID,
+ EC_BGP_EVPN_ROUTE_INVALID,
"%u:%s - Rx EVPN Type-4 NLRI with unsupported IP address length %d",
peer->bgp->vrf_id, peer->host, ipaddr_len);
return -1;
* Note that the IP and GW should both be IPv4 or both IPv6.
*/
if (psize != 34 && psize != 58) {
- flog_err(BGP_ERR_EVPN_ROUTE_INVALID,
- "%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
- peer->bgp->vrf_id, peer->host, psize);
+ flog_err(EC_BGP_EVPN_ROUTE_INVALID,
+ "%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
+ peer->bgp->vrf_id, peer->host, psize);
return -1;
}
ippfx_len = *pfx++;
if (ippfx_len > IPV6_MAX_BITLEN) {
flog_err(
- BGP_ERR_EVPN_ROUTE_INVALID,
+ EC_BGP_EVPN_ROUTE_INVALID,
"%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
peer->bgp->vrf_id, peer->host, ippfx_len);
return -1;
ret = delete_evpn_type5_route(bgp_vrf, &evp);
if (ret) {
flog_err(
- BGP_ERR_EVPN_ROUTE_DELETE,
+ EC_BGP_EVPN_ROUTE_DELETE,
"%u failed to delete type-5 route for prefix %s in vrf %s",
bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)),
vrf_id_to_name(bgp_vrf->vrf_id));
build_type5_prefix_from_ip_prefix(&evp, p);
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
if (ret)
- flog_err(BGP_ERR_EVPN_ROUTE_CREATE,
- "%u: Failed to create type-5 route for prefix %s",
- bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)));
+ flog_err(EC_BGP_EVPN_ROUTE_CREATE,
+ "%u: Failed to create type-5 route for prefix %s",
+ bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)));
}
/* Inject all prefixes of a particular address-family (currently, IPv4 or
withdraw ? NULL : attr, pnt,
psize, addpath_id)) {
flog_err(
- BGP_ERR_EVPN_FAIL,
+ EC_BGP_EVPN_FAIL,
"%u:%s - Error in processing EVPN type-2 NLRI size %d",
peer->bgp->vrf_id, peer->host, psize);
return -1;
withdraw ? NULL : attr, pnt,
psize, addpath_id)) {
flog_err(
- BGP_ERR_PKT_PROCESS,
+ EC_BGP_PKT_PROCESS,
"%u:%s - Error in processing EVPN type-3 NLRI size %d",
peer->bgp->vrf_id, peer->host, psize);
return -1;
withdraw ? NULL : attr, pnt,
psize, addpath_id)) {
flog_err(
- BGP_ERR_PKT_PROCESS,
+ EC_BGP_PKT_PROCESS,
"%u:%s - Error in processing EVPN type-4 NLRI size %d",
peer->bgp->vrf_id, peer->host, psize);
return -1;
if (process_type5_route(peer, afi, safi, attr, pnt,
psize, addpath_id, withdraw)) {
flog_err(
- BGP_ERR_PKT_PROCESS,
+ EC_BGP_PKT_PROCESS,
"%u:%s - Error in processing EVPN type-5 NLRI size %d",
peer->bgp->vrf_id, peer->host, psize);
return -1;
/* Lookup VNI hash - should exist. */
vpn = bgp_evpn_lookup_vni(bgp, vni);
if (!vpn || !is_vni_live(vpn)) {
- zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
+ flog_warn(EC_BGP_EVPN_VPN_VNI,
+ "%u: VNI hash entry for VNI %u %s at MACIP DEL",
bgp->vrf_id, vni, vpn ? "not live" : "not found");
return -1;
}
/* Lookup VNI hash - should exist. */
vpn = bgp_evpn_lookup_vni(bgp, vni);
if (!vpn || !is_vni_live(vpn)) {
- zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
+ flog_warn(EC_BGP_EVPN_VPN_VNI,
+ "%u: VNI hash entry for VNI %u %s at MACIP ADD",
bgp->vrf_id, vni, vpn ? "not live" : "not found");
return -1;
}
char buf2[INET6_ADDRSTRLEN];
flog_err(
- BGP_ERR_EVPN_ROUTE_CREATE,
+ EC_BGP_EVPN_ROUTE_CREATE,
"%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s (flags: 0x%x)",
bgp->vrf_id, vpn->vni,
CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY)
bgp_def = bgp_get_default();
if (!bgp_def) {
flog_err(
- BGP_ERR_NO_DFLT,
+ EC_BGP_NO_DFLT,
"Cannot process L3VNI %u ADD - default BGP instance not yet created",
l3vni);
return -1;
BGP_INSTANCE_TYPE_VRF);
switch (ret) {
case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET:
- flog_err(BGP_ERR_MULTI_INSTANCE,
- "'bgp multiple-instance' not present\n");
+ flog_err(EC_BGP_MULTI_INSTANCE,
+ "'bgp multiple-instance' not present\n");
return -1;
case BGP_ERR_AS_MISMATCH:
- flog_err(BGP_ERR_EVPN_AS_MISMATCH,
- "BGP is already running; AS is %u\n", as);
+ flog_err(EC_BGP_EVPN_AS_MISMATCH,
+ "BGP is already running; AS is %u\n", as);
return -1;
case BGP_ERR_INSTANCE_MISMATCH:
- flog_err(BGP_ERR_EVPN_INSTANCE_MISMATCH,
- "BGP instance name and AS number mismatch\n");
+ flog_err(EC_BGP_EVPN_INSTANCE_MISMATCH,
+ "BGP instance name and AS number mismatch\n");
return -1;
}
bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
if (!bgp_vrf) {
flog_err(
- BGP_ERR_NO_DFLT,
+ EC_BGP_NO_DFLT,
"Cannot process L3VNI %u Del - Could not find BGP instance",
l3vni);
return -1;
bgp_def = bgp_get_default();
if (!bgp_def) {
flog_err(
- BGP_ERR_NO_DFLT,
+ EC_BGP_NO_DFLT,
"Cannot process L3VNI %u Del - Could not find default BGP instance",
l3vni);
return -1;
vpn = bgp_evpn_lookup_vni(bgp, vni);
if (!vpn) {
if (bgp_debug_zebra(NULL))
- zlog_warn(
+ flog_warn(
+ EC_BGP_EVPN_VPN_VNI,
"%u: VNI hash entry for VNI %u not found at DEL",
bgp->vrf_id, vni);
return 0;
vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id);
if (!vpn) {
flog_err(
- BGP_ERR_VNI,
+ EC_BGP_VNI,
"%u: Failed to allocate VNI entry for VNI %u - at Add",
bgp->vrf_id, vni);
return -1;
/* 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, 0)) {
- flog_err(BGP_ERR_EVPN_ROUTE_CREATE,
- "%u: Type3 route creation failure for VNI %u",
- bgp->vrf_id, vni);
+ flog_err(EC_BGP_EVPN_ROUTE_CREATE,
+ "%u: Type3 route creation failure for VNI %u",
+ bgp->vrf_id, vni);
return -1;
}
struct evpnes *es = NULL;
if (!bgp->esihash) {
- flog_err(BGP_ERR_ES_CREATE, "%u: ESI hash not yet created",
- bgp->vrf_id);
+ flog_err(EC_BGP_ES_CREATE, "%u: ESI hash not yet created",
+ bgp->vrf_id);
return -1;
}
/* Lookup ESI hash - should exist. */
es = bgp_evpn_lookup_es(bgp, esi);
if (!es) {
- zlog_warn("%u: ESI hash entry for ESI %s at Local ES DEL",
- bgp->vrf_id,
- esi_to_str(esi, buf, sizeof(buf)));
+ flog_warn(EC_BGP_EVPN_ESI,
+ "%u: ESI hash entry for ESI %s at Local ES DEL",
+ bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
return -1;
}
struct prefix_evpn p;
if (!bgp->esihash) {
- flog_err(BGP_ERR_ES_CREATE, "%u: ESI hash not yet created",
- bgp->vrf_id);
+ flog_err(EC_BGP_ES_CREATE, "%u: ESI hash not yet created",
+ bgp->vrf_id);
return -1;
}
es = bgp_evpn_es_new(bgp, esi, originator_ip);
if (!es) {
flog_err(
- BGP_ERR_ES_CREATE,
+ EC_BGP_ES_CREATE,
"%u: Failed to allocate ES entry for ESI %s - at Local ES Add",
bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
return -1;
build_evpn_type4_prefix(&p, esi, originator_ip->ipaddr_v4);
if (update_evpn_type4_route(bgp, es, &p)) {
- flog_err(BGP_ERR_EVPN_ROUTE_CREATE,
- "%u: Type4 route creation failure for ESI %s",
- bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
+ flog_err(EC_BGP_EVPN_ROUTE_CREATE,
+ "%u: Type4 route creation failure for ESI %s",
+ bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
return -1;
}
if (!vpn) {
/* Check if this L2VNI is already configured as L3VNI */
if (bgp_evpn_lookup_l3vni_l2vni_table(vni)) {
- flog_err(BGP_ERR_VNI,
- "%u: Failed to create L2VNI %u, it is configured as L3VNI",
- bgp->vrf_id, vni);
+ flog_err(
+ EC_BGP_VNI,
+ "%u: Failed to create L2VNI %u, it is configured as L3VNI",
+ bgp->vrf_id, vni);
return NULL;
}
vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0);
if (!vpn) {
flog_err(
- BGP_ERR_VNI,
+ EC_BGP_VNI,
"%u: Failed to allocate VNI entry for VNI %u - at Config",
bgp->vrf_id, vni);
return NULL;
* 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"
safi = packet->safi;
if (afi == AFI_IP6) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "BGP flowspec IPv6 not supported");
+ flog_err(EC_LIB_DEVELOPMENT, "BGP flowspec IPv6 not supported");
return -1;
}
if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT) {
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "BGP flowspec nlri length maximum reached (%u)",
- packet->length);
+ flog_err(EC_BGP_FLOWSPEC_PACKET,
+ "BGP flowspec nlri length maximum reached (%u)",
+ packet->length);
return -1;
}
/* When packet overflow occur return immediately. */
if (pnt + psize > lim) {
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "Flowspec NLRI length inconsistent ( size %u seen)",
- psize);
+ flog_err(
+ EC_BGP_FLOWSPEC_PACKET,
+ "Flowspec NLRI length inconsistent ( size %u seen)",
+ psize);
return -1;
}
if (bgp_fs_nlri_validate(pnt, psize) < 0) {
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "Bad flowspec format or NLRI options not supported");
+ flog_err(
+ EC_BGP_FLOWSPEC_PACKET,
+ "Bad flowspec format or NLRI options not supported");
return -1;
}
p.family = AF_FLOWSPEC;
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
NULL, NULL, 0, NULL);
if (ret) {
- flog_err(BGP_ERR_FLOWSPEC_INSTALLATION,
- "Flowspec NLRI failed to be %s.",
- attr ? "added" : "withdrawn");
+ flog_err(EC_BGP_FLOWSPEC_INSTALLATION,
+ "Flowspec NLRI failed to be %s.",
+ attr ? "added" : "withdrawn");
return -1;
}
}
len,
mval, error);
if (*error < 0)
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "%s: flowspec_op_decode error %d",
- __func__, *error);
+ flog_err(EC_BGP_FLOWSPEC_PACKET,
+ "%s: flowspec_op_decode error %d", __func__, *error);
else
*match_num = *error;
return ret;
len - offset,
prefix, &error);
if (error < 0)
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "%s: flowspec_ip_address error %d",
- __func__, error);
+ flog_err(EC_BGP_FLOWSPEC_PACKET,
+ "%s: flowspec_ip_address error %d",
+ __func__, error);
else
bpem->match_bitmask |= bitmask;
offset += ret;
len - offset,
&bpem->tcpflags, &error);
if (error < 0)
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "%s: flowspec_tcpflags_decode error %d",
- __func__, error);
+ flog_err(
+ EC_BGP_FLOWSPEC_PACKET,
+ "%s: flowspec_tcpflags_decode error %d",
+ __func__, error);
else
bpem->match_tcpflags_num = error;
/* contains the number of slots used */
len - offset, &bpem->fragment,
&error);
if (error < 0)
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "%s: flowspec_fragment_type_decode error %d",
- __func__, error);
+ flog_err(
+ EC_BGP_FLOWSPEC_PACKET,
+ "%s: flowspec_fragment_type_decode error %d",
+ __func__, error);
else
bpem->match_fragment_num = error;
offset += ret;
break;
default:
- flog_err(LIB_ERR_DEVELOPMENT, "%s: unknown type %d\n",
- __func__, type);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: unknown type %d\n",
+ __func__, type);
}
}
return error;
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
int idx = 0;
- const char *no = strmatch(argv[0]->text, (char *)"no") ? "no" : NULL;
+ const char *no = strmatch(argv[0]->text, "no") ? "no" : NULL;
char *ifname = argv_find(argv, argc, "INTERFACE", &idx) ?
argv[idx]->arg : NULL;
*/
if (peer->curr) {
flog_err(
- BGP_ERR_PKT_PROCESS,
+ EC_BGP_PKT_PROCESS,
"[%s] Dropping pending packet on connection transfer:",
peer->host);
uint16_t type = stream_getc_from(peer->curr,
if (bgp_getsockname(peer) < 0) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
(CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
? "accept"
if (from_peer->status > Active) {
if (bgp_getsockname(from_peer) < 0) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
(CHECK_FLAG(from_peer->sflags,
static int bgp_connect_success(struct peer *peer)
{
if (peer->fd < 0) {
- flog_err(BGP_ERR_CONNECT,
- "bgp_connect_success peer's fd is negative value %d",
- peer->fd);
+ flog_err(EC_BGP_CONNECT,
+ "bgp_connect_success peer's fd is negative value %d",
+ peer->fd);
bgp_stop(peer);
return -1;
}
if (bgp_getsockname(peer) < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: bgp_getsockname(): failed for peer %s, fd %d",
__FUNCTION__, peer->host, peer->fd);
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
if (BGP_PEER_START_SUPPRESSED(peer)) {
if (bgp_debug_neighbor_events(peer))
- flog_err(BGP_ERR_FSM,
- "%s [FSM] Trying to start suppressed peer"
- " - this is never supposed to happen!",
- peer->host);
+ flog_err(EC_BGP_FSM,
+ "%s [FSM] Trying to start suppressed peer"
+ " - this is never supposed to happen!",
+ peer->host);
return -1;
}
if (peer->bgp->vrf_id == VRF_UNKNOWN) {
if (bgp_debug_neighbor_events(peer))
flog_err(
- BGP_ERR_FSM,
+ EC_BGP_FSM,
"%s [FSM] In a VRF that is not initialised yet",
peer->host);
return -1;
"%s [FSM] Non blocking connect waiting result, fd %d",
peer->host, peer->fd);
if (peer->fd < 0) {
- flog_err(BGP_ERR_FSM,
- "bgp_start peer's fd is negative value %d",
- peer->fd);
+ flog_err(EC_BGP_FSM,
+ "bgp_start peer's fd is negative value %d",
+ peer->fd);
return -1;
}
/*
peer and change to Idle status. */
static int bgp_fsm_event_error(struct peer *peer)
{
- flog_err(BGP_ERR_FSM,
- "%s [FSM] unexpected packet received in state %s", peer->host,
- lookup_msg(bgp_status_msg, peer->status, NULL));
+ flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
+ peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, 0);
}
other = peer->doppelganger;
peer = peer_xfer_conn(peer);
if (!peer) {
- flog_err(BGP_ERR_CONNECT, "%%Neighbor failed in xfer_conn");
+ flog_err(EC_BGP_CONNECT, "%%Neighbor failed in xfer_conn");
return -1;
}
static int bgp_ignore(struct peer *peer)
{
flog_err(
- BGP_ERR_FSM,
+ EC_BGP_FSM,
"%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
peer->host, bgp_event_str[peer->cur_event],
lookup_msg(bgp_status_msg, peer->status, NULL),
static int bgp_fsm_exeption(struct peer *peer)
{
flog_err(
- BGP_ERR_FSM,
+ EC_BGP_FSM,
"%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
peer->host, bgp_event_str[peer->cur_event],
lookup_msg(bgp_status_msg, peer->status, NULL),
*/
if (!dyn_nbr && !passive_conn && peer->bgp) {
flog_err(
- BGP_ERR_FSM,
+ EC_BGP_FSM,
"%s [FSM] Failure handling event %s in state %s, "
"prior events %s, %s, fd %d",
peer->host, bgp_event_str[peer->cur_event],
#include <zebra.h>
#include <pthread.h> // for pthread_mutex_unlock, pthread_mutex_lock
-#include "frr_pthread.h" // for frr_pthread_get, frr_pthread
+#include "frr_pthread.h"
#include "linklist.h" // for list_delete, list_delete_all_node, lis...
#include "log.h" // for zlog_debug, safe_strerror, zlog_err
#include "memory.h" // for MTYPE_TMP, XCALLOC, XFREE
void bgp_writes_on(struct peer *peer)
{
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_IO);
+ struct frr_pthread *fpt = bgp_pth_io;
assert(fpt->running);
assert(peer->status != Deleted);
void bgp_writes_off(struct peer *peer)
{
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_IO);
+ struct frr_pthread *fpt = bgp_pth_io;
assert(fpt->running);
thread_cancel_async(fpt->master, &peer->t_write, NULL);
void bgp_reads_on(struct peer *peer)
{
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_IO);
+ struct frr_pthread *fpt = bgp_pth_io;
assert(fpt->running);
assert(peer->status != Deleted);
void bgp_reads_off(struct peer *peer)
{
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_IO);
+ struct frr_pthread *fpt = bgp_pth_io;
assert(fpt->running);
thread_cancel_async(fpt->master, &peer->t_read, NULL);
if (peer->fd < 0)
return -1;
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_IO);
+ struct frr_pthread *fpt = bgp_pth_io;
pthread_mutex_lock(&peer->io_mtx);
{
if (peer->fd < 0 || bm->terminating)
return -1;
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_IO);
+ struct frr_pthread *fpt = bgp_pth_io;
pthread_mutex_lock(&peer->io_mtx);
{
SET_FLAG(status, BGP_IO_TRANS_ERR);
/* Fatal error; tear down session */
} else if (nbytes < 0) {
- flog_err(BGP_ERR_UPDATE_RCV,
- "%s [Error] bgp_read_packet error: %s", peer->host,
- safe_strerror(errno));
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%s [Error] bgp_read_packet error: %s", peer->host,
+ safe_strerror(errno));
if (peer->status == Established) {
if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)) {
if (CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON))
return;
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_KEEPALIVES);
+ struct frr_pthread *fpt = bgp_pth_ka;
assert(fpt->running);
/* placeholder bucket data to use for fast key lookups */
if (!CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON))
return;
- struct frr_pthread *fpt = frr_pthread_get(PTHREAD_KEEPALIVES);
+ struct frr_pthread *fpt = bgp_pth_ka;
assert(fpt->running);
/* placeholder bucket data to use for fast key lookups */
/* If we RX multiple labels we will end up keeping only the last
* one. We do not yet support a label stack greater than 1. */
if (label_depth > 1)
- zlog_warn("%s rcvd UPDATE with label stack %d deep", peer->host,
+ zlog_info("%s rcvd UPDATE with label stack %d deep", peer->host,
label_depth);
if (!(bgp_is_withdraw_label(label) || label_bos(label)))
- zlog_warn(
+ flog_warn(
+ EC_BGP_INVALID_LABEL_STACK,
"%s rcvd UPDATE with invalid label stack - no bottom of stack",
peer->host);
/* sanity check against packet data */
if ((pnt + psize) > lim) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
peer->host, prefixlen, (uint)(lim - pnt));
return -1;
/* There needs to be at least one label */
if (prefixlen < 24) {
- flog_err(BGP_ERR_UPDATE_RCV,
- "%s [Error] Update packet error"
- " (wrong label length %d)",
- peer->host, prefixlen);
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%s [Error] Update packet error"
+ " (wrong label length %d)",
+ peer->host, prefixlen);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_INVAL_NETWORK);
return -1;
* ignored.
*/
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
peer->host, inet_ntoa(p.u.prefix4));
continue;
char buf[BUFSIZ];
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
char buf[BUFSIZ];
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s: IPv6 unicast NLRI is multicast address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
/* Packet length consistency check. */
if (pnt != lim) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
peer->host, lim - pnt);
return -1;
if (lcbq->label == MPLS_LABEL_NONE) {
/* shouldn't happen */
- flog_err(BGP_ERR_LABEL, "%s: error: label==MPLS_LABEL_NONE",
- __func__);
+ flog_err(EC_BGP_LABEL, "%s: error: label==MPLS_LABEL_NONE",
+ __func__);
return WQ_SUCCESS;
}
if (rc) {
/* shouldn't happen */
- flog_err(BGP_ERR_LABEL,
- "%s: can't insert new LCB into ledger list",
- __func__);
+ flog_err(EC_BGP_LABEL,
+ "%s: can't insert new LCB into ledger list",
+ __func__);
XFREE(MTYPE_BGP_LABEL_CB, lcb);
return;
}
struct lp_fifo *lf;
if (last < first) {
- flog_err(BGP_ERR_LABEL,
- "%s: zebra label chunk invalid: first=%u, last=%u",
- __func__, first, last);
+ flog_err(EC_BGP_LABEL,
+ "%s: zebra label chunk invalid: first=%u, last=%u",
+ __func__, first, last);
return;
}
int chunks_needed;
void *labelid;
struct lp_lcb *lcb;
+ int lm_init_ok;
/*
* Get label chunk allocation request dispatched to zebra
chunks_needed = (labels_needed / LP_CHUNK_SIZE) + 1;
labels_needed = chunks_needed * LP_CHUNK_SIZE;
+ lm_init_ok = lm_label_manager_connect(zclient, 1) == 0;
+
+ if (!lm_init_ok)
+ zlog_err("%s: label manager connection error", __func__);
+
zclient_send_get_label_chunk(zclient, 0, labels_needed);
lp->pending_count = labels_needed;
{"no_kernel", no_argument, NULL, 'n'},
{"skip_runas", no_argument, NULL, 'S'},
{"ecmp", required_argument, NULL, 'e'},
+ {"int_num", required_argument, NULL, 'I'},
{0}};
/* signal definitions */
char *bgp_address = NULL;
int no_fib_flag = 0;
int skip_runas = 0;
+ int instance = 0;
frr_preinit(&bgpd_di, argc, argv);
frr_opt_add(
- "p:l:Sne:" DEPRECATED_OPTIONS, longopts,
+ "p:l:Sne:I:" DEPRECATED_OPTIONS, longopts,
" -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
" -l, --listenon Listen on specified address (implies -n)\n"
" -n, --no_kernel Do not install route to kernel.\n"
" -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
- " -e, --ecmp Specify ECMP to use.\n");
+ " -e, --ecmp Specify ECMP to use.\n"
+ " -I, --int_num Set instance number (label-manager)\n");
/* Command line argument treatment. */
while (1) {
if (multipath_num > MULTIPATH_NUM
|| multipath_num <= 0) {
flog_err(
- BGP_ERR_MULTIPATH,
+ EC_BGP_MULTIPATH,
"Multipath Number specified must be less than %d and greater than 0",
MULTIPATH_NUM);
return 1;
case 'S':
skip_runas = 1;
break;
+ case 'I':
+ instance = atoi(optarg);
+ if (instance > (unsigned short)-1)
+ zlog_err("Instance %i out of range (0..%u)",
+ instance, (unsigned short)-1);
+ break;
default:
frr_help_exit(1);
break;
bgp_vrf_init();
/* BGP related initialization. */
- bgp_init();
+ bgp_init((unsigned short)instance);
snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), ", bgp@%s:%d",
(bm->address ? bm->address : "<all>"), bm->port);
if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
peer->host, prefixlen);
return -1;
/* sanity check against packet data */
if ((pnt + psize) > lim) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
peer->host, prefixlen, (uint)(lim - pnt));
return -1;
/* sanity check against storage for the IP address portion */
if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
peer->host,
prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
/* Sanity check against max bitlen of the address family */
if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
peer->host,
prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
#endif
default:
- flog_err(BGP_ERR_UPDATE_RCV, "Unknown RD type %d",
- type);
+ flog_err(EC_BGP_UPDATE_RCV, "Unknown RD type %d", type);
break; /* just report */
}
/* Packet length consistency check. */
if (pnt != lim) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
peer->host, lim - pnt);
return -1;
return 0;
}
/* Shouldn't happen: different label allocation */
- flog_err(BGP_ERR_LABEL,
- "%s: %s had label %u but got new assignment %u",
- __func__, vp->bgp->name_pretty, vp->tovpn_label,
- label);
+ flog_err(EC_BGP_LABEL,
+ "%s: %s had label %u but got new assignment %u",
+ __func__, vp->bgp->name_pretty, vp->tovpn_label,
+ label);
/* use new one */
}
#include "filter.h"
#include "ns.h"
#include "lib_errors.h"
+#include "nexthop.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_open.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_errors.h"
#include "bgpd/bgp_network.h"
+#include "bgpd/bgp_zebra.h"
extern struct zebra_privs_t bgpd_privs;
#endif /* HAVE_TCP_MD5SIG */
if (ret < 0)
- zlog_warn("can't set TCP_MD5SIG option on socket %d: %s",
+ flog_warn(EC_BGP_NO_TCP_MD5,
+ "can't set TCP_MD5SIG option on socket %d: %s",
socket, safe_strerror(en));
return ret;
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl);
if (ret) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop(AF_INET, &peer->remote_id, buf,
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL);
if (ret) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop(AF_INET, &peer->remote_id, buf,
MAXTTL + 1 - peer->gtsm_hops);
if (ret) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
__func__,
inet_ntop(AF_INET, &peer->remote_id, buf,
rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
if (rc != 0) {
#if defined(HAVE_CUMULUS)
- flog_err(
- LIB_ERR_SOCKET,
- "[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
- safe_strerror(errno), sock);
+ flog_err(EC_LIB_SOCKET,
+ "[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
+ safe_strerror(errno), sock);
return -1;
#endif
}
/* Register accept thread. */
accept_sock = THREAD_FD(thread);
if (accept_sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "accept_sock is nevative value %d",
+ flog_err_sys(EC_LIB_SOCKET, "accept_sock is nevative value %d",
accept_sock);
return -1;
}
/* Accept client connection. */
bgp_sock = sockunion_accept(accept_sock, &su);
if (bgp_sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"[Error] BGP socket accept failed (%s)",
safe_strerror(errno));
return -1;
sockopt_reuseaddr(peer->fd);
sockopt_reuseport(peer->fd);
if (sockopt_mark_default(peer->fd, DATAPLANE_MARK, &bgpd_privs) < 0)
- zlog_warn("Unable to set mark on FD for peer %s, err=%s",
+ flog_warn(EC_BGP_NO_SOCKOPT_MARK,
+ "Unable to set mark on FD for peer %s, err=%s",
peer->host, safe_strerror(errno));
#ifdef IPTOS_PREC_INTERNETCONTROL
if (!peer->su_remote)
return -1;
- if (bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop,
- peer)) {
-#if defined(HAVE_CUMULUS)
- flog_err(
- BGP_ERR_NH_UPD,
- "%s: nexthop_set failed, resetting connection - intf %p",
- peer->host, peer->nexthop.ifp);
+ if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote,
+ &peer->nexthop, peer)) {
+ flog_err(EC_BGP_NH_UPD,
+ "%s: nexthop_set failed, resetting connection - intf %p",
+ peer->host, peer->nexthop.ifp);
return -1;
-#endif
}
return 0;
}
}
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "bind: %s", safe_strerror(en));
+ flog_err_sys(EC_LIB_SOCKET, "bind: %s", safe_strerror(en));
return ret;
}
ret = listen(sock, SOMAXCONN);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "listen: %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "listen: %s", safe_strerror(errno));
return ret;
}
bgp->vrf_id);
}
if (ret != 0) {
- flog_err_sys(LIB_ERR_SOCKET, "getaddrinfo: %s",
+ flog_err_sys(EC_LIB_SOCKET, "getaddrinfo: %s",
gai_strerror(ret));
return -1;
}
? bgp->name : NULL));
}
if (sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "socket: %s",
+ flog_err_sys(EC_LIB_SOCKET, "socket: %s",
safe_strerror(errno));
continue;
}
freeaddrinfo(ainfo_save);
if (count == 0 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%s: no usable addresses please check other programs usage of specified port %d",
__func__, port);
- flog_err_sys(LIB_ERR_SOCKET, "%s: Program cannot continue",
+ flog_err_sys(EC_LIB_SOCKET, "%s: Program cannot continue",
__func__);
exit(-1);
}
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
- for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
- if ((bnc = rn->info) != NULL) {
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ bnc = bgp_nexthop_get_node_info(rn);
+ if (bnc != NULL) {
bnc_free(bnc);
- rn->info = NULL;
+ bgp_nexthop_set_node_info(rn, NULL);
bgp_unlock_node(rn);
}
+ }
}
static void *bgp_tip_hash_alloc(void *p)
rn = bgp_node_get(bgp->connected_table[AFI_IP],
(struct prefix *)&p);
- if (rn->info) {
- bc = rn->info;
+ bc = bgp_connected_get_node_info(rn);
+ if (bc)
bc->refcnt++;
- } else {
+ else {
bc = XCALLOC(MTYPE_BGP_CONN,
sizeof(struct bgp_connected_ref));
bc->refcnt = 1;
- rn->info = bc;
+ bgp_connected_set_node_info(rn, bc);
}
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
rn = bgp_node_get(bgp->connected_table[AFI_IP6],
(struct prefix *)&p);
- if (rn->info) {
- bc = rn->info;
+
+ bc = bgp_connected_get_node_info(rn);
+ if (bc)
bc->refcnt++;
- } else {
+ else {
bc = XCALLOC(MTYPE_BGP_CONN,
sizeof(struct bgp_connected_ref));
bc->refcnt = 1;
- rn->info = bc;
+ bgp_connected_set_node_info(rn, bc);
}
}
}
if (!rn)
return;
- bc = rn->info;
+ bc = bgp_connected_get_node_info(rn);
bc->refcnt--;
if (bc->refcnt == 0) {
XFREE(MTYPE_BGP_CONN, bc);
- rn->info = NULL;
+ bgp_connected_set_node_info(rn, NULL);
}
bgp_unlock_node(rn);
bgp_unlock_node(rn);
struct route_node *rn)
{
struct bgp_connected_ref *bc;
+ struct bgp_node *bn = bgp_node_from_rnode(rn);
- bc = rn->info;
+ bc = bgp_connected_get_node_info(bn);
if (!bc)
return;
bc->refcnt--;
if (bc->refcnt == 0) {
XFREE(MTYPE_BGP_CONN, bc);
- rn->info = NULL;
+ bgp_connected_set_node_info(bn, NULL);
}
}
for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn;
rn = bgp_route_next(rn)) {
- if ((bnc = rn->info) != NULL) {
- if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) {
- vty_out(vty,
- " %s valid [IGP metric %d], #paths %d\n",
- inet_ntop(rn->p.family,
- &rn->p.u.prefix, buf,
- sizeof(buf)),
- bnc->metric, bnc->path_count);
-
- if (!detail)
- continue;
-
- bgp_show_nexthops_detail(vty, bgp, bnc);
-
- } else {
- vty_out(vty, " %s invalid\n",
- inet_ntop(rn->p.family,
- &rn->p.u.prefix, buf,
- sizeof(buf)));
- if (CHECK_FLAG(bnc->flags,
- BGP_NEXTHOP_CONNECTED))
- vty_out(vty,
- " Must be Connected\n");
+ bnc = bgp_nexthop_get_node_info(rn);
+ if (!bnc)
+ continue;
+
+ if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) {
+ vty_out(vty,
+ " %s valid [IGP metric %d], #paths %d\n",
+ inet_ntop(rn->p.family,
+ &rn->p.u.prefix, buf,
+ sizeof(buf)),
+ bnc->metric, bnc->path_count);
+
+ if (!detail)
+ continue;
+
+ bgp_show_nexthops_detail(vty, bgp, bnc);
+
+ } else {
+ vty_out(vty, " %s invalid\n",
+ inet_ntop(rn->p.family,
+ &rn->p.u.prefix, buf,
+ sizeof(buf)));
+ if (CHECK_FLAG(bnc->flags,
+ BGP_NEXTHOP_CONNECTED))
+ vty_out(vty, " Must be Connected\n");
}
- tbuf = time(NULL)
- - (bgp_clock() - bnc->last_update);
- vty_out(vty, " Last update: %s", ctime(&tbuf));
- vty_out(vty, "\n");
- }
+ tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
+ vty_out(vty, " Last update: %s", ctime(&tbuf));
+ vty_out(vty, "\n");
}
}
}
}
unregister_zebra_rnh(bnc,
CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
- bnc->node->info = NULL;
+ bgp_nexthop_set_node_info(bnc->node, NULL);
bgp_unlock_node(bnc->node);
bnc->node = NULL;
bnc_free(bnc);
rn = bgp_node_get(peer->bgp->nexthop_cache_table[afi], &p);
- if (!rn->info)
+ bnc = bgp_nexthop_get_node_info(rn);
+ if (!bnc)
return;
- bnc = rn->info;
-
/* cleanup the peer reference */
bnc->nht_info = NULL;
else
rn = bgp_node_get(bgp_nexthop->nexthop_cache_table[afi], &p);
- if (!rn->info) {
+ bnc = bgp_nexthop_get_node_info(rn);
+ if (!bnc) {
bnc = bnc_new();
- rn->info = bnc;
+ bgp_nexthop_set_node_info(rn, bnc);
bnc->node = rn;
bnc->bgp = bgp_nexthop;
bgp_lock_node(rn);
}
}
- bnc = rn->info;
bgp_unlock_node(rn);
if (is_bgp_static_route) {
SET_FLAG(bnc->flags, BGP_STATIC_ROUTE);
rn = bgp_node_lookup(
peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
- if (!rn || !rn->info) {
+ if (!rn) {
if (BGP_DEBUG(nht, NHT))
zlog_debug("Cannot find connected NHT node for peer %s",
peer->host);
- if (rn)
- bgp_unlock_node(rn);
return;
}
- bnc = rn->info;
+ bnc = bgp_nexthop_get_node_info(rn);
+ if (!bnc) {
+ if (BGP_DEBUG(nht, NHT))
+ zlog_debug("Cannot find connected NHT node for peer %s on route_node as expected",
+ peer->host);
+ bgp_unlock_node(rn);
+ return;
+ }
bgp_unlock_node(rn);
if (bnc->nht_info != peer) {
zlog_debug("Freeing connected NHT node %p for peer %s",
bnc, peer->host);
unregister_zebra_rnh(bnc, 0);
- bnc->node->info = NULL;
+ bgp_nexthop_set_node_info(bnc->node, NULL);
bgp_unlock_node(bnc->node);
bnc_free(bnc);
}
bgp = bgp_lookup_by_vrf_id(vrf_id);
if (!bgp) {
flog_err(
- BGP_ERR_NH_UPD,
+ EC_BGP_NH_UPD,
"parse nexthop update: instance not found for vrf_id %u",
vrf_id);
return;
bgp->import_check_table[family2afi(nhr.prefix.family)],
&nhr.prefix);
- if (!rn || !rn->info) {
+ if (!rn) {
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&nhr.prefix, buf, sizeof(buf));
zlog_debug("parse nexthop update(%s): rn not found",
buf);
}
- if (rn)
- bgp_unlock_node(rn);
return;
}
- bnc = rn->info;
+ bnc = bgp_nexthop_get_node_info(rn);
+ if (!bnc) {
+ if (BGP_DEBUG(nht, NHT)) {
+ char buf[PREFIX2STR_BUFFER];
+
+ prefix2str(&nhr.prefix, buf, sizeof(buf));
+ zlog_debug("parse nexthop update(%s): bnc node info not found",
+ buf);
+ }
+ bgp_unlock_node(rn);
+ return;
+ }
+
bgp_unlock_node(rn);
bnc->last_update = bgp_clock();
bnc->change_flags = 0;
for (rn = bgp_table_top(bgp->nexthop_cache_table[afi]); rn;
rn = bgp_route_next(rn)) {
- bnc = rn->info;
+ bnc = bgp_nexthop_get_node_info(rn);
if (!bnc)
continue;
bnc->bgp->vrf_id);
/* TBD: handle the failure */
if (ret < 0)
- zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
+ flog_warn(EC_BGP_ZEBRA_SEND,
+ "sendmsg_nexthop: zclient_send_message() failed");
if ((command == ZEBRA_NEXTHOP_REGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_REGISTER))
/* Verify length is 4 */
if (hdr->length != 4) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_LENGTH,
"MP Cap: Received invalid length %d, non-multiple of 4",
hdr->length);
return -1;
/* Verify length is a multiple of 4 */
if ((caphdr->length - 2) % 4) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_LENGTH,
"Restart Cap: Received invalid length %d, non-multiple of 4",
caphdr->length);
return -1;
SET_FLAG(peer->cap, PEER_CAP_AS4_RCV);
if (hdr->length != CAPABILITY_CODE_AS4_LEN) {
- flog_err(BGP_ERR_PKT_OPEN,
- "%s AS4 capability has incorrect data length %d",
- peer->host, hdr->length);
+ flog_err(EC_BGP_PKT_OPEN,
+ "%s AS4 capability has incorrect data length %d",
+ peer->host, hdr->length);
return 0;
}
/* Verify length is a multiple of 4 */
if (hdr->length % 4) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_LENGTH,
"Add Path: Received invalid length %d, non-multiple of 4",
hdr->length);
return -1;
/* Verify length is a multiple of 4 */
if (hdr->length % 6) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_LENGTH,
"Extended NH: Received invalid length %d, non-multiple of 6",
hdr->length);
return -1;
if (afi != AFI_IP || nh_afi != AFI_IP6
|| !(safi == SAFI_UNICAST
|| safi == SAFI_LABELED_UNICAST)) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_DATA,
"%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
"in Extended Next-hop capability, ignoring",
peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
len = stream_getc(s);
if (stream_get_getp(s) + len > end) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_DATA,
"%s: Received malformed hostname capability from peer %s",
__FUNCTION__, peer->host);
return -1;
}
if (stream_get_getp(s) + 1 > end) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_DATA,
"%s: Received invalid domain name len (hostname capability) from peer %s",
__FUNCTION__, peer->host);
return -1;
len = stream_getc(s);
if (stream_get_getp(s) + len > end) {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_DATA,
"%s: Received runt domain name (hostname capability) from peer %s",
__FUNCTION__, peer->host);
return -1;
specific
capabilities. It seems reasonable for now...
*/
- zlog_warn("%s Vendor specific capability %d",
+ flog_warn(EC_BGP_CAPABILITY_VENDOR,
+ "%s Vendor specific capability %d",
peer->host, caphdr.code);
} else {
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_UNKNOWN,
"%s unrecognized capability code: %d - ignored",
peer->host, caphdr.code);
memcpy(*error, sp, caphdr.length + 2);
}
if (stream_get_getp(s) != (start + caphdr.length)) {
if (stream_get_getp(s) > (start + caphdr.length))
- zlog_warn(
+ flog_warn(
+ EC_BGP_CAPABILITY_INVALID_LENGTH,
"%s Cap-parser for %s read past cap-length, %u!",
peer->host,
lookup_msg(capcode_str, caphdr.code,
&& !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
&& !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
&& !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
- flog_err(BGP_ERR_PKT_OPEN,
- "%s [Error] Configured AFI/SAFIs do not "
- "overlap with received MP capabilities",
- peer->host);
+ flog_err(EC_BGP_PKT_OPEN,
+ "%s [Error] Configured AFI/SAFIs do not "
+ "overlap with received MP capabilities",
+ peer->host);
if (error != error_data)
bgp_notify_send_with_data(
/* Just in case we have a silly peer who sends AS4 capability set to 0
*/
if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) && !as4) {
- flog_err(BGP_ERR_PKT_OPEN,
- "%s bad OPEN, got AS4 capability, but AS4 set to 0",
- peer->host);
+ flog_err(EC_BGP_PKT_OPEN,
+ "%s bad OPEN, got AS4 capability, but AS4 set to 0",
+ peer->host);
bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_BAD_PEER_AS,
notify_data_remote_as4, 4);
*/
if (as4 == BGP_AS_TRANS) {
flog_err(
- BGP_ERR_PKT_OPEN,
+ EC_BGP_PKT_OPEN,
"%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
peer->host);
bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
&& as4 != remote_as) {
/* raise error, log this, close session */
flog_err(
- BGP_ERR_PKT_OPEN,
+ EC_BGP_PKT_OPEN,
"%s bad OPEN, got AS4 capability, but remote_as %u"
" mismatch with 16bit 'myasn' %u in open",
peer->host, as4, remote_as);
/* Get sockname. */
if ((ret = bgp_getsockname(peer)) < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: bgp_getsockname() failed for peer: %s",
__FUNCTION__, peer->host);
return BGP_Stop;
if (!peer->nexthop.v4.s_addr) {
#if defined(HAVE_CUMULUS)
flog_err(
- BGP_ERR_SND_FAIL,
+ EC_BGP_SND_FAIL,
"%s: No local IPv4 addr resetting connection, fd %d",
peer->host, peer->fd);
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) {
#if defined(HAVE_CUMULUS)
flog_err(
- BGP_ERR_SND_FAIL,
+ EC_BGP_SND_FAIL,
"%s: No local IPv6 addr resetting connection, fd %d",
peer->host, peer->fd);
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
/* Status must be Established. */
if (peer->status != Established) {
- flog_err(BGP_ERR_INVALID_STATUS,
- "%s [FSM] Update packet received under status %s",
- peer->host,
- lookup_msg(bgp_status_msg, peer->status, NULL));
+ flog_err(EC_BGP_INVALID_STATUS,
+ "%s [FSM] Update packet received under status %s",
+ peer->host,
+ lookup_msg(bgp_status_msg, peer->status, NULL));
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
return BGP_Stop;
}
Attribute Length + 23 exceeds the message Length), then the Error
Subcode is set to Malformed Attribute List. */
if (stream_pnt(s) + 2 > end) {
- flog_err(BGP_ERR_UPDATE_RCV,
- "%s [Error] Update packet error"
- " (packet length is short for unfeasible length)",
- peer->host);
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%s [Error] Update packet error"
+ " (packet length is short for unfeasible length)",
+ peer->host);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_ATTR);
return BGP_Stop;
/* Unfeasible Route Length check. */
if (stream_pnt(s) + withdraw_len > end) {
- flog_err(BGP_ERR_UPDATE_RCV,
- "%s [Error] Update packet error"
- " (packet unfeasible length overflow %d)",
- peer->host, withdraw_len);
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%s [Error] Update packet error"
+ " (packet unfeasible length overflow %d)",
+ peer->host, withdraw_len);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_ATTR);
return BGP_Stop;
/* Attribute total length check. */
if (stream_pnt(s) + 2 > end) {
- zlog_warn(
- "%s [Error] Packet Error"
- " (update packet is short for attribute length)",
+ flog_warn(
+ EC_BGP_UPDATE_PACKET_SHORT,
+ "%s [Error] Packet Error (update packet is short for attribute length)",
peer->host);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_ATTR);
/* Attribute length check. */
if (stream_pnt(s) + attribute_len > end) {
- zlog_warn(
- "%s [Error] Packet Error"
- " (update packet attribute length overflow %d)",
+ flog_warn(
+ EC_BGP_UPDATE_PACKET_LONG,
+ "%s [Error] Packet Error (update packet attribute length overflow %d)",
peer->host, attribute_len);
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_MAL_ATTR);
if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
peer->host);
}
if (nlri_ret < 0) {
- flog_err(BGP_ERR_UPDATE_RCV,
- "%s [Error] Error parsing NLRI", peer->host);
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%s [Error] Error parsing NLRI", peer->host);
if (peer->status == Established)
bgp_notify_send(
peer, BGP_NOTIFY_UPDATE_ERR,
/* If peer does not have the capability, send notification. */
if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)) {
- flog_err(BGP_ERR_NO_CAP,
- "%s [Error] BGP route refresh is not enabled",
- peer->host);
+ flog_err(EC_BGP_NO_CAP,
+ "%s [Error] BGP route refresh is not enabled",
+ peer->host);
bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
BGP_NOTIFY_HEADER_BAD_MESTYPE);
return BGP_Stop;
/* Status must be Established. */
if (peer->status != Established) {
flog_err(
- BGP_ERR_INVALID_STATUS,
+ EC_BGP_INVALID_STATUS,
"%s [Error] Route refresh packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
return BGP_Stop;
}
} else {
- zlog_warn(
+ flog_warn(
+ EC_BGP_UNRECOGNIZED_CAPABILITY,
"%s unrecognized capability code: %d - ignored",
peer->host, hdr->code);
}
/* If peer does not have the capability, send notification. */
if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) {
- flog_err(BGP_ERR_NO_CAP,
- "%s [Error] BGP dynamic capability is not enabled",
- peer->host);
+ flog_err(EC_BGP_NO_CAP,
+ "%s [Error] BGP dynamic capability is not enabled",
+ peer->host);
bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
BGP_NOTIFY_HEADER_BAD_MESTYPE);
return BGP_Stop;
/* Status must be Established. */
if (peer->status != Established) {
flog_err(
- BGP_ERR_NO_CAP,
+ EC_BGP_NO_CAP,
"%s [Error] Dynamic capability packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
mprc = bgp_open_receive(peer, size);
if (mprc == BGP_Stop)
flog_err(
- BGP_ERR_PKT_OPEN,
+ EC_BGP_PKT_OPEN,
"%s: BGP OPEN receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
mprc = bgp_update_receive(peer, size);
if (mprc == BGP_Stop)
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s: BGP UPDATE receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
mprc = bgp_notify_receive(peer, size);
if (mprc == BGP_Stop)
flog_err(
- BGP_ERR_NOTIFY_RCV,
+ EC_BGP_NOTIFY_RCV,
"%s: BGP NOTIFY receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
mprc = bgp_keepalive_receive(peer, size);
if (mprc == BGP_Stop)
flog_err(
- BGP_ERR_KEEP_RCV,
+ EC_BGP_KEEP_RCV,
"%s: BGP KEEPALIVE receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
mprc = bgp_route_refresh_receive(peer, size);
if (mprc == BGP_Stop)
flog_err(
- BGP_ERR_RFSH_RCV,
+ EC_BGP_RFSH_RCV,
"%s: BGP ROUTEREFRESH receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
mprc = bgp_capability_receive(peer, size);
if (mprc == BGP_Stop)
flog_err(
- BGP_ERR_CAP_RCV,
+ EC_BGP_CAP_RCV,
"%s: BGP CAPABILITY receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
action_count++;
if (action_count > ACTIONS_MAX_NUM) {
if (BGP_DEBUG(pbr, PBR_ERROR))
- flog_err(BGP_ERR_FLOWSPEC_PACKET,
- "%s: flowspec actions exceeds limit (max %u)",
- __func__, action_count);
+ flog_err(
+ EC_BGP_FLOWSPEC_PACKET,
+ "%s: flowspec actions exceeds limit (max %u)",
+ __func__, action_count);
break;
}
api_action = &api->actions[action_count - 1];
}
/* ipset create */
- if (bpm && !bpm->installed)
+ if (!bpm->installed)
bgp_send_pbr_ipset_match(bpm, true);
/* ipset add */
- if (bpme && !bpme->installed)
+ if (!bpme->installed)
bgp_send_pbr_ipset_entry_match(bpme, true);
/* iptables */
- if (bpm && !bpm->installed_in_iptable)
+ if (!bpm->installed_in_iptable)
bgp_send_pbr_iptable(bpa, bpm, true);
/* A previous entry may already exist
if (!bgp_zebra_tm_chunk_obtained()) {
if (BGP_DEBUG(pbr, PBR_ERROR))
- flog_err(BGP_ERR_TABLE_CHUNK,
- "%s: table chunk not obtained yet",
- __func__);
+ flog_err(EC_BGP_TABLE_CHUNK,
+ "%s: table chunk not obtained yet", __func__);
return;
}
if (bgp_pbr_build_and_validate_entry(p, info, &api) < 0) {
if (BGP_DEBUG(pbr, PBR_ERROR))
- flog_err(BGP_ERR_FLOWSPEC_INSTALLATION,
- "%s: cancel updating entry %p in bgp pbr",
- __func__, info);
+ flog_err(EC_BGP_FLOWSPEC_INSTALLATION,
+ "%s: cancel updating entry %p in bgp pbr",
+ __func__, info);
return;
}
bgp_pbr_handle_entry(bgp, info, &api, nlri_update);
if (ri->peer->pcount[table->afi][table->safi])
ri->peer->pcount[table->afi][table->safi]--;
else
- flog_err(LIB_ERR_DEVELOPMENT,
+ flog_err(EC_LIB_DEVELOPMENT,
"Asked to decrement 0 prefix count for peer");
} else if (BGP_INFO_COUNTABLE(ri)
&& !CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
rn = bgp_route_next(rn)) {
struct bgp_node *rm;
- struct bgp_info *ri;
/* look for neighbor in tables */
if ((table = rn->info) == NULL)
/* Prefix length check. */
if (p.prefixlen > prefix_blen(&p) * 8) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error (wrong prefix length %d for afi %u)",
peer->host, p.prefixlen, packet->afi);
return -1;
/* When packet overflow occur return immediately. */
if (pnt + psize > lim) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error (prefix length %d overflows packet)",
peer->host, p.prefixlen);
return -1;
* prefix */
if (psize > (ssize_t)sizeof(p.u)) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
peer->host, p.prefixlen, sizeof(p.u));
return -1;
* ignored.
*/
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s: IPv4 unicast NLRI is multicast address %s, ignoring",
peer->host, inet_ntoa(p.u.prefix4));
continue;
char buf[BUFSIZ];
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s: IPv6 unicast NLRI is link-local address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
char buf[BUFSIZ];
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s: IPv6 unicast NLRI is multicast address %s, ignoring",
peer->host,
inet_ntop(AF_INET6, &p.u.prefix6, buf,
/* Packet length consistency check. */
if (pnt != lim) {
flog_err(
- BGP_ERR_UPDATE_RCV,
+ EC_BGP_UPDATE_RCV,
"%s [Error] Update packet error (prefix length mismatch with total length)",
peer->host);
return -1;
break;
if (ri) {
- union gw_addr add;
memset(&add, 0, sizeof(union gw_addr));
if (attrhash_cmp(ri->attr, attr_new)
&& overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add)
return CMD_WARNING_CONFIG_FAILED;
}
- bgp_static = rn->info;
+ bgp_static = bgp_static_get_node_info(rn);
if ((label_index != BGP_INVALID_LABEL_INDEX)
&& (label_index != bgp_static->label_index)) {
/* Clear configuration. */
bgp_static_free(bgp_static);
- rn->info = NULL;
+ bgp_static_set_node_info(rn, NULL);
bgp_unlock_node(rn);
bgp_unlock_node(rn);
} else {
/* Set BGP static route configuration. */
rn = bgp_node_get(bgp->route[afi][safi], &p);
- if (rn->info) {
+ bgp_static = bgp_static_get_node_info(rn);
+ if (bgp_static) {
/* Configuration change. */
- bgp_static = rn->info;
-
/* Label index cannot be changed. */
if (bgp_static->label_index != label_index) {
vty_out(vty, "%% cannot change label-index\n");
bgp_static->rmap.map =
route_map_lookup_by_name(rmap);
}
- rn->info = bgp_static;
+ bgp_static_set_node_info(rn, bgp_static);
}
bgp_static->valid = 1;
for (rm = bgp_table_top(table); rm;
rm = bgp_route_next(rm)) {
- bgp_static = rm->info;
+ bgp_static =
+ bgp_static_get_node_info(rm);
bgp_static_update_safi(bgp, &rm->p,
bgp_static, afi,
safi);
}
} else {
- bgp_static_update(bgp, &rn->p, rn->info, afi,
- safi);
+ bgp_static_update(bgp, &rn->p,
+ bgp_static_get_node_info(rn),
+ afi, safi);
}
}
}
for (rm = bgp_table_top(table); rm;
rm = bgp_route_next(rm)) {
- bgp_static = rm->info;
+ bgp_static =
+ bgp_static_get_node_info(rm);
bgp_static_withdraw_safi(
bgp, &rm->p, AFI_IP, safi,
(struct prefix_rd *)&rn->p);
bgp_static_free(bgp_static);
- rn->info = NULL;
+ bgp_static_set_node_info(rn, NULL);
bgp_unlock_node(rn);
}
} else {
- bgp_static = rn->info;
+ bgp_static = bgp_static_get_node_info(rn);
bgp_static_withdraw(bgp, &rn->p, afi, safi);
bgp_static_free(bgp_static);
- rn->info = NULL;
+ bgp_static_set_node_info(rn, NULL);
bgp_unlock_node(rn);
}
}
for (rm = bgp_table_top(table); rm;
rm = bgp_route_next(rm)) {
- bgp_static = rm->info;
+ bgp_static =
+ bgp_static_get_node_info(rm);
bgp_static_update_safi(bgp, &rm->p,
bgp_static, afi,
safi);
}
} else {
- bgp_static = rn->info;
+ bgp_static = bgp_static_get_node_info(rn);
bgp_static_update(bgp, &rn->p, bgp_static, afi,
safi);
}
if (gwip)
prefix_copy(&bgp_static->gatewayIp, &gw_ip);
}
- rn->info = bgp_static;
+ bgp_static_set_node_info(rn, bgp_static);
bgp_static->valid = 1;
bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
if (rn) {
bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
- bgp_static = rn->info;
+ bgp_static = bgp_static_get_node_info(rn);
bgp_static_free(bgp_static);
- rn->info = NULL;
+ bgp_static_set_node_info(rn, NULL);
bgp_unlock_node(rn);
bgp_unlock_node(rn);
} else
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;
if (!ri)
return 0;
+ if (origin != ri->attr->origin)
+ return 0;
+
if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae))
return 0;
* 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)
child = bgp_node_get(table, p);
/* Aggregate address configuration check. */
- for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
- if ((aggregate = rn->info) != NULL
- && rn->p.prefixlen < p->prefixlen) {
+ for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
+ aggregate = bgp_aggregate_get_node_info(rn);
+ if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
bgp_aggregate_route(bgp, &rn->p, ri, afi, safi, NULL,
aggregate);
}
+ }
bgp_unlock_node(child);
}
child = bgp_node_get(table, p);
/* Aggregate address configuration check. */
- for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
- if ((aggregate = rn->info) != NULL
- && rn->p.prefixlen < p->prefixlen) {
+ for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
+ aggregate = bgp_aggregate_get_node_info(rn);
+ if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
aggregate);
}
+ }
bgp_unlock_node(child);
}
return CMD_WARNING_CONFIG_FAILED;
}
- aggregate = rn->info;
+ aggregate = bgp_aggregate_get_node_info(rn);
bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, 0, aggregate);
/* Unlock aggregate address configuration. */
- rn->info = NULL;
+ bgp_aggregate_set_node_info(rn, NULL);
bgp_aggregate_free(aggregate);
bgp_unlock_node(rn);
bgp_unlock_node(rn);
aggregate->summary_only = summary_only;
aggregate->as_set = as_set;
aggregate->safi = safi;
- rn->info = aggregate;
+ bgp_aggregate_set_node_info(rn, aggregate);
/* Aggregate address insert into BGP routing table. */
bgp_aggregate_route(bgp, &p, NULL, afi, safi, NULL, aggregate);
continue;
}
if (type == bgp_show_type_prefix_longer) {
- struct prefix *p = output_arg;
-
+ p = output_arg;
if (!prefix_match(p, &rn->p))
continue;
}
if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
pc->count[PCOUNT_COUNTED]++;
if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
- flog_err(LIB_ERR_DEVELOPMENT,
- "Attempting to count but flags say it is unusable");
+ flog_err(
+ EC_LIB_DEVELOPMENT,
+ "Attempting to count but flags say it is unusable");
} else {
if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
- flog_err(LIB_ERR_DEVELOPMENT,
- "Not counted but flags say we should");
+ flog_err(
+ EC_LIB_DEVELOPMENT,
+ "Not counted but flags say we should");
}
}
}
/* Get BGP distance node. */
rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
- if (rn->info) {
- bdistance = rn->info;
+ bdistance = bgp_distance_get_node(rn);
+ if (bdistance)
bgp_unlock_node(rn);
- } else {
+ else {
bdistance = bgp_distance_new();
- rn->info = bdistance;
+ bgp_distance_set_node_info(rn, bdistance);
}
/* Set distance value. */
return CMD_WARNING_CONFIG_FAILED;
}
- bdistance = rn->info;
+ bdistance = bgp_distance_get_node(rn);
distance = atoi(distance_str);
if (bdistance->distance != distance) {
sockunion2hostprefix(&peer->su, &q);
rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
if (rn) {
- bdistance = rn->info;
+ bdistance = bgp_distance_get_node(rn);
bgp_unlock_node(rn);
if (bdistance->access_list) {
/* Backdoor check. */
rn = bgp_node_lookup(bgp->route[afi][safi], p);
if (rn) {
- bgp_static = rn->info;
+ bgp_static = bgp_static_get_node_info(rn);
bgp_unlock_node(rn);
if (bgp_static->backdoor) {
continue;
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
- if ((bgp_static = rn->info) == NULL)
+ bgp_static = bgp_static_get_node_info(rn);
+ if (bgp_static == NULL)
continue;
p = &rn->p;
continue;
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
- if ((bgp_static = rn->info) == NULL)
+ bgp_static = bgp_static_get_node_info(rn);
+ if (bgp_static == NULL)
continue;
char *macrouter = NULL;
/* Network configuration. */
for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
rn = bgp_route_next(rn)) {
- if ((bgp_static = rn->info) == NULL)
+ bgp_static = bgp_static_get_node_info(rn);
+ if (bgp_static == NULL)
continue;
p = &rn->p;
/* Aggregate-address configuration. */
for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
rn = bgp_route_next(rn)) {
- if ((bgp_aggregate = rn->info) == NULL)
+ bgp_aggregate = bgp_aggregate_get_node_info(rn);
+ if (bgp_aggregate == NULL)
continue;
p = &rn->p;
}
for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
- rn = bgp_route_next(rn))
- if ((bdistance = rn->info) != NULL) {
+ rn = bgp_route_next(rn)) {
+ bdistance = bgp_distance_get_node(rn);
+ if (bdistance != NULL) {
char buf[PREFIX_STRLEN];
vty_out(vty, " distance %d %s %s\n",
bdistance->access_list ? bdistance->access_list
: "");
}
+ }
}
/* Allocate routing table structure and install commands. */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
struct list *red_list;
- struct listnode *node;
struct bgp_redist *red;
red_list = bgp->redist[afi][i];
#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"
#if defined(FOUND_SSH)
#include "rtrlib/transport/ssh/ssh_transport.h"
#endif
+#endif
#include "hook.h"
#include "libfrr.h"
#include "version.h"
void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p,
uint8_t maxlen, struct list *matches);
+
+static inline struct bgp_aggregate *
+bgp_aggregate_get_node_info(struct bgp_node *node)
+{
+ return node->info;
+}
+
+static inline void bgp_aggregate_set_node_info(struct bgp_node *node,
+ struct bgp_aggregate *aggregate)
+{
+ node->info = aggregate;
+}
+
+static inline struct bgp_distance *bgp_distance_get_node(struct bgp_node *node)
+{
+ return node->info;
+}
+
+static inline void bgp_distance_set_node_info(struct bgp_node *node,
+ struct bgp_distance *distance)
+{
+ node->info = distance;
+}
+
+static inline struct bgp_static *bgp_static_get_node_info(struct bgp_node *node)
+{
+ return node->info;
+}
+
+static inline void bgp_static_set_node_info(struct bgp_node *node,
+ struct bgp_static *bgp_static)
+{
+ node->info = bgp_static;
+}
+
+static inline struct bgp_connected_ref *
+bgp_connected_get_node_info(struct bgp_node *node)
+{
+ return node->info;
+}
+
+static inline void bgp_connected_set_node_info(struct bgp_node *node,
+ struct bgp_connected_ref *bc)
+{
+ node->info = bc;
+}
+
+static inline struct bgp_nexthop_cache *
+bgp_nexthop_get_node_info(struct bgp_node *node)
+{
+ return node->info;
+}
+
+static inline void bgp_nexthop_set_node_info(struct bgp_node *node,
+ struct bgp_nexthop_cache *bnc)
+{
+ node->info = bnc;
+}
+
#endif /* _QUAGGA_BGP_TABLE_H */
if (!updgrp) {
updgrp = update_group_create(paf);
if (!updgrp) {
- flog_err(BGP_ERR_UPDGRP_CREATE,
- "couldn't create update group for peer %s",
- paf->peer->host);
+ flog_err(EC_BGP_UPDGRP_CREATE,
+ "couldn't create update group for peer %s",
+ paf->peer->host);
return;
}
}
break;
default:
/* TODO: handle IPv6 nexthops */
- zlog_warn(
+ flog_warn(
+ EC_BGP_INVALID_NEXTHOP_LENGTH,
"%s: %s: invalid MP nexthop length (AFI IP): %u",
__func__, peer->host, nhlen);
stream_free(s);
break;
default:
/* TODO: handle IPv4 nexthops */
- zlog_warn(
+ flog_warn(
+ EC_BGP_INVALID_NEXTHOP_LENGTH,
"%s: %s: invalid MP nexthop length (AFI IP6): %u",
__func__, peer->host, nhlen);
stream_free(s);
* return */
if (space_remaining < space_needed) {
flog_err(
- BGP_ERR_UPDGRP_ATTR_LEN,
+ EC_BGP_UPDGRP_ATTR_LEN,
"u%" PRIu64 ":s%" PRIu64
" attributes too long, cannot send UPDATE",
subgrp->update_group->id, subgrp->id);
for (ALL_LIST_ELEMENTS_RO(inst, node, bgp)) {
const char *name, *type;
struct peer *peer;
- struct listnode *node, *nnode;
+ struct listnode *node2, *nnode2;
int peers_cfg, peers_estb;
json_object *json_vrf = NULL;
json_vrf = json_object_new_object();
- for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+ for (ALL_LIST_ELEMENTS(bgp->peer, node2, nnode2, peer)) {
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue;
peers_cfg++;
if (use_json) {
if (!(json = json_object_new_object())) {
flog_err(
- BGP_ERR_JSON_MEM_ERROR,
+ EC_BGP_JSON_MEM_ERROR,
"Unable to allocate memory for JSON object");
vty_out(vty,
"{\"error\": {\"message:\": \"Unable to allocate memory for JSON object\"}}}\n");
struct nbr_connected *nc;
struct listnode *node, *nnode;
struct bgp *bgp;
+ struct peer *peer;
bgp = bgp_lookup_by_vrf_id(vrf_id);
if (!bgp)
bgp_nbr_connected_delete(bgp, nc, 1);
/* Fast external-failover */
- {
- struct peer *peer;
-
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
- return 0;
+ if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
#if defined(HAVE_CUMULUS)
struct nbr_connected *nc;
struct listnode *node, *nnode;
struct bgp *bgp;
+ struct peer *peer;
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
&new_vrf_id);
bgp_nbr_connected_delete(bgp, nc, 1);
/* Fast external-failover */
- {
- struct peer *peer;
-
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
- return 0;
-
+ if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
continue;
return 0;
}
-int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
- struct bgp_nexthop *nexthop, struct peer *peer)
+
+bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
+ struct bgp_nexthop *nexthop, struct peer *peer)
{
int ret = 0;
struct interface *ifp = NULL;
memset(nexthop, 0, sizeof(struct bgp_nexthop));
if (!local)
- return -1;
+ return false;
if (!remote)
- return -1;
+ return false;
if (local->sa.sa_family == AF_INET) {
nexthop->v4 = local->sin.sin_addr;
peer->bgp->vrf_id);
}
- if (!ifp)
- return -1;
+ if (!ifp) {
+ /*
+ * BGP views do not currently get proper data
+ * from zebra( when attached ) to be able to
+ * properly resolve nexthops, so give this
+ * instance type a pass.
+ */
+ if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
+ return true;
+ /*
+ * If we have no interface data but we have established
+ * some connection w/ zebra than something has gone
+ * terribly terribly wrong here, so say this failed
+ * If we do not any zebra connection then not
+ * having a ifp pointer is ok.
+ */
+ return zclient_num_connects ? false : true;
+ }
nexthop->ifp = ifp;
/* If we have identified the local interface, there is no error for now.
*/
- return 0;
+ return true;
}
static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
return -1;
ret = tm_get_table_chunk(zclient, chunk_size, start, end);
if (ret < 0) {
- flog_err(BGP_ERR_TABLE_CHUNK,
- "BGP: Error getting table chunk %u", chunk_size);
+ flog_err(EC_BGP_TABLE_CHUNK,
+ "BGP: Error getting table chunk %u", chunk_size);
return -1;
}
zlog_info("BGP: Table Manager returns range from chunk %u is [%u %u]",
ipa_len = stream_getl(s);
if (ipa_len != 0 && ipa_len != IPV4_MAX_BYTELEN
&& ipa_len != IPV6_MAX_BYTELEN) {
- flog_err(BGP_ERR_MACIP_LEN,
- "%u:Recv MACIP %s with invalid IP addr length %d",
- vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
- ipa_len);
+ flog_err(EC_BGP_MACIP_LEN,
+ "%u:Recv MACIP %s with invalid IP addr length %d",
+ vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
+ ipa_len);
return -1;
}
STREAM_GETL(s, last);
if (zclient->redist_default != proto) {
- flog_err(BGP_ERR_LM_ERROR, "Got LM msg with wrong proto %u",
- proto);
+ flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong proto %u",
+ proto);
return;
}
if (zclient->instance != instance) {
- flog_err(BGP_ERR_LM_ERROR, "Got LM msg with wrong instance %u",
- proto);
+ flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong instance %u",
+ proto);
return;
}
first < MPLS_LABEL_UNRESERVED_MIN ||
last > MPLS_LABEL_UNRESERVED_MAX) {
- flog_err(BGP_ERR_LM_ERROR, "%s: Invalid Label chunk: %u - %u",
- __func__, first, last);
+ flog_err(EC_BGP_LM_ERROR, "%s: Invalid Label chunk: %u - %u",
+ __func__, first, last);
return;
}
if (BGP_DEBUG(zebra, ZEBRA)) {
extern struct zebra_privs_t bgpd_privs;
-void bgp_zebra_init(struct thread_master *master)
+void bgp_zebra_init(struct thread_master *master, unsigned short instance)
{
zclient_num_connects = 0;
zclient->ipset_notify_owner = ipset_notify_owner;
zclient->ipset_entry_notify_owner = ipset_entry_notify_owner;
zclient->iptable_notify_owner = iptable_notify_owner;
+ zclient->instance = instance;
}
void bgp_zebra_destroy(void)
#include "vxlan.h"
-extern void bgp_zebra_init(struct thread_master *master);
+extern void bgp_zebra_init(struct thread_master *master,
+ unsigned short instance);
extern void bgp_zebra_init_tm_connect(struct bgp *bgp);
extern uint32_t bgp_zebra_tm_get_id(void);
extern bool bgp_zebra_tm_chunk_obtained(void);
extern int bgp_zebra_num_connects(void);
+extern bool bgp_zebra_nexthop_set(union sockunion *, union sockunion *,
+ struct bgp_nexthop *, struct peer *);
+
struct bgp_pbr_action;
struct bgp_pbr_match;
struct bgp_pbr_match_entry;
int active;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s",
- __func__, peer->host);
+ flog_err(EC_BGP_PEER_GROUP, "%s was called for peer-group %s",
+ __func__, peer->host);
return 1;
}
safi_t safi)
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s",
- __func__, peer->host);
+ flog_err(EC_BGP_PEER_GROUP, "%s was called for peer-group %s",
+ __func__, peer->host);
return 1;
}
peer->afc[afi][safi] = 0;
if (peer_af_delete(peer, afi, safi) != 0) {
- flog_err(BGP_ERR_PEER_DELETE,
- "couldn't delete af structure for peer %s",
- peer->host);
+ flog_err(EC_BGP_PEER_DELETE,
+ "couldn't delete af structure for peer %s",
+ peer->host);
return 1;
}
group = peer->group;
if (peer_af_delete(peer, afi, safi) != 0) {
- flog_err(BGP_ERR_PEER_DELETE,
- "couldn't delete af structure for peer %s",
- peer->host);
+ flog_err(EC_BGP_PEER_DELETE,
+ "couldn't delete af structure for peer %s",
+ peer->host);
}
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
}
if (CHECK_FLAG(bgp->af_flags[afi][safi],
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
- struct listnode *node;
char *name;
for (ALL_LIST_ELEMENTS_RO(
{.completions = NULL},
};
+struct frr_pthread *bgp_pth_io;
+struct frr_pthread *bgp_pth_ka;
+
static void bgp_pthreads_init()
{
+ assert(!bgp_pth_io);
+ assert(!bgp_pth_ka);
+
frr_pthread_init();
struct frr_pthread_attr io = {
- .id = PTHREAD_IO,
.start = frr_pthread_attr_default.start,
.stop = frr_pthread_attr_default.stop,
};
struct frr_pthread_attr ka = {
- .id = PTHREAD_KEEPALIVES,
.start = bgp_keepalives_start,
.stop = bgp_keepalives_stop,
};
- frr_pthread_new(&io, "BGP I/O thread", "bgpd_io");
- frr_pthread_new(&ka, "BGP Keepalives thread", "bgpd_ka");
+ bgp_pth_io = frr_pthread_new(&io, "BGP I/O thread", "bgpd_io");
+ bgp_pth_ka = frr_pthread_new(&ka, "BGP Keepalives thread", "bgpd_ka");
}
void bgp_pthreads_run()
{
- struct frr_pthread *io = frr_pthread_get(PTHREAD_IO);
- struct frr_pthread *ka = frr_pthread_get(PTHREAD_KEEPALIVES);
-
- frr_pthread_run(io, NULL);
- frr_pthread_run(ka, NULL);
+ frr_pthread_run(bgp_pth_io, NULL);
+ frr_pthread_run(bgp_pth_ka, NULL);
/* Wait until threads are ready. */
- frr_pthread_wait_running(io);
- frr_pthread_wait_running(ka);
+ frr_pthread_wait_running(bgp_pth_io);
+ frr_pthread_wait_running(bgp_pth_ka);
}
void bgp_pthreads_finish()
frr_pthread_finish();
}
-void bgp_init(void)
+void bgp_init(unsigned short instance)
{
/* allocates some vital data structures used by peer commands in
bgp_pthreads_init();
/* Init zebra. */
- bgp_zebra_init(bm->master);
+ bgp_zebra_init(bm->master, instance);
#if ENABLE_BGP_VNC
vnc_zebra_init(bm->master);
#include "qobj.h"
#include <pthread.h>
+#include "frr_pthread.h"
#include "lib/json.h"
#include "vrf.h"
#include "vty.h"
for (afi = AFI_IP; afi < AFI_MAX; afi++) \
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+extern struct frr_pthread *bgp_pth_io;
+extern struct frr_pthread *bgp_pth_ka;
+
/* BGP master for system wide configurations and variables. */
struct bgp_master {
/* BGP instance list. */
/* BGP thread master. */
struct thread_master *master;
-/* BGP pthreads. */
-#define PTHREAD_IO (1 << 1)
-#define PTHREAD_KEEPALIVES (1 << 2)
-
/* work queues */
struct work_queue *process_main_queue;
extern void bgp_reset(void);
extern time_t bgp_clock(void);
extern void bgp_zclient_reset(void);
-extern int bgp_nexthop_set(union sockunion *, union sockunion *,
- struct bgp_nexthop *, struct peer *);
extern struct bgp *bgp_get_default(void);
extern struct bgp *bgp_lookup(as_t, const char *);
extern struct bgp *bgp_lookup_by_name(const char *);
extern void bgp_master_init(struct thread_master *master);
-extern void bgp_init(void);
+extern void bgp_init(unsigned short instance);
extern void bgp_pthreads_run(void);
extern void bgp_pthreads_finish(void);
extern void bgp_route_map_init(void);
vty_out(vty, "!\n");
if (hc->l2_groups) {
- struct rfapi_l2_group_cfg *rfg = NULL;
+ struct rfapi_l2_group_cfg *rfgc = NULL;
struct listnode *gnode;
- for (ALL_LIST_ELEMENTS_RO(hc->l2_groups, gnode, rfg)) {
+ for (ALL_LIST_ELEMENTS_RO(hc->l2_groups, gnode, rfgc)) {
struct listnode *lnode;
void *data;
++write;
- vty_out(vty, " vnc l2-group %s\n", rfg->name);
- if (rfg->logical_net_id != 0)
+ vty_out(vty, " vnc l2-group %s\n", rfgc->name);
+ if (rfgc->logical_net_id != 0)
vty_out(vty,
" logical-network-id %u\n",
- rfg->logical_net_id);
- if (rfg->labels != NULL
- && listhead(rfg->labels) != NULL) {
+ rfgc->logical_net_id);
+ if (rfgc->labels != NULL
+ && listhead(rfgc->labels) != NULL) {
vty_out(vty, " labels ");
- for (ALL_LIST_ELEMENTS_RO(rfg->labels,
+ for (ALL_LIST_ELEMENTS_RO(rfgc->labels,
lnode,
data)) {
vty_out(vty, "%hu ",
vty_out(vty, "\n");
}
- if (rfg->rt_import_list && rfg->rt_export_list
- && ecommunity_cmp(rfg->rt_import_list,
- rfg->rt_export_list)) {
+ if (rfgc->rt_import_list && rfgc->rt_export_list
+ && ecommunity_cmp(rfgc->rt_import_list,
+ rfgc->rt_export_list)) {
char *b = ecommunity_ecom2str(
- rfg->rt_import_list,
+ rfgc->rt_import_list,
ECOMMUNITY_FORMAT_ROUTE_MAP,
ECOMMUNITY_ROUTE_TARGET);
vty_out(vty, " rt both %s\n", b);
XFREE(MTYPE_ECOMMUNITY_STR, b);
} else {
- if (rfg->rt_import_list) {
+ if (rfgc->rt_import_list) {
char *b = ecommunity_ecom2str(
- rfg->rt_import_list,
+ rfgc->rt_import_list,
ECOMMUNITY_FORMAT_ROUTE_MAP,
ECOMMUNITY_ROUTE_TARGET);
vty_out(vty, " rt import %s\n",
b);
XFREE(MTYPE_ECOMMUNITY_STR, b);
}
- if (rfg->rt_export_list) {
+ if (rfgc->rt_export_list) {
char *b = ecommunity_ecom2str(
- rfg->rt_export_list,
+ rfgc->rt_export_list,
ECOMMUNITY_FORMAT_ROUTE_MAP,
ECOMMUNITY_ROUTE_TARGET);
vty_out(vty, " rt export %s\n",
.cfg_group_cb)(
vty, bgp->rfapi->rfp,
RFAPI_RFP_CFG_GROUP_L2,
- rfg->name, rfg->rfp_cfg);
+ rfgc->name, rfgc->rfp_cfg);
vty_out(vty, " exit-vnc\n");
vty_out(vty, "!\n");
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
if (bi) {
- char buf[PREFIX_STRLEN];
-
prefix2str(p, buf, sizeof(buf));
vnc_zlog_debug_verbose(
"%s: Found route (safi=%d) to delete at prefix %s",
size);
break;
default:
- flog_err(LIB_ERR_DEVELOPMENT, "%s: Unknown group type=%d",
- __func__, type);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: Unknown group type=%d",
+ __func__, type);
/* should never happen */
assert("Unknown type" == NULL);
break;
criteria, search_cb);
break;
default:
- flog_err(LIB_ERR_DEVELOPMENT, "%s: Unknown group type=%d",
- __func__, type);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: Unknown group type=%d",
+ __func__, type);
/* should never happen */
assert("Unknown type" == NULL);
break;
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
* 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"
* Purpose: Handle import of routes from BGP to RFAPI
*/
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
break;
default:
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
return;
}
break;
default:
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
return;
}
rfapiCopyUnEncap2VPN(ern->info, info_new);
agg_unlock_node(ern); /* undo lock in route_note_match */
} else {
- char buf[PREFIX_STRLEN];
+ char bpf[PREFIX_STRLEN];
- prefix2str(&vn_prefix, buf, sizeof(buf));
+ prefix2str(&vn_prefix, bpf, sizeof(bpf));
/* Not a big deal, just means VPN route got here first */
vnc_zlog_debug_verbose("%s: no encap route for vn addr %s",
- __func__, buf);
+ __func__, bpf);
info_new->extra->vnc.import.un_family = 0;
}
default:
/* not expected */
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad safi %d", __func__,
- safi);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad safi %d", __func__, safi);
return rfapiBgpInfoFilteredImportBadSafi;
}
}
/* TBD remove unneeded includes */
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
* Purpose: maintain per-nve ribs and generate change lists
*/
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-#include <errno.h>
-
#include "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/agg_table.h"
HVTYNL);
}
if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
- char buf[BUFSIZ];
const char *sp;
sp = rfapi_ntop(bi->extra->vnc.import.aux_prefix.family,
"Missing parameter for local-next-hop\n");
return CMD_WARNING_CONFIG_FAILED;
}
- ++argv, --argc;
+ ++argv;
+ --argc;
arg_lnh = argv[0]->arg;
}
if (strmatch(argv[0]->text, "local-cost")) {
"Missing parameter for local-cost\n");
return CMD_WARNING_CONFIG_FAILED;
}
- ++argv, --argc;
+ ++argv;
+ --argc;
arg_lnh_cost = argv[0]->arg;
}
}
list_delete_all_node(adb_delete_list);
if (!(pPrefix && !RFAPI_0_PREFIX(pPrefix))) {
- void *cursor;
-
/*
* Caller didn't specify a prefix, or specified
* (0/32 or 0/128)
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: can't get afi of route node", __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of route node",
+ __func__);
return;
}
struct prefix ce_nexthop;
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi", __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi", __func__);
return;
}
afi_t afi = family2afi(rn->p.family);
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: can't get afi of route node", __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of route node",
+ __func__);
return;
}
afi_t afi = family2afi(rn->p.family);
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi route node",
- __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi route node",
+ __func__);
return;
}
afi_t afi = family2afi(rfd->vn_addr.addr_family);
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: can't get afi of nve vn addr", __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of nve vn addr",
+ __func__);
return;
}
if (afi == AFI_IP || afi == AFI_IP6) {
rt = import_table->imported_vpn[afi];
} else {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d",
- __func__, afi);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d",
+ __func__, afi);
return;
}
afi_t afi = family2afi(rfd->vn_addr.addr_family);
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: can't get afi of nve vn addr", __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of nve vn addr",
+ __func__);
return;
}
if (afi == AFI_IP || afi == AFI_IP6) {
rt = import_table->imported_vpn[afi];
} else {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d",
- __func__, afi);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d",
+ __func__, afi);
return;
}
if (afi == AFI_IP || afi == AFI_IP6) {
rt = import_table->imported_vpn[afi];
} else {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
return;
}
struct attr *iattr;
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: can't get afi of route node", __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of route node",
+ __func__);
return;
}
struct vnc_export_info *eti;
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi route node",
- __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi route node",
+ __func__);
return;
}
*/
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix",
- __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of prefix",
+ __func__);
return;
}
}
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix",
- __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of prefix",
+ __func__);
return;
}
assert(rfg);
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix",
- __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of prefix",
+ __func__);
return;
}
bgp_attr_dup(&hattr, attr); /* hattr becomes a ghost attr */
if (rmap) {
- struct bgp_info info;
+ struct bgp_info binfo;
route_map_result_t ret;
- memset(&info, 0, sizeof(info));
- info.peer = peer;
- info.attr = &hattr;
- ret = route_map_apply(rmap, prefix, RMAP_BGP, &info);
+ memset(&binfo, 0, sizeof(binfo));
+ binfo.peer = peer;
+ binfo.attr = &hattr;
+ ret = route_map_apply(rmap, prefix, RMAP_BGP, &binfo);
if (ret == RMAP_DENYMATCH) {
bgp_attr_flush(&hattr);
vnc_zlog_debug_verbose(
}
if (list_adopted) {
struct listnode *node;
- struct agg_node *bi_exterior;
+ struct agg_node *an_bi_exterior;
- for (ALL_LIST_ELEMENTS_RO(list_adopted, node, bi_exterior)) {
+ for (ALL_LIST_ELEMENTS_RO(list_adopted, node, an_bi_exterior)) {
skiplist_delete(it->monitor_exterior_orphans,
- bi_exterior, NULL);
+ an_bi_exterior, NULL);
}
list_delete_and_null(&list_adopted);
}
VNC_RHNCK(enter);
if (!afi) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: can't get afi of prefix",
- __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of prefix",
+ __func__);
return;
}
return;
if (rn->p.family != AF_INET && rn->p.family != AF_INET6) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: invalid route node addr family", __func__);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "%s: invalid route node addr family", __func__);
return;
}
return;
if (afi != AFI_IP && afi != AFI_IP6) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: invalid vn addr family",
- __func__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: invalid vn addr family",
+ __func__);
return;
}
if (afi == AFI_IP || afi == AFI_IP6) {
rt = import_table->imported_vpn[afi];
} else {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
return;
}
if (!family) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: computed bad family: %d",
- __func__, family);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: computed bad family: %d",
+ __func__, family);
return;
}
--- /dev/null
+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:
+++ /dev/null
-#
-# 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)
* 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"
--- /dev/null
+#
+# 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
--- /dev/null
+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:
+++ /dev/null
-#
-# 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 =
* 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>
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
+++ /dev/null
-#
-# Automake fragment intended to be shared by Makefile.am files in the
-# tree. When used, should be included at the very top of the file.
-#
-AM_CPPFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@
-AM_CFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ $(WERROR)
-
-AM_V_CLIPPY = $(am__v_CLIPPY_$(V))
-am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY))
-am__v_CLIPPY_0 = @echo " CLIPPY " $@;
-am__v_CLIPPY_1 =
-
-CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py
-
-SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h
-.c_clippy.c:
- @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; }
- $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $<
-
-## automake's "ylwrap" is a great piece of GNU software... not.
-.l.c:
- $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $<
-.y.c:
- $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $<
-
-
-if HAVE_PROTOBUF
-
-# Uncomment to use an non-system version of libprotobuf-c.
-#
-# Q_PROTOBUF_C_CLIENT_INCLUDES = -I$(top_srcdir)/third-party/protobuf-c/src
-# Q_PROTOBUF_C_CLIENT_LDOPTS = $(top_builddir)/third-party/protobuf-c/src/libprotobuf-c.la
-
-Q_PROTOBUF_C_CLIENT_INCLUDES=
-Q_PROTOBUF_C_CLIENT_LDOPTS=-lprotobuf-c
-
-Q_PROTOC=protoc
-Q_PROTOC_C=protoc-c
-
-# Rules
-.proto.pb.h:
- $(Q_PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^
-
-AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V))
-am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY))
-am__v_PROTOC_C_0 = @echo " PROTOC_C" $@;
-am__v_PROTOC_C_1 =
-
-.proto.pb-c.c:
- $(AM_V_PROTOC_C)$(Q_PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^
-.pb-c.c.pb-c.h:
- @/bin/true
-
-#
-# Information about how to link to various libraries.
-#
-Q_FRR_PB_CLIENT_LDOPTS = $(top_srcdir)/qpb/libfrr_pb.la $(Q_PROTOBUF_C_CLIENT_LDOPTS)
-
-Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfrrfpm_pb.la $(Q_FRR_PB_CLIENT_LDOPTS)
-
-endif # HAVE_PROTOBUF
# 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)
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
AC_C_FLAG([-Wunreachable-code])
AC_C_FLAG([-Wpacked])
AC_C_FLAG([-Wpadded])
+ AC_C_FLAG([-Wshadow])
else
AC_C_FLAG([-Wno-unused-result])
fi
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
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 --------------
AC_PROG_MAKE_SET
AC_CHECK_TOOL(AR, ar)
-dnl -----------------
-dnl System extensions
-dnl -----------------
-AC_GNU_SOURCE
-
dnl -------
dnl libtool
dnl -------
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,
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)
# 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.
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.
#
])
])
+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>
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)
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)
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
])dnl
dnl disable doc check
-AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [no])
-AM_CONDITIONAL(DOC, test "${enable_doc}" != "no")
+AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [/bin/false])
+if test "$SPHINXBUILD" = "/bin/false"; then
+ if test "${enable_doc}" = "yes"; then
+ AC_MSG_ERROR([Documentation was explicitly requested with --enable-doc but sphinx-build is not available. Please disable docs or install sphinx.])
+ fi
+fi
+AM_CONDITIONAL(DOC, test "${enable_doc}" != "no" -a "$SPHINXBUILD" != "/bin/false")
AM_CONDITIONAL(DOC_HTML, test "${enable_doc_html}" = "yes")
dnl --------------------
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)
AC_DEFINE(DISABLE_BGP_ANNOUNCE,0,Disable BGP installation to zebra)
fi
-if test "${with_rfp_path}" = "yes" || test x"${with_rfp_path}" = x""; then
- with_rfp_path="bgpd/rfp-example"
-fi
-if test "${with_rfp_path}" != "no"; then
- VNC_RFP_PATH="${with_rfp_path}"
- AC_SUBST(VNC_RFP_PATH)
-fi
-
if test "${enable_bgp_vnc}" != "no";then
AC_DEFINE(ENABLE_BGP_VNC,1,Enable BGP VNC support)
- RFPTEST="${with_rfp_path}/rfptest"
- LIBRFP="${with_rfp_path}/librfp"
- RFPINC="${with_rfp_path}/librfp"
-else
- RFPTEST=
- LIBRFP=
- RFPINC="bgpd/rfp-example/librfp"
fi
-# set
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
-AC_SUBST(RFPTEST)
-AC_SUBST(LIBRFP)
-AC_SUBST(RFPINC)
-AC_SUBST(BGPD)
AC_SUBST(SOLARIS)
-AC_SUBST(VTYSH)
AC_SUBST(CURSES)
AC_CHECK_LIB(crypt, crypt, [],
[AC_CHECK_LIB(crypto, DES_crypt)])
dnl has been specified, which might not provide
dnl mallinfo, e.g. such as Umem on Solaris.
dnl -----------------------------------------
-AC_CHECK_HEADERS([malloc.h malloc/malloc.h],,, [FRR_INCLUDES])
+AC_CHECK_HEADERS([malloc.h malloc_np.h malloc/malloc.h],,, [FRR_INCLUDES])
AC_CACHE_CHECK([whether mallinfo is available], [frr_cv_mallinfo], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
+#ifdef HAVE_MALLOC_NP_H
+#include <malloc_np.h>
+#endif
#ifdef HAVE_MALLOC_MALLOC_H
#include <malloc/malloc.h>
#endif
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.])]
)
AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile])
AC_CONFIG_FILES([
- bgpd/Makefile
- vtysh/Makefile
- tests/Makefile
- bgpd/rfp-example/rfptest/Makefile
- bgpd/rfp-example/librfp/Makefile
redhat/frr.spec
solaris/Makefile
debianpkg/changelog
pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
pkgsrc/eigrpd.sh])
-if test "${enable_bgp_vnc}" != "no"; then
- if test "${with_rfp_path}" != "bgpd/rfp-example" ; then
- AC_CONFIG_FILES([${with_rfp_path}/rfptest/Makefile ${with_rfp_path}/librfp/Makefile])
- fi
-fi
-
AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl])
AC_CONFIG_COMMANDS([lib/route_types.h], [
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}\``
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
-AUTHORS
-NEWS
-README
+README.md
doc/user/*.rst
doc/figures/*.png
-!Makefile
mdate-sh
draft-zebra-00.txt
*.pdf
frr.ps
frr.dvi
stamp-vti
-.nfs*
*.aux
*.cp
*.cps
*.toc
*.tp
*.vr
-.arch-inventory
-.arch-ids
-*~
-*.loT
refix
.. code-block:: shell
sudo groupadd -g 92 frr
- sudo groupadd -r -g 85 frrvt
- sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \
+ sudo groupadd -r -g 85 frrvty
+ sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \
-c "FRR FRRouting suite" -d /var/run/frr frr
Download Source, configure and compile it
--enable-ospfapi=yes \
--enable-user=frr \
--enable-group=frr \
- --enable-vty-group=frrvt \
+ --enable-vty-group=frrvty \
--enable-rtadv \
--disable-exampledir \
--enable-watchfrr \
--enable-eigrpd \
--enable-babeld \
--with-pkg-git-version \
- --with-pkg-extra-version=-MyOwnFRRVersion
- make SPHINXBUILD=sphinx-build2.7
- make check PYTHON=/usr/bin/python2.7 SPHINXBUILD=sphinx-build2.7
- sudo make SPHINXBUILD=sphinx-build2.7 install
+ --with-pkg-extra-version=-MyOwnFRRVersion \
+ SPHINXBUILD=sphinx-build2.7
+ make
+ make check PYTHON=/usr/bin/python2.7
+ sudo make install
Create empty FRR configuration files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
sudo groupadd -g 92 frr
- sudo groupadd -r -g 85 frrvt
- sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \
+ sudo groupadd -r -g 85 frrvty
+ sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \
-c "FRR FRRouting suite" -d /var/run/frr frr
Download Source, configure and compile it
--enable-ospfapi=yes \
--enable-user=frr \
--enable-group=frr \
- --enable-vty-group=frrvt \
+ --enable-vty-group=frrvty \
--enable-rtadv \
--enable-systemd=yes \
--disable-exampledir \
sudo touch /etc/frr/babeld.conf
sudo chown -R frr:frr /etc/frr/
sudo touch /etc/frr/vtysh.conf
- sudo chown frr:frrvt /etc/frr/vtysh.conf
+ sudo chown frr:frrvty /etc/frr/vtysh.conf
sudo chmod 640 /etc/frr/*.conf
Install daemon config file
::
sudo groupadd -g 92 frr
- sudo groupadd -r -g 85 frrvt
- sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \
+ sudo groupadd -r -g 85 frrvty
+ sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \
-c "FRR FRRouting suite" -d /var/run/frr frr
Download Source, configure and compile it
--enable-ospfapi=yes \
--enable-user=frr \
--enable-group=frr \
- --enable-vty-group=frrvt \
+ --enable-vty-group=frrvty \
--enable-rtadv \
--disable-exampledir \
--enable-watchfrr \
sudo touch /etc/frr/babeld.conf
sudo chown -R frr:frr /etc/frr/
sudo touch /etc/frr/vtysh.conf
- sudo chown frr:frrvt /etc/frr/vtysh.conf
+ sudo chown frr:frrvty /etc/frr/vtysh.conf
sudo chmod 640 /etc/frr/*.conf
Install daemon config file
.. code-block:: make
- include ../common.am
-
# ...
# if linked into a LTLIBRARY (.la/.so):
- some measure of time (dependent on the specific case) has passed, so that
the compatibility grace period is considered expired.
+For CLI commands, the deprecation period is 1 year.
+
In all cases, compatibility pieces should be marked with compiler/preprocessor
annotations to print warnings at compile time, pointing to the appropriate
update path. A ``-Werror`` build should fail if compatibility bits are used. To
.. include:: common-options.rst
+LABEL MANAGER
+-------------
+
+.. option:: -I, --int_num
+
+ Set zclient id. This is required when using Zebra label manager in proxy mode.
+
FILES
=====
pbrd 2615
staticd 2616
bfdd 2617
+ fabricd 2618
Port 2607 is used for ospfd's Opaque LSA API.
('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 -------------------------------------------
--- /dev/null
+*******
+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
+
bgpd
eigrpd
isisd
+ fabricd
ldpd
nhrpd
ospf6d
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 \
rstman1_DATA =
rstman8_DATA =
-rstman1_DATA += $(MANBUILD)/frr.1
+if DOC
+rstman1_DATA += $(man1)
+rstman8_DATA += $(man8)
+endif # DOC
-if PIMD
-rstman8_DATA += $(MANBUILD)/pimd.8
-rstman8_DATA += $(MANBUILD)/mtracebis.8
-endif
-
-if PBRD
-rstman8_DATA += $(MANBUILD)/pbrd.8
-endif
-
-if BGPD
-rstman8_DATA += $(MANBUILD)/bgpd.8
-endif
-
-if ISISD
-rstman8_DATA += $(MANBUILD)/isisd.8
-endif
-
-if OSPF6D
-rstman8_DATA += $(MANBUILD)/ospf6d.8
-endif
-
-if OSPFCLIENT
-rstman8_DATA += $(MANBUILD)/ospfclient.8
-endif
-
-if OSPFD
-rstman8_DATA += $(MANBUILD)/ospfd.8
-endif
-
-if LDPD
-rstman8_DATA += $(MANBUILD)/ldpd.8
-endif
-
-if RIPD
-rstman8_DATA += $(MANBUILD)/ripd.8
-endif
-
-if RIPNGD
-rstman8_DATA += $(MANBUILD)/ripngd.8
-endif
-
-if NHRPD
-rstman8_DATA += $(MANBUILD)/nhrpd.8
-endif
-
-if VTYSH
-rstman1_DATA += $(MANBUILD)/vtysh.1
-endif
-
-if WATCHFRR
-rstman8_DATA += $(MANBUILD)/watchfrr.8
-endif
-
-if ZEBRA
-rstman8_DATA += $(MANBUILD)/zebra.8
-endif
-
-if EIGRPD
-rstman8_DATA += $(MANBUILD)/eigrpd.8
-endif
-
-if SHARPD
-rstman8_DATA += $(MANBUILD)/sharpd.8
-endif
-
-if STATICD
-rstman8_DATA += $(MANBUILD)/staticd.8
-endif
-
-if BFDD
-rstman8_DATA += $(MANBUILD)/bfdd.8
-endif
+man1 = $(MANBUILD)/frr.1
+man8 =
# dependency
-$(rstman8_DATA) $(rstman1_DATA): $(MANBUILD)/man.stamp
+$(man8) $(man1): $(MANBUILD)/man.stamp
#
# hook-ins for clean / doc
+++ /dev/null
-.arch-ids
-.arch-inventory
-*~
-*.loT
-
specified number of hops away will be allowed to become neighbors. This
command is mutually exclusive with *ebgp-multihop*.
+.. index:: [no] bgp fast-external-failover
+.. clicmd:: [no] bgp fast-external-failover
+
+ This command causes bgp to not take down ebgp peers immediately
+ when a link flaps. `bgp fast-external-failover` is the default
+ and will not be displayed as part of a `show run`. The no form
+ of the command turns off this ability.
+
.. _bgp-peer-filtering:
Peer Filtering
--- /dev/null
+.. _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
bfd
bgp
babeld
+ fabricd
ldpd
eigrpd
isisd
Do not build isisd.
+.. option:: --disable-fabricd
+
+ Do not build fabricd.
+
.. option:: --enable-isis-topology
Enable IS-IS topology generator.
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
.. _configuring-ospfd:
-Configuring ospfd
-=================
+Configuring OSPF
+================
-There are no *ospfd* specific options. Common options can be specified
-(:ref:`common-invocation-options`) to *ospfd*. *ospfd* needs to acquire
-interface information from *zebra* in order to function. Therefore *zebra* must
-be running before invoking *ospfd*. Also, if *zebra* is restarted then *ospfd*
-must be too.
+*ospfd* accepts all :ref:`common-invocation-options`.
+
+.. option:: -n, --instance
+
+ Specify the instance number for this invocation of *ospfd*.
+
+.. option:: -a, --apiserver
+
+ Enable the OSPF API server
+
+*ospfd* must acquire interface information from *zebra* in order to function.
+Therefore *zebra* must be running before invoking *ospfd*. Also, if *zebra* is
+restarted then *ospfd* must be too.
Like other daemons, *ospfd* configuration is done in :abbr:`OSPF` specific
-configuration file :file:`ospfd.conf`.
+configuration file :file:`ospfd.conf` when the integrated config is not used.
+
+.. _ospf-multi-instance:
+
+Multi-instance Support
+----------------------
+
+OSPF supports multiple instances. Each instance is identified by a positive
+nonzero integer that must be provided when adding configuration items specific
+to that instance. Enabling instances is done with :file:`/etc/frr/daemons` in
+the following manner:
+
+::
+
+ ...
+ ospfd=yes
+ ospfd_instances=1,5,6
+ ...
+
+The ``ospfd_instances`` variable controls which instances are started and what
+their IDs are. In this example, after starting FRR you should see the following
+processes:
+
+.. code-block:: shell
+
+ # ps -ef | grep "ospfd"
+ frr 11816 1 0 17:30 ? 00:00:00 /usr/lib/frr/ospfd --daemon -A 127.0.0.1 -n 1
+ frr 11822 1 0 17:30 ? 00:00:00 /usr/lib/frr/ospfd --daemon -A 127.0.0.1 -n 2
+ frr 11828 1 0 17:30 ? 00:00:00 /usr/lib/frr/ospfd --daemon -A 127.0.0.1 -n 3
+
+
+The instance number should be specified in the config when addressing a particular instance:
+
+.. code-block:: frr
+
+ router ospf 5
+ router-id 1.2.3.4
+ area 0.0.0.0 authentication message-digest
+ ...
.. _ospf-router:
-OSPF router
-===========
+Routers
+-------
-To start OSPF process you have to specify the OSPF router. As of this
-writing, *ospfd* does not support multiple OSPF processes.
+To start OSPF process you have to specify the OSPF router.
-.. index:: router ospf
-.. clicmd:: router ospf
+.. index:: router ospf [(1-65535)] vrf NAME
+.. clicmd:: router ospf [(1-65535)] vrf NAME
-.. index:: no router ospf
-.. clicmd:: no router ospf
+.. index:: no router ospf [(1-65535)] vrf NAME
+.. clicmd:: no router ospf [(1-65535)] vrf NAME
- Enable or disable the OSPF process. *ospfd* does not yet
- support multiple OSPF processes. So you can not specify an OSPF process
- number.
+ Enable or disable the OSPF process.
.. index:: ospf router-id A.B.C.D
.. clicmd:: ospf router-id A.B.C.D
-.. index:: no ospf router-id
-.. clicmd:: no ospf router-id
+.. index:: no ospf router-id [A.B.C.D]
+.. clicmd:: no ospf router-id [A.B.C.D]
- This sets the router-ID of the OSPF process. The
- router-ID may be an IP address of the router, but need not be - it can
- be any arbitrary 32bit number. However it MUST be unique within the
- entire OSPF domain to the OSPF speaker - bad things will happen if
- multiple OSPF speakers are configured with the same router-ID! If one
- is not specified then *ospfd* will obtain a router-ID
- automatically from *zebra*.
+ This sets the router-ID of the OSPF process. The router-ID may be an IP
+ address of the router, but need not be - it can be any arbitrary 32bit
+ number. However it MUST be unique within the entire OSPF domain to the OSPF
+ speaker - bad things will happen if multiple OSPF speakers are configured
+ with the same router-ID! If one is not specified then *ospfd* will obtain a
+ router-ID automatically from *zebra*.
.. index:: ospf abr-type TYPE
.. clicmd:: ospf abr-type TYPE
.. _ospf-area:
-OSPF area
-=========
+Areas
+-----
.. index:: area A.B.C.D range A.B.C.D/M
.. clicmd:: area A.B.C.D range A.B.C.D/M
.. _ospf-interface:
-OSPF interface
-==============
+Interfaces
+----------
.. index:: ip ospf area AREA [ADDR]
.. clicmd:: ip ospf area AREA [ADDR]
.. _redistribute-routes-to-ospf:
-Redistribute routes to OSPF
-===========================
+Redistribution
+--------------
.. index:: redistribute (kernel|connected|static|rip|bgp)
.. clicmd:: redistribute (kernel|connected|static|rip|bgp)
.. _showing-ospf-information:
-Showing OSPF information
-========================
+Showing Information
+===================
.. _show-ip-ospf:
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.
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
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
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 \
-!Makefile
-Makefile.in
-*.o
-*.a
eigrpd
eigrpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
/* clang-format off */
static struct log_ref ferr_eigrp_err[] = {
{
- .code = EIGRP_ERR_PACKET,
+ .code = EC_EIGRP_PACKET,
.title = "EIGRP Packet Error",
.description = "EIGRP has a packet that does not correctly decode or encode",
.suggestion = "Gather log files from both sides of the neighbor relationship and open an issue"
},
{
- .code = EIGRP_ERR_CONFIG,
+ .code = EC_EIGRP_CONFIG,
.title = "EIGRP Configuration Error",
.description = "EIGRP has detected a configuration error",
.suggestion = "Correct the configuration issue, if it still persists open an Issue"
#include "lib/ferr.h"
enum eigrp_log_refs {
- EIGRP_ERR_PACKET = EIGRP_FERR_START,
- EIGRP_ERR_CONFIG,
+ EC_EIGRP_PACKET = EIGRP_FERR_START,
+ EC_EIGRP_CONFIG,
};
extern void eigrp_error_init(void);
* 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"
ret = sscanf(ver_string, "%" SCNu32 ".%" SCNu32, &FRR_MAJOR,
&FRR_MINOR);
if (ret != 2)
- flog_err(EIGRP_ERR_PACKET,
- "Did not Properly parse %s, please fix VERSION string",
- VERSION);
+ flog_err(EC_EIGRP_PACKET,
+ "Did not Properly parse %s, please fix VERSION string",
+ VERSION);
}
/**
void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty)
{
if (nbr == NULL) {
- flog_err(EIGRP_ERR_CONFIG,
- "Nbr Hard restart: Neighbor not specified.");
+ flog_err(EC_EIGRP_CONFIG,
+ "Nbr Hard restart: Neighbor not specified.");
return;
}
/* Get one packet from queue. */
ep = eigrp_fifo_next(ei->obuf);
if (!ep) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: Interface %s no packet on queue?",
- __PRETTY_FUNCTION__, ei->ifp->name);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "%s: Interface %s no packet on queue?",
+ __PRETTY_FUNCTION__, ei->ifp->name);
goto out;
}
if (ep->length < EIGRP_HEADER_LEN) {
- flog_err(EIGRP_ERR_PACKET,
- "%s: Packet just has a header?", __PRETTY_FUNCTION__);
+ flog_err(EC_EIGRP_PACKET, "%s: Packet just has a header?",
+ __PRETTY_FUNCTION__);
eigrp_header_dump((struct eigrp_header *)ep->s->data);
eigrp_packet_delete(ei);
goto out;
stream_putw(s, length);
break;
default:
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: Unexpected prefix length: %d",
- __PRETTY_FUNCTION__, pe->destination->prefixlen);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: Unexpected prefix length: %d",
+ __PRETTY_FUNCTION__, pe->destination->prefixlen);
return 0;
}
stream_putl(s, 0x00000000);
if (!dest) {
char buf[PREFIX_STRLEN];
- flog_err(EIGRP_ERR_PACKET,
- "%s: Received prefix %s which we do not know about",
- __PRETTY_FUNCTION__,
- prefix2str(&dest_addr, buf, sizeof(buf)));
+ flog_err(
+ EC_EIGRP_PACKET,
+ "%s: Received prefix %s which we do not know about",
+ __PRETTY_FUNCTION__,
+ prefix2str(&dest_addr, buf, sizeof(buf)));
eigrp_IPv4_InternalTLV_free(tlv);
continue;
}
}
break;
default:
- flog_err(LIB_ERR_DEVELOPMENT, "%s: Please implement handler",
- __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: Please implement handler",
+ __PRETTY_FUNCTION__);
break;
}
distance_done:
if ((eigrp_socket = eigrp_sock_init()) < 0) {
flog_err_sys(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"eigrp_new: fatal error: eigrp_sock_init was unable to open a socket");
exit(1);
}
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 = \
+++ /dev/null
-!Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
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 \
# 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
+++ /dev/null
-Makefile
-Makefile.in
-.nfs*
-*~
-*.loT
-
-!Makefile
-Makefile.in
-*.o
isisd
-.deps
+fabricd
isisd.conf
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+! -*- 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
+!
--- /dev/null
+/*
+ * 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
#include "isisd/isis_events.h"
#include "isisd/isis_mt.h"
#include "isisd/isis_tlvs.h"
+#include "isisd/fabricd.h"
extern struct isis *isis;
}
}
+ 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;
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);
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);
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;
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);
#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"
#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)
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;
{
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);
}
}
}
if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) {
flog_err(
- ISIS_ERR_CONFIG,
+ EC_ISIS_CONFIG,
"Interface MTU %zu on %s is too low to support area lsp mtu %u!",
isis_circuit_pdu_size(circuit),
circuit->interface->name, circuit->area->lsp_mtu);
circuit->circuit_id = isis_circuit_id_gen(isis, circuit->interface);
if (!circuit->circuit_id) {
flog_err(
- ISIS_ERR_CONFIG,
+ EC_ISIS_CONFIG,
"There are already 255 broadcast circuits active!");
return ISIS_ERROR;
}
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;
}
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 */
vty_out(vty, " IP Prefix(es):\n");
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
ip_addr)) {
- prefix2str(ip_addr, buf, sizeof(buf)),
- vty_out(vty, " %s\n", buf);
+ prefix2str(ip_addr, buf, sizeof(buf));
+ vty_out(vty, " %s\n", buf);
}
}
if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) {
vty_out(vty, " IPv6 Link-Locals:\n");
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
ip_addr)) {
- prefix2str(ip_addr, (char *)buf, BUFSIZ),
- vty_out(vty, " %s\n", buf);
+ prefix2str(ip_addr, (char *)buf, BUFSIZ);
+ vty_out(vty, " %s\n", buf);
}
}
if (circuit->ipv6_non_link
vty_out(vty, " IPv6 Prefixes:\n");
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
ip_addr)) {
- prefix2str(ip_addr, (char *)buf, BUFSIZ),
- vty_out(vty, " %s\n", buf);
+ prefix2str(ip_addr, (char *)buf, BUFSIZ);
+ vty_out(vty, " %s\n", buf);
}
}
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++;
+ }
}
}
== 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++;
}
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);
== 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++;
}
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);
/* 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++;
}
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++;
}
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);
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++;
}
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);
/* 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++;
}
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++;
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++;
}
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++;
}
}
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++;
}
/* 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;
}
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 */
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
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 */
isis_circuit_if_add(circuit, (struct interface *)arg);
if (isis_circuit_up(circuit) != ISIS_OK) {
flog_err(
- ISIS_ERR_CONFIG,
+ EC_ISIS_CONFIG,
"Could not bring up %s because of invalid config.",
circuit->interface->name);
flog_err(
- ISIS_ERR_CONFIG,
+ EC_ISIS_CONFIG,
"Clearing config for %s. Please re-examine it.",
circuit->interface->name);
if (circuit->ip_router) {
/* clang-format off */
static struct log_ref ferr_isis_err[] = {
{
- .code = ISIS_ERR_PACKET,
+ .code = EC_ISIS_PACKET,
.title = "ISIS Packet Error",
.description = "Isis has detected an error with a packet from a peer",
.suggestion = "Gather log information and open an issue then restart FRR"
},
{
- .code = ISIS_ERR_CONFIG,
+ .code = EC_ISIS_CONFIG,
.title = "ISIS Configuration Error",
.description = "Isis has detected an error within configuration for the router",
.suggestion = "Ensure configuration is correct"
#include "lib/ferr.h"
enum isis_log_refs {
- ISIS_ERR_PACKET = ISIS_FERR_START,
- ISIS_ERR_CONFIG,
+ EC_ISIS_PACKET = ISIS_FERR_START,
+ EC_ISIS_CONFIG,
};
extern void isis_error_init(void);
if (!(newtype & circuit->area->is_type)) {
flog_err(
- ISIS_ERR_CONFIG,
+ EC_ISIS_CONFIG,
"ISIS-Evt (%s) circuit type change - invalid level %s because area is %s",
circuit->area->area_tag, circuit_t2string(newtype),
circuit_t2string(circuit->area->is_type));
#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);
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);
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);
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);
}
/*
if (lsp->tlvs)
lsp_inc_seqno(lsp, 0);
else
- lsp_purge(lsp, lsp0->level);
+ lsp_purge(lsp, lsp0->level, NULL);
}
return;
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
{
if (lsp->own_lsp) {
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP",
area->area_tag, rawlspid_print(lsp->hdr.lsp_id));
lsp_clear_data(lsp);
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) {
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)
*/
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(
/* 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);
}
/*
- * 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)
{
lsp = lsp_search(lspid, lspdb);
if (!lsp) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "ISIS-Upd (%s): lsp_regenerate: no L%d LSP found!",
- area->area_tag, level);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "ISIS-Upd (%s): lsp_regenerate: no L%d LSP found!",
+ area->area_tag, level);
return ISIS_ERROR;
}
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);
*/
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);
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]);
lsp = lsp_search(lsp_id, lspdb);
if (!lsp) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "lsp_regenerate_pseudo: no l%d LSP %s found!", level,
- rawlspid_print(lsp_id));
+ flog_err(EC_LIB_DEVELOPMENT,
+ "lsp_regenerate_pseudo: no l%d LSP %s found!", level,
+ rawlspid_print(lsp_id));
return ISIS_ERROR;
}
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)
/*
* 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) {
*/
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) {
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 && lsp) {
+ 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;
}
if (!lsp)
return;
- lsp_purge(lsp, level);
+ lsp_purge(lsp, level, NULL);
}
/*
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);
+ }
+}
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 */
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 */
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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
#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};
},
};
+#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",
{
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. */
prefix_list_init();
isis_init();
isis_circuit_init();
+ isis_vty_init();
isis_spf_cmds_init();
isis_redist_init();
isis_route_map_init();
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++;
}
}
#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)
retval = circuit->tx(circuit, level);
if (retval != ISIS_OK)
- flog_err(ISIS_ERR_PACKET,
- "ISIS-Upd (%s): Send L%d LSP PSNP on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
+ flog_err(EC_ISIS_PACKET,
+ "ISIS-Upd (%s): Send L%d LSP PSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
return retval;
}
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)) {
}
if (!p2p_hello && !(level & iih.circ_type)) {
- flog_err(ISIS_ERR_PACKET,
- "Level %d LAN Hello with Circuit Type %d", level,
- iih.circ_type);
+ flog_err(EC_ISIS_PACKET,
+ "Level %d LAN Hello with Circuit Type %d", level,
+ iih.circ_type);
return ISIS_ERROR;
}
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)
* 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);
* 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),
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:
* 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)
} /* 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)
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)
}
/* 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 */
if (!lsp0) {
zlog_debug(
"Got lsp frag, while zero lsp not in database");
- return ISIS_OK;
+ goto out;
}
}
/* i */
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)
}
/* 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;
}
/* 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);
}
}
retval = ISIS_OK;
out:
+ if (circuit_scoped) {
+ fabricd_trigger_csnp(circuit->area);
+ }
+
isis_free_tlvs(tlvs);
return retval;
}
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 */
}
}
+ 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) {
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 {
continue;
}
}
- struct isis_lsp *lsp =
- lsp_new(circuit->area, entry->id,
+ lsp = lsp_new(circuit->area, entry->id,
entry->rem_lifetime, 0, 0,
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;
}
}
}
}
/* 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);
break;
case L1_LINK_STATE:
case L2_LINK_STATE:
+ case FS_LINK_STATE:
*size = ISIS_LSP_HDR_LEN;
break;
case L1_COMPLETE_SEQ_NUM:
/* Verify that at least the 8 bytes fixed header have been received */
if (stream_get_endp(circuit->rcv_stream) < ISIS_FIXED_HDR_LEN) {
- flog_err(ISIS_ERR_PACKET, "PDU is too short to be IS-IS.");
+ flog_err(EC_ISIS_PACKET, "PDU is too short to be IS-IS.");
return ISIS_ERROR;
}
uint8_t max_area_addrs = stream_getc(circuit->rcv_stream);
if (idrp == ISO9542_ESIS) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "No support for ES-IS packet IDRP=%" PRIx8, idrp);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "No support for ES-IS packet IDRP=%" PRIx8, idrp);
return ISIS_ERROR;
}
if (idrp != ISO10589_ISIS) {
- flog_err(ISIS_ERR_PACKET, "Not an IS-IS packet IDRP=%" PRIx8,
- idrp);
+ flog_err(EC_ISIS_PACKET, "Not an IS-IS packet IDRP=%" PRIx8,
+ idrp);
return ISIS_ERROR;
}
if (id_len != 0 && id_len != ISIS_SYS_ID_LEN) {
flog_err(
- ISIS_ERR_PACKET,
+ EC_ISIS_PACKET,
"IDFieldLengthMismatch: ID Length field in a received PDU %" PRIu8
", while the parameter for this IS is %u",
id_len, ISIS_SYS_ID_LEN);
}
if (length != expected_length) {
- flog_err(ISIS_ERR_PACKET,
- "Exepected fixed header length = %" PRIu8
- " but got %" PRIu8,
- expected_length, length);
+ flog_err(EC_ISIS_PACKET,
+ "Exepected fixed header length = %" PRIu8
+ " but got %" PRIu8,
+ expected_length, length);
return ISIS_ERROR;
}
if (stream_get_endp(circuit->rcv_stream) < length) {
flog_err(
- ISIS_ERR_PACKET,
+ EC_ISIS_PACKET,
"PDU is too short to contain fixed header of given PDU type.");
return ISIS_ERROR;
}
}
/* 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,
+ EC_ISIS_PACKET,
"maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8
" while the parameter for this IS is %u",
max_area_addrs, isis->max_area_addrs);
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:
&& !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);
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);
retval = circuit->tx(circuit, level);
if (retval != ISIS_OK)
- flog_err(ISIS_ERR_PACKET,
- "ISIS-Adj (%s): Send L%d IIH on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
+ flog_err(EC_ISIS_PACKET,
+ "ISIS-Adj (%s): Send L%d IIH on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
return retval;
}
int retval = circuit->tx(circuit, level);
if (retval != ISIS_OK) {
- flog_err(ISIS_ERR_PACKET,
- "ISIS-Snp (%s): Send L%d CSNP on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
+ flog_err(EC_ISIS_PACKET,
+ "ISIS-Snp (%s): Send L%d CSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
isis_free_tlvs(tlvs);
return retval;
}
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 */
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 */
int retval = circuit->tx(circuit, level);
if (retval != ISIS_OK) {
- flog_err(ISIS_ERR_PACKET,
- "ISIS-Snp (%s): Send L%d PSNP on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
+ flog_err(EC_ISIS_PACKET,
+ "ISIS-Snp (%s): Send L%d PSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
isis_free_tlvs(tlvs);
return retval;
}
/*
* 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;
* the circuit's MTU. So handle and log this case here. */
if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) {
flog_err(
- ISIS_ERR_PACKET,
+ EC_ISIS_PACKET,
"ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08" PRIx32
", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
"s on %s. LSP Size is %zu while interface stream size is %zu.",
/* 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
clear_srm = 0;
retval = circuit->tx(circuit, lsp->level);
if (retval != ISIS_OK) {
- flog_err(ISIS_ERR_PACKET,
- "ISIS-Upd (%s): Send L%d LSP on %s failed %s",
- circuit->area->area_tag, lsp->level,
- circuit->interface->name,
- (retval == ISIS_WARNING) ? "temporarily"
- : "permanently");
+ flog_err(EC_ISIS_PACKET,
+ "ISIS-Upd (%s): Send L%d LSP on %s failed %s",
+ circuit->area->area_tag, lsp->level,
+ circuit->interface->name,
+ (retval == ISIS_WARNING) ? "temporarily"
+ : "permanently");
}
out:
* to clear
* the fag.
*/
- ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
-
- return retval;
}
#ifndef _ZEBRA_ISIS_PDU_H
#define _ZEBRA_ISIS_PDU_H
+#include "isisd/isis_tx_queue.h"
+
#ifdef __SUNPRO_C
#pragma pack(1)
#endif
#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;
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);
if (redist->map_name) {
map_ret =
- route_map_apply(redist->map, (struct prefix *)p,
- RMAP_ISIS, &area_info);
+ route_map_apply(redist->map, p, RMAP_ISIS, &area_info);
if (map_ret == RMAP_DENYMATCH)
area_info.distance = 255;
}
* 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);
}
isis_redist_update_ext_reach(area, level, redist, p,
- (struct prefix_ipv6 *)src_p, info);
+ (const struct prefix_ipv6 *)src_p,
+ info);
}
}
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"
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;
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;
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;
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;
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"
{
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;
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);
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;
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;
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)
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)
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);
}
#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 ?
*/
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);
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,
adj);
}
}
+
+ if (fabricd_spftree(area) != NULL)
+ isis_spftree_adj_del(fabricd_spftree(area), adj);
}
/*
#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);
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);
}
/*
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;
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);
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));
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);
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))
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,
}
}
- 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,
/*
* 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,
&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,
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);
? VTYPE_NONPSEUDO_IS
: VTYPE_NONPSEUDO_TE_IS,
lsp_id, adj,
+ spftree->hopcount_metric ? 1 :
circuit->te_metric
[spftree->level - 1],
parent);
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)
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;
? VTYPE_NONPSEUDO_IS
: VTYPE_NONPSEUDO_TE_IS,
lsp_id, adj,
+ spftree->hopcount_metric ? 1 :
circuit->te_metric
[spftree->level - 1],
parent);
}
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);
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,
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;
/*
* 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) */
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);
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;
}
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;
}
}
+ 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");
}
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 */
--- /dev/null
+/*
+ * 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((const struct prefix *)&va->N.ip.src,
+ (const 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(EC_LIB_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
* 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()
{
/*------------------------------------------------------------------------*
* 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,
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")
{
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")
return CMD_SUCCESS;
}
+#endif
/* Initialize MPLS_TE */
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;
}
/* 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)
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;
}
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;
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);
}
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);
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;
{
struct isis_extended_ip_reach *item =
(struct isis_extended_ip_reach *)i;
+ isis_free_subtlvs(item->subtlvs);
XFREE(MTYPE_ISIS_TLV, item);
}
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;
}
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);
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)
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;
sbuf_push(buf, indent, " Password: %s\n", obuf);
break;
case ISIS_PASSWD_TYPE_HMAC_MD5:
- for (unsigned int i = 0; i < 16; i++) {
- snprintf(obuf + 2 * i, sizeof(obuf) - 2 * i,
- "%02" PRIx8, auth->value[i]);
+ for (unsigned int j = 0; j < 16; j++) {
+ snprintf(obuf + 2 * j, sizeof(obuf) - 2 * j,
+ "%02" PRIx8, auth->value[j]);
}
sbuf_push(buf, indent, " HMAC-MD5: %s\n", obuf);
break;
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)
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)
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;
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);
rv->threeway_adj = copy_tlv_threeway_adj(tlvs->threeway_adj);
+ rv->spine_leaf = copy_tlv_spine_leaf(tlvs->spine_leaf);
+
return rv;
}
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);
&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)
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,
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);
}
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;
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,
.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");
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] = {
[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,
[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,
[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,
}
};
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));
}
}
}
+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)
{
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));
+ }
+}
uint32_t metric;
bool down;
struct prefix_ipv4 prefix;
+
+ struct isis_subtlvs *subtlvs;
};
struct isis_ipv6_reach;
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,
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,
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;
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 {
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,
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,
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,
ISIS_TLV_THREE_WAY_ADJ = 240,
ISIS_TLV_MAX = 256,
+ ISIS_SUBTLV_PREFIX_SID = 3,
ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22
};
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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
+++ /dev/null
-/*
- * 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);
-}
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * IS-IS Rout(e)ing protocol - isis_vty_isisd.c
+ *
+ * This file contains the CLI that is specific to IS-IS
+ *
+ * Copyright (C) 2001,2002 Sampo Saaristo
+ * Tampere University of Technology
+ * Institute of Communications Engineering
+ * Copyright (C) 2016 David Lamparter, for NetDEF, Inc.
+ * Copyright (C) 2018 Christian Franke, for NetDEF, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public Licenseas published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "command.h"
+
+#include "isis_circuit.h"
+#include "isis_csm.h"
+#include "isis_misc.h"
+#include "isis_mt.h"
+#include "isisd.h"
+#include "isis_vty_common.h"
+
+static int level_for_arg(const char *arg)
+{
+ if (!strcmp(arg, "level-1"))
+ return IS_LEVEL_1;
+ else
+ return IS_LEVEL_2;
+}
+
+DEFUN (isis_circuit_type,
+ isis_circuit_type_cmd,
+ "isis circuit-type <level-1|level-1-2|level-2-only>",
+ "IS-IS routing protocol\n"
+ "Configure circuit type for interface\n"
+ "Level-1 only adjacencies are formed\n"
+ "Level-1-2 adjacencies are formed\n"
+ "Level-2 only adjacencies are formed\n")
+{
+ int idx_level = 2;
+ int is_type;
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ is_type = string2circuit_t(argv[idx_level]->arg);
+ if (!is_type) {
+ vty_out(vty, "Unknown circuit-type \n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (circuit->state == C_STATE_UP
+ && circuit->area->is_type != IS_LEVEL_1_AND_2
+ && circuit->area->is_type != is_type) {
+ vty_out(vty, "Invalid circuit level for area %s.\n",
+ circuit->area->area_tag);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ isis_circuit_is_type_set(circuit, is_type);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_circuit_type,
+ no_isis_circuit_type_cmd,
+ "no isis circuit-type <level-1|level-1-2|level-2-only>",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Configure circuit type for interface\n"
+ "Level-1 only adjacencies are formed\n"
+ "Level-1-2 adjacencies are formed\n"
+ "Level-2 only adjacencies are formed\n")
+{
+ int is_type;
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ /*
+ * Set the circuits level to its default value
+ */
+ if (circuit->state == C_STATE_UP)
+ is_type = circuit->area->is_type;
+ else
+ is_type = IS_LEVEL_1_AND_2;
+ isis_circuit_is_type_set(circuit, is_type);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_network,
+ isis_network_cmd,
+ "isis network point-to-point",
+ "IS-IS routing protocol\n"
+ "Set network type\n"
+ "point-to-point network type\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) {
+ vty_out(vty,
+ "isis network point-to-point is valid only on broadcast interfaces\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_network,
+ no_isis_network_cmd,
+ "no isis network point-to-point",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set network type for circuit\n"
+ "point-to-point network type\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) {
+ vty_out(vty,
+ "isis network point-to-point is valid only on broadcast interfaces\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_priority,
+ isis_priority_cmd,
+ "isis priority (0-127)",
+ "IS-IS routing protocol\n"
+ "Set priority for Designated Router election\n"
+ "Priority value\n")
+{
+ uint8_t prio = atoi(argv[2]->arg);
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->priority[0] = prio;
+ circuit->priority[1] = prio;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_priority,
+ no_isis_priority_cmd,
+ "no isis priority [(0-127)]",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set priority for Designated Router election\n"
+ "Priority value\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->priority[0] = DEFAULT_PRIORITY;
+ circuit->priority[1] = DEFAULT_PRIORITY;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_priority_level,
+ isis_priority_level_cmd,
+ "isis priority (0-127) <level-1|level-2>",
+ "IS-IS routing protocol\n"
+ "Set priority for Designated Router election\n"
+ "Priority value\n"
+ "Specify priority for level-1 routing\n"
+ "Specify priority for level-2 routing\n")
+{
+ uint8_t prio = atoi(argv[2]->arg);
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->priority[level_for_arg(argv[3]->text)] = prio;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_priority_level,
+ no_isis_priority_level_cmd,
+ "no isis priority [(0-127)] <level-1|level-2>",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set priority for Designated Router election\n"
+ "Priority value\n"
+ "Specify priority for level-1 routing\n"
+ "Specify priority for level-2 routing\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ int level = level_for_arg(argv[argc - 1]->text);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->priority[level] = DEFAULT_PRIORITY;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_metric_level,
+ isis_metric_level_cmd,
+ "isis metric (0-16777215) <level-1|level-2>",
+ "IS-IS routing protocol\n"
+ "Set default metric for circuit\n"
+ "Default metric value\n"
+ "Specify metric for level-1 routing\n"
+ "Specify metric for level-2 routing\n")
+{
+ uint32_t met = atoi(argv[2]->arg);
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ CMD_FERR_RETURN(isis_circuit_metric_set(circuit,
+ level_for_arg(argv[3]->text),
+ met),
+ "Failed to set metric: $ERR");
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_metric_level,
+ no_isis_metric_level_cmd,
+ "no isis metric [(0-16777215)] <level-1|level-2>",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set default metric for circuit\n"
+ "Default metric value\n"
+ "Specify metric for level-1 routing\n"
+ "Specify metric for level-2 routing\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ int level = level_for_arg(argv[argc - 1]->text);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ CMD_FERR_RETURN(isis_circuit_metric_set(circuit, level,
+ DEFAULT_CIRCUIT_METRIC),
+ "Failed to set L1 metric: $ERR");
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_hello_interval_level,
+ isis_hello_interval_level_cmd,
+ "isis hello-interval (1-600) <level-1|level-2>",
+ "IS-IS routing protocol\n"
+ "Set Hello interval\n"
+ "Holdtime 1 second, interval depends on multiplier\n"
+ "Specify hello-interval for level-1 IIHs\n"
+ "Specify hello-interval for level-2 IIHs\n")
+{
+ uint32_t interval = atoi(argv[2]->arg);
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->hello_interval[level_for_arg(argv[3]->text)] = interval;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_hello_interval_level,
+ no_isis_hello_interval_level_cmd,
+ "no isis hello-interval [(1-600)] <level-1|level-2>",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set Hello interval\n"
+ "Holdtime 1 second, interval depends on multiplier\n"
+ "Specify hello-interval for level-1 IIHs\n"
+ "Specify hello-interval for level-2 IIHs\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ int level = level_for_arg(argv[argc - 1]->text);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->hello_interval[level] = DEFAULT_HELLO_INTERVAL;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_hello_multiplier_level,
+ isis_hello_multiplier_level_cmd,
+ "isis hello-multiplier (2-100) <level-1|level-2>",
+ "IS-IS routing protocol\n"
+ "Set multiplier for Hello holding time\n"
+ "Hello multiplier value\n"
+ "Specify hello multiplier for level-1 IIHs\n"
+ "Specify hello multiplier for level-2 IIHs\n")
+{
+ uint16_t mult = atoi(argv[2]->arg);
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->hello_multiplier[level_for_arg(argv[3]->text)] = mult;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_hello_multiplier_level,
+ no_isis_hello_multiplier_level_cmd,
+ "no isis hello-multiplier [(2-100)] <level-1|level-2>",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set multiplier for Hello holding time\n"
+ "Hello multiplier value\n"
+ "Specify hello multiplier for level-1 IIHs\n"
+ "Specify hello multiplier for level-2 IIHs\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ int level = level_for_arg(argv[argc - 1]->text);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->hello_multiplier[level] = DEFAULT_HELLO_MULTIPLIER;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_threeway_adj,
+ isis_threeway_adj_cmd,
+ "[no] isis three-way-handshake",
+ NO_STR
+ "IS-IS commands\n"
+ "Enable/Disable three-way handshake\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->disable_threeway_adj = !strcmp(argv[0]->text, "no");
+ return CMD_SUCCESS;
+}
+
+DEFUN (isis_hello_padding,
+ isis_hello_padding_cmd,
+ "isis hello padding",
+ "IS-IS routing protocol\n"
+ "Add padding to IS-IS hello packets\n"
+ "Pad hello packets\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->pad_hellos = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_hello_padding,
+ no_isis_hello_padding_cmd,
+ "no isis hello padding",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Add padding to IS-IS hello packets\n"
+ "Pad hello packets\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->pad_hellos = 0;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (csnp_interval_level,
+ csnp_interval_level_cmd,
+ "isis csnp-interval (1-600) <level-1|level-2>",
+ "IS-IS routing protocol\n"
+ "Set CSNP interval in seconds\n"
+ "CSNP interval value\n"
+ "Specify interval for level-1 CSNPs\n"
+ "Specify interval for level-2 CSNPs\n")
+{
+ uint16_t interval = atoi(argv[2]->arg);
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->csnp_interval[level_for_arg(argv[3]->text)] = interval;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_csnp_interval_level,
+ no_csnp_interval_level_cmd,
+ "no isis csnp-interval [(1-600)] <level-1|level-2>",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set CSNP interval in seconds\n"
+ "CSNP interval value\n"
+ "Specify interval for level-1 CSNPs\n"
+ "Specify interval for level-2 CSNPs\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ int level = level_for_arg(argv[argc - 1]->text);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->csnp_interval[level] = DEFAULT_CSNP_INTERVAL;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (psnp_interval_level,
+ psnp_interval_level_cmd,
+ "isis psnp-interval (1-120) <level-1|level-2>",
+ "IS-IS routing protocol\n"
+ "Set PSNP interval in seconds\n"
+ "PSNP interval value\n"
+ "Specify interval for level-1 PSNPs\n"
+ "Specify interval for level-2 PSNPs\n")
+{
+ uint16_t interval = atoi(argv[2]->arg);
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->psnp_interval[level_for_arg(argv[3]->text)] = (uint16_t)interval;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_psnp_interval_level,
+ no_psnp_interval_level_cmd,
+ "no isis psnp-interval [(1-120)] <level-1|level-2>",
+ NO_STR
+ "IS-IS routing protocol\n"
+ "Set PSNP interval in seconds\n"
+ "PSNP interval value\n"
+ "Specify interval for level-1 PSNPs\n"
+ "Specify interval for level-2 PSNPs\n")
+{
+ struct isis_circuit *circuit = isis_circuit_lookup(vty);
+ int level = level_for_arg(argv[argc - 1]->text);
+ if (!circuit)
+ return CMD_ERR_NO_MATCH;
+
+ circuit->psnp_interval[level] = DEFAULT_PSNP_INTERVAL;
+
+ return CMD_SUCCESS;
+}
+
+static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area)
+{
+ struct isis_circuit *circuit;
+ struct listnode *node;
+
+ if (!vty)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ if (!area) {
+ vty_out(vty, "ISIS area is invalid\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
+ if ((area->is_type & IS_LEVEL_1)
+ && (circuit->is_type & IS_LEVEL_1)
+ && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) {
+ vty_out(vty, "ISIS circuit %s metric is invalid\n",
+ circuit->interface->name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if ((area->is_type & IS_LEVEL_2)
+ && (circuit->is_type & IS_LEVEL_2)
+ && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) {
+ vty_out(vty, "ISIS circuit %s metric is invalid\n",
+ circuit->interface->name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (metric_style,
+ metric_style_cmd,
+ "metric-style <narrow|transition|wide>",
+ "Use old-style (ISO 10589) or new-style packet formats\n"
+ "Use old style of TLVs with narrow metric\n"
+ "Send and accept both styles of TLVs during transition\n"
+ "Use new style of TLVs to carry wider metric\n")
+{
+ int idx_metric_style = 1;
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+ int ret;
+
+ if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) {
+ isis_area_metricstyle_set(area, false, true);
+ return CMD_SUCCESS;
+ }
+
+ if (area_is_mt(area)) {
+ vty_out(vty,
+ "Narrow metrics cannot be used while multi topology IS-IS is active\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = validate_metric_style_narrow(vty, area);
+ if (ret != CMD_SUCCESS)
+ return ret;
+
+ if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0)
+ isis_area_metricstyle_set(area, true, true);
+ else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0)
+ isis_area_metricstyle_set(area, true, false);
+ return CMD_SUCCESS;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_metric_style,
+ no_metric_style_cmd,
+ "no metric-style",
+ NO_STR
+ "Use old-style (ISO 10589) or new-style packet formats\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+ int ret;
+
+ if (area_is_mt(area)) {
+ vty_out(vty,
+ "Narrow metrics cannot be used while multi topology IS-IS is active\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = validate_metric_style_narrow(vty, area);
+ if (ret != CMD_SUCCESS)
+ return ret;
+
+ isis_area_metricstyle_set(area, true, false);
+ return CMD_SUCCESS;
+}
+
+DEFUN (set_attached_bit,
+ set_attached_bit_cmd,
+ "set-attached-bit",
+ "Set attached bit to identify as L1/L2 router for inter-area traffic\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ isis_area_attached_bit_set(area, true);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_set_attached_bit,
+ no_set_attached_bit_cmd,
+ "no set-attached-bit",
+ NO_STR
+ "Reset attached bit\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ isis_area_attached_bit_set(area, false);
+ return CMD_SUCCESS;
+}
+
+DEFUN (dynamic_hostname,
+ dynamic_hostname_cmd,
+ "hostname dynamic",
+ "Dynamic hostname for IS-IS\n"
+ "Dynamic hostname\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ isis_area_dynhostname_set(area, true);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_dynamic_hostname,
+ no_dynamic_hostname_cmd,
+ "no hostname dynamic",
+ NO_STR
+ "Dynamic hostname for IS-IS\n"
+ "Dynamic hostname\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ isis_area_dynhostname_set(area, false);
+ return CMD_SUCCESS;
+}
+
+DEFUN (is_type,
+ is_type_cmd,
+ "is-type <level-1|level-1-2|level-2-only>",
+ "IS Level for this routing process (OSI only)\n"
+ "Act as a station router only\n"
+ "Act as both a station router and an area router\n"
+ "Act as an area router only\n")
+{
+ int idx_level = 1;
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+ int type;
+
+ type = string2circuit_t(argv[idx_level]->arg);
+ if (!type) {
+ vty_out(vty, "Unknown IS level \n");
+ return CMD_SUCCESS;
+ }
+
+ isis_area_is_type_set(area, type);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_is_type,
+ no_is_type_cmd,
+ "no is-type <level-1|level-1-2|level-2-only>",
+ NO_STR
+ "IS Level for this routing process (OSI only)\n"
+ "Act as a station router only\n"
+ "Act as both a station router and an area router\n"
+ "Act as an area router only\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+ int type;
+
+ /*
+ * Put the is-type back to defaults:
+ * - level-1-2 on first area
+ * - level-1 for the rest
+ */
+ if (listgetdata(listhead(isis->area_list)) == area)
+ type = IS_LEVEL_1_AND_2;
+ else
+ type = IS_LEVEL_1;
+
+ isis_area_is_type_set(area, type);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (lsp_gen_interval_level,
+ lsp_gen_interval_level_cmd,
+ "lsp-gen-interval <level-1|level-2> (1-120)",
+ "Minimum interval between regenerating same LSP\n"
+ "Set interval for level 1 only\n"
+ "Set interval for level 2 only\n"
+ "Minimum interval in seconds\n")
+{
+ uint16_t interval = atoi(argv[2]->arg);
+
+ return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[1]->text),
+ interval);
+}
+
+DEFUN (no_lsp_gen_interval_level,
+ no_lsp_gen_interval_level_cmd,
+ "no lsp-gen-interval <level-1|level-2> [(1-120)]",
+ NO_STR
+ "Minimum interval between regenerating same LSP\n"
+ "Set interval for level 1 only\n"
+ "Set interval for level 2 only\n"
+ "Minimum interval in seconds\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[2]->text),
+ DEFAULT_MIN_LSP_GEN_INTERVAL);
+}
+
+DEFUN (max_lsp_lifetime_level,
+ max_lsp_lifetime_level_cmd,
+ "max-lsp-lifetime <level-1|level-2> (350-65535)",
+ "Maximum LSP lifetime\n"
+ "Maximum LSP lifetime for Level 1 only\n"
+ "Maximum LSP lifetime for Level 2 only\n"
+ "LSP lifetime in seconds\n")
+{
+ uint16_t lifetime = atoi(argv[2]->arg);
+
+ return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text),
+ lifetime);
+}
+
+DEFUN (no_max_lsp_lifetime_level,
+ no_max_lsp_lifetime_level_cmd,
+ "no max-lsp-lifetime <level-1|level-2> [(350-65535)]",
+ NO_STR
+ "Maximum LSP lifetime\n"
+ "Maximum LSP lifetime for Level 1 only\n"
+ "Maximum LSP lifetime for Level 2 only\n"
+ "LSP lifetime in seconds\n")
+{
+ return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text),
+ DEFAULT_LSP_LIFETIME);
+}
+
+DEFUN (spf_interval_level,
+ spf_interval_level_cmd,
+ "spf-interval <level-1|level-2> (1-120)",
+ "Minimum interval between SPF calculations\n"
+ "Set interval for level 1 only\n"
+ "Set interval for level 2 only\n"
+ "Minimum interval between consecutive SPFs in seconds\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+ uint16_t interval = atoi(argv[2]->arg);
+
+ area->min_spf_interval[level_for_arg(argv[1]->text)] = interval;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_spf_interval_level,
+ no_spf_interval_level_cmd,
+ "no spf-interval <level-1|level-2> [(1-120)]",
+ NO_STR
+ "Minimum interval between SPF calculations\n"
+ "Set interval for level 1 only\n"
+ "Set interval for level 2 only\n"
+ "Minimum interval between consecutive SPFs in seconds\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+ int level = level_for_arg(argv[1]->text);
+
+ area->min_spf_interval[level] = MINIMUM_SPF_INTERVAL;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (lsp_refresh_interval_level,
+ lsp_refresh_interval_level_cmd,
+ "lsp-refresh-interval <level-1|level-2> (1-65235)",
+ "LSP refresh interval\n"
+ "LSP refresh interval for Level 1 only\n"
+ "LSP refresh interval for Level 2 only\n"
+ "LSP refresh interval in seconds\n")
+{
+ uint16_t interval = atoi(argv[2]->arg);
+ return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[1]->text),
+ interval);
+}
+
+DEFUN (no_lsp_refresh_interval_level,
+ no_lsp_refresh_interval_level_cmd,
+ "no lsp-refresh-interval <level-1|level-2> [(1-65235)]",
+ NO_STR
+ "LSP refresh interval\n"
+ "LSP refresh interval for Level 1 only\n"
+ "LSP refresh interval for Level 2 only\n"
+ "LSP refresh interval in seconds\n")
+{
+ return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[2]->text),
+ DEFAULT_MAX_LSP_GEN_INTERVAL);
+}
+
+DEFUN (area_passwd,
+ area_passwd_cmd,
+ "area-password <clear|md5> WORD [authenticate snp <send-only|validate>]",
+ "Configure the authentication password for an area\n"
+ "Authentication type\n"
+ "Authentication type\n"
+ "Area password\n"
+ "Authentication\n"
+ "SNP PDUs\n"
+ "Send but do not check PDUs on receiving\n"
+ "Send and check PDUs on receiving\n")
+{
+ return isis_vty_password_set(vty, argc, argv, IS_LEVEL_1);
+}
+
+DEFUN (no_area_passwd,
+ no_area_passwd_cmd,
+ "no area-password",
+ NO_STR
+ "Configure the authentication password for an area\n")
+{
+ VTY_DECLVAR_CONTEXT(isis_area, area);
+
+ return isis_area_passwd_unset(area, IS_LEVEL_1);
+}
+
+void isis_vty_daemon_init(void)
+{
+ install_element(INTERFACE_NODE, &isis_circuit_type_cmd);
+ install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd);
+
+ install_element(INTERFACE_NODE, &isis_network_cmd);
+ install_element(INTERFACE_NODE, &no_isis_network_cmd);
+
+ install_element(INTERFACE_NODE, &isis_priority_cmd);
+ install_element(INTERFACE_NODE, &no_isis_priority_cmd);
+ install_element(INTERFACE_NODE, &isis_priority_level_cmd);
+ install_element(INTERFACE_NODE, &no_isis_priority_level_cmd);
+
+ install_element(INTERFACE_NODE, &isis_metric_level_cmd);
+ install_element(INTERFACE_NODE, &no_isis_metric_level_cmd);
+
+ install_element(INTERFACE_NODE, &isis_hello_interval_level_cmd);
+ install_element(INTERFACE_NODE, &no_isis_hello_interval_level_cmd);
+
+ install_element(INTERFACE_NODE, &isis_hello_multiplier_level_cmd);
+ install_element(INTERFACE_NODE, &no_isis_hello_multiplier_level_cmd);
+
+ install_element(INTERFACE_NODE, &isis_threeway_adj_cmd);
+
+ install_element(INTERFACE_NODE, &isis_hello_padding_cmd);
+ install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd);
+
+ install_element(INTERFACE_NODE, &csnp_interval_level_cmd);
+ install_element(INTERFACE_NODE, &no_csnp_interval_level_cmd);
+
+ install_element(INTERFACE_NODE, &psnp_interval_level_cmd);
+ install_element(INTERFACE_NODE, &no_psnp_interval_level_cmd);
+
+ install_element(ROUTER_NODE, &metric_style_cmd);
+ install_element(ROUTER_NODE, &no_metric_style_cmd);
+
+ install_element(ROUTER_NODE, &set_attached_bit_cmd);
+ install_element(ROUTER_NODE, &no_set_attached_bit_cmd);
+
+ install_element(ROUTER_NODE, &dynamic_hostname_cmd);
+ install_element(ROUTER_NODE, &no_dynamic_hostname_cmd);
+
+ install_element(ROUTER_NODE, &is_type_cmd);
+ install_element(ROUTER_NODE, &no_is_type_cmd);
+
+ install_element(ROUTER_NODE, &lsp_gen_interval_level_cmd);
+ install_element(ROUTER_NODE, &no_lsp_gen_interval_level_cmd);
+
+ install_element(ROUTER_NODE, &max_lsp_lifetime_level_cmd);
+ install_element(ROUTER_NODE, &no_max_lsp_lifetime_level_cmd);
+
+ install_element(ROUTER_NODE, &spf_interval_level_cmd);
+ install_element(ROUTER_NODE, &no_spf_interval_level_cmd);
+
+ install_element(ROUTER_NODE, &lsp_refresh_interval_level_cmd);
+ install_element(ROUTER_NODE, &no_lsp_refresh_interval_level_cmd);
+
+ install_element(ROUTER_NODE, &area_passwd_cmd);
+ install_element(ROUTER_NODE, &no_area_passwd_cmd);
+}
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) {
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) {
*/
if (api.prefix.prefixlen == 0
&& api.src_prefix.prefixlen == 0
- && api.type == ZEBRA_ROUTE_ISIS) {
+ && api.type == PROTO_TYPE) {
command = ZEBRA_REDISTRIBUTE_ROUTE_DEL;
}
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;
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
#include "isisd/isis_mt.h"
+#include "isisd/fabricd.h"
struct isis *isis = NULL;
*/
/* isis->debugs = 0xFFFF; */
isisMplsTE.status = disable; /* Only support TE metric */
+
QOBJ_REG(isis, isis);
}
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;
listnode_add(isis->area_list, area);
area->isis = isis;
+ if (fabricd)
+ area->fabricd = fabricd_new(area);
QOBJ_REG(area, isis_area);
return area;
area = isis_area_lookup(area_tag);
if (area) {
- VTY_PUSH_CONTEXT(ISIS_NODE, area);
+ VTY_PUSH_CONTEXT(ROUTER_NODE, area);
return CMD_SUCCESS;
}
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;
}
QOBJ_UNREG(area);
+ if (fabricd)
+ fabricd_finish(area->fabricd);
+
if (area->circuit_list) {
for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
circuit)) {
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);
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")
{
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")
{
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);
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")
{
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")
{
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")
{
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);
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);
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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);
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");
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;
}
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,
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")
{
*/
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;
*/
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);
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) {
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) {
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);
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]
}
write += area_write_mt_settings(area, vty);
+ write += fabricd_write_settings(area, vty);
}
isis_mpls_te_config_write_router(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);
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();
}
#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;
*/
int lsp_regenerate_pending[ISIS_LEVELS];
+ struct fabricd *fabricd;
+
/*
* Configurables
*/
/* 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]
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;
#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 { \
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 \
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 \
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)
-!Makefile
-Makefile.in
-*.o
ldpd
ldpd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
switch (a->source.type) {
case HELLO_LINK:
- if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
- (char *)b->source.link.ia->iface->name) < 0)
+ if (if_cmp_name_func(a->source.link.ia->iface->name,
+ b->source.link.ia->iface->name) < 0)
return (-1);
- if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
- (char *)b->source.link.ia->iface->name) > 0)
+ if (if_cmp_name_func(a->source.link.ia->iface->name,
+ b->source.link.ia->iface->name) > 0)
return (1);
return (ldp_addrcmp(a->source.link.ia->af,
&a->source.link.src_addr, &b->source.link.src_addr));
static __inline int
iface_compare(const struct iface *a, const struct iface *b)
{
- return (if_cmp_name_func((char *)a->name, (char *)b->name));
+ return if_cmp_name_func(a->name, b->name);
}
struct iface *
static __inline int
l2vpn_if_compare(const struct l2vpn_if *a, const struct l2vpn_if *b)
{
- return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
+ return if_cmp_name_func(a->ifname, b->ifname);
}
struct l2vpn_if *
static __inline int
l2vpn_pw_compare(const struct l2vpn_pw *a, const struct l2vpn_pw *b)
{
- return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
+ return if_cmp_name_func(a->ifname, b->ifname);
}
struct l2vpn_pw *
{
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)
sock_set_nonblock(zclient_sync->sock);
/* Connect to label manager */
- while (lm_label_manager_connect(zclient_sync) != 0) {
+ while (lm_label_manager_connect(zclient_sync, 0) != 0) {
log_warnx("Error connecting to label manager!");
sleep(1);
}
nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
if (nullfd == -1) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: failed to open /dev/null: %s", __func__,
safe_strerror(errno));
} else {
* 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>
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 = \
-!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
msg[strlen(msg) - 1] = '\0';
switch (slm->priority) {
case LOG_EMERG:
- flog_err(LIB_ERR_SNMP,
- "snmp[emerg]: %s", msg ? msg : slm->msg);
+ flog_err(EC_LIB_SNMP, "snmp[emerg]: %s", msg ? msg : slm->msg);
break;
case LOG_ALERT:
- flog_err(LIB_ERR_SNMP,
- "snmp[alert]: %s", msg ? msg : slm->msg);
+ flog_err(EC_LIB_SNMP, "snmp[alert]: %s", msg ? msg : slm->msg);
break;
case LOG_CRIT:
- flog_err(LIB_ERR_SNMP,
- "snmp[crit]: %s", msg ? msg : slm->msg);
+ flog_err(EC_LIB_SNMP, "snmp[crit]: %s", msg ? msg : slm->msg);
break;
case LOG_ERR:
- flog_err(LIB_ERR_SNMP,
- "snmp[err]: %s", msg ? msg : slm->msg);
+ flog_err(EC_LIB_SNMP, "snmp[err]: %s", msg ? msg : slm->msg);
break;
case LOG_WARNING:
- zlog_warn("snmp[warning]: %s", msg ? msg : slm->msg);
+ flog_warn(EC_LIB_SNMP, "snmp[warning]: %s",
+ msg ? msg : slm->msg);
break;
case LOG_NOTICE:
zlog_notice("snmp[notice]: %s", msg ? msg : slm->msg);
} else {
/* This should absolutely never occur. */
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"%s: corruption detected: iov_small overflowed; "
"head %p, tail %p, head->next %p",
__func__, (void *)b->head,
iov_size =
((iov_index > IOV_MAX) ? IOV_MAX : iov_index);
if ((nbytes = writev(fd, c_iov, iov_size)) < 0) {
- zlog_warn("%s: writev to fd %d failed: %s",
- __func__, fd, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "%s: writev to fd %d failed: %s",
+ __func__, fd, safe_strerror(errno));
break;
}
}
#else /* IOV_MAX */
if ((nbytes = writev(fd, iov, iov_index)) < 0)
- zlog_warn("%s: writev to fd %d failed: %s", __func__, fd,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "%s: writev to fd %d failed: %s",
+ __func__, fd, safe_strerror(errno));
#endif /* IOV_MAX */
/* Free printed buffer data. */
if (ERRNO_IO_RETRY(errno))
/* Calling code should try again later. */
return BUFFER_PENDING;
- zlog_warn("%s: write error on fd %d: %s", __func__, fd,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "%s: write error on fd %d: %s",
+ __func__, fd, safe_strerror(errno));
return BUFFER_ERROR;
}
/* Free printed buffer data. */
while (written > 0) {
- struct buffer_data *d;
if (!(d = b->head)) {
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"%s: corruption detected: buffer queue empty, but written is %lu",
__func__, (unsigned long)written);
break;
if (ERRNO_IO_RETRY(errno))
nbytes = 0;
else {
- zlog_warn("%s: write error on fd %d: %s", __func__, fd,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "%s: write error on fd %d: %s",
+ __func__, fd, safe_strerror(errno));
return BUFFER_ERROR;
}
}
*/
"bfd", /* BFD_NODE */
"bfd peer", /* BFD_PEER_NODE */
+ "openfabric", // OPENFABRIC_NODE
};
/* clang-format on */
*/
static int compare_completions(const void *fst, const void *snd)
{
- struct cmd_token *first = *(struct cmd_token **)fst,
- *secnd = *(struct cmd_token **)snd;
+ const struct cmd_token *first = *(const struct cmd_token * const *)fst,
+ *secnd = *(const struct cmd_token * const *)snd;
return strcmp(first->text, secnd->text);
}
/* retrieve action */
token = strsep(&working, " ");
+ assert(token);
/* match result to known actions */
if (strmatch(token, "include")) {
case LDP_NODE:
case LDP_L2VPN_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
case LDP_L2VPN_NODE:
case LDP_PSEUDOWIRE_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case KEYCHAIN_KEY_NODE:
case VTY_NODE:
cwd[MAXPATHLEN] = '\0';
if (getcwd(cwd, MAXPATHLEN) == NULL) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"config_log_file: Unable to alloc mem!");
return CMD_WARNING_CONFIG_FAILED;
}
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 */
};
#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"
* 02111-1307, USA.
*/
+%top{
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+}
%{
/* ignore flex generated code in static analyzer */
#ifndef __clang_analyzer__
enum matcher_rv status = MATCHER_NO_MATCH;
// get the minimum match level that can count as a full match
- struct cmd_token *token = start->data;
+ struct cmd_token *copy, *token = start->data;
enum match_type minmatch = min_match_level(token->type);
/* check history/stack of tokens
}
if (*currbest) {
// copy token, set arg and prepend to currbest
- struct cmd_token *token = start->data;
- struct cmd_token *copy = cmd_token_dup(token);
+ token = start->data;
+ copy = cmd_token_dup(token);
copy->arg = XSTRDUP(MTYPE_CMD_ARG, input_token);
listnode_add_before(*currbest, (*currbest)->head, copy);
} else if (n + 1 == vector_active(vline) && status == MATCHER_NO_MATCH)
* 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>
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));
-%{
/*
* 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"
* 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>
#include <zebra.h>
#include <pthread.h>
+#ifdef HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
#include <sched.h>
#include "frr_pthread.h"
#include "memory.h"
-#include "hash.h"
+#include "linklist.h"
DEFINE_MTYPE(LIB, FRR_PTHREAD, "FRR POSIX Thread");
DEFINE_MTYPE(LIB, PTHREAD_PRIM, "POSIX synchronization primitives");
-/* id for next created pthread */
-static _Atomic uint32_t next_id = 0;
-
/* default frr_pthread start/stop routine prototypes */
static void *fpt_run(void *arg);
static int fpt_halt(struct frr_pthread *fpt, void **res);
/* default frr_pthread attributes */
struct frr_pthread_attr frr_pthread_attr_default = {
- .id = 0,
.start = fpt_run,
.stop = fpt_halt,
};
-/* hash table to keep track of all frr_pthreads */
-static struct hash *frr_pthread_hash;
-static pthread_mutex_t frr_pthread_hash_mtx = PTHREAD_MUTEX_INITIALIZER;
-
-/* frr_pthread_hash->hash_cmp */
-static int frr_pthread_hash_cmp(const void *value1, const void *value2)
-{
- const struct frr_pthread *tq1 = value1;
- const struct frr_pthread *tq2 = value2;
-
- return (tq1->attr.id == tq2->attr.id);
-}
-
-/* frr_pthread_hash->hash_key */
-static unsigned int frr_pthread_hash_key(void *value)
-{
- return ((struct frr_pthread *)value)->attr.id;
-}
+/* list to keep track of all frr_pthreads */
+static pthread_mutex_t frr_pthread_list_mtx = PTHREAD_MUTEX_INITIALIZER;
+static struct list *frr_pthread_list;
/* ------------------------------------------------------------------------ */
void frr_pthread_init()
{
- pthread_mutex_lock(&frr_pthread_hash_mtx);
+ pthread_mutex_lock(&frr_pthread_list_mtx);
{
- frr_pthread_hash = hash_create(frr_pthread_hash_key,
- frr_pthread_hash_cmp, NULL);
+ frr_pthread_list = list_new();
+ frr_pthread_list->del = (void (*)(void *))&frr_pthread_destroy;
}
- pthread_mutex_unlock(&frr_pthread_hash_mtx);
+ pthread_mutex_unlock(&frr_pthread_list_mtx);
}
void frr_pthread_finish()
{
- pthread_mutex_lock(&frr_pthread_hash_mtx);
+ pthread_mutex_lock(&frr_pthread_list_mtx);
{
- hash_clean(frr_pthread_hash,
- (void (*)(void *))frr_pthread_destroy);
- hash_free(frr_pthread_hash);
+ list_delete_and_null(&frr_pthread_list);
}
- pthread_mutex_unlock(&frr_pthread_hash_mtx);
+ pthread_mutex_unlock(&frr_pthread_list_mtx);
}
struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr,
const char *name, const char *os_name)
{
- static struct frr_pthread holder = {};
struct frr_pthread *fpt = NULL;
attr = attr ? attr : &frr_pthread_attr_default;
- pthread_mutex_lock(&frr_pthread_hash_mtx);
+ fpt = XCALLOC(MTYPE_FRR_PTHREAD, sizeof(struct frr_pthread));
+ /* initialize mutex */
+ pthread_mutex_init(&fpt->mtx, NULL);
+ /* create new thread master */
+ fpt->master = thread_master_create(name);
+ /* set attributes */
+ fpt->attr = *attr;
+ name = (name ? name : "Anonymous thread");
+ fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name);
+ if (os_name)
+ snprintf(fpt->os_name, OS_THREAD_NAMELEN, "%s", os_name);
+ /* initialize startup synchronization primitives */
+ fpt->running_cond_mtx = XCALLOC(
+ MTYPE_PTHREAD_PRIM, sizeof(pthread_mutex_t));
+ fpt->running_cond = XCALLOC(MTYPE_PTHREAD_PRIM,
+ sizeof(pthread_cond_t));
+ pthread_mutex_init(fpt->running_cond_mtx, NULL);
+ pthread_cond_init(fpt->running_cond, NULL);
+
+ pthread_mutex_lock(&frr_pthread_list_mtx);
{
- holder.attr.id = attr->id;
-
- if (!hash_lookup(frr_pthread_hash, &holder)) {
- fpt = XCALLOC(MTYPE_FRR_PTHREAD,
- sizeof(struct frr_pthread));
- /* initialize mutex */
- pthread_mutex_init(&fpt->mtx, NULL);
- /* create new thread master */
- fpt->master = thread_master_create(name);
- /* set attributes */
- fpt->attr = *attr;
- name = (name ? name : "Anonymous thread");
- fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name);
- if (os_name)
- snprintf(fpt->os_name, OS_THREAD_NAMELEN,
- "%s", os_name);
- if (attr == &frr_pthread_attr_default)
- fpt->attr.id = frr_pthread_get_id();
- /* initialize startup synchronization primitives */
- fpt->running_cond_mtx = XCALLOC(
- MTYPE_PTHREAD_PRIM, sizeof(pthread_mutex_t));
- fpt->running_cond = XCALLOC(MTYPE_PTHREAD_PRIM,
- sizeof(pthread_cond_t));
- pthread_mutex_init(fpt->running_cond_mtx, NULL);
- pthread_cond_init(fpt->running_cond, NULL);
-
- /* insert into global thread hash */
- hash_get(frr_pthread_hash, fpt, hash_alloc_intern);
- }
+ listnode_add(frr_pthread_list, fpt);
}
- pthread_mutex_unlock(&frr_pthread_hash_mtx);
+ pthread_mutex_unlock(&frr_pthread_list_mtx);
return fpt;
}
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
}
return ret;
}
-struct frr_pthread *frr_pthread_get(uint32_t id)
-{
- static struct frr_pthread holder = {};
- struct frr_pthread *fpt;
-
- pthread_mutex_lock(&frr_pthread_hash_mtx);
- {
- holder.attr.id = id;
- fpt = hash_lookup(frr_pthread_hash, &holder);
- }
- pthread_mutex_unlock(&frr_pthread_hash_mtx);
-
- return fpt;
-}
-
int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr)
{
int ret;
return ret;
}
-/*
- * Callback for hash_iterate to stop all frr_pthread's.
- */
-static void frr_pthread_stop_all_iter(struct hash_backet *hb, void *arg)
-{
- struct frr_pthread *fpt = hb->data;
- frr_pthread_stop(fpt, NULL);
-}
-
void frr_pthread_stop_all()
{
- pthread_mutex_lock(&frr_pthread_hash_mtx);
+ pthread_mutex_lock(&frr_pthread_list_mtx);
{
- hash_iterate(frr_pthread_hash, frr_pthread_stop_all_iter, NULL);
+ struct listnode *n;
+ struct frr_pthread *fpt;
+ for (ALL_LIST_ELEMENTS_RO(frr_pthread_list, n, fpt))
+ frr_pthread_stop(fpt, NULL);
}
- pthread_mutex_unlock(&frr_pthread_hash_mtx);
-}
-
-uint32_t frr_pthread_get_id(void)
-{
- _Atomic uint32_t nxid;
- nxid = atomic_fetch_add_explicit(&next_id, 1, memory_order_seq_cst);
- /* just a sanity check, this should never happen */
- assert(nxid <= (UINT32_MAX - 1));
- return nxid;
-}
-
-void frr_pthread_yield(void)
-{
- (void)sched_yield();
+ pthread_mutex_unlock(&frr_pthread_list_mtx);
}
/*
struct frr_pthread_attr;
struct frr_pthread_attr {
- _Atomic uint32_t id;
void *(*start)(void *);
int (*stop)(struct frr_pthread *, void **);
};
*/
void frr_pthread_destroy(struct frr_pthread *fpt);
-/*
- * Gets an existing frr_pthread by its id.
- *
- * @return frr_thread associated with the provided id, or NULL on error
- */
-struct frr_pthread *frr_pthread_get(uint32_t id);
-
/*
* Creates a new pthread and binds it to a frr_pthread.
*
/* Stops all frr_pthread's. */
void frr_pthread_stop_all(void);
-/* Yields the current thread of execution */
-void frr_pthread_yield(void);
-
-/*
- * Returns a unique identifier for use with frr_pthread_new().
- *
- * Internally, this is an integer that increments after each call to this
- * function. Because the number of pthreads created should never exceed INT_MAX
- * during the life of the program, there is no overflow protection. If by
- * chance this function returns an ID which is already in use,
- * frr_pthread_new() will fail when it is provided.
- *
- * @return unique identifier
- */
-uint32_t frr_pthread_get_id(void);
+#ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK
+#define pthread_condattr_setclock(A, B)
+#endif
#endif /* _FRR_PTHREAD_H */
return 0;
out_err:
- flog_err(LIB_ERR_ZMQ, "ZeroMQ read error: %s(%d)", strerror(errno),
- errno);
+ flog_err(EC_LIB_ZMQ, "ZeroMQ read error: %s(%d)", strerror(errno),
+ errno);
if (cb->read.cb_error)
cb->read.cb_error(cb->read.arg, cb->zmqsock);
return 1;
return 0;
out_err:
- flog_err(LIB_ERR_ZMQ, "ZeroMQ write error: %s(%d)", strerror(errno),
- errno);
+ flog_err(EC_LIB_ZMQ, "ZeroMQ write error: %s(%d)", strerror(errno),
+ errno);
if (cb->write.cb_error)
cb->write.cb_error(cb->write.arg, cb->zmqsock);
return 1;
* 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>
* 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"
struct graph_node *gn = stack[stackpos];
struct cmd_token *tok = gn->data;
char *appendp = cmd + strlen(cmd);
- size_t i, j;
+ size_t j;
if (tok->type < SPECIAL_TKN) {
sprintf(appendp, "%s ", tok->text);
if (++stackpos == CMD_ARGC_MAX)
return;
- for (i = 0; i < vector_active(gn->to); i++) {
+ for (size_t i = 0; i < vector_active(gn->to); i++) {
struct graph_node *gnext = vector_slot(gn->to, i);
for (j = 0; j < stackpos; j++)
if (stack[j] == gnext)
* 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"
* DEALINGS IN THE SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "memory.h"
#include "hook.h"
* before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
* devpty0, de0 < del0
*/
-int if_cmp_name_func(char *p1, char *p2)
+int if_cmp_name_func(const char *p1, const char *p2)
{
unsigned int l1, l2;
long int x1, x2;
if (!*p2)
return 1;
- x1 = strtol(p1, &p1, 10);
- x2 = strtol(p2, &p2, 10);
+ x1 = strtol(p1, (char **)&p1, 10);
+ x2 = strtol(p2, (char **)&p2, 10);
/* let's compare numbers now */
if (x1 < x2)
static int if_cmp_func(const struct interface *ifp1,
const struct interface *ifp2)
{
- return if_cmp_name_func((char *)ifp1->name, (char *)ifp2->name);
+ return if_cmp_name_func(ifp1->name, ifp2->name);
}
static int if_cmp_index_func(const struct interface *ifp1,
one. */
struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty)
{
- struct interface *ifp;
+ struct interface *ifp = NULL;
- ifp = if_lookup_by_name(name, vrf_id);
- if (ifp)
- return ifp;
- /* Not Found on same VRF. If the interface command
- * was entered in vty without a VRF (passed as VRF_DEFAULT),
- * accept the ifp we found. If a vrf was entered and there is
- * a mismatch, reject it if from vty.
- */
- ifp = if_lookup_by_name_all_vrf(name);
- if (!ifp)
+ if (vrf_is_mapped_on_netns(vrf_lookup_by_id(vrf_id))) {
+ ifp = if_lookup_by_name(name, vrf_id);
+ if (ifp)
+ return ifp;
+ if (vty) {
+ /* If the interface command was entered in vty without a
+ * VRF (passed as VRF_DEFAULT), search an interface with
+ * this name in all VRs
+ */
+ if (vrf_id == VRF_DEFAULT)
+ return if_lookup_by_name_all_vrf(name);
+ return NULL;
+ }
return if_create(name, vrf_id);
- if (vty) {
- if (vrf_id == VRF_DEFAULT)
+ }
+ /* vrf is based on vrf-lite */
+ ifp = if_lookup_by_name_all_vrf(name);
+ if (ifp) {
+ if (ifp->vrf_id == vrf_id)
return ifp;
- return NULL;
+ /* Found a match on a different VRF. If the interface command
+ * was entered in vty without a VRF (passed as VRF_DEFAULT),
+ * accept the ifp we found. If a vrf was entered and there is a
+ * mismatch, reject it if from vty. If it came from the kernel
+ * or by way of zclient, believe it and update the ifp
+ * accordingly.
+ */
+ if (vty) {
+ if (vrf_id == VRF_DEFAULT)
+ return ifp;
+ return NULL;
+ }
+ /* If it came from the kernel or by way of zclient, believe it
+ * and update the ifp accordingly.
+ */
+ if_update_to_new_vrf(ifp, vrf_id);
+ return ifp;
}
- /* if vrf backend uses NETNS, then
- * this should not be considered as an update
- * then create the new interface
- */
- if (ifp->vrf_id != vrf_id && vrf_is_mapped_on_netns(
- vrf_lookup_by_id(vrf_id)))
- return if_create(name, vrf_id);
- /* If it came from the kernel
- * or by way of zclient, believe it and update
- * the ifp accordingly.
- */
- if_update_to_new_vrf(ifp, vrf_id);
- return ifp;
+ return if_create(name, vrf_id);
}
void if_set_index(struct interface *ifp, ifindex_t ifindex)
* 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;
int idx_ifname = 1;
int idx_vrf = 3;
const char *ifname = argv[idx_ifname]->arg;
- const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL;
+ const char *vrfname =
+ (argc > 2) ? argv[idx_vrf]->arg : VRF_DEFAULT_NAME;
struct interface *ifp;
vrf_id_t vrf_id = VRF_DEFAULT;
#endif /* SUNOS_5 */
if (!ifp) {
- vty_out(vty, "%% interface %s not in %s\n", ifname, vrfname);
+ vty_out(vty, "%% interface %s not in %s vrf\n", ifname,
+ vrfname);
return CMD_WARNING_CONFIG_FAILED;
}
VTY_PUSH_CONTEXT(INTERFACE_NODE, ifp);
llts(ZEBRA_LLT_IEEE802154, "IEEE 802.15.4");
llts(ZEBRA_LLT_IEEE802154_PHY, "IEEE 802.15.4 Phy");
default:
- flog_err(LIB_ERR_DEVELOPMENT, "Unknown value %d", llt);
+ flog_err(EC_LIB_DEVELOPMENT, "Unknown value %d", llt);
return "Unknown type!";
#undef llts
}
#define IFNAME_RB_INSERT(vrf, ifp) \
if (RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp))) \
- flog_err( \
- LIB_ERR_INTERFACE, \
- "%s(%s): corruption detected -- interface with this " \
- "name exists already in VRF %u!", \
- __func__, (ifp)->name, (ifp)->vrf_id);
+ flog_err(EC_LIB_INTERFACE, \
+ "%s(%s): corruption detected -- interface with this " \
+ "name exists already in VRF %u!", \
+ __func__, (ifp)->name, (ifp)->vrf_id);
#define IFNAME_RB_REMOVE(vrf, ifp) \
if (RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)) == NULL) \
- flog_err( \
- LIB_ERR_INTERFACE, \
- "%s(%s): corruption detected -- interface with this " \
- "name doesn't exist in VRF %u!", \
- __func__, (ifp)->name, (ifp)->vrf_id);
+ flog_err(EC_LIB_INTERFACE, \
+ "%s(%s): corruption detected -- interface with this " \
+ "name doesn't exist in VRF %u!", \
+ __func__, (ifp)->name, (ifp)->vrf_id);
#define IFINDEX_RB_INSERT(vrf, ifp) \
if (RB_INSERT(if_index_head, &vrf->ifaces_by_index, (ifp))) \
- flog_err( \
- LIB_ERR_INTERFACE, \
- "%s(%u): corruption detected -- interface with this " \
- "ifindex exists already in VRF %u!", \
- __func__, (ifp)->ifindex, (ifp)->vrf_id);
+ flog_err(EC_LIB_INTERFACE, \
+ "%s(%u): corruption detected -- interface with this " \
+ "ifindex exists already in VRF %u!", \
+ __func__, (ifp)->ifindex, (ifp)->vrf_id);
#define IFINDEX_RB_REMOVE(vrf, ifp) \
if (RB_REMOVE(if_index_head, &vrf->ifaces_by_index, (ifp)) == NULL) \
- flog_err( \
- LIB_ERR_INTERFACE, \
- "%s(%u): corruption detected -- interface with this " \
- "ifindex doesn't exist in VRF %u!", \
- __func__, (ifp)->ifindex, (ifp)->vrf_id);
+ flog_err(EC_LIB_INTERFACE, \
+ "%s(%u): corruption detected -- interface with this " \
+ "ifindex doesn't exist in VRF %u!", \
+ __func__, (ifp)->ifindex, (ifp)->vrf_id);
#define FOR_ALL_INTERFACES(vrf, ifp) \
if (vrf) \
#endif /* IFF_VIRTUAL */
/* Prototypes. */
-extern int if_cmp_name_func(char *, char *);
+extern int if_cmp_name_func(const char *p1, const char *p2);
/*
* Passing in VRF_UNKNOWN is a valid thing to do, unless we
#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)
{
return (buf);
}
-int ibuf_realloc(struct ibuf *buf, size_t len)
+static int ibuf_realloc(struct ibuf *buf, size_t len)
{
uint8_t *b;
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;
{
struct ibuf *buf;
- while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
+ while ((buf = TAILQ_POP_FIRST(&msgbuf->bufs, entry)) != NULL)
ibuf_dequeue(msgbuf, buf);
}
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);
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);
* 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 */
+static struct log_ref ferr_lib_warn[] = {
+ {
+ .code = EC_LIB_SNMP,
+ .title = "SNMP has discovered a warning",
+ .description = "The SNMP AgentX library has returned a warning that we should report to the end user",
+ .suggestion = "Gather Log data and open an Issue.",
+ },
+ {
+ .code = EC_LIB_STREAM,
+ .title = "The stream subsystem has encountered an error",
+ .description = "During sanity checking stream.c has detected an error in the data associated with a particular stream",
+ .suggestion = "Gather log data and open an Issue, restart FRR",
+ },
+ {
+ .code = EC_LIB_LINUX_NS,
+ .title = "The Linux namespace subsystem has encountered a parsing error",
+ .description = "During system startup an invalid parameter for the namesapce was give to FRR",
+ .suggestion = "Gather log data and open an Issue. restart FRR",
+ },
+ {
+ .code = EC_LIB_SLOW_THREAD,
+ .title = "The Event subsystem has detected a slow process",
+ .description = "The Event subsystem has detected a slow process, this typically indicates that FRR is having trouble completing work in a timely manner. This can be either a misconfiguration, bug, or some combination therof.",
+ .suggestion = "Gather log data and open an Issue",
+ },
+ {
+ .code = EC_LIB_RMAP_RECURSION_LIMIT,
+ .title = "Reached the Route-Map Recursion Limit",
+ .description = "The Route-Map subsystem has detected a route-map depth of RMAP_RECURSION_LIMIT and has stopped processing",
+ .suggestion = "Re-work the Route-Map in question to not have so many route-map statements, or recompile FRR with a higher limit",
+ },
+ {
+ .code = EC_LIB_BACKUP_CONFIG,
+ .title = "Unable to open configuration file",
+ .description = "The config subsystem attempted to read in it's configuration file which failed, so we are falling back to the backup config file to see if it is available",
+ .suggestion = "Create configuration file",
+ },
+ {
+ .code = EC_LIB_VRF_LENGTH,
+ .title = "The VRF subsystem has encountered a parsing error",
+ .description = "The VRF subsystem, during initialization, has found a parsing error with input it has received",
+ .suggestion = "Check the length of the vrf name and adjust accordingly",
+ },
+ {
+ .code = END_FERR,
+ },
+};
+
static struct log_ref ferr_lib_err[] = {
{
- .code = LIB_ERR_PRIVILEGES,
+ .code = EC_LIB_PRIVILEGES,
.title = "Failure to raise or lower privileges",
.description = "FRR attempted to raise or lower its privileges and was unable to do so",
.suggestion = "Ensure that you are running FRR as the frr user and that the user has sufficient privileges to properly access root privileges"
},
{
- .code = LIB_ERR_VRF_START,
+ .code = EC_LIB_VRF_START,
.title = "VRF Failure on Start",
.description = "Upon startup FRR failed to properly initialize and startup the VRF subsystem",
.suggestion = "Ensure that there is sufficient memory to start processes and restart FRR",
},
{
- .code = LIB_ERR_SOCKET,
+ .code = EC_LIB_SOCKET,
.title = "Socket Error",
.description = "When attempting to access a socket a system error has occured and we were unable to properly complete the request",
- .suggestion = "Ensure that there are sufficient system resources available and ensure that the frr user has sufficient permisions to work",
+ .suggestion = "Ensure that there are sufficient system resources available and ensure that the frr user has sufficient permisions to work. If necessary open an Issue",
},
{
- .code = LIB_ERR_ZAPI_MISSMATCH,
+ .code = EC_LIB_ZAPI_MISSMATCH,
.title = "ZAPI Error",
.description = "A version miss-match has been detected between zebra and client protocol",
.suggestion = "Two different versions of FRR have been installed and the install is not properly setup. Completely stop FRR, remove it from the system and reinstall. Typically only developers should see this issue."
},
{
- .code = LIB_ERR_ZAPI_ENCODE,
+ .code = EC_LIB_ZAPI_ENCODE,
.title = "ZAPI Error",
.description = "The ZAPI subsystem has detected an encoding issue, between zebra and a client protocol",
- .suggestion = "Restart FRR"
+ .suggestion = "Gather data and open an Issue, also Restart FRR"
},
{
- .code = LIB_ERR_ZAPI_SOCKET,
+ .code = EC_LIB_ZAPI_SOCKET,
.title = "ZAPI Error",
.description = "The ZAPI subsystem has detected a socket error between zebra and a client",
.suggestion = "Restart FRR"
},
{
- .code = LIB_ERR_SYSTEM_CALL,
+ .code = EC_LIB_SYSTEM_CALL,
.title = "System Call Error",
.description = "FRR has detected a error from using a vital system call and has probably already exited",
.suggestion = "Ensure permissions are correct for FRR files, users and groups are correct. Additionally check that sufficient system resources are available."
},
{
- .code = LIB_ERR_VTY,
+ .code = EC_LIB_VTY,
.title = "VTY Subsystem Error",
.description = "FRR has detected a problem with the specified configuration file",
.suggestion = "Ensure configuration file exists and has correct permissions for operations Additionally ensure that all config lines are correct as well",
},
{
- .code = LIB_ERR_SNMP,
- .title = "SNMP Subsystem Error",
- .description = "FRR has detected a problem with the snmp library it uses A callback from this subsystem has indicated some error",
- .suggestion = "Examine callback message and ensure snmp is properly setup and working"
- },
- {
- .code = LIB_ERR_INTERFACE,
+ .code = EC_LIB_INTERFACE,
.title = "Interface Subsystem Error",
.description = "FRR has detected a problem with interface data from the kernel as it deviates from what we would expect to happen via normal netlink messaging",
.suggestion = "Open an Issue with all relevant log files and restart FRR"
},
{
- .code = LIB_ERR_NS,
+ .code = EC_LIB_NS,
.title = "NameSpace Subsystem Error",
.description = "FRR has detected a problem with NameSpace data from the kernel as it deviates from what we would expect to happen via normal kernel messaging",
.suggestion = "Open an Issue with all relevant log files and restart FRR"
},
{
- .code = LIB_ERR_DEVELOPMENT,
+ .code = EC_LIB_DEVELOPMENT,
.title = "Developmental Escape Error",
.description = "FRR has detected an issue where new development has not properly updated all code paths.",
.suggestion = "Open an Issue with all relevant log files"
},
{
- .code = LIB_ERR_ZMQ,
+ .code = EC_LIB_ZMQ,
.title = "ZMQ Subsystem Error",
.description = "FRR has detected an issue with the Zero MQ subsystem and ZeroMQ is not working properly now",
.suggestion = "Open an Issue with all relevant log files and restart FRR"
},
{
- .code = LIB_ERR_UNAVAILABLE,
+ .code = EC_LIB_UNAVAILABLE,
.title = "Feature or system unavailable",
.description = "FRR was not compiled with support for a particular feature, or it is not available on the current platform",
.suggestion = "Recompile FRR with the feature enabled, or find out what platforms support the feature"
void lib_error_init(void)
{
+ log_ref_add(ferr_lib_warn);
log_ref_add(ferr_lib_err);
}
#include "lib/ferr.h"
enum lib_log_refs {
- LIB_ERR_PRIVILEGES = LIB_FERR_START,
- LIB_ERR_VRF_START,
- LIB_ERR_SOCKET,
- LIB_ERR_ZAPI_MISSMATCH,
- LIB_ERR_ZAPI_ENCODE,
- LIB_ERR_ZAPI_SOCKET,
- LIB_ERR_SYSTEM_CALL,
- LIB_ERR_VTY,
- LIB_ERR_SNMP,
- LIB_ERR_INTERFACE,
- LIB_ERR_NS,
- LIB_ERR_DEVELOPMENT,
- LIB_ERR_ZMQ,
- LIB_ERR_UNAVAILABLE,
+ EC_LIB_PRIVILEGES = LIB_FERR_START,
+ EC_LIB_VRF_START,
+ EC_LIB_SOCKET,
+ EC_LIB_ZAPI_MISSMATCH,
+ EC_LIB_ZAPI_ENCODE,
+ EC_LIB_ZAPI_SOCKET,
+ EC_LIB_SYSTEM_CALL,
+ EC_LIB_VTY,
+ EC_LIB_INTERFACE,
+ EC_LIB_NS,
+ EC_LIB_DEVELOPMENT,
+ EC_LIB_ZMQ,
+ EC_LIB_UNAVAILABLE,
+ EC_LIB_SNMP,
+ EC_LIB_STREAM,
+ EC_LIB_LINUX_NS,
+ EC_LIB_SLOW_THREAD,
+ EC_LIB_RMAP_RECURSION_LIMIT,
+ EC_LIB_BACKUP_CONFIG,
+ EC_LIB_VRF_LENGTH,
};
extern void lib_error_init(void);
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(
+ EC_LIB_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(
+ EC_LIB_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;
if (errno == EEXIST)
return;
- zlog_warn("failed to mkdir \"%s\": %s", path, strerror(errno));
+ flog_err(EC_LIB_SYSTEM_CALL, "failed to mkdir \"%s\": %s", path,
+ strerror(errno));
return;
}
zprivs_get_ids(&ids);
if (chown(path, ids.uid_normal, ids.gid_normal))
- zlog_warn("failed to chown \"%s\": %s", path, strerror(errno));
+ flog_err(EC_LIB_SYSTEM_CALL, "failed to chown \"%s\": %s", path,
+ strerror(errno));
}
static struct thread_master *master;
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);
nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
if (nullfd == -1) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: failed to open /dev/null: %s", __func__,
safe_strerror(errno));
} else {
} else if (di->daemon_mode) {
int nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
if (nullfd == -1) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: failed to open /dev/null: %s",
__func__, safe_strerror(errno));
} else {
qsort(items, n, sizeof(void *), realcmp);
- for (unsigned int i = 0; i < n; ++i)
- listnode_add(list, items[i]);
+ for (unsigned int j = 0; j < n; ++j)
+ listnode_add(list, items[j]);
XFREE(MTYPE_TMP, items);
}
size = backtrace(array, array_size(array));
if (size <= 0 || (size_t)size > array_size(array)) {
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"Cannot get backtrace, returned invalid # of frames %d "
"(valid range is between 1 and %lu)",
size, (unsigned long)(array_size(array)));
}
zlog(priority, "Backtrace for %d stack frames:", size);
if (!(strings = backtrace_symbols(array, size))) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Cannot get backtrace symbols (out of memory?)");
for (i = 0; i < size; i++)
zlog(priority, "[bt %d] %p", i, array[i]);
void memory_oom(size_t size, const char *name)
{
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"out of memory: failed to allocate %zu bytes for %s"
"object",
size, name);
pthread_mutex_unlock(&loglock);
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"Log rotate failed: cannot open file %s for append: %s",
zl->filename, safe_strerror(save_errno));
ret = -1;
DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE),
DESC_ENTRY(ZEBRA_IPMR_ROUTE_STATS),
DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT),
+ DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT_ASYNC),
DESC_ENTRY(ZEBRA_GET_LABEL_CHUNK),
DESC_ENTRY(ZEBRA_RELEASE_LABEL_CHUNK),
DESC_ENTRY(ZEBRA_ADVERTISE_ALL_VNI),
unsigned int i;
if (zroute >= array_size(route_types)) {
- flog_err(LIB_ERR_DEVELOPMENT, "unknown zebra route type: %u",
- zroute);
+ flog_err(EC_LIB_DEVELOPMENT, "unknown zebra route type: %u",
+ zroute);
return &unknown;
}
if (zroute == route_types[zroute].type)
return &route_types[i];
}
}
- flog_err(LIB_ERR_DEVELOPMENT,
- "internal error: cannot find route type %u in table!",
- zroute);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "internal error: cannot find route type %u in table!", zroute);
return &unknown;
}
const char *zserv_command_string(unsigned int command)
{
if (command >= array_size(command_types)) {
- flog_err(LIB_ERR_DEVELOPMENT, "unknown zserv command type: %u",
- command);
+ flog_err(EC_LIB_DEVELOPMENT, "unknown zserv command type: %u",
+ command);
return unknown.string;
}
return command_types[command].string;
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"))
return ZEBRA_ROUTE_BABEL;
else if (strmatch(s, "sharp"))
return ZEBRA_ROUTE_SHARP;
+ else if (strmatch(s, "openfabric"))
+ return ZEBRA_ROUTE_OPENFABRIC;
}
return -1;
}
zlog_err("[EC %"PRIu32"] " format, ferr_id, ##__VA_ARGS__)
#define flog_err_sys(ferr_id, format, ...) \
flog_err(ferr_id, format, ##__VA_ARGS__)
+#define flog_warn(ferr_id, format, ...) \
+ zlog_warn("[EC %"PRIu32"] " format, ferr_id, ##__VA_ARGS__)
extern void zlog_thread_info(int log_level);
#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
#include <malloc/malloc.h>
#endif
#include <dlfcn.h>
+#ifdef HAVE_LINK_H
#include <link.h>
+#endif
#include "log.h"
#include "memory.h"
}
if (!ns_is_enabled(ns)) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Can not enable NS %u: %s!", ns->ns_id,
safe_strerror(errno));
return 0;
/* Non default NS. leave */
if (ns->ns_id == NS_UNKNOWN) {
- flog_err(LIB_ERR_NS,
- "Can not enable NS %s %u: Invalid NSID",
- ns->name, ns->ns_id);
+ flog_err(EC_LIB_NS,
+ "Can not enable NS %s %u: Invalid NSID",
+ ns->name, ns->ns_id);
return 0;
}
if (func)
pathname,
safe_strerror(errno));
else
- zlog_warn("Invalid pathname for %s: %s",
- pathname,
+ flog_warn(EC_LIB_LINUX_NS,
+ "Invalid pathname for %s: %s", pathname,
safe_strerror(errno));
return NULL;
}
vty_out(vty, "NS name (%s) invalid: too long (>%d)\n",
check_base, NS_NAMSIZ - 1);
else
- zlog_warn("NS name (%s) invalid: too long (>%d)",
+ flog_warn(EC_LIB_LINUX_NS,
+ "NS name (%s) invalid: too long (>%d)",
check_base, NS_NAMSIZ - 1);
return NULL;
}
ns_init();
default_ns = ns_get_created_internal(NULL, NULL, default_ns_id);
if (!default_ns) {
- flog_err(LIB_ERR_NS, "%s: failed to create the default NS!",
- __func__);
+ flog_err(EC_LIB_NS, "%s: failed to create the default NS!",
+ __func__);
exit(1);
}
if (have_netns()) {
/* Enable the default NS. */
if (!ns_enable(default_ns, NULL)) {
- flog_err(LIB_ERR_NS, "%s: failed to enable the default NS!",
- __func__);
+ flog_err(EC_LIB_NS, "%s: failed to enable the default NS!",
+ __func__);
exit(1);
}
}
#include <zebra.h>
#include "log.h"
#include "network.h"
+#include "lib_errors.h"
/* Read nbytes from fd and store into ptr. */
int readn(int fd, uint8_t *ptr, int nbytes)
should
never be negative. */
if ((flags = fcntl(fd, F_GETFL)) < 0) {
- zlog_warn("fcntl(F_GETFL) failed for fd %d: %s", fd,
- safe_strerror(errno));
+ flog_err(EC_LIB_SYSTEM_CALL,
+ "fcntl(F_GETFL) failed for fd %d: %s", fd,
+ safe_strerror(errno));
return -1;
}
if (fcntl(fd, F_SETFL, (flags | O_NONBLOCK)) < 0) {
- zlog_warn("fcntl failed setting fd %d non-blocking: %s", fd,
- safe_strerror(errno));
+ flog_err(EC_LIB_SYSTEM_CALL,
+ "fcntl failed setting fd %d non-blocking: %s", fd,
+ safe_strerror(errno));
return -1;
}
return 0;
* 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>
oldumask = umask(0777 & ~PIDFILE_MASK);
fd = open(path, O_RDWR | O_CREAT, PIDFILE_MASK);
if (fd < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Can't create pid lock file %s (%s), exiting",
path, safe_strerror(errno));
umask(oldumask);
lock.l_whence = SEEK_SET;
if (fcntl(fd, F_SETLK, &lock) < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Could not lock pid_file %s (%s), exiting",
path, safe_strerror(errno));
exit(1);
pidsize = strlen(buf);
if ((tmp = write(fd, buf, pidsize)) != (int)pidsize)
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"Could not write pid %d to pid_file %s, rc was %d: %s",
(int)pid, path, tmp, safe_strerror(errno));
else if (ftruncate(fd, pidsize) < 0)
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"Could not truncate pid_file %s to %u bytes: %s",
path, (unsigned int)pidsize,
safe_strerror(errno));
char buf_tmp[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof(buf));
prefix2str(&p_tmp, buf_tmp, sizeof(buf_tmp));
- zlog_warn(
+ vty_out(vty,
+ "%% Prefix-list %s prefix changed from %s to %s to match length\n",
+ name, buf, buf_tmp);
+ zlog_info(
"Prefix-list %s prefix changed from %s to %s to match length",
name, buf, buf_tmp);
p = p_tmp;
if (pentry->any)
vty_out(vty, "any");
else {
- struct prefix *p = &pentry->prefix;
+ struct prefix *pf = &pentry->prefix;
char buf[BUFSIZ];
vty_out(vty, "%s/%d",
- inet_ntop(p->family, p->u.val, buf,
+ inet_ntop(pf->family, pf->u.val, buf,
BUFSIZ),
- p->prefixlen);
+ pf->prefixlen);
if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge);
memcpy((void *)dest->u.prefix_flowspec.ptr,
(void *)src->u.prefix_flowspec.ptr, len);
} else {
- flog_err(LIB_ERR_DEVELOPMENT,
- "prefix_copy(): Unknown address family %d",
- src->family);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "prefix_copy(): Unknown address family %d",
+ src->family);
assert(0);
}
}
#include "log.h"
#include "privs.h"
#include "memory.h"
+#include "lib_errors.h"
#ifdef HAVE_CAPABILITIES
if (cap_get_flag(zprivs_state.caps,
zprivs_state.syscaps_p->caps[i], CAP_EFFECTIVE,
&val)) {
- zlog_warn(
+ flog_err(
+ EC_LIB_SYSTEM_CALL,
"zprivs_state_caps: could not cap_get_flag, %s",
safe_strerror(errno));
return ZPRIVS_UNKNOWN;
* 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>
#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 */
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, "-"
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"
#include "log.h"
#include "hash.h"
#include "libfrr.h"
+#include "lib_errors.h"
DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP, "Route map")
DEFINE_MTYPE(LIB, ROUTE_MAP_NAME, "Route map name")
struct route_map_rule *set;
if (recursion > RMAP_RECURSION_LIMIT) {
- zlog_warn(
+ flog_warn(
+ EC_LIB_RMAP_RECURSION_LIMIT,
"route-map recursion limit (%d) reached, discarding route",
RMAP_RECURSION_LIMIT);
recursion = 0;
sigdelset(&newmask, SIGKILL);
if ((sigprocmask(SIG_BLOCK, &newmask, &oldmask)) < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"quagga_signal_timer: couldnt block signals!");
return -1;
}
}
if (sigaction(sigmap[i].sigs[j], &act, NULL)
< 0)
- zlog_warn(
+ flog_err(
+ EC_LIB_SYSTEM_CALL,
"Unable to set signal handler for signal %d: %s",
sigmap[i].sigs[j],
safe_strerror(errno));
/* DEBUG */
if (!key) {
- flog_err(LIB_ERR_DEVELOPMENT, "%s: key is 0, value is %p",
- __func__, value);
+ flog_err(EC_LIB_DEVELOPMENT, "%s: key is 0, value is %p",
+ __func__, value);
}
p = l->header;
}
k = randomLevel();
+ assert(k >= 0);
if (k > l->level) {
k = ++l->level;
update[k] = l->header;
size /= 2;
if (size != orig_req)
- zlog_warn("%s: fd %d: SO_RCVBUF set to %d (requested %d)",
- __func__, sock, size, orig_req);
+ flog_err(EC_LIB_SOCKET,
+ "%s: fd %d: SO_RCVBUF set to %d (requested %d)",
+ __func__, sock, size, orig_req);
}
void setsockopt_so_sendbuf(const int sock, int size)
size /= 2;
if (size != orig_req)
- zlog_warn("%s: fd %d: SO_SNDBUF set to %d (requested %d)",
- __func__, sock, size, orig_req);
+ flog_err(EC_LIB_SOCKET,
+ "%s: fd %d: SO_SNDBUF set to %d (requested %d)",
+ __func__, sock, size, orig_req);
}
int getsockopt_so_sendbuf(const int sock)
int ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&optval,
&optlen);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"fd %d: can't getsockopt SO_SNDBUF: %d (%s)", sock,
errno, safe_strerror(errno));
return ret;
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val,
sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_RECVPKTINFO : %s",
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "can't setsockopt IPV6_RECVPKTINFO : %s",
+ safe_strerror(errno));
#else /*RFC2292*/
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &val, sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_PKTINFO : %s",
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_PKTINFO : %s",
+ safe_strerror(errno));
#endif /* INIA_IPV6 */
return ret;
}
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_CHECKSUM, &val, sizeof(val));
#endif /* GNU_LINUX */
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_CHECKSUM");
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_CHECKSUM");
return ret;
}
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val,
sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_MULTICAST_HOPS");
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_MULTICAST_HOPS");
return ret;
}
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val,
sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_UNICAST_HOPS");
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_UNICAST_HOPS");
return ret;
}
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val,
sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_RECVHOPLIMIT");
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_RECVHOPLIMIT");
#else /*RFC2292*/
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_HOPLIMIT, &val, sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_HOPLIMIT");
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_HOPLIMIT");
#endif
return ret;
}
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IPV6_MULTICAST_LOOP");
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IPV6_MULTICAST_LOOP");
return ret;
}
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, &tclass,
sizeof(tclass));
if (ret < 0)
- zlog_warn("Can't set IPV6_TCLASS option for fd %d to %#x: %s",
- sock, tclass, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "Can't set IPV6_TCLASS option for fd %d to %#x: %s",
+ sock, tclass, safe_strerror(errno));
#endif
return ret;
}
ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&val,
sizeof(val));
if (ret < 0)
- zlog_warn("can't setsockopt IP_MULTICAST_LOOP");
+ flog_err(EC_LIB_SOCKET, "can't setsockopt IP_MULTICAST_LOOP");
return ret;
}
#if defined(IP_PKTINFO)
if ((ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)))
< 0)
- zlog_warn("Can't set IP_PKTINFO option for fd %d to %d: %s",
- sock, val, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "Can't set IP_PKTINFO option for fd %d to %d: %s",
+ sock, val, safe_strerror(errno));
#elif defined(IP_RECVIF)
if ((ret = setsockopt(sock, IPPROTO_IP, IP_RECVIF, &val, sizeof(val)))
< 0)
- zlog_warn("Can't set IP_RECVIF option for fd %d to %d: %s",
- sock, val, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "Can't set IP_RECVIF option for fd %d to %d: %s", sock,
+ val, safe_strerror(errno));
#else
#warning "Neither IP_PKTINFO nor IP_RECVIF is available."
#warning "Will not be able to receive link info."
ret = setsockopt(sock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
if (ret < 0)
- zlog_warn("Can't set IP_TOS option for fd %d to %#x: %s", sock,
- tos, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "Can't set IP_TOS option for fd %d to %#x: %s", sock,
+ tos, safe_strerror(errno));
return ret;
}
ret = setsockopt_ipv6_pktinfo(sock, val);
break;
default:
- zlog_warn("setsockopt_ifindex: unknown address family %d", af);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "setsockopt_ifindex: unknown address family %d", af);
}
return ret;
}
return (getsockopt_ipv6_ifindex(msgh));
break;
default:
- zlog_warn("getsockopt_ifindex: unknown address family %d", af);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "getsockopt_ifindex: unknown address family %d", af);
return 0;
}
}
ret = 0;
else
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"sockopt_tcp_signature: setsockopt(%d): %s",
sock, safe_strerror(errno));
}
sock = socket(su->sa.sa_family, SOCK_STREAM, 0);
if (sock < 0) {
char buf[SU_ADDRSTRLEN];
- zlog_warn("Can't make socket for %s : %s",
- sockunion_log(su, buf, SU_ADDRSTRLEN),
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "Can't make socket for %s : %s",
+ sockunion_log(su, buf, SU_ADDRSTRLEN),
+ safe_strerror(errno));
return -1;
}
sock = socket(su->sa.sa_family, SOCK_STREAM, 0);
if (sock < 0)
- zlog_warn("can't make socket sockunion_stream_socket");
+ flog_err(EC_LIB_SOCKET,
+ "can't make socket sockunion_stream_socket");
return sock;
}
ret = bind(sock, (struct sockaddr *)su, size);
if (ret < 0) {
char buf[SU_ADDRSTRLEN];
- zlog_warn("can't bind socket for %s : %s",
- sockunion_log(su, buf, SU_ADDRSTRLEN),
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "can't bind socket for %s : %s",
+ sockunion_log(su, buf, SU_ADDRSTRLEN),
+ safe_strerror(errno));
}
return ret;
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
sizeof(on));
if (ret < 0) {
- zlog_warn("can't set sockopt SO_REUSEADDR to socket %d", sock);
+ flog_err(EC_LIB_SOCKET,
+ "can't set sockopt SO_REUSEADDR to socket %d", sock);
return -1;
}
return 0;
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void *)&on,
sizeof(on));
if (ret < 0) {
- zlog_warn("can't set sockopt SO_REUSEPORT to socket %d", sock);
+ flog_err(EC_LIB_SOCKET,
+ "can't set sockopt SO_REUSEPORT to socket %d", sock);
return -1;
}
return 0;
ret = setsockopt(sock, IPPROTO_IP, IP_TTL, (void *)&ttl,
sizeof(int));
if (ret < 0) {
- zlog_warn("can't set sockopt IP_TTL %d to socket %d",
- ttl, sock);
+ flog_err(EC_LIB_SOCKET,
+ "can't set sockopt IP_TTL %d to socket %d",
+ ttl, sock);
return -1;
}
return 0;
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
(void *)&ttl, sizeof(int));
if (ret < 0) {
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"can't set sockopt IPV6_UNICAST_HOPS %d to socket %d",
ttl, sock);
return -1;
int ret = setsockopt(sock, IPPROTO_IP, IP_MINTTL, &minttl,
sizeof(minttl));
if (ret < 0)
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"can't set sockopt IP_MINTTL to %d on socket %d: %s",
minttl, sock, safe_strerror(errno));
return ret;
int ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MINHOPCOUNT,
&minttl, sizeof(minttl));
if (ret < 0)
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"can't set sockopt IPV6_MINHOPCOUNT to %d on socket %d: %s",
minttl, sock, safe_strerror(errno));
return ret;
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on,
sizeof(int));
if (ret < 0) {
- zlog_warn(
- "can't set sockopt IPV6_V6ONLY "
- "to socket %d",
- sock);
+ flog_err(EC_LIB_SOCKET,
+ "can't set sockopt IPV6_V6ONLY "
+ "to socket %d",
+ sock);
return -1;
}
return 0;
ret = getsockname(fd, (struct sockaddr *)&name, &len);
if (ret < 0) {
- zlog_warn("Can't get local address and port by getsockname: %s",
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "Can't get local address and port by getsockname: %s",
+ safe_strerror(errno));
return NULL;
}
len = sizeof name;
ret = getpeername(fd, (struct sockaddr *)&name, &len);
if (ret < 0) {
- zlog_warn("Can't get remote address and port: %s",
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "Can't get remote address and port: %s",
+ safe_strerror(errno));
return NULL;
}
const struct prefix *dst_p, *src_p;
srcdest_rnode_prefixes(rn, &dst_p, &src_p);
- return srcdest2str(dst_p, (struct prefix_ipv6*)src_p, str, size);
+ return srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, str, size);
}
* using stream_put..._at() functions.
*/
#define STREAM_WARN_OFFSETS(S) \
- zlog_warn("&(struct stream): %p, size: %lu, getp: %lu, endp: %lu\n", \
+ flog_warn(EC_LIB_STREAM, \
+ "&(struct stream): %p, size: %lu, getp: %lu, endp: %lu\n", \
(void *)(S), (unsigned long)(S)->size, \
(unsigned long)(S)->getp, (unsigned long)(S)->endp)
#define STREAM_BOUND_WARN(S, WHAT) \
do { \
- zlog_warn("%s: Attempt to %s out of bounds", __func__, \
- (WHAT)); \
+ flog_warn(EC_LIB_STREAM, "%s: Attempt to %s out of bounds", \
+ __func__, (WHAT)); \
STREAM_WARN_OFFSETS(S); \
assert(0); \
} while (0)
#define STREAM_BOUND_WARN2(S, WHAT) \
do { \
- zlog_warn("%s: Attempt to %s out of bounds", __func__, \
- (WHAT)); \
+ flog_warn(EC_LIB_STREAM, "%s: Attempt to %s out of bounds", \
+ __func__, (WHAT)); \
STREAM_WARN_OFFSETS(S); \
} while (0)
#define CHECK_SIZE(S, Z) \
do { \
if (((S)->endp + (Z)) > (S)->size) { \
- zlog_warn( \
+ flog_warn( \
+ EC_LIB_STREAM, \
"CHECK_SIZE: truncating requested size %lu\n", \
(unsigned long)(Z)); \
STREAM_WARN_OFFSETS(S); \
}
/* 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);
}
/* 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);
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);
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);
/* Error: was it transient (return -2) or fatal (return -1)? */
if (ERRNO_IO_RETRY(errno))
return -2;
- zlog_warn("%s: read failed on fd %d: %s", __func__, fd,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "%s: read failed on fd %d: %s", __func__, fd,
+ safe_strerror(errno));
return -1;
}
/* Error: was it transient (return -2) or fatal (return -1)? */
if (ERRNO_IO_RETRY(errno))
return -2;
- zlog_warn("%s: read failed on fd %d: %s", __func__, fd,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "%s: read failed on fd %d: %s", __func__, fd,
+ safe_strerror(errno));
return -1;
}
/* 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
/* 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
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/sha256.h \
lib/sigevent.h \
lib/skiplist.h \
+ lib/smux.h \
lib/sockopt.h \
lib/sockunion.h \
lib/spf_backoff.h \
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 \
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
int ncols = 0;
/* count how many columns we have */
- for (int i = 0; format[i]; i++)
- ncols += !!(format[i] == '|');
+ for (int j = 0; format[j]; j++)
+ ncols += !!(format[j] == '|');
ncols++;
if (tt->ncols == 0)
memcpy(&buf[pos], left, lsize);
pos += lsize;
- for (size_t i = 0; i < width - lsize - rsize; i++)
+ for (size_t l = 0; l < width - lsize - rsize; l++)
buf[pos++] = row[0].style.border.top;
pos -= width - lsize - rsize;
buf[pos++] = row[j].style.border.left;
/* print left padding */
- for (int i = 0; i < row[j].style.lpad; i++)
+ for (int k = 0; k < row[j].style.lpad; k++)
buf[pos++] = ' ';
/* calculate padding for sprintf */
pos += sprintf(&buf[pos], fmt, abspad, row[j].text);
/* print right padding */
- for (int i = 0; i < row[j].style.rpad; i++)
+ for (int k = 0; k < row[j].style.rpad; k++)
buf[pos++] = ' ';
/* if right border && not last col print right border */
memcpy(&buf[pos], left, lsize);
pos += lsize;
- for (size_t i = 0; i < width - lsize - rsize; i++)
+ for (size_t l = 0; l < width - lsize - rsize; l++)
buf[pos++] = row[0].style.border.bottom;
pos -= width - lsize - rsize;
memcpy(&buf[pos], left, lsize);
pos += lsize;
- for (size_t i = 0; i < width - lsize - rsize; i++)
+ for (size_t l = 0; l < width - lsize - rsize; l++)
buf[pos++] = tt->style.border.bottom;
memcpy(&buf[pos], right, rsize);
#include "network.h"
#include "jhash.h"
#include "frratomic.h"
+#include "lib_errors.h"
DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread")
DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master")
}
/* else die */
- zlog_warn("poll() error: %s", safe_strerror(errno));
+ flog_err(EC_LIB_SYSTEM_CALL, "poll() error: %s",
+ safe_strerror(errno));
pthread_mutex_unlock(&m->mtx);
fetch = NULL;
break;
* Whinge about it now, so we're aware this is yet another task
* to fix.
*/
- zlog_warn(
+ flog_warn(
+ EC_LIB_SLOW_THREAD,
"SLOW THREAD: task %s (%lx) ran for %lums (cpu time %lums)",
thread->funcname, (unsigned long)thread->func,
realtime / 1000, cputime / 1000);
#define thread_add_timer_tv(m,f,a,v,t) funcname_thread_add_timer_tv(m,f,a,v,t,#f,__FILE__,__LINE__)
#define thread_add_event(m,f,a,v,t) funcname_thread_add_event(m,f,a,v,t,#f,__FILE__,__LINE__)
#define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
+#define thread_execute_name(m, f, a, v, n) \
+ funcname_thread_execute(m, f, a, v, n, __FILE__, __LINE__)
/* Prototypes. */
extern struct thread_master *thread_master_create(const char *);
/* The default VRF always exists. */
default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
if (!default_vrf) {
- flog_err(LIB_ERR_VRF_START,
- "vrf_init: failed to create the default VRF!");
+ flog_err(EC_LIB_VRF_START,
+ "vrf_init: failed to create the default VRF!");
exit(1);
}
- if (vrf_is_backend_netns())
+ if (vrf_is_backend_netns()) {
+ struct ns *ns;
+
strlcpy(default_vrf->data.l.netns_name,
VRF_DEFAULT_NAME, NS_NAMSIZ);
+ ns = ns_lookup(ns_get_default_id());
+ ns->vrf_ctxt = default_vrf;
+ default_vrf->ns_ctxt = ns;
+ }
/* Enable the default VRF. */
if (!vrf_enable(default_vrf)) {
- flog_err(LIB_ERR_VRF_START,
- "vrf_init: failed to enable the default VRF!");
+ flog_err(EC_LIB_VRF_START,
+ "vrf_init: failed to enable the default VRF!");
exit(1);
}
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0)
- flog_err_sys(LIB_ERR_SOCKET, "%s: Can't switch to VRF %u (%s)",
+ flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
__func__, vrf_id, safe_strerror(errno));
if (ret > 0 && interfacename && vrf_default_accepts_vrf(type)) {
save_errno = errno;
ret2 = vrf_switchback_to_initial();
if (ret2 < 0)
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno));
errno = save_errno;
"%% VRF name %s invalid: length exceeds %d bytes\n",
vrfname, VRF_NAMSIZ);
else
- zlog_warn(
+ flog_warn(
+ EC_LIB_VRF_LENGTH,
"%% VRF name %s invalid: length exceeds %d bytes\n",
vrfname, VRF_NAMSIZ);
return CMD_WARNING_CONFIG_FAILED;
"VRF %u is already configured with VRF %s\n",
vrf->vrf_id, vrf->name);
else
- zlog_warn("VRF %u is already configured with VRF %s\n",
+ zlog_info("VRF %u is already configured with VRF %s\n",
vrf->vrf_id, vrf->name);
return CMD_WARNING_CONFIG_FAILED;
}
"VRF %u already configured with NETNS %s\n",
vrf->vrf_id, ns->name);
else
- zlog_warn(
+ zlog_info(
"VRF %u already configured with NETNS %s",
vrf->vrf_id, ns->name);
return CMD_WARNING_CONFIG_FAILED;
" with VRF %u(%s)\n",
ns->name, vrf2->vrf_id, vrf2->name);
else
- zlog_warn("NS %s is already configured with VRF %u(%s)",
+ zlog_info("NS %s is already configured with VRF %u(%s)",
ns->name, vrf2->vrf_id, vrf2->name);
return CMD_WARNING_CONFIG_FAILED;
}
vty_out(vty, "Can not associate NS %u with NETNS %s\n",
ns->ns_id, ns->name);
else
- zlog_warn("Can not associate NS %u with NETNS %s",
+ zlog_info("Can not associate NS %u with NETNS %s",
ns->ns_id, ns->name);
return CMD_WARNING_CONFIG_FAILED;
}
{
if (!vrf || vrf->data.l.netns_name[0] == '\0')
return 0;
- if (vrf->vrf_id == VRF_DEFAULT)
- return 0;
return 1;
}
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0)
- flog_err_sys(LIB_ERR_SOCKET, "%s: Can't switch to VRF %u (%s)",
+ flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
__func__, vrf_id, safe_strerror(errno));
ret = getaddrinfo(node, service, hints, res);
save_errno = errno;
ret2 = vrf_switchback_to_initial();
if (ret2 < 0)
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno));
errno = save_errno;
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "%s: Can't switch to VRF %u (%s)",
+ flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
__func__, vrf_id, safe_strerror(errno));
return 0;
}
saved_errno = errno;
ret = vrf_switchback_to_initial();
if (ret < 0)
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno));
errno = saved_errno;
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0)
- flog_err_sys(LIB_ERR_SOCKET, "%s: Can't switch to VRF %u (%s)",
+ flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
__func__, vrf_id, safe_strerror(errno));
ret = sockunion_socket(su);
save_errno = errno;
ret2 = vrf_switchback_to_initial();
if (ret2 < 0)
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno));
errno = save_errno;
#define VRF_GET_ID(V, NAME, USE_JSON) \
do { \
- struct vrf *vrf; \
- if (!(vrf = vrf_lookup_by_name(NAME))) { \
+ struct vrf *_vrf; \
+ if (!(_vrf = vrf_lookup_by_name(NAME))) { \
if (USE_JSON) { \
vty_out(vty, "{}\n"); \
} else { \
} \
return CMD_WARNING; \
} \
- if (vrf->vrf_id == VRF_UNKNOWN) { \
+ if (_vrf->vrf_id == VRF_UNKNOWN) { \
if (USE_JSON) { \
vty_out(vty, "{}\n"); \
} else { \
} \
return CMD_WARNING; \
} \
- (V) = vrf->vrf_id; \
+ (V) = _vrf->vrf_id; \
} while (0)
/*
*/
extern void vrf_init(int (*create)(struct vrf *vrf), int (*enable)(struct vrf *vrf),
int (*disable)(struct vrf *vrf), int (*delete)(struct vrf *vrf),
- int ((*update)(struct vrf *vrf)));
+ int (*update)(struct vrf *vrf));
/*
* Call vrf_terminate when the protocol is being shutdown
/* Fatal I/O error. */
vty->monitor =
0; /* disable monitoring to avoid infinite recursion */
- zlog_warn("%s: write failed to vty client fd %d, closing: %s",
- __func__, vty->fd, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "%s: write failed to vty client fd %d, closing: %s",
+ __func__, vty->fd, safe_strerror(errno));
buffer_reset(vty->obuf);
buffer_reset(vty->lbuf);
/* cannot call vty_close, because a parent routine may still try
if ((realtime = thread_consumed_time(&after, &before, &cputime))
> CONSUMED_TIME_CHECK)
/* Warn about CPU hog that must be fixed. */
- zlog_warn(
+ flog_warn(
+ EC_LIB_SLOW_THREAD,
"SLOW COMMAND: command took %lums (cpu time %lums): %s",
realtime / 1000, cputime / 1000, buf);
}
case LDP_L2VPN_NODE:
case LDP_PSEUDOWIRE_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case KEYCHAIN_KEY_NODE:
case VTY_NODE:
case LDP_L2VPN_NODE:
case LDP_PSEUDOWIRE_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case KEYCHAIN_NODE:
case KEYCHAIN_KEY_NODE:
case VTY_NODE:
switch (vty->sb_buf[0]) {
case TELOPT_NAWS:
if (vty->sb_len != TELNET_NAWS_SB_LEN)
- zlog_warn(
+ flog_err(
+ EC_LIB_SYSTEM_CALL,
"RFC 1073 violation detected: telnet NAWS option "
"should send %d characters, but we received %lu",
TELNET_NAWS_SB_LEN,
(unsigned long)vty->sb_len);
else if (sizeof(vty->sb_buf) < TELNET_NAWS_SB_LEN)
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"Bug detected: sizeof(vty->sb_buf) %lu < %d, too small to handle the telnet NAWS option",
(unsigned long)sizeof(vty->sb_buf),
TELNET_NAWS_SB_LEN);
}
vty->monitor = 0; /* disable monitoring to avoid
infinite recursion */
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"%s: read error on vty client fd %d, closing: %s",
__func__, vty->fd, safe_strerror(errno));
buffer_reset(vty->obuf);
case BUFFER_ERROR:
vty->monitor =
0; /* disable monitoring to avoid infinite recursion */
- zlog_warn("buffer_flush failed on vty client fd %d, closing",
+ zlog_info("buffer_flush failed on vty client fd %d, closing",
vty->fd);
buffer_reset(vty->lbuf);
buffer_reset(vty->obuf);
/* We can handle IPv4 or IPv6 socket. */
vty_sock = sockunion_accept(accept_sock, &su);
if (vty_sock < 0) {
- zlog_warn("can't accept vty socket : %s", safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "can't accept vty socket : %s",
+ safe_strerror(errno));
return -1;
}
set_nonblocking(vty_sock);
ret = getaddrinfo(hostname, port_str, &req, &ainfo);
if (ret != 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "getaddrinfo failed: %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "getaddrinfo failed: %s",
gai_strerror(ret));
exit(1);
}
/* Make UNIX domain socket. */
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"Cannot create unix stream socket: %s",
safe_strerror(errno));
return;
ret = bind(sock, (struct sockaddr *)&serv, len);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "Cannot bind path %s: %s", path,
+ flog_err_sys(EC_LIB_SOCKET, "Cannot bind path %s: %s", path,
safe_strerror(errno));
close(sock); /* Avoid sd leak. */
return;
ret = listen(sock, 5);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "listen(fd %d) failed: %s", sock,
+ flog_err_sys(EC_LIB_SOCKET, "listen(fd %d) failed: %s", sock,
safe_strerror(errno));
close(sock); /* Avoid sd leak. */
return;
if ((int)ids.gid_vty > 0) {
/* set group of socket */
if (chown(path, -1, ids.gid_vty)) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"vty_serv_un: could chown socket, %s",
safe_strerror(errno));
}
(socklen_t *)&client_len);
if (sock < 0) {
- zlog_warn("can't accept vty socket : %s", safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET, "can't accept vty socket : %s",
+ safe_strerror(errno));
return -1;
}
if (set_nonblocking(sock) < 0) {
- zlog_warn(
- "vtysh_accept: could not set vty socket %d to non-blocking,"
- " %s, closing",
+ flog_err(
+ EC_LIB_SOCKET,
+ "vtysh_accept: could not set vty socket %d to non-blocking, %s, closing",
sock, safe_strerror(errno));
close(sock);
return -1;
case BUFFER_ERROR:
vty->monitor =
0; /* disable monitoring to avoid infinite recursion */
- zlog_warn("%s: write error to fd %d, closing", __func__,
- vty->fd);
+ flog_err(EC_LIB_SOCKET, "%s: write error to fd %d, closing",
+ __func__, vty->fd);
buffer_reset(vty->lbuf);
buffer_reset(vty->obuf);
vty_close(vty);
}
vty->monitor = 0; /* disable monitoring to avoid
infinite recursion */
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"%s: read failed on vtysh client fd %d, closing: %s",
__func__, sock, safe_strerror(errno));
}
nl = strchr(vty->error_buf, '\n');
if (nl)
*nl = '\0';
- flog_err(LIB_ERR_VTY,
- "ERROR: %s on config line %u: %s", message, line_num,
- vty->error_buf);
+ flog_err(EC_LIB_VTY, "ERROR: %s on config line %u: %s", message,
+ line_num, vty->error_buf);
}
vty_close(vty);
if (!IS_DIRECTORY_SEP(config_file[0])) {
if (getcwd(cwd, MAXPATHLEN) == NULL) {
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"Failure to determine Current Working Directory %d!",
errno);
exit(1);
confp = fopen(fullpath, "r");
if (confp == NULL) {
- zlog_warn("%s: failed to open configuration file %s: %s, checking backup",
- __func__, fullpath, safe_strerror(errno));
+ flog_warn(
+ EC_LIB_BACKUP_CONFIG,
+ "%s: failed to open configuration file %s: %s, checking backup",
+ __func__, fullpath, safe_strerror(errno));
confp = vty_use_backup_config(fullpath);
if (confp)
- zlog_warn(
+ flog_warn(
+ EC_LIB_BACKUP_CONFIG,
"WARNING: using backup configuration file!");
else {
- flog_err(LIB_ERR_VTY,
- "can't open configuration file [%s]",
- config_file);
+ flog_err(EC_LIB_VTY,
+ "can't open configuration file [%s]",
+ config_file);
exit(1);
}
}
#endif /* VTYSH */
confp = fopen(config_default_dir, "r");
if (confp == NULL) {
- zlog_warn("%s: failed to open configuration file %s: %s, checking backup",
- __func__, config_default_dir,
- safe_strerror(errno));
+ flog_err(
+ EC_LIB_SYSTEM_CALL,
+ "%s: failed to open configuration file %s: %s, checking backup",
+ __func__, config_default_dir,
+ safe_strerror(errno));
confp = vty_use_backup_config(config_default_dir);
if (confp) {
- zlog_warn(
+ flog_warn(
+ EC_LIB_BACKUP_CONFIG,
"WARNING: using backup configuration file!");
fullpath = config_default_dir;
} else {
- flog_err(LIB_ERR_VTY,
- "can't open configuration file [%s]",
- config_default_dir);
+ flog_err(EC_LIB_VTY,
+ "can't open configuration file [%s]",
+ config_default_dir);
goto tmp_free_and_out;
}
} else
* Hence not worrying about it too much.
*/
if (!chdir(SYSCONFDIR)) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Failure to chdir to %s, errno: %d",
SYSCONFDIR, errno);
exit(-1);
}
if (getcwd(cwd, MAXPATHLEN) == NULL) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Failure to getcwd, errno: %d", errno);
exit(-1);
}
static int debug_timer_wheel = 0;
-static int wheel_timer_thread(struct thread *t)
+static int wheel_timer_thread(struct thread *t);
+
+static int wheel_timer_thread_helper(struct thread *t)
{
struct listnode *node, *nextnode;
unsigned long long curr_slot;
return 0;
}
+static int wheel_timer_thread(struct thread *t)
+{
+ struct timer_wheel *wheel;
+
+ wheel = THREAD_ARG(t);
+
+ thread_execute_name(wheel->master, wheel_timer_thread_helper,
+ wheel, 0, wheel->name);
+
+ return 0;
+}
+
struct timer_wheel *wheel_init(struct thread_master *master, int period,
size_t slots, unsigned int (*slot_key)(void *),
- void (*slot_run)(void *))
+ void (*slot_run)(void *),
+ const char *run_name)
{
struct timer_wheel *wheel;
size_t i;
wheel = XCALLOC(MTYPE_TIMER_WHEEL, sizeof(struct timer_wheel));
+ wheel->name = XSTRDUP(MTYPE_TIMER_WHEEL, run_name);
wheel->slot_key = slot_key;
wheel->slot_run = slot_run;
THREAD_OFF(wheel->timer);
XFREE(MTYPE_TIMER_WHEEL_LIST, wheel->wheel_slot_lists);
+ XFREE(MTYPE_TIMER_WHEEL, wheel->name);
XFREE(MTYPE_TIMER_WHEEL, wheel);
}
#define __WHEEL_H__
struct timer_wheel {
+ char *name;
struct thread_master *master;
int slots;
long long curr_slot;
*/
struct timer_wheel *wheel_init(struct thread_master *master, int period,
size_t slots, unsigned int (*slot_key)(void *),
- void (*slot_run)(void *));
+ void (*slot_run)(void *),
+ const char *run_name);
/*
* Delete the specified timer wheel created
ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
if (ret < 0) {
if (zclient_debug)
- zlog_warn("%s connect failure: %d(%s)",
- __PRETTY_FUNCTION__, errno,
- safe_strerror(errno));
+ zlog_debug("%s connect failure: %d(%s)",
+ __PRETTY_FUNCTION__, errno,
+ safe_strerror(errno));
close(sock);
return -1;
}
return -1;
switch (buffer_flush_available(zclient->wb, zclient->sock)) {
case BUFFER_ERROR:
- zlog_warn(
+ flog_err(
+ EC_LIB_ZAPI_SOCKET,
"%s: buffer_flush_available failed on zclient fd %d, closing",
__func__, zclient->sock);
return zclient_failed(zclient);
STREAM_DATA(zclient->obuf),
stream_get_endp(zclient->obuf))) {
case BUFFER_ERROR:
- zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
- __func__, zclient->sock);
+ flog_err(EC_LIB_ZAPI_SOCKET,
+ "%s: buffer_write failed to zclient fd %d, closing",
+ __func__, zclient->sock);
return zclient_failed(zclient);
break;
case BUFFER_EMPTY:
STREAM_GETW(s, *cmd);
if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
- flog_err(LIB_ERR_ZAPI_MISSMATCH,
- "%s: socket %d version mismatch, marker %d, version %d",
- __func__, sock, *marker, *version);
+ flog_err(
+ EC_LIB_ZAPI_MISSMATCH,
+ "%s: socket %d version mismatch, marker %d, version %d",
+ __func__, sock, *marker, *version);
return -1;
}
}
if (set_nonblocking(zclient->sock) < 0)
- zlog_warn("%s: set_nonblocking(%d) failed", __func__,
- zclient->sock);
+ flog_err(EC_LIB_ZAPI_SOCKET, "%s: set_nonblocking(%d) failed",
+ __func__, zclient->sock);
/* Clear fail count. */
zclient->fail = 0;
char buf[PREFIX2STR_BUFFER];
prefix2str(&api->prefix, buf, sizeof(buf));
- zlog_warn(
- "%s: prefix %s: can't encode %u nexthops "
- "(maximum is %u)",
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "%s: prefix %s: can't encode %u nexthops (maximum is %u)",
__func__, buf, api->nexthop_num, MULTIPATH_NUM);
return -1;
}
16);
stream_putl(s, api_nh->ifindex);
break;
- default:
- zlog_warn(
- "%s: Specified Nexthop type %d does not exist",
- __PRETTY_FUNCTION__, api_nh->type);
- return -1;
}
/* MPLS labels for BGP-LU or Segment Routing */
char buf[PREFIX2STR_BUFFER];
prefix2str(&api->prefix, buf,
sizeof(buf));
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "%s: prefix %s: can't encode "
- "%u labels (maximum is %u)",
- __func__, buf,
- api_nh->label_num,
- MPLS_MAX_LABELS);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: prefix %s: can't encode "
+ "%u labels (maximum is %u)",
+ __func__, buf,
+ api_nh->label_num,
+ MPLS_MAX_LABELS);
return -1;
}
/* Type, flags, message. */
STREAM_GETC(s, api->type);
if (api->type > ZEBRA_ROUTE_MAX) {
- zlog_warn("%s: Specified route type: %d is not a legal value\n",
- __PRETTY_FUNCTION__, api->type);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: Specified route type: %d is not a legal value\n",
+ __PRETTY_FUNCTION__, api->type);
return -1;
}
switch (api->prefix.family) {
case AF_INET:
if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
- zlog_warn(
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
"%s: V4 prefixlen is %d which should not be more than 32",
__PRETTY_FUNCTION__, api->prefix.prefixlen);
return -1;
break;
case AF_INET6:
if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
- zlog_warn(
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
"%s: v6 prefixlen is %d which should not be more than 128",
__PRETTY_FUNCTION__, api->prefix.prefixlen);
return -1;
}
break;
default:
- zlog_warn("%s: Specified family %d is not v4 or v6",
- __PRETTY_FUNCTION__, api->prefix.family);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: Specified family %d is not v4 or v6",
+ __PRETTY_FUNCTION__, api->prefix.family);
return -1;
}
STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
api->src_prefix.family = AF_INET6;
STREAM_GETC(s, api->src_prefix.prefixlen);
if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
- zlog_warn(
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
"%s: SRC Prefix prefixlen received: %d is too large",
__PRETTY_FUNCTION__, api->src_prefix.prefixlen);
return -1;
if (api->prefix.family != AF_INET6
|| api->src_prefix.prefixlen == 0) {
- zlog_warn(
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
"%s: SRC prefix specified in some manner that makes no sense",
__PRETTY_FUNCTION__);
return -1;
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
STREAM_GETW(s, api->nexthop_num);
if (api->nexthop_num > MULTIPATH_NUM) {
- zlog_warn("%s: invalid number of nexthops (%u)",
- __func__, api->nexthop_num);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: invalid number of nexthops (%u)",
+ __func__, api->nexthop_num);
return -1;
}
STREAM_GET(&api_nh->gate.ipv6, s, 16);
STREAM_GETL(s, api_nh->ifindex);
break;
- default:
- zlog_warn(
- "%s: Specified nexthop type %d does not exist",
- __PRETTY_FUNCTION__, api_nh->type);
- return -1;
}
/* MPLS labels for BGP-LU or Segment Routing */
STREAM_GETC(s, api_nh->label_num);
if (api_nh->label_num > MPLS_MAX_LABELS) {
- zlog_warn(
- "%s: invalid number of MPLS "
- "labels (%u)",
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "%s: invalid number of MPLS labels (%u)",
__func__, api_nh->label_num);
return -1;
}
}
STREAM_GETC(s, nhr->nexthops[i].label_num);
if (nhr->nexthops[i].label_num > MPLS_MAX_LABELS) {
- zlog_warn("%s: invalid number of MPLS labels (%u)",
- __func__, nhr->nexthops[i].label_num);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: invalid number of MPLS labels (%u)",
+ __func__, nhr->nexthops[i].label_num);
return false;
}
if (nhr->nexthops[i].label_num)
/* Lookup this by interface index. */
ifp = if_lookup_by_name(ifname_tmp, vrf_id);
if (ifp == NULL) {
- zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d",
- ifname_tmp, vrf_id);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "INTERFACE_STATE: Cannot find IF %s in VRF %d",
+ ifname_tmp, vrf_id);
return NULL;
}
for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
iflp->unrsv_bw[i] = stream_getf(s);
if (i < bwclassnum)
- flog_err(LIB_ERR_ZAPI_MISSMATCH,
- "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
- " - outdated library?",
- __func__, bwclassnum, MAX_CLASS_TYPE);
+ flog_err(
+ EC_LIB_ZAPI_MISSMATCH,
+ "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
+ " - outdated library?",
+ __func__, bwclassnum, MAX_CLASS_TYPE);
}
iflp->admin_grp = stream_getl(s);
iflp->rmt_as = stream_getl(s);
struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
if (ifp == NULL) {
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "%s: unknown ifindex %u, shouldn't happen", __func__,
- ifindex);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "%s: unknown ifindex %u, shouldn't happen", __func__,
+ ifindex);
return NULL;
}
/* Lookup index. */
ifp = if_lookup_by_index(ifindex, vrf_id);
if (ifp == NULL) {
- zlog_warn("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
- (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
- ifindex, vrf_id);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
+ (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
+ ifindex, vrf_id);
return NULL;
}
/* carp interfaces on OpenBSD with 0.0.0.0/0 as
* "peer" */
char buf[PREFIX_STRLEN];
- zlog_warn(
- "warning: interface %s address %s "
- "with peer flag set, but no peer address!",
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "warning: interface %s address %s with peer flag set, but no peer address!",
ifp->name,
prefix2str(ifc->address, buf,
sizeof buf));
/* Lookup index. */
ifp = if_lookup_by_index(ifindex, vrf_id);
if (ifp == NULL) {
- zlog_warn("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
- (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
- : "DELETE",
- ifindex, vrf_id);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
+ (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
+ : "DELETE",
+ ifindex, vrf_id);
return NULL;
}
/* Lookup interface. */
ifp = if_lookup_by_index(ifindex, vrf_id);
if (ifp == NULL) {
- zlog_warn("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
- ifindex, vrf_id);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
+ ifindex, vrf_id);
return NULL;
}
size);
}
if (ret != 0) {
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "%s: Invalid Sync Message Reply", __func__);
+ flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
+ __func__);
return -1;
}
* immediately reads the answer from the input buffer.
*
* @param zclient Zclient used to connect to label manager (zebra)
+ * @param async Synchronous (0) or asynchronous (1) operation
* @result Result of response
*/
-int lm_label_manager_connect(struct zclient *zclient)
+int lm_label_manager_connect(struct zclient *zclient, int async)
{
int ret;
struct stream *s;
uint8_t result;
+ uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
+ ZEBRA_LABEL_MANAGER_CONNECT;
if (zclient_debug)
zlog_debug("Connecting to Label Manager (LM)");
- if (zclient->sock < 0)
+ if (zclient->sock < 0) {
+ zlog_debug("%s: invalid zclient socket", __func__);
return -1;
+ }
/* send request */
s = zclient->obuf;
stream_reset(s);
- zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT);
+ zclient_create_header(s, cmd, VRF_DEFAULT);
/* proto */
stream_putc(s, zclient->redist_default);
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock");
+ flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET, "Zclient sock closed");
+ flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
close(zclient->sock);
zclient->sock = -1;
return -1;
if (zclient_debug)
zlog_debug("LM connect request sent (%d bytes)", ret);
+ if (async)
+ return 0;
+
/* read response */
- if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT)
+ if (zclient_read_sync_response(zclient, cmd)
!= 0)
return -1;
/* sanity */
if (proto != zclient->redist_default)
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "Wrong proto (%u) in LM connect response. Should be %u",
- proto, zclient->redist_default);
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "Wrong proto (%u) in LM connect response. Should be %u",
+ proto, zclient->redist_default);
if (instance != zclient->instance)
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "Wrong instId (%u) in LM connect response. Should be %u",
- instance, zclient->instance);
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "Wrong instId (%u) in LM connect response. Should be %u",
+ instance, zclient->instance);
/* result code */
result = stream_getc(s);
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET,
- "Can't write to zclient sock");
+ flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET,
- "Zclient sock closed");
+ flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
close(zclient->sock);
zclient->sock = -1;
return -1;
/* sanities */
if (proto != zclient->redist_default)
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "Wrong proto (%u) in get chunk response. Should be %u",
- proto, zclient->redist_default);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "Wrong proto (%u) in get chunk response. Should be %u",
+ proto, zclient->redist_default);
if (instance != zclient->instance)
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "Wrong instId (%u) in get chunk response Should be %u",
- instance, zclient->instance);
+ flog_err(EC_LIB_ZAPI_ENCODE,
+ "Wrong instId (%u) in get chunk response Should be %u",
+ instance, zclient->instance);
/* keep */
response_keep = stream_getc(s);
/* not owning this response */
if (keep != response_keep) {
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
- *start, *end, keep, response_keep);
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
+ "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
+ *start, *end, keep, response_keep);
}
/* sanity */
if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
|| *end > MPLS_LABEL_UNRESERVED_MAX) {
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "Invalid Label chunk: %u - %u", *start, *end);
+ flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
+ *start, *end);
return -1;
}
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock");
+ flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET,
- "Zclient sock connection closed");
+ flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
close(zclient->sock);
zclient->sock = -1;
return -1;
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET,
- "%s: can't write to zclient->sock", __func__);
+ flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
+ __func__);
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET,
- "%s: zclient->sock connection closed", __func__);
+ flog_err(EC_LIB_ZAPI_SOCKET,
+ "%s: zclient->sock connection closed", __func__);
close(zclient->sock);
zclient->sock = -1;
return -1;
stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
break;
default:
- flog_err(LIB_ERR_ZAPI_ENCODE,
- "%s: unknown af", __func__);
+ flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
return -1;
}
command = stream_getw(zclient->ibuf);
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
- flog_err(LIB_ERR_ZAPI_MISSMATCH,
- "%s: socket %d version mismatch, marker %d, version %d",
- __func__, zclient->sock, marker, version);
+ flog_err(
+ EC_LIB_ZAPI_MISSMATCH,
+ "%s: socket %d version mismatch, marker %d, version %d",
+ __func__, zclient->sock, marker, version);
return zclient_failed(zclient);
}
if (length < ZEBRA_HEADER_SIZE) {
- flog_err(LIB_ERR_ZAPI_MISSMATCH,
- "%s: socket %d message length %u is less than %d ",
- __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
+ flog_err(EC_LIB_ZAPI_MISSMATCH,
+ "%s: socket %d message length %u is less than %d ",
+ __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
return zclient_failed(zclient);
}
/* Length check. */
if (length > STREAM_SIZE(zclient->ibuf)) {
struct stream *ns;
- zlog_warn(
+ flog_err(
+ EC_LIB_ZAPI_ENCODE,
"%s: message size %u exceeds buffer size %lu, expanding...",
__func__, length,
(unsigned long)STREAM_SIZE(zclient->ibuf));
ZEBRA_MPLS_LABELS_DELETE,
ZEBRA_IPMR_ROUTE_STATS,
ZEBRA_LABEL_MANAGER_CONNECT,
+ ZEBRA_LABEL_MANAGER_CONNECT_ASYNC,
ZEBRA_GET_LABEL_CHUNK,
ZEBRA_RELEASE_LABEL_CHUNK,
ZEBRA_FEC_REGISTER,
uint8_t keep,
uint32_t chunk_size);
-extern int lm_label_manager_connect(struct zclient *zclient);
+extern int lm_label_manager_connect(struct zclient *zclient, int async);
extern int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
uint32_t chunk_size, uint32_t *start,
uint32_t *end);
#include "compiler.h"
#ifdef SUNOS_5
-#define _XPG4_2
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
#endif
#define MAX(a, b) \
({ \
- typeof(a) _a = (a); \
- typeof(b) _b = (b); \
- _a > _b ? _a : _b; \
+ typeof(a) _max_a = (a); \
+ typeof(b) _max_b = (b); \
+ _max_a > _max_b ? _max_a : _max_b; \
})
#ifdef MIN
#undef MIN
#endif
#define MIN(a, b) \
({ \
- typeof(a) _a = (a); \
- typeof(b) _b = (b); \
- _a < _b ? _a : _b; \
+ typeof(a) _min_a = (a); \
+ typeof(b) _min_b = (b); \
+ _min_a < _min_b ? _min_a : _min_b; \
})
#ifndef offsetof
#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 */
-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
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])
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
* (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>
* (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>
/* clang-format off */
static struct log_ref ferr_nhrp_err[] = {
{
- .code = NHRP_ERR_SWAN,
+ .code = EC_NHRP_SWAN,
.title = "NHRP Strong Swan Error",
.description = "NHRP has detected a error with the Strongswan code",
.suggestion = "Ensure that StrongSwan is configured correctly. Restart StrongSwan and FRR"
},
{
- .code = NHRP_ERR_RESOLVER,
+ .code = EC_NHRP_RESOLVER,
.title = "NHRP DNS Resolution",
.description = "NHRP has detected an error in an attempt to resolve a hostname",
.suggestion = "Ensure that DNS is working properly and the hostname is configured in dns. If you are still seeing this error, open an issue"
#include "lib/ferr.h"
enum nhrp_log_refs {
- NHRP_ERR_SWAN = NHRP_FERR_START,
- NHRP_ERR_RESOLVER,
+ EC_NHRP_SWAN = NHRP_FERR_START,
+ EC_NHRP_RESOLVER,
};
extern void nhrp_error_init(void);
* (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>
* (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"
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include "zebra.h"
* (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"
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <netinet/if_ether.h>
#include "zebra.h"
reply = packet_types[hdr->type].type == PACKET_REPLY;
debugf(NHRP_DEBUG_COMMON, "%s %s(%d) %s -> %s", dir,
- packet_types[hdr->type].name ?: "Unknown", hdr->type,
- reply ? buf[1] : buf[0], reply ? buf[0] : buf[1]);
+ (packet_types[hdr->type].name ? packet_types[hdr->type].name
+ : "Unknown"),
+ hdr->type, reply ? buf[1] : buf[0], reply ? buf[0] : buf[1]);
}
static int proto2afi(uint16_t proto)
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "nhrpd.h"
#include "table.h"
#include "memory.h"
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "nhrpd.h"
#include "table.h"
#include "memory.h"
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <ares.h>
#include <ares_version.h>
union sockunion *))
{
if (query->callback != NULL) {
- flog_err(NHRP_ERR_RESOLVER,
- "Trying to resolve '%s', but previous query was not finished yet",
- hostname);
+ flog_err(
+ EC_NHRP_RESOLVER,
+ "Trying to resolve '%s', but previous query was not finished yet",
+ hostname);
return;
}
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@
* (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>
if (str2sockunion(buf,
&sactx->local.host)
< 0)
- flog_err(NHRP_ERR_SWAN,
- "VICI: bad strongSwan local-host: %s",
- buf);
+ flog_err(
+ EC_NHRP_SWAN,
+ "VICI: bad strongSwan local-host: %s",
+ buf);
} else if (blob_equal(key, "local-id")
&& ctx->nsections == 1) {
sactx->local.id = *val;
if (str2sockunion(buf,
&sactx->remote.host)
< 0)
- flog_err(NHRP_ERR_SWAN,
- "VICI: bad strongSwan remote-host: %s",
- buf);
+ flog_err(
+ EC_NHRP_SWAN,
+ "VICI: bad strongSwan remote-host: %s",
+ buf);
} else if (blob_equal(key, "remote-id")
&& ctx->nsections == 1) {
sactx->remote.id = *val;
case VICI_KEY_VALUE:
if (blob_equal(key, "errmsg")
&& blob2buf(val, buf, sizeof(buf)))
- flog_err(NHRP_ERR_SWAN, "VICI: strongSwan: %s", buf);
+ flog_err(EC_NHRP_SWAN, "VICI: strongSwan: %s", buf);
break;
default:
break;
break;
case VICI_EVENT_UNKNOWN:
case VICI_CMD_UNKNOWN:
- flog_err(NHRP_ERR_SWAN,
+ flog_err(
+ EC_NHRP_SWAN,
"VICI: StrongSwan does not support mandatory events (unpatched?)");
break;
case VICI_EVENT_CONFIRM:
* (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>
* (at your option) any later version.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <fcntl.h>
#include <errno.h>
#include <string.h>
-!Makefile
-Makefile.in
-*.o
-*.patch
ospf6d
ospf6d.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
* old as the route.
*/
if (listcount(route->paths) > 1) {
- struct listnode *anode;
- struct ospf6_path *o_path;
-
for (ALL_LIST_ELEMENTS_RO(route->paths, anode,
o_path)) {
inet_ntop(AF_INET,
? 1
: 2,
buf, listcount(route->paths),
- listcount(route->nh_list));
+ route->nh_list ?
+ listcount(route->nh_list) : 0);
}
if (listcount(route->paths)) {
{
const struct ospf6_lsa_handler *handler;
handler = ospf6_get_lsa_handler(type);
- return handler->debug;
+ return handler->lh_debug;
}
/* RFC2328: Section 13.2 */
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;
}
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;
}
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));
}
#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) \
/* receive message */
len = ospf6_recvmsg(&src, &dst, &ifindex, iovector);
if (len > iobuflen) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "Excess message read");
+ flog_err(EC_LIB_DEVELOPMENT, "Excess message read");
return 0;
}
/* send message */
len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector);
if (len != ntohs(oh->length))
- flog_err(LIB_ERR_DEVELOPMENT, "Could not send entire message");
+ flog_err(EC_LIB_DEVELOPMENT, "Could not send entire message");
}
static uint32_t ospf6_packet_max(struct ospf6_interface *oi)
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);
}
}
sizeof(mreq6));
if (ret < 0) {
flog_err_sys(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"Network: setsockopt (%d) on ifindex %d failed: %s",
option, ifindex, safe_strerror(errno));
return ret;
if (link_error == 0 && num == table->count)
return;
- flog_err(LIB_ERR_DEVELOPMENT, "PANIC !!");
- flog_err(LIB_ERR_DEVELOPMENT, "Something has gone wrong with ospf6_route_table[%p]", table);
+ flog_err(EC_LIB_DEVELOPMENT, "PANIC !!");
+ flog_err(EC_LIB_DEVELOPMENT,
+ "Something has gone wrong with ospf6_route_table[%p]", table);
zlog_debug("table count = %d, real number = %d", table->count, num);
zlog_debug("DUMP START");
for (r = ospf6_route_head(table); r; r = ospf6_route_next(r)) {
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);
ifindex = (VERTEX_IS_TYPE(NETWORK, v) ? ospf6_spf_get_ifindex_from_nh(v)
: ROUTER_LSDESC_GET_IFID(lsdesc));
if (ifindex == 0) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "No nexthop ifindex at vertex %s", v->name);
+ flog_err(EC_LIB_DEVELOPMENT, "No nexthop ifindex at vertex %s",
+ v->name);
return;
}
ret = zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
if (ret < 0)
- flog_err(LIB_ERR_ZAPI_SOCKET,
- "zclient_route_send() %s failed: %s",
- (type == REM ? "delete" : "add"),
- safe_strerror(errno));
+ flog_err(EC_LIB_ZAPI_SOCKET,
+ "zclient_route_send() %s failed: %s",
+ (type == REM ? "delete" : "add"),
+ safe_strerror(errno));
return;
}
#define threadtimer_string(now, t, buf, size) \
do { \
- struct timeval result; \
+ struct timeval _result; \
if (!t) \
snprintf(buf, size, "inactive"); \
else { \
- timersub(&t->u.sands, &now, &result); \
- timerstring(&result, buf, size); \
+ timersub(&t->u.sands, &now, &_result); \
+ timerstring(&_result, buf, size); \
} \
} while (0)
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 = \
-!Makefile
-Makefile.in
-*.o
ospfclient
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-refix
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
-!Makefile
-Makefile.in
-*.o
ospfd
ospfd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"
+#include "ospfd/ospf_errors.h"
static struct ospf_area_range *ospf_area_range_new(struct prefix_ipv4 *p)
{
prefix2str((struct prefix *)p, buf,
sizeof(buf));
- zlog_warn("%s: Could not refresh %s to %s",
+ flog_warn(EC_OSPF_LSA_MISSING,
+ "%s: Could not refresh %s to %s",
__func__, buf,
inet_ntoa(area->area_id));
return;
char buf[PREFIX2STR_BUFFER];
prefix2str((struct prefix *)p, buf, sizeof(buf));
- zlog_warn("%s: Could not originate %s to %s", __func__,
+ flog_warn(EC_OSPF_LSA_MISSING,
+ "%s: Could not originate %s to %s", __func__,
buf, inet_ntoa(area->area_id));
return;
}
char buf[PREFIX2STR_BUFFER];
prefix2str((struct prefix *)p, buf, sizeof(buf));
- zlog_warn("%s: Could not refresh/originate %s to %s",
+ flog_warn(EC_OSPF_LSA_MISSING,
+ "%s: Could not refresh/originate %s to %s",
__func__, buf, inet_ntoa(area->area_id));
return;
}
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"
+#include "ospfd/ospf_errors.h"
#include "ospfd/ospf_api.h"
#include "ospfd/ospf_apiserver.h"
NULL, /* ospf_apiserver_lsa_refresher */
ospf_apiserver_lsa_update, ospf_apiserver_lsa_delete);
if (rc != 0) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_OPAQUE_REGISTRATION,
"ospf_apiserver_init: Failed to register opaque type [0/0]");
}
NULL /* ospf_apiserver_lsa_delete */);
if (rc != 0) {
- zlog_warn("Failed to register opaque type [%d/%d]", lsa_type,
+ flog_warn(EC_OSPF_OPAQUE_REGISTRATION,
+ "Failed to register opaque type [%d/%d]", lsa_type,
opaque_type);
return OSPF_API_OPAQUETYPEINUSE;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(ospf, lsa->oi, lsa) == NULL) {
- zlog_warn("ospf_apiserver_originate1: ospf_lsa_install failed");
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "ospf_apiserver_originate1: ospf_lsa_install failed");
return -1;
}
/* Install LSA into LSDB. */
if (ospf_lsa_install(ospf, new->oi, new) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_INSTALL_FAILURE,
"ospf_apiserver_lsa_refresher: ospf_lsa_install failed");
ospf_lsa_unlock(&new);
goto out;
inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf,
INET6_BUFSIZ);
- zlog_warn(
- "Redistribute[%s][%d][%u]: %s/%d discarding old info with NH %s.",
- ospf_redist_string(type), instance,
- ospf->vrf_id, inet_ntoa(p.prefix), p.prefixlen,
- inetbuf);
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "Redistribute[%s][%d][%u]: %s/%d discarding old info with NH %s.",
+ ospf_redist_string(type), instance,
+ ospf->vrf_id, inet_ntoa(p.prefix),
+ p.prefixlen, inetbuf);
XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info);
rn->info = NULL;
}
#include "lib/ferr.h"
#include "ospf_errors.h"
+/* clang-format off */
+static struct log_ref ferr_ospf_warn[] = {
+ {
+ .code = EC_OSPF_SET_METRIC_PLUS,
+ .title = "OSPF does not support `set metric +rtt/-rtt`",
+ .description = "This implementation of OSPF does not currently support `set metric +rtt/-rtt`",
+ .suggestion = "Do not use this particular set command for an ospf route-map",
+ },
+ {
+ .code = EC_OSPF_MD5,
+ .title = "OSPF has noticed a MD5 issue",
+ .description = "Something has gone wrong with the calculation of the MD5 data",
+ .suggestion = "Ensure your key is correct, gather log data from this side as well as peer and open an Issue",
+ },
+ {
+ .code = EC_OSPF_PACKET,
+ .title = "OSPF has detected packet information missmatch",
+ .description = "OSPF has detected that packet information received is incorrect",
+ .suggestion = "Ensure interface configuration is correct, gather log files from here and the peer and open an Issue",
+ },
+ {
+ .code = EC_OSPF_LARGE_LSA,
+ .title = "OSPF has determined that a LSA packet will be too large",
+ .description = "OSPF has received data that is causing it to recalculate how large packets should be and has discovered that the packet size needed would be too large and we will need to fragment packets",
+ .suggestion = "Further divide up your network with areas",
+ },
+ {
+ .code = EC_OSPF_LSA_UNEXPECTED,
+ .title = "OSPF has received a LSA-type that it was not expecting",
+ .description = "OSPF has received a LSA-type that it was not expecting during processing",
+ .suggestion = "Gather log data from this machine and it's peer and open an Issue",
+ },
+ {
+ .code = EC_OSPF_LSA,
+ .title = "OSPF has discovered inconsistent internal state for a LSA",
+ .description = "During handling of a LSA, OSPF has discovered that the LSA's internal state is inconsistent",
+ .suggestion = "Gather log data and open an Issue",
+ },
+ {
+ .code = EC_OSPF_OPAQUE_REGISTRATION,
+ .title = "OSPF has failed to properly register Opaque Handler",
+ .description = "During initialization OSPF has detected a failure to install an opaque handler",
+ .suggestion = "Gather log data and open an Issue",
+ },
+ {
+ .code = EC_OSPF_TE_UNEXPECTED,
+ .title = "OSPF has received TE information that it was not expecting",
+ .description = "OSPF has received TE information that it was not expecting during normal processing of data",
+ .suggestion = "Gather log data from this machine and it's peer and open an Issue",
+ },
+ {
+ .code = EC_OSPF_LSA_INSTALL_FAILURE,
+ .title = "OSPF was unable to save the LSA into it's database",
+ .description = "During processing of a new lsa and attempting to save the lsa into the OSPF database, this process failed.",
+ .suggestion = "Gather log data from this machine and open an Issue",
+ },
+ {
+ .code = EC_OSPF_LSA_NULL,
+ .title = "OSPF has received a NULL lsa pointer",
+ .description = "When processing a LSA update we have found and noticed an internal error where we are passing around a NULL pointer",
+ .suggestion = "Gather data from this machine and it's peer and open an Issue",
+ },
+ {
+ .code = EC_OSPF_EXT_LSA_UNEXPECTED,
+ .title = "OSPF has received EXT information that leaves it in an unexpected state",
+ .description = "While processing EXT LSA information, OSPF has noticed that the internal state of OSPF has gotten inconsistent",
+ .suggestion = "Gather data from this machine and it's peer and open an Issue",
+ },
+ {
+ .code = EC_OSPF_LSA_MISSING,
+ .title = "OSPF attempted to look up a LSA and it was not found",
+ .description = "During processing of new LSA information, we attempted to look up an old LSA and it was not found",
+ .suggestion = "Gather data from this machine and open an Issue",
+ },
+ {
+ .code = EC_OSPF_PTP_NEIGHBOR,
+ .title = "OSPF has detected more than 1 neighbor on a P2P interface",
+ .description = "If you configure a ospf interface as P2P we should not detect more than one neighbor on the interface",
+ .suggestion = "Fix your config",
+ },
+ {
+ .code = EC_OSPF_LSA_SIZE,
+ .title = "OSPF has detected an invalid LSA size",
+ .description = "OSPF has detected a state where we are attempting to grow a LSA but the LSA has reached it's maximum size",
+ .suggestion = "Gather data and open an Issue",
+ },
+ {
+ .code = END_FERR,
+ }
+};
+
static struct log_ref ferr_ospf_err[] = {
{
- .code = OSPF_ERR_PKT_PROCESS,
+ .code = EC_OSPF_PKT_PROCESS,
.title = "Failure to process a packet",
.description = "OSPF attempted to process a received packet but could not",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = OSPF_ERR_ROUTER_LSA_MISMATCH,
+ .code = EC_OSPF_ROUTER_LSA_MISMATCH,
.title = "Failure to process Router LSA",
.description = "OSPF attempted to process a Router LSA but Advertising ID mismatch with link id",
.suggestion = "Check OSPF network config for any config issue, If the problem persists, report the problem for troubleshooting"
},
{
- .code = OSPF_ERR_DOMAIN_CORRUPT,
+ .code = EC_OSPF_DOMAIN_CORRUPT,
.title = "OSPF Domain Corruption",
.description = "OSPF attempted to process a Router LSA but Advertising ID mismatch with link id",
.suggestion = "Check OSPF network Database for corrupted LSA, If the problem persists, shutdown OSPF domain and report the problem for troubleshooting"
},
{
- .code = OSPF_ERR_INIT_FAIL,
+ .code = EC_OSPF_INIT_FAIL,
.title = "OSPF Initialization failure",
.description = "OSPF failed to initialized OSPF default insance",
.suggestion = "Ensure there is adequate memory on the device. If the problem persists, report the problem for troubleshooting"
},
{
- .code = OSPF_ERR_SR_INVALID_DB,
+ .code = EC_OSPF_SR_INVALID_DB,
.title = "OSPF SR Invalid DB",
.description = "OSPF Segment Routing Database is invalid",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = OSPF_ERR_SR_NODE_CREATE,
+ .code = EC_OSPF_SR_NODE_CREATE,
.title = "OSPF SR hash node creation failed",
.description = "OSPF Segment Routing node creation failed",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
{
- .code = OSPF_ERR_SR_INVALID_LSA_ID,
+ .code = EC_OSPF_SR_INVALID_LSA_ID,
.title = "OSPF SR Invalid LSA ID",
.description = "OSPF Segment Routing invalid lsa id",
.suggestion = "Restart OSPF instance, If the problem persists, report the problem for troubleshooting"
},
{
- .code = OSPF_ERR_SR_INVALID_ALGORITHM,
+ .code = EC_OSPF_INVALID_ALGORITHM,
.title = "OSPF SR Invalid Algorithm",
.description = "OSPF Segment Routing invalid Algorithm",
.suggestion = "Most likely a bug. If the problem persists, report the problem for troubleshooting"
},
-
+ {
+ .code = EC_OSPF_FSM_INVALID_STATE,
+ .title = "OSPF FSM invalid state detected",
+ .description = "OSPF has attempted to change states when it should not be able to",
+ .suggestion = "Gather log files and open an issue",
+ },
{
.code = END_FERR,
}
};
+/* clang-format on */
void ospf_error_init(void)
{
+ log_ref_add(ferr_ospf_warn);
log_ref_add(ferr_ospf_err);
}
#include "lib/ferr.h"
enum ospf_log_refs {
- OSPF_ERR_PKT_PROCESS = OSPF_FERR_START,
- OSPF_ERR_ROUTER_LSA_MISMATCH,
- OSPF_ERR_DOMAIN_CORRUPT,
- OSPF_ERR_INIT_FAIL,
- OSPF_ERR_SR_INVALID_DB,
- OSPF_ERR_SR_NODE_CREATE,
- OSPF_ERR_SR_INVALID_LSA_ID,
- OSPF_ERR_SR_INVALID_ALGORITHM,
+ EC_OSPF_PKT_PROCESS = OSPF_FERR_START,
+ EC_OSPF_ROUTER_LSA_MISMATCH,
+ EC_OSPF_DOMAIN_CORRUPT,
+ EC_OSPF_INIT_FAIL,
+ EC_OSPF_SR_INVALID_DB,
+ EC_OSPF_SR_NODE_CREATE,
+ EC_OSPF_SR_INVALID_LSA_ID,
+ EC_OSPF_INVALID_ALGORITHM,
+ EC_OSPF_FSM_INVALID_STATE,
+ EC_OSPF_SET_METRIC_PLUS,
+ EC_OSPF_MD5,
+ EC_OSPF_PACKET,
+ EC_OSPF_LARGE_LSA,
+ EC_OSPF_LSA_UNEXPECTED,
+ EC_OSPF_LSA,
+ EC_OSPF_OPAQUE_REGISTRATION,
+ EC_OSPF_TE_UNEXPECTED,
+ EC_OSPF_LSA_INSTALL_FAILURE,
+ EC_OSPF_LSA_NULL,
+ EC_OSPF_EXT_LSA_UNEXPECTED,
+ EC_OSPF_LSA_MISSING,
+ EC_OSPF_PTP_NEIGHBOR,
+ EC_OSPF_LSA_SIZE,
};
extern void ospf_error_init(void);
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_sr.h"
#include "ospfd/ospf_ext.h"
+#include "ospfd/ospf_errors.h"
/* Following structure are internal use only. */
NULL); /* del_lsa_hook */
if (rc != 0) {
- zlog_warn("EXT (%s): Failed to register Extended Link LSA",
+ flog_warn(EC_OSPF_OPAQUE_REGISTRATION,
+ "EXT (%s): Failed to register Extended Link LSA",
__func__);
return rc;
}
ospf_ext_pref_lsa_update, /* new_lsa_hook */
NULL); /* del_lsa_hook */
if (rc != 0) {
- zlog_warn("EXT (%s): Failed to register Extended Prefix LSA",
+ flog_warn(EC_OSPF_OPAQUE_REGISTRATION,
+ "EXT (%s): Failed to register Extended Prefix LSA",
__func__);
return rc;
}
void ospf_ext_term(void)
{
- if ((OspfEXT.scope != OSPF_OPAQUE_AREA_LSA)
- && (OspfEXT.scope != OSPF_OPAQUE_AS_LSA))
- zlog_warn(
- "EXT: Unable to unregister Extended Prefix "
- "Opaque LSA functions: Wrong scope!");
- else
+ if ((OspfEXT.scope == OSPF_OPAQUE_AREA_LSA)
+ || (OspfEXT.scope == OSPF_OPAQUE_AS_LSA))
ospf_delete_opaque_functab(OspfEXT.scope,
OPAQUE_TYPE_EXTENDED_PREFIX_LSA);
if ((algorithm != SR_ALGORITHM_SPF)
&& (algorithm != SR_ALGORITHM_STRICT_SPF)) {
- zlog_warn("EXT (%s): unrecognized algorithm, not SPF or S-SPF",
- __func__);
+ flog_err(EC_OSPF_INVALID_ALGORITHM,
+ "EXT (%s): unrecognized algorithm, not SPF or S-SPF",
+ __func__);
return;
}
int rc = -1;
if (lookup_ext_by_ifp(ifp) != NULL) {
- zlog_warn("EXT (%s): interface %s is already in use", __func__,
- ifp ? ifp->name : "-");
rc = 0; /* Do nothing here. */
return rc;
}
rc = 0;
} else {
- zlog_warn("EXT (%s): interface %s is not found", __func__,
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): interface %s is not found", __func__,
ifp ? ifp->name : "-");
}
/* Get interface information for Segment Routing */
exti = lookup_ext_by_ifp(oi->ifp);
- if (exti == NULL) {
- zlog_warn("EXT (%s): Cannot get Extended info. from OI(%s)",
- __func__, IF_NAME(oi));
+ if (exti == NULL)
return;
- }
/* Determine if interface is related to Adjacency or LAN Adj. SID */
if (oi->type != OSPF_IFTYPE_LOOPBACK) {
/* Get interface information for Segment Routing */
exti = lookup_ext_by_ifp(oi->ifp);
if (exti == NULL) {
- zlog_warn("EXT (%s): Cannot get Extended info. from OI(%s)",
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Cannot get Extended info. from OI(%s)",
__func__, IF_NAME(oi));
return;
}
/* Get interface information for Segment Routing */
exti = lookup_ext_by_ifp(oi->ifp);
if (exti == NULL) {
- zlog_warn("EXT (%s): Cannot get Extended info. from OI(%s)",
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Cannot get Extended info. from OI(%s)",
__func__, IF_NAME(oi));
return;
}
if (oi->area == NULL || oi->area->ospf == NULL) {
- zlog_warn("EXT (%s): Cannot refer to OSPF from OI(%s)",
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Cannot refer to OSPF from OI(%s)",
__func__, IF_NAME(oi));
return;
}
{
/* Sanity Check */
if (lsa == NULL) {
- zlog_warn("EXT (%s): Abort! LSA is NULL", __func__);
+ flog_warn(EC_OSPF_LSA_NULL, "EXT (%s): Abort! LSA is NULL",
+ __func__);
return -1;
}
/* Sanity Check */
if (lsa == NULL) {
- zlog_warn("EXT (%s): Abort! LSA is NULL", __func__);
+ flog_warn(EC_OSPF_LSA_NULL, "EXT (%s): Abort! LSA is NULL",
+ __func__);
return -1;
}
/* Create a stream for LSA. */
s = stream_new(OSPF_MAX_LSA_SIZE);
- if (s == NULL) {
- zlog_warn("EXT (%s): stream_new() error", __func__);
- return NULL;
- }
/* Prepare LSA Header */
lsah = (struct lsa_header *)STREAM_DATA(s);
/* Create a stream for LSA. */
s = stream_new(OSPF_MAX_LSA_SIZE);
- if (s == NULL) {
- zlog_warn("EXT (%s): stream_new() error", __func__);
- return NULL;
- }
lsah = (struct lsa_header *)STREAM_DATA(s);
options = OSPF_OPTION_O; /* Don't forget this :-) */
/* Create new Opaque-LSA/Extended Prefix Opaque LSA instance. */
new = ospf_ext_pref_lsa_new(area, exti);
if (new == NULL) {
- zlog_warn("EXT (%s): ospf_ext_pref_lsa_new() error", __func__);
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): ospf_ext_pref_lsa_new() error", __func__);
return rc;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(area->ospf, NULL /*oi */, new) == NULL) {
- zlog_warn("EXT (%s): ospf_lsa_install() error", __func__);
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "EXT (%s): ospf_lsa_install() error", __func__);
ospf_lsa_unlock(&new);
return rc;
}
/* Create new Opaque-LSA/Extended Link Opaque LSA instance. */
new = ospf_ext_link_lsa_new(area, exti);
if (new == NULL) {
- zlog_warn("EXT (%s): ospf_ext_link_lsa_new() error", __func__);
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): ospf_ext_link_lsa_new() error", __func__);
return rc;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(area->ospf, NULL /*oi */, new) == NULL) {
- zlog_warn("EXT (%s): ospf_lsa_install() error", __func__);
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "EXT (%s): ospf_lsa_install() error", __func__);
ospf_lsa_unlock(&new);
return rc;
}
if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED)) {
if (CHECK_FLAG(exti->flags,
EXT_LPFLG_LSA_FORCED_REFRESH)) {
- zlog_warn(
- "EXT (%s): Refresh instead of "
- "Originate",
+ flog_warn(
+ EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Refresh instead of Originate",
__func__);
UNSET_FLAG(exti->flags,
EXT_LPFLG_LSA_FORCED_REFRESH);
if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED)) {
if (CHECK_FLAG(exti->flags,
EXT_LPFLG_LSA_FORCED_REFRESH)) {
- zlog_warn(
- "EXT (%s): Refresh instead of "
- "Originate",
+ flog_warn(
+ EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Refresh instead of Originate",
__func__);
UNSET_FLAG(exti->flags,
EXT_LPFLG_LSA_FORCED_REFRESH);
/* Lookup this lsa corresponding Extended parameters */
exti = lookup_ext_by_instance(lsa);
if (exti == NULL) {
- zlog_warn("EXT (%s): Invalid parameter LSA ID", __func__);
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Invalid parameter LSA ID", __func__);
/* Flush it anyway. */
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
}
/* Check if Interface was not disable in the interval */
if ((exti != NULL) && !CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE)) {
- zlog_warn("EXT (%s): Interface was Disabled: Flush it!",
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Interface was Disabled: Flush it!",
__func__);
/* Flush it anyway. */
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
new = ospf_ext_pref_lsa_new(area, exti);
if (new == NULL) {
- zlog_warn("EXT (%s): ospf_ext_pref_lsa_new() error", __func__);
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): ospf_ext_pref_lsa_new() error", __func__);
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
- zlog_warn("EXT (%s): ospf_lsa_install() error", __func__);
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "EXT (%s): ospf_lsa_install() error", __func__);
ospf_lsa_unlock(&new);
return NULL;
}
/* Lookup this LSA corresponding Extended parameters */
exti = lookup_ext_by_instance(lsa);
if (exti == NULL) {
- zlog_warn("EXT (%s): Invalid parameter LSA ID", __func__);
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Invalid parameter LSA ID", __func__);
/* Flush it anyway. */
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
}
/* Check if Interface was not disable in the interval */
if ((exti != NULL) && !CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE)) {
- zlog_warn("EXT (%s): Interface was Disabled: Flush it!",
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Interface was Disabled: Flush it!",
__func__);
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
}
/* Create new Opaque-LSA/Extended Link instance */
new = ospf_ext_link_lsa_new(area, exti);
if (new == NULL) {
- zlog_warn("EXT (%s): Error creating new LSA", __func__);
+ flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Error creating new LSA", __func__);
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
/* Install this LSA into LSDB. */
/* Given "lsa" will be freed in the next function */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
- zlog_warn("EXT (%s): Error installing new LSA", __func__);
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "EXT (%s): Error installing new LSA", __func__);
ospf_lsa_unlock(&new);
return NULL;
}
/* Set LSA header information */
if (exti->area == NULL) {
- zlog_warn(
- "EXT (%s): Flooding is Area scope but area is not yet "
- "set",
+ flog_warn(
+ EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Flooding is Area scope but area is not yet set",
__func__);
if (OspfEXT.area == NULL) {
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
UNSET_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED);
ospf_opaque_lsa_flush_schedule(&lsa);
break;
- default:
- zlog_warn("EXT (%s): Unknown opcode", __func__);
- break;
}
}
/* Set LSA header information */
if (exti->area == NULL) {
- zlog_warn(
- "EXT (%s): Flooding is Area scope but area is not "
- "yet set",
+ flog_warn(
+ EC_OSPF_EXT_LSA_UNEXPECTED,
+ "EXT (%s): Flooding is Area scope but area is not yet set",
__func__);
if (OspfEXT.area == NULL) {
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
UNSET_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED);
ospf_opaque_lsa_flush_schedule(&lsa);
break;
- default:
- zlog_warn("EXT (%s): Unknown opcode", __func__);
- break;
}
}
IP addresses for these packets are the neighbors' IP
addresses. */
if (oi->type == OSPF_IFTYPE_NBMA) {
- struct route_node *rn;
struct ospf_neighbor *nbr;
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
void ospf_ia_routing(struct ospf *ospf, struct route_table *rt,
struct route_table *rtrs)
{
+ struct listnode *node;
struct ospf_area *area;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_ia_routing():start");
if (IS_OSPF_ABR(ospf)) {
- struct listnode *node;
- struct ospf_area *area;
-
switch (ospf->abr_type) {
case OSPF_ABR_STAND:
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_ia_routing():Standard ABR");
if ((area = ospf->backbone)) {
- struct listnode *node;
-
if (IS_DEBUG_OSPF_EVENT) {
zlog_debug(
"ospf_ia_routing():backbone area found");
break;
}
} else {
- struct listnode *node;
-
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_ia_routing():not ABR, considering all areas");
* there should be due to the ospf_spf_has_link() check
* in SPF. Lets warn and try pick a link anyway.
*/
- zlog_warn("ospf_vl_set_params: No backlink for %s!",
+ zlog_info("ospf_vl_set_params: No backlink for %s!",
vl_data->vl_oi->ifp->name);
for (i = 0; i < ntohs(rl->links); i++) {
switch (rl->link[i].type) {
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_abr.h"
-
+#include "ospfd/ospf_errors.h"
uint32_t get_metric(uint8_t *metric)
{
/* PtoP link must have only 1 neighbor. */
if (ospf_nbr_count(oi, 0) > 1)
- zlog_warn("Point-to-Point link has more than 1 neighobrs.");
+ flog_warn(EC_OSPF_PTP_NEIGHBOR,
+ "Point-to-Point link has more than 1 neighobrs.");
return nbr;
}
}
if (ret == OSPF_MAX_LSA_SIZE) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_SIZE,
"%s: Out of space in LSA stream, left %zd, size %zd",
__func__, STREAM_WRITEABLE(*s),
STREAM_SIZE(*s));
}
if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) {
- if (IS_DEBUG_OSPF_NSSA)
- zlog_debug(
- "ospf_lsa_translated_nssa_originate(): "
- "Could not install LSA "
- "id %s",
- inet_ntoa(type7->data->id));
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "ospf_lsa_translated_nssa_originate(): "
+ "Could not install LSA "
+ "id %s",
+ inet_ntoa(type7->data->id));
return NULL;
}
}
if (!(new = ospf_lsa_install(ospf, NULL, new))) {
- if (IS_DEBUG_OSPF_NSSA)
- zlog_debug(
- "ospf_translated_nssa_refresh(): Could not install "
- "translated LSA, Id %s",
- inet_ntoa(type7->data->id));
+ flog_warn(
+ EC_OSPF_LSA_INSTALL_FAILURE,
+ "ospf_translated_nssa_refresh(): Could not install translated LSA, Id %s",
+ inet_ntoa(type7->data->id));
return NULL;
}
if (!ext_list)
return 0;
- for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+ for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
/* Originate As-external-LSA from all type of distribute source.
*/
- if ((rt = ext->external_info))
- for (rn = route_top(rt); rn; rn = route_next(rn))
- if ((ei = rn->info) != NULL)
- if (!is_prefix_default(
- (struct prefix_ipv4 *)&ei
- ->p))
- if (!ospf_external_lsa_originate(
- ospf, ei))
- zlog_warn(
- "LSA: AS-external-LSA was not originated.");
+ rt = ext->external_info;
+ if (!rt)
+ continue;
+
+ for (rn = route_top(rt); rn; rn = route_next(rn)) {
+ ei = rn->info;
+
+ if (!ei)
+ continue;
+
+ if (is_prefix_default((struct prefix_ipv4 *)&ei->p))
+ continue;
+
+ if (!ospf_external_lsa_originate(ospf, ei))
+ flog_warn(
+ EC_OSPF_LSA_INSTALL_FAILURE,
+ "LSA: AS-external-LSA was not originated.");
+ }
+ }
return 0;
}
{
struct ospf_lsa *old;
- if (!lsdb) {
- zlog_warn("%s: Called with NULL lsdb!", __func__);
- if (!lsa)
- zlog_warn("%s: and NULL LSA!", __func__);
- else
- zlog_warn("LSA[Type%d:%s]: not associated with LSDB!",
- lsa->data->type, inet_ntoa(lsa->data->id));
+ if (!lsdb)
return;
- }
old = ospf_lsdb_lookup(lsdb, lsa);
if (lsa->lsdb) {
ospf_discard_from_db(ospf, lsa->lsdb, lsa);
ospf_lsdb_delete(lsa->lsdb, lsa);
- } else
- zlog_warn(
- "%s: LSA[Type%d:%s]: No associated LSDB!",
- __func__, lsa->data->type,
- inet_ntoa(lsa->data->id));
+ } else {
+ if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
+ zlog_debug(
+ "%s: LSA[Type%d:%s]: No associated LSDB!",
+ __func__, lsa->data->type,
+ inet_ntoa(lsa->data->id));
+ }
}
/* A MaxAge LSA must be removed immediately from the router's link
struct prefix_ls lp;
struct route_node *rn;
- if (!lsdb) {
- zlog_warn("%s: Called with NULL LSDB", __func__);
- if (lsa)
- zlog_warn("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
- lsa->data->type, inet_ntoa(lsa->data->id),
- (void *)lsa, (void *)lsa->lsdb);
+ if (!lsdb || !lsa)
return;
- }
-
- if (!lsa) {
- zlog_warn("%s: Called with NULL LSA", __func__);
- return;
- }
assert(lsa->data->type < OSPF_MAX_LSA);
table = lsdb->type[lsa->data->type].db;
ospf',
when quagga(ospfd) is restarted */
if (!ospf_get_instance(instance)) {
- flog_err(OSPF_ERR_INIT_FAIL, "OSPF instance init failed: %s",
- strerror(errno));
+ flog_err(EC_OSPF_INIT_FAIL, "OSPF instance init failed: %s",
+ strerror(errno));
exit(1);
}
rn = route_node_get(oi->nbrs, &p);
if (rn->info) {
/* There is already pseudo neighbor. */
- zlog_warn(
- "router_id %s already present in neighbor table. node refcount %u",
- inet_ntoa(router_id), rn->lock);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "router_id %s already present in neighbor table. node refcount %u",
+ inet_ntoa(router_id), rn->lock);
route_unlock_node(rn);
} else
rn->info = oi->nbr_self;
p->u.prefix4, htonl(OSPF_ALLSPFROUTERS),
ifindex);
if (ret < 0)
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
"ifindex %u, AllSPFRouters): %s; perhaps a kernel limit "
"on # of multicast group memberships has been exceeded?",
p->u.prefix4, htonl(OSPF_ALLSPFROUTERS),
ifindex);
if (ret < 0)
- zlog_warn(
- "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
- "ifindex %u, AllSPFRouters): %s",
- top->fd, inet_ntoa(p->u.prefix4), ifindex,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
+ "ifindex %u, AllSPFRouters): %s",
+ top->fd, inet_ntoa(p->u.prefix4), ifindex,
+ safe_strerror(errno));
else {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
p->u.prefix4, htonl(OSPF_ALLDROUTERS),
ifindex);
if (ret < 0)
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
"ifindex %u, AllDRouters): %s; perhaps a kernel limit "
"on # of multicast group memberships has been exceeded?",
p->u.prefix4, htonl(OSPF_ALLDROUTERS),
ifindex);
if (ret < 0)
- zlog_warn(
- "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
- "ifindex %u, AllDRouters): %s",
- top->fd, inet_ntoa(p->u.prefix4), ifindex,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
+ "ifindex %u, AllDRouters): %s",
+ top->fd, inet_ntoa(p->u.prefix4), ifindex,
+ safe_strerror(errno));
else
zlog_debug(
"interface %s [%u] leave AllDRouters Multicast group.",
/* Prevent receiving self-origined multicast packets. */
ret = setsockopt_ipv4_multicast_loop(top->fd, 0);
if (ret < 0)
- zlog_warn("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
- top->fd, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
+ top->fd, safe_strerror(errno));
/* Explicitly set multicast ttl to 1 -- endo. */
val = 1;
ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val,
len);
if (ret < 0)
- zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
- top->fd, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
+ top->fd, safe_strerror(errno));
#ifndef GNU_LINUX
/* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
* packet out of ifindex. Below would be used Non Linux system.
*/
ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
if (ret < 0)
- zlog_warn(
- "can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, "
- "ifindex %u): %s",
- top->fd, inet_ntoa(p->u.prefix4), ifindex,
- safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, "
+ "ifindex %u): %s",
+ top->fd, inet_ntoa(p->u.prefix4), ifindex,
+ safe_strerror(errno));
#endif
return ret;
ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP,
ospf->vrf_id, ospf->name);
if (ospf_sock < 0) {
- zlog_err("ospf_read_sock_init: socket: %s",
+ flog_err(EC_LIB_SOCKET,
+ "ospf_read_sock_init: socket: %s",
safe_strerror(errno));
exit(1);
}
ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
sizeof(hincl));
if (ret < 0) {
- zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
- ospf_sock, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "Can't set IP_HDRINCL option for fd %d: %s",
+ ospf_sock, safe_strerror(errno));
close(ospf_sock);
break;
}
ret = setsockopt_ipv4_tos(ospf_sock,
IPTOS_PREC_INTERNETCONTROL);
if (ret < 0) {
- zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s",
- tos, ospf_sock, safe_strerror(errno));
+ flog_err(EC_LIB_SOCKET,
+ "can't set sockopt IP_TOS %d to socket %d: %s",
+ tos, ospf_sock, safe_strerror(errno));
close(ospf_sock); /* Prevent sd leak. */
break;
}
#else /* !IPTOS_PREC_INTERNETCONTROL */
#warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
- zlog_warn("IP_HDRINCL option not available");
+ flog_err(EC_LIB_UNAVAILABLE, "IP_HDRINCL option not available");
#endif /* IP_HDRINCL */
ret = setsockopt_ifindex(AF_INET, ospf_sock, 1);
if (ret < 0)
- zlog_warn("Can't set pktinfo option for fd %d",
- ospf_sock);
+ flog_err(EC_LIB_SOCKET,
+ "Can't set pktinfo option for fd %d",
+ ospf_sock);
setsockopt_so_sendbuf(ospf_sock, bufsize);
setsockopt_so_recvbuf(ospf_sock, bufsize);
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_bfd.h"
+#include "ospfd/ospf_errors.h"
DEFINE_HOOK(ospf_nsm_change,
(struct ospf_neighbor * on, int state, int oldstate),
ospf_router_lsa_update_area(oi->area);
if (oi->type == OSPF_IFTYPE_VIRTUALLINK) {
- struct ospf_area *vl_area = ospf_area_lookup_by_area_id(
+ vl_area = ospf_area_lookup_by_area_id(
oi->ospf, oi->vl_data->vl_area_id);
if (vl_area)
* not
* try set next_state.
*/
- zlog_warn(
+ flog_err(
+ EC_OSPF_FSM_INVALID_STATE,
"NSM[%s:%s]: %s (%s): "
"Warning: action tried to change next_state to %s",
IF_NAME(nbr->oi), inet_ntoa(nbr->router_id),
#include "ospfd/ospf_sr.h"
#include "ospfd/ospf_ri.h"
#include "ospfd/ospf_ext.h"
+#include "ospfd/ospf_errors.h"
DEFINE_MTYPE_STATIC(OSPFD, OSPF_OPAQUE_FUNCTAB, "OSPF opaque function table")
DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_TYPE, "OSPF opaque per-type info")
funclist = ospf_opaque_type11_funclist;
break;
default:
- zlog_warn("ospf_get_opaque_funclist: Unexpected LSA-type(%u)",
+ flog_warn(EC_OSPF_LSA_UNEXPECTED,
+ "ospf_get_opaque_funclist: Unexpected LSA-type(%u)",
lsa_type);
break;
}
{
struct list *funclist;
struct ospf_opaque_functab *new;
- int rc = -1;
- if ((funclist = ospf_get_opaque_funclist(lsa_type)) == NULL) {
- zlog_warn(
- "ospf_register_opaque_functab: Cannot get funclist"
- " for Type-%u LSAs?",
- lsa_type);
- goto out;
- } else {
- struct listnode *node, *nnode;
- struct ospf_opaque_functab *functab;
+ if ((funclist = ospf_get_opaque_funclist(lsa_type)) == NULL)
+ return -1;
- for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab))
- if (functab->opaque_type == opaque_type) {
- zlog_warn(
- "ospf_register_opaque_functab: Duplicated entry?:"
- " lsa_type(%u), opaque_type(%u)",
- lsa_type, opaque_type);
- goto out;
- }
- }
+ struct listnode *node, *nnode;
+ struct ospf_opaque_functab *functab;
+
+ for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab))
+ if (functab->opaque_type == opaque_type) {
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_register_opaque_functab: Duplicated entry?: lsa_type(%u), opaque_type(%u)",
+ lsa_type, opaque_type);
+ return -1;
+ }
new = XCALLOC(MTYPE_OSPF_OPAQUE_FUNCTAB,
sizeof(struct ospf_opaque_functab));
new->del_lsa_hook = del_lsa_hook;
listnode_add(funclist, new);
- rc = 0;
-out:
- return rc;
+ return 0;
}
void ospf_delete_opaque_functab(uint8_t lsa_type, uint8_t opaque_type)
listnode_add(top->opaque_lsa_self, oipt);
break;
default:
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_UNEXPECTED,
"register_opaque_info_per_type: Unexpected LSA-type(%u)",
new->data->type);
free_opaque_info_per_type((void *)oipt);
break;
}
default:
- zlog_warn("free_opaque_info_owner: Unexpected LSA-type(%u)",
+ flog_warn(EC_OSPF_LSA_UNEXPECTED,
+ "free_opaque_info_owner: Unexpected LSA-type(%u)",
oipt->lsa_type);
break; /* This case may not exist. */
}
if ((oi = lsa->oi) != NULL)
listtop = oi->opaque_lsa_self;
else
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"Type-9 Opaque-LSA: Reference to OI is missing?");
break;
case OSPF_OPAQUE_AREA_LSA:
if ((area = lsa->area) != NULL)
listtop = area->opaque_lsa_self;
else
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"Type-10 Opaque-LSA: Reference to AREA is missing?");
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"Type-11 Opaque-LSA: Reference to OSPF is missing?");
break; /* Unlikely to happen. */
}
listtop = top->opaque_lsa_self;
break;
default:
- zlog_warn("lookup_opaque_info_by_type: Unexpected LSA-type(%u)",
+ flog_warn(EC_OSPF_LSA_UNEXPECTED,
+ "lookup_opaque_info_by_type: Unexpected LSA-type(%u)",
lsa->data->type);
break;
}
int delay = 0;
if ((top = oi_to_top(oi)) == NULL || (area = oi->area) == NULL) {
- zlog_warn(
- "ospf_opaque_lsa_originate_schedule: Invalid argument?");
- goto out;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_opaque_lsa_originate_schedule: Invalid argument?");
+ return;
}
/* It may not a right time to schedule origination now. */
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_opaque_lsa_originate_schedule: Not operational.");
- goto out; /* This is not an error. */
+ return; /* This is not an error. */
}
if (delay0 != NULL)
if (delay0 != NULL)
*delay0 = delay;
-
-out:
- return;
}
static int ospf_opaque_type9_lsa_originate(struct thread *t)
continue;
if ((*functab->lsa_originator)(arg) != 0) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)",
oipt->opaque_type);
continue;
}
/* Register the new lsa entry and get its control info. */
else if ((oipi = register_opaque_lsa(lsa)) == NULL) {
- zlog_warn("ospf_opaque_lsa_install: register_opaque_lsa() ?");
+ flog_warn(EC_OSPF_LSA,
+ "ospf_opaque_lsa_install: register_opaque_lsa() ?");
goto out;
}
case OSPF_OPAQUE_LINK_LSA:
if ((top = oi_to_top(lsa->oi)) == NULL) {
/* Above conditions must have passed. */
- zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?");
+ flog_warn(EC_OSPF_LSA,
+ "ospf_opaque_lsa_install: Something wrong?");
goto out;
}
break;
case OSPF_OPAQUE_AREA_LSA:
if (lsa->area == NULL || (top = lsa->area->ospf) == NULL) {
/* Above conditions must have passed. */
- zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?");
+ flog_warn(EC_OSPF_LSA,
+ "ospf_opaque_lsa_install: Something wrong?");
goto out;
}
break;
top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) {
/* Above conditions must have passed. */
- zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?");
+ flog_warn(EC_OSPF_LSA,
+ "ospf_opaque_lsa_install: Something wrong?");
goto out;
}
break;
default:
- zlog_warn("ospf_opaque_lsa_install: Unexpected LSA-type(%u)",
+ flog_warn(EC_OSPF_LSA_UNEXPECTED,
+ "ospf_opaque_lsa_install: Unexpected LSA-type(%u)",
lsa->data->type);
goto out;
}
case OSPF_OPAQUE_LINK_LSA:
if ((oi = (struct ospf_interface *)lsa_type_dependent)
== NULL) {
- zlog_warn(
- "ospf_opaque_lsa_reoriginate_schedule:"
- " Type-9 Opaque-LSA: Invalid parameter?");
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_opaque_lsa_reoriginate_schedule: Type-9 Opaque-LSA: Invalid parameter?");
goto out;
}
if ((top = oi_to_top(oi)) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?",
IF_NAME(oi));
goto out;
if (!list_isempty(ospf_opaque_type9_funclist)
&& list_isempty(oi->opaque_lsa_self)
&& oi->t_opaque_lsa_self != NULL) {
- zlog_warn(
- "Type-9 Opaque-LSA (opaque_type=%u):"
- " Common origination for OI(%s) has already started",
+ flog_warn(
+ EC_OSPF_LSA,
+ "Type-9 Opaque-LSA (opaque_type=%u): Common origination for OI(%s) has already started",
opaque_type, IF_NAME(oi));
goto out;
}
break;
case OSPF_OPAQUE_AREA_LSA:
if ((area = (struct ospf_area *)lsa_type_dependent) == NULL) {
- zlog_warn(
- "ospf_opaque_lsa_reoriginate_schedule:"
- " Type-10 Opaque-LSA: Invalid parameter?");
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_opaque_lsa_reoriginate_schedule: Type-10 Opaque-LSA: Invalid parameter?");
goto out;
}
if ((top = area->ospf) == NULL) {
- zlog_warn(
- "ospf_opaque_lsa_reoriginate_schedule:"
- " AREA(%s) -> TOP?",
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_opaque_lsa_reoriginate_schedule: AREA(%s) -> TOP?",
inet_ntoa(area->area_id));
goto out;
}
if (!list_isempty(ospf_opaque_type10_funclist)
&& list_isempty(area->opaque_lsa_self)
&& area->t_opaque_lsa_self != NULL) {
- zlog_warn(
- "Type-10 Opaque-LSA (opaque_type=%u):"
- " Common origination for AREA(%s) has already started",
+ flog_warn(
+ EC_OSPF_LSA,
+ "Type-10 Opaque-LSA (opaque_type=%u): Common origination for AREA(%s) has already started",
opaque_type, inet_ntoa(area->area_id));
goto out;
}
break;
case OSPF_OPAQUE_AS_LSA:
if ((top = (struct ospf *)lsa_type_dependent) == NULL) {
- zlog_warn(
- "ospf_opaque_lsa_reoriginate_schedule:"
- " Type-11 Opaque-LSA: Invalid parameter?");
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_opaque_lsa_reoriginate_schedule: Type-11 Opaque-LSA: Invalid parameter?");
goto out;
}
if (!list_isempty(ospf_opaque_type11_funclist)
&& list_isempty(top->opaque_lsa_self)
&& top->t_opaque_lsa_self != NULL) {
- zlog_warn(
- "Type-11 Opaque-LSA (opaque_type=%u):"
- " Common origination has already started",
+ flog_warn(
+ EC_OSPF_LSA,
+ "Type-11 Opaque-LSA (opaque_type=%u): Common origination has already started",
opaque_type);
goto out;
}
func = ospf_opaque_type11_lsa_reoriginate_timer;
break;
default:
- zlog_warn(
- "ospf_opaque_lsa_reoriginate_schedule:"
- " Unexpected LSA-type(%u)",
+ flog_warn(
+ EC_OSPF_LSA_UNEXPECTED,
+ "ospf_opaque_lsa_reoriginate_schedule: Unexpected LSA-type(%u)",
lsa_type);
goto out;
}
if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) {
struct ospf_opaque_functab *functab;
if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL) {
- zlog_warn(
- "ospf_opaque_lsa_reoriginate_schedule:"
- " No associated function?: lsa_type(%u),"
- " opaque_type(%u)",
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_opaque_lsa_reoriginate_schedule: No associated function?: lsa_type(%u), opaque_type(%u)",
lsa_type, opaque_type);
goto out;
}
if ((oipt = register_opaque_info_per_type(functab, lsa))
== NULL) {
- zlog_warn(
- "ospf_opaque_lsa_reoriginate_schedule:"
- " Cannot get a control info?: lsa_type(%u),"
- " opaque_type(%u)",
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_opaque_lsa_reoriginate_schedule: Cannot get a control info?: lsa_type(%u), opaque_type(%u)",
lsa_type, opaque_type);
goto out;
}
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_type9_lsa_reoriginate_timer: No associated function?");
goto out;
}
oi = (struct ospf_interface *)oipt->owner;
if ((top = oi_to_top(oi)) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?");
goto out;
}
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_type10_lsa_reoriginate_timer: No associated function?");
goto out;
}
area = (struct ospf_area *)oipt->owner;
if (area == NULL || (top = area->ospf) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?");
goto out;
}
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL) {
- zlog_warn(
- "ospf_opaque_type11_lsa_reoriginate_timer:"
- " No associated function?");
+ flog_warn(
+ EC_OSPF_LSA,
+ "ospf_opaque_type11_lsa_reoriginate_timer: No associated function?");
goto out;
}
if ((top = (struct ospf *)oipt->owner) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?");
goto out;
}
if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
|| (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_opaque_lsa_refresh_schedule: Invalid parameter?");
goto out;
}
/* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
if ((lsa = oipi->lsa) == NULL) {
- zlog_warn("ospf_opaque_lsa_refresh_schedule: Something wrong?");
+ flog_warn(EC_OSPF_LSA,
+ "ospf_opaque_lsa_refresh_schedule: Something wrong?");
goto out;
}
ospf_ls_retransmit_delete_nbr_as(top, lsa);
break;
default:
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_UNEXPECTED,
"ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)",
lsa->data->type);
goto out;
if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
|| (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) {
- zlog_warn("ospf_opaque_lsa_flush_schedule: Invalid parameter?");
+ flog_warn(EC_OSPF_LSA,
+ "ospf_opaque_lsa_flush_schedule: Invalid parameter?");
goto out;
}
/* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
if ((lsa = oipi->lsa) == NULL) {
- zlog_warn("ospf_opaque_lsa_flush_schedule: Something wrong?");
+ flog_warn(EC_OSPF_LSA,
+ "ospf_opaque_lsa_flush_schedule: Something wrong?");
goto out;
}
ospf_ls_retransmit_delete_nbr_as(top, lsa);
break;
default:
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_UNEXPECTED,
"ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)",
lsa->data->type);
goto out;
ospf_flood_through_as(top, NULL /*inbr*/, lsa);
break;
default:
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_UNEXPECTED,
"ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)",
lsa->data->type);
return;
if (oi == NULL || (area = oi->area) == NULL
|| (top = area->ospf) == NULL)
- zlog_warn("Broken relationship for \"OI -> AREA -> OSPF\"?");
+ flog_warn(EC_OSPF_LSA,
+ "Broken relationship for \"OI -> AREA -> OSPF\"?");
return top;
}
#include "checksum.h"
#include "md5.h"
#include "vrf.h"
-#include "ospf_errors.h"
+#include "lib_errors.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_dump.h"
+#include "ospfd/ospf_errors.h"
/*
* OSPF Fragmentation / fragmented writes
{
if (!oi->obuf) {
flog_err(
- OSPF_ERR_PKT_PROCESS,
+ EC_OSPF_PKT_PROCESS,
"ospf_packet_add(interface %s in state %d [%s], packet type %s, "
"destination %s) called with NULL obuf, ignoring "
"(please report this bug)!\n",
{
if (!oi->obuf) {
flog_err(
- OSPF_ERR_PKT_PROCESS,
+ EC_OSPF_PKT_PROCESS,
"ospf_packet_add(interface %s in state %d [%s], packet type %s, "
"destination %s) called with NULL obuf, ignoring "
"(please report this bug)!\n",
if (stream_get_endp(op->s) != op->length)
/* XXX size_t */
- zlog_warn(
+ zlog_debug(
"ospf_packet_dup stream %lu ospf_packet %u size mismatch",
(unsigned long)STREAM_SIZE(op->s), op->length);
ck = ospf_crypt_key_lookup(OSPF_IF_PARAM(oi, auth_crypt),
ospfh->u.crypt.key_id);
if (ck == NULL) {
- zlog_warn("interface %s: ospf_check_md5 no key %d", IF_NAME(oi),
- ospfh->u.crypt.key_id);
+ flog_warn(EC_OSPF_MD5, "interface %s: ospf_check_md5 no key %d",
+ IF_NAME(oi), ospfh->u.crypt.key_id);
return 0;
}
if (nbr
&& ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_MD5,
"interface %s: ospf_check_md5 bad sequence %d (expect %d)",
IF_NAME(oi), ntohl(ospfh->u.crypt.crypt_seqnum),
ntohl(nbr->crypt_seqnum));
/* compare the two */
if (memcmp((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE)) {
- zlog_warn("interface %s: ospf_check_md5 checksum mismatch",
+ flog_warn(EC_OSPF_MD5,
+ "interface %s: ospf_check_md5 checksum mismatch",
IF_NAME(oi));
return 0;
}
if (stream_get_endp(op->s) != op->length)
/* XXX size_t */
- zlog_warn(
+ flog_warn(
+ EC_OSPF_MD5,
"ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
(unsigned long)stream_get_endp(op->s), op->length);
sockopt_iphdrincl_swab_systoh(iph);
if (ret < 0)
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"*** ospf_write_frags: sendmsg failed to %s,"
" id %d, off %d, len %d, mtu %u failed with %s",
inet_ntoa(iph->ip_dst), iph->ip_id, iph->ip_off,
iph.ip_len, oi->ifp->name, oi->ifp->mtu);
if (ret < 0)
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"*** sendmsg in ospf_write failed to %s, "
"id %d, off %d, len %d, interface %s, mtu %u: %s",
inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off,
if (oi->type != OSPF_IFTYPE_POINTOPOINT
&& oi->type != OSPF_IFTYPE_VIRTUALLINK)
if (oi->address->prefixlen != p.prefixlen) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
inet_ntoa(ospfh->router_id), IF_NAME(oi),
(int)oi->address->prefixlen, (int)p.prefixlen);
/* Compare Router Dead Interval. */
if (OSPF_IF_PARAM(oi, v_wait) != ntohl(hello->dead_interval)) {
- zlog_warn(
- "Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
- "(expected %u, but received %u).",
- inet_ntoa(ospfh->router_id), OSPF_IF_PARAM(oi, v_wait),
- ntohl(hello->dead_interval));
+ flog_warn(EC_OSPF_PACKET,
+ "Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
+ "(expected %u, but received %u).",
+ inet_ntoa(ospfh->router_id),
+ OSPF_IF_PARAM(oi, v_wait),
+ ntohl(hello->dead_interval));
return;
}
if (OSPF_IF_PARAM(oi, fast_hello) == 0) {
if (OSPF_IF_PARAM(oi, v_hello)
!= ntohs(hello->hello_interval)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Packet %s [Hello:RECV]: HelloInterval mismatch "
"(expected %u, but received %u).",
inet_ntoa(ospfh->router_id),
* Drop this Hello packet not to establish neighbor
* relationship.
*/
- zlog_warn("Packet %s [Hello:RECV]: T-bit on, drop it.",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet %s [Hello:RECV]: T-bit on, drop it.",
inet_ntoa(ospfh->router_id));
return;
}
* This router does know the correct usage of O-bit
* the bit should be set in DD packet only.
*/
- zlog_warn("Packet %s [Hello:RECV]: O-bit abuse?",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet %s [Hello:RECV]: O-bit abuse?",
inet_ntoa(ospfh->router_id));
#ifdef STRICT_OBIT_USAGE_CHECK
return; /* Reject this packet. */
&& CHECK_FLAG(hello->options, OSPF_OPTION_NP)
&& !CHECK_FLAG(OPTIONS(oi), OSPF_OPTION_E)
&& !CHECK_FLAG(hello->options, OSPF_OPTION_E))) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x",
inet_ntoa(ospfh->router_id), OPTIONS(oi),
hello->options);
Packet's Options field should be ignored. */
if (CHECK_FLAG(OPTIONS(oi), OSPF_OPTION_E)
!= CHECK_FLAG(hello->options, OSPF_OPTION_E)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Packet %s [Hello:RECV]: my options: %x, his options %x",
inet_ntoa(ospfh->router_id), OPTIONS(oi),
hello->options);
/* Unknown LS type. */
if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA) {
- zlog_warn("Packet [DD:RECV]: Unknown LS type %d.",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet [DD:RECV]: Unknown LS type %d.",
lsah->type);
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
return;
if (IS_OPAQUE_LSA(lsah->type)
&& !CHECK_FLAG(nbr->options, OSPF_OPTION_O)) {
- zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
+ flog_warn(EC_OSPF_PACKET,
+ "LSA[Type%d:%s]: Opaque capability mismatch?",
lsah->type, inet_ntoa(lsah->id));
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
return;
but
allow if from NSSA. */
if (oi->area->external_routing == OSPF_AREA_STUB) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
lsah->type, inet_ntoa(lsah->id),
(oi->area->external_routing
nbr = ospf_nbr_lookup(oi, iph, ospfh);
if (nbr == NULL) {
- zlog_warn("Packet[DD]: Unknown Neighbor %s",
+ flog_warn(EC_OSPF_PACKET, "Packet[DD]: Unknown Neighbor %s",
inet_ntoa(ospfh->router_id));
return;
}
/* Check MTU. */
if ((OSPF_IF_PARAM(oi, mtu_ignore) == 0)
&& (ntohs(dd->mtu) > oi->ifp->mtu)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
inet_ntoa(nbr->router_id), ntohs(dd->mtu), IF_NAME(oi),
oi->ifp->mtu);
* In Hello protocol, optional capability must have checked
* to prevent this T-bit enabled router be my neighbor.
*/
- zlog_warn("Packet[DD]: Neighbor %s: T-bit on?",
+ flog_warn(EC_OSPF_PACKET, "Packet[DD]: Neighbor %s: T-bit on?",
inet_ntoa(nbr->router_id));
return;
}
case NSM_Down:
case NSM_Attempt:
case NSM_TwoWay:
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Packet[DD]: Neighbor %s state is %s, packet discarded.",
inet_ntoa(nbr->router_id),
lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
/* Reset I, leaving MS */
UNSET_FLAG(nbr->dd_flags, OSPF_DD_FLAG_I);
} else {
- zlog_warn("Packet[DD]: Neighbor %s Negotiation fails.",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet[DD]: Neighbor %s Negotiation fails.",
inet_ntoa(nbr->router_id));
break;
}
if (!CHECK_FLAG(nbr->options, OSPF_OPTION_O)
&& IPV4_ADDR_SAME(&DR(oi),
&nbr->address.u.prefix4)) {
- zlog_warn(
- "DR-neighbor[%s] is NOT opaque-capable; "
- "Opaque-LSAs cannot be reliably advertised "
- "in this network.",
+ flog_warn(
+ EC_OSPF_PACKET,
+ "DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.",
inet_ntoa(nbr->router_id));
/* This situation is undesirable, but not a real
* error. */
/* Check Master/Slave bit mismatch */
if (IS_SET_DD_MS(dd->flags)
!= IS_SET_DD_MS(nbr->last_recv.flags)) {
- zlog_warn("Packet[DD]: Neighbor %s MS-bit mismatch.",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet[DD]: Neighbor %s MS-bit mismatch.",
inet_ntoa(nbr->router_id));
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
if (IS_DEBUG_OSPF_EVENT)
/* Save the new options for debugging */
nbr->options = dd->options;
#endif /* ORIGINAL_CODING */
- zlog_warn("Packet[DD]: Neighbor %s options mismatch.",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet[DD]: Neighbor %s options mismatch.",
inet_ntoa(nbr->router_id));
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
break;
&& ntohl(dd->dd_seqnum) != nbr->dd_seqnum)
|| (!IS_SET_DD_MS(nbr->dd_flags)
&& ntohl(dd->dd_seqnum) != nbr->dd_seqnum + 1)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Packet[DD]: Neighbor %s sequence number mismatch.",
inet_ntoa(nbr->router_id));
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
break;
default:
- zlog_warn("Packet[DD]: Neighbor %s NSM illegal status %u.",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet[DD]: Neighbor %s NSM illegal status %u.",
inet_ntoa(nbr->router_id), nbr->state);
break;
}
nbr = ospf_nbr_lookup(oi, iph, ospfh);
if (nbr == NULL) {
- zlog_warn("Link State Request: Unknown Neighbor %s.",
+ flog_warn(EC_OSPF_PACKET,
+ "Link State Request: Unknown Neighbor %s.",
inet_ntoa(ospfh->router_id));
return;
}
/* Neighbor State should be Exchange or later. */
if (nbr->state != NSM_Exchange && nbr->state != NSM_Loading
&& nbr->state != NSM_Full) {
- zlog_warn(
- "Link State Request received from %s: "
- "Neighbor state is %s, packet discarded.",
+ flog_warn(
+ EC_OSPF_PACKET,
+ "Link State Request received from %s: Neighbor state is %s, packet discarded.",
inet_ntoa(ospfh->router_id),
lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
return;
length = ntohs(lsah->length);
if (length > size) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Link State Update: LSA length exceeds packet size.");
break;
}
* have a better
* chance to compress repeated messages in syslog on the
* other */
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
sum, lsah->checksum, inet_ntoa(lsah->id),
inet_ntoa(nbr->src), inet_ntoa(nbr->router_id),
/* Examine the LSA's LS type. */
if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA) {
- zlog_warn("Link State Update: Unknown LS type %d",
+ flog_warn(EC_OSPF_PACKET,
+ "Link State Update: Unknown LS type %d",
lsah->type);
continue;
}
* the bit will be set in Type-9,10,11 LSAs
* only.
*/
- zlog_warn("LSA[Type%d:%s]: O-bit abuse?",
+ flog_warn(EC_OSPF_PACKET,
+ "LSA[Type%d:%s]: O-bit abuse?",
lsah->type, inet_ntoa(lsah->id));
continue;
}
continue;
}
} else if (IS_OPAQUE_LSA(lsah->type)) {
- zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
+ flog_warn(EC_OSPF_PACKET,
+ "LSA[Type%d:%s]: Opaque capability mismatch?",
lsah->type, inet_ntoa(lsah->id));
continue;
}
/* Check neighbor. */
nbr = ospf_nbr_lookup(oi, iph, ospfh);
if (nbr == NULL) {
- zlog_warn("Link State Update: Unknown Neighbor %s on int: %s",
+ flog_warn(EC_OSPF_PACKET,
+ "Link State Update: Unknown Neighbor %s on int: %s",
inet_ntoa(ospfh->router_id), IF_NAME(oi));
return;
}
char buf2[INET_ADDRSTRLEN];
char buf3[INET_ADDRSTRLEN];
- flog_err(OSPF_ERR_ROUTER_LSA_MISMATCH,
- "Incoming Router-LSA from %s with "
- "Adv-ID[%s] != LS-ID[%s]",
- inet_ntop(AF_INET, &ospfh->router_id,
- buf1, INET_ADDRSTRLEN),
- inet_ntop(AF_INET, &lsa->data->id,
- buf2, INET_ADDRSTRLEN),
- inet_ntop(AF_INET,
- &lsa->data->adv_router,
- buf3, INET_ADDRSTRLEN));
+ flog_err(EC_OSPF_ROUTER_LSA_MISMATCH,
+ "Incoming Router-LSA from %s with "
+ "Adv-ID[%s] != LS-ID[%s]",
+ inet_ntop(AF_INET, &ospfh->router_id,
+ buf1, INET_ADDRSTRLEN),
+ inet_ntop(AF_INET, &lsa->data->id,
+ buf2, INET_ADDRSTRLEN),
+ inet_ntop(AF_INET,
+ &lsa->data->adv_router, buf3,
+ INET_ADDRSTRLEN));
flog_err(
- OSPF_ERR_DOMAIN_CORRUPT,
+ EC_OSPF_DOMAIN_CORRUPT,
"OSPF domain compromised by attack or corruption. "
"Verify correct operation of -ALL- OSPF routers.");
DISCARD_LSA(lsa, 0);
* Just send an LSAck message to cease retransmission.
*/
if (IS_LSA_MAXAGE(lsa)) {
- zlog_warn("LSA[%s]: Boomerang effect?",
+ zlog_info("LSA[%s]: Boomerang effect?",
dump_lsa_key(lsa));
ospf_ls_ack_send(nbr, lsa);
ospf_lsa_discard(lsa);
if (ospf_ls_request_lookup(nbr, lsa)) {
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq);
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"LSA[%s] instance exists on Link state request list",
dump_lsa_key(lsa));
nbr = ospf_nbr_lookup(oi, iph, ospfh);
if (nbr == NULL) {
- zlog_warn("Link State Acknowledgment: Unknown Neighbor %s.",
+ flog_warn(EC_OSPF_PACKET,
+ "Link State Acknowledgment: Unknown Neighbor %s.",
inet_ntoa(ospfh->router_id));
return;
}
ret = stream_recvmsg(ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE + 1);
if (ret < 0) {
- zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
+ flog_warn(EC_OSPF_PACKET, "stream_recvmsg failed: %s",
+ safe_strerror(errno));
return NULL;
}
if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
{
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"ospf_recv_packet: discarding runt packet of length %d "
"(ip header size is %u)",
ret, (unsigned int)sizeof(iph));
*ifp = if_lookup_by_index(ifindex, ospf->vrf_id);
if (ret != ip_len) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"ospf_recv_packet read length mismatch: ip_len is %d, "
"but recvmsg returned %d",
ip_len, ret);
case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */
if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type(oi))) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: auth-type mismatch, local %s, rcvd Null",
IF_NAME(oi),
lookup_msg(ospf_auth_type_str,
}
if (!ospf_check_sum(ospfh)) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: Null auth OK, but checksum error, Router-ID %s",
IF_NAME(oi),
inet_ntoa(ospfh->router_id));
if (OSPF_AUTH_SIMPLE
!= (iface_auth_type = ospf_auth_type(oi))) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: auth-type mismatch, local %s, rcvd Simple",
IF_NAME(oi),
lookup_msg(ospf_auth_type_str,
if (memcmp(OSPF_IF_PARAM(oi, auth_simple), ospfh->u.auth_data,
OSPF_AUTH_SIMPLE_SIZE)) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn("interface %s: Simple auth failed",
+ flog_warn(EC_OSPF_PACKET,
+ "interface %s: Simple auth failed",
IF_NAME(oi));
return 0;
}
if (!ospf_check_sum(ospfh)) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: Simple auth OK, checksum error, Router-ID %s",
IF_NAME(oi),
inet_ntoa(ospfh->router_id));
if (OSPF_AUTH_CRYPTOGRAPHIC
!= (iface_auth_type = ospf_auth_type(oi))) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
IF_NAME(oi),
lookup_msg(ospf_auth_type_str,
}
if (ospfh->checksum) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: OSPF header checksum is not 0",
IF_NAME(oi));
return 0;
bug? */
!ospf_check_md5_digest(oi, ospfh)) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn("interface %s: MD5 auth failed",
+ flog_warn(EC_OSPF_MD5,
+ "interface %s: MD5 auth failed",
IF_NAME(oi));
return 0;
}
return 1;
default:
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: invalid packet auth-type (%02x)",
IF_NAME(oi), pkt_auth_type);
return 0;
{
/* Check Area ID. */
if (!ospf_check_area_id(oi, ospfh)) {
- zlog_warn("interface %s: ospf_read invalid Area ID %s.",
+ flog_warn(EC_OSPF_PACKET,
+ "interface %s: ospf_read invalid Area ID %s.",
IF_NAME(oi), inet_ntoa(ospfh->area_id));
return -1;
}
/* Check network mask, Silently discarded. */
if (!ospf_check_network_mask(oi, iph->ip_src)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"interface %s: ospf_read network address is not same [%s]",
IF_NAME(oi), inet_ntoa(iph->ip_src));
return -1;
*/
else if (oi->ifp != ifp) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_warn("Packet from [%s] received on wrong link %s",
+ flog_warn(EC_OSPF_PACKET,
+ "Packet from [%s] received on wrong link %s",
inet_ntoa(iph->ip_src), ifp->name);
return 0;
} else if (oi->state == ISM_Down) {
char buf[2][INET_ADDRSTRLEN];
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Ignoring packet from %s to %s received on interface that is "
"down [%s]; interface flags are %s",
inet_ntop(AF_INET, &iph->ip_src, buf[0],
*/
if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS)
&& (oi->state != ISM_DR && oi->state != ISM_Backup)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
inet_ntoa(iph->ip_src), IF_NAME(oi),
lookup_msg(ospf_ism_state_msg, oi->state, NULL));
ospf_ls_ack(iph, ospfh, ibuf, oi, length);
break;
default:
- zlog_warn("interface %s: OSPF packet header type %d is illegal",
+ flog_warn(EC_OSPF_PACKET,
+ "interface %s: OSPF packet header type %d is illegal",
IF_NAME(oi), ospfh->type);
break;
}
if ((OSPF_LS_UPD_MIN_SIZE + ntohs(lsa->data->length))
> ospf_packet_max(oi)) {
if (!warned) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LARGE_LSA,
"ospf_ls_upd_packet_new: oversized LSA encountered!"
"will need to fragment. Not optimal. Try divide up"
" your network with areas. Use 'debug ospf packet send'"
size = oi->ifp->mtu;
if (size > OSPF_MAX_PACKET_SIZE) {
- zlog_warn(
- "ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
- " %d bytes, packet size %ld, dropping it completely."
- " OSPF routing is broken!",
- inet_ntoa(lsa->data->id), ntohs(lsa->data->length),
- (long int)size);
+ flog_warn(EC_OSPF_LARGE_LSA,
+ "ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
+ " %d bytes, packet size %ld, dropping it completely."
+ " OSPF routing is broken!",
+ inet_ntoa(lsa->data->id), ntohs(lsa->data->length),
+ (long int)size);
list_delete_node(update, ln);
return NULL;
}
if (oi->type == OSPF_IFTYPE_NBMA) {
if (flag == OSPF_SEND_PACKET_INDIRECT)
- zlog_warn(
+ flog_warn(
+ EC_OSPF_PACKET,
"* LS-Update is directly sent on NBMA network.");
if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix))
- zlog_warn("* LS-Update is sent to myself.");
+ flog_warn(EC_OSPF_PACKET,
+ "* LS-Update is sent to myself.");
}
rn = route_node_get(oi->ls_upd_queue, (struct prefix *)&p);
ospf_lsa_lock(lsa)); /* oi->ls_upd_queue */
if (send_lsupd_now) {
struct list *send_update_list;
- struct route_node *rn, *rnext;
+ struct route_node *rnext;
for (rn = route_top(oi->ls_upd_queue); rn; rn = rnext) {
rnext = route_next(rn);
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_sr.h"
#include "ospfd/ospf_ri.h"
+#include "ospfd/ospf_errors.h"
/* Store Router Information PCE TLV and SubTLV in network byte order. */
struct ospf_pce_info {
NULL); /* del_lsa_hook */
if (rc != 0) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_OPAQUE_REGISTRATION,
"ospf_router_info_init: Failed to register functions");
return rc;
}
if ((OspfRI.scope != OSPF_OPAQUE_AS_LSA)
&& (OspfRI.scope != OSPF_OPAQUE_AREA_LSA)) {
- zlog_warn(
- "Unable to unregister Router Info functions: Wrong scope!");
+ assert("Unable to unregister Router Info functions: Wrong scope!"
+ == NULL);
return -1;
}
uint16_t length;
/* Create a stream for LSA. */
- if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
- zlog_warn("ospf_router_info_lsa_new: stream_new() ?");
- return NULL;
- }
+ s = stream_new(OSPF_MAX_LSA_SIZE);
+
lsah = (struct lsa_header *)STREAM_DATA(s);
options = OSPF_OPTION_E; /* Enable AS external as we flood RI with
}
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
- if ((new = ospf_router_info_lsa_new()) == NULL) {
- zlog_warn(
- "ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
- return rc;
- }
+ new = ospf_router_info_lsa_new();
new->vrf_id = vrf_id;
/* Get ospf info */
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_INSTALL_FAILURE,
"ospf_router_info_lsa_originate1: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
return rc;
}
} else {
if (!is_mandated_params_set(OspfRI))
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_router_info_lsa_originate: lacks mandated ROUTER INFORMATION parameters");
/* Ok, let's try to originate an LSA */
/* Verify that the Router Information ID is supported */
if (GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)) != 0) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_router_info_lsa_refresh: Unsupported Router Information ID");
return NULL;
}
}
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
- if ((new = ospf_router_info_lsa_new()) == NULL) {
- zlog_warn(
- "ospf_router_info_lsa_refresh: ospf_router_info_lsa_new() ?");
- return NULL;
- }
+ new = ospf_router_info_lsa_new();
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
new->vrf_id = lsa->vrf_id;
/* Given "lsa" will be freed in the next function. */
top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
- zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
return new;
}
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA,
"ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set");
OspfRI.area = ospf_area_lookup_by_area_id(top, OspfRI.area_id);
}
UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
ospf_opaque_lsa_flush_schedule(&lsa);
break;
- default:
- zlog_warn("ospf_router_info_lsa_schedule: Unknown opcode (%u)",
- opcode);
- break;
}
return;
/* Sanity Check */
if (lsa == NULL) {
- zlog_warn("OSPF-RI (%s): Abort! LSA is NULL", __func__);
+ flog_warn(EC_OSPF_LSA, "OSPF-RI (%s): Abort! LSA is NULL",
+ __func__);
return -1;
}
/* First start to register Router Information callbacks */
if ((ospf_router_info_register(scope)) != 0) {
- zlog_warn(
+ vty_out(vty,
+ "%% Unable to register Router Information callbacks.");
+ flog_err(
+ EC_OSPF_INIT_FAIL,
"Unable to register Router Information callbacks. Abort!");
return CMD_WARNING_CONFIG_FAILED;
}
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_zebra.h"
+#include "ospfd/ospf_errors.h"
/* Hook function for updating route_map assignment. */
static void ospf_route_map_update(const char *name)
metric->type = metric_absolute;
if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) {
- zlog_warn("OSPF does not support 'set metric +rtt / -rtt'");
+ flog_warn(EC_OSPF_SET_METRIC_PLUS,
+ "OSPF does not support 'set metric +rtt / -rtt'");
return metric;
}
if (len <= 0)
type_next = 1;
else {
- len = 1;
type_next = 0;
*type = *offset;
}
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_sr.h"
+#include "ospfd/ospf_errors.h"
/* Variables to ensure a SPF scheduled log message is printed only once */
zlog_debug("found the LSA");
break;
default:
- zlog_warn("Invalid LSA link type %d", type);
+ flog_warn(EC_OSPF_LSA,
+ "Invalid LSA link type %d", type);
continue;
}
} else {
* 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>
srn = hash_get(OspfSR.neighbors, (void *)&(ospf->router_id),
(void *)sr_node_new);
- /* Sanity Check */
- if (srn == NULL)
- return rc;
-
/* Complete & Store self SR Node */
srn->srgb.range_size = OspfSR.srgb.range_size;
srn->srgb.lower_bound = OspfSR.srgb.lower_bound;
case EXT_SUBTLV_PREFIX_SID:
psid = (struct ext_subtlv_prefix_sid *)sub_tlvh;
if (psid->algorithm != SR_ALGORITHM_SPF) {
- flog_err(OSPF_ERR_SR_INVALID_ALGORITHM,
- "SR (%s): Unsupported Algorithm",
- __func__);
+ flog_err(EC_OSPF_INVALID_ALGORITHM,
+ "SR (%s): Unsupported Algorithm",
+ __func__);
XFREE(MTYPE_OSPF_SR_PARAMS, srp);
return NULL;
}
return;
if (OspfSR.neighbors == NULL) {
- flog_err(OSPF_ERR_SR_INVALID_DB,
- "SR (%s): Abort! no valid SR DataBase", __func__);
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Abort! no valid SR DataBase", __func__);
return;
}
/* Sanity check */
if (srn == NULL) {
- flog_err(OSPF_ERR_SR_NODE_CREATE,
- "SR (%s): Abort! can't create SR node in hash table",
- __func__);
+ flog_err(EC_OSPF_SR_NODE_CREATE,
+ "SR (%s): Abort! can't create SR node in hash table",
+ __func__);
return;
}
if ((srn->instance != 0) && (srn->instance != ntohl(lsah->id.s_addr))) {
- flog_err(OSPF_ERR_SR_INVALID_LSA_ID,
- "SR (%s): Abort! Wrong "
- "LSA ID 4.0.0.%u for SR node %s/%u",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router), srn->instance);
+ flog_err(EC_OSPF_SR_INVALID_LSA_ID,
+ "SR (%s): Abort! Wrong "
+ "LSA ID 4.0.0.%u for SR node %s/%u",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ inet_ntoa(lsah->adv_router), srn->instance);
return;
}
/* Check that we collect mandatory parameters */
if (srn->algo[0] == SR_ALGORITHM_UNSET || srgb.range_size == 0
|| srgb.lower_bound == 0) {
- zlog_warn("SR (%s): Missing mandatory parameters. Abort!",
- __func__);
+ flog_err(EC_OSPF_SR_NODE_CREATE,
+ "SR (%s): Missing mandatory parameters. Abort!",
+ __func__);
hash_release(OspfSR.neighbors, &(srn->adv_router));
XFREE(MTYPE_OSPF_SR_PARAMS, srn);
return;
/* Sanity check */
if (OspfSR.neighbors == NULL) {
- flog_err(OSPF_ERR_SR_INVALID_DB,
- "SR (%s): Abort! no valid SR Data Base", __func__);
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Abort! no valid SR Data Base", __func__);
return;
}
/* Sanity check */
if (srn == NULL) {
- flog_err(OSPF_ERR_SR_NODE_CREATE,
- "SR (%s): Abort! no entry in SRDB for SR Node %s",
- __func__, inet_ntoa(lsah->adv_router));
+ flog_err(EC_OSPF_SR_NODE_CREATE,
+ "SR (%s): Abort! no entry in SRDB for SR Node %s",
+ __func__, inet_ntoa(lsah->adv_router));
return;
}
if ((srn->instance != 0) && (srn->instance != ntohl(lsah->id.s_addr))) {
- flog_err(
- OSPF_ERR_SR_INVALID_LSA_ID,
- "SR (%s): Abort! Wrong LSA ID 4.0.0.%u for SR node %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ flog_err(EC_OSPF_SR_INVALID_LSA_ID,
+ "SR (%s): Abort! Wrong LSA ID 4.0.0.%u for SR node %s",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ inet_ntoa(lsah->adv_router));
return;
}
/* Sanity check */
if (OspfSR.neighbors == NULL) {
- flog_err(OSPF_ERR_SR_INVALID_DB,
- "SR (%s): Abort! no valid SR DataBase", __func__);
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Abort! no valid SR DataBase", __func__);
return;
}
/* Sanity check */
if (srn == NULL) {
- flog_err(OSPF_ERR_SR_NODE_CREATE,
- "SR (%s): Abort! can't create SR node in hash table",
- __func__);
+ flog_err(EC_OSPF_SR_NODE_CREATE,
+ "SR (%s): Abort! can't create SR node in hash table",
+ __func__);
return;
}
/* Sanity check */
if (OspfSR.neighbors == NULL) {
- flog_err(OSPF_ERR_SR_INVALID_DB,
- "SR (%s): Abort! no valid SR DataBase", __func__);
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Abort! no valid SR DataBase", __func__);
return;
}
* processing Router Information LSA deletion
*/
if (srn == NULL) {
- zlog_warn("SR (%s): Stop! no entry in SRDB for SR Node %s",
- __func__, inet_ntoa(lsah->adv_router));
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Stop! no entry in SRDB for SR Node %s",
+ __func__, inet_ntoa(lsah->adv_router));
return;
}
listnode_delete(srn->ext_link, srl);
XFREE(MTYPE_OSPF_SR_PARAMS, srl);
} else {
- zlog_warn(
- "SR (%s): Didn't found corresponding SR Link 8.0.0.%u "
- "for SR Node %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Didn't found corresponding SR Link 8.0.0.%u "
+ "for SR Node %s",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ inet_ntoa(lsah->adv_router));
}
}
/* Sanity check */
if (OspfSR.neighbors == NULL) {
- flog_err(OSPF_ERR_SR_INVALID_DB,
- "SR (%s): Abort! no valid SR DataBase", __func__);
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Abort! no valid SR DataBase", __func__);
return;
}
/* Sanity check */
if (srn == NULL) {
- flog_err(OSPF_ERR_SR_NODE_CREATE,
- "SR (%s): Abort! can't create SR node in hash table",
- __func__);
+ flog_err(EC_OSPF_SR_NODE_CREATE,
+ "SR (%s): Abort! can't create SR node in hash table",
+ __func__);
return;
}
/* Sanity check */
if (OspfSR.neighbors == NULL) {
- flog_err(OSPF_ERR_SR_INVALID_DB,
- "SR (%s): Abort! no valid SR DataBase", __func__);
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Abort! no valid SR DataBase", __func__);
return;
}
* processing Router Information LSA deletion
*/
if (srn == NULL) {
- zlog_warn("SR (%s): Stop! no entry in SRDB for SR Node %s",
- __func__, inet_ntoa(lsah->adv_router));
+ flog_err(EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Stop! no entry in SRDB for SR Node %s",
+ __func__, inet_ntoa(lsah->adv_router));
return;
}
listnode_delete(srn->ext_link, srp);
XFREE(MTYPE_OSPF_SR_PARAMS, srp);
} else {
- zlog_warn(
- "SR (%s): Didn't found corresponding SR Prefix "
- "7.0.0.%u for SR Node %s",
+ flog_err(
+ EC_OSPF_SR_INVALID_DB,
+ "SR (%s): Didn't found corresponding SR Prefix 7.0.0.%u for SR Node %s",
__func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
inet_ntoa(lsah->adv_router));
}
/* Start Segment Routing */
OspfSR.enabled = true;
- if (!ospf_sr_start(ospf)) {
- zlog_warn("SR: Unable to start Segment Routing. Abort!");
- return CMD_WARNING;
- }
+ ospf_sr_start(ospf);
/* Set Router Information SR parameters */
if (IS_DEBUG_OSPF_EVENT)
* update of this Extended Prefix
*/
listnode_add(OspfSR.self->ext_prefix, new);
- zlog_warn(
+ zlog_info(
"Interface for prefix %s/%u not found. Deferred LSA "
"flooding",
inet_ntoa(p.u.prefix4), p.prefixlen);
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_te.h"
#include "ospfd/ospf_vty.h"
+#include "ospfd/ospf_errors.h"
/*
* Global variable to manage Opaque-LSA/MPLS-TE on this node.
ospf_mpls_te_lsa_refresh, NULL, /* ospf_mpls_te_new_lsa_hook */
NULL /* ospf_mpls_te_del_lsa_hook */);
if (rc != 0) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_OPAQUE_REGISTRATION,
"ospf_mpls_te_init: Failed to register Traffic Engineering functions");
return rc;
}
ospf_mpls_te_lsa_refresh, NULL, NULL);
if (rc != 0) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_OPAQUE_REGISTRATION,
"ospf_router_info_init: Failed to register Inter-AS functions");
return rc;
}
if (lp->instance == key)
return lp;
- zlog_warn("lookup_linkparams_by_instance: Entry not found: key(%x)",
+ zlog_info("lookup_linkparams_by_instance: Entry not found: key(%x)",
key);
return NULL;
}
if ((oi == NULL) || (oi->ifp != ifp)) {
if (IS_DEBUG_OSPF_TE)
- zlog_warn(
+ zlog_debug(
"MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s",
ifp->name);
return;
int rc = 0;
if (ntohs(OspfMplsTE.router_addr.header.type) == 0) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"MPLS-TE(is_mandated_params_set) Missing Router Address");
return rc;
}
if (ntohs(lp->link_type.header.type) == 0) {
- zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link Type");
+ flog_warn(EC_OSPF_TE_UNEXPECTED,
+ "MPLS-TE(is_mandated_params_set) Missing Link Type");
return rc;
}
if (!IS_INTER_AS(lp->type) && (ntohs(lp->link_id.header.type) == 0)) {
- zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link ID");
+ flog_warn(EC_OSPF_TE_UNEXPECTED,
+ "MPLS-TE(is_mandated_params_set) Missing Link ID");
return rc;
}
static int ospf_mpls_te_new_if(struct interface *ifp)
{
struct mpls_te_link *new;
- int rc = -1;
if (IS_DEBUG_OSPF_TE)
zlog_debug(
"MPLS-TE(ospf_mpls_te_new_if) Add new %s interface %s to MPLS-TE list",
ifp->link_params ? "Active" : "Inactive", ifp->name);
- if (lookup_linkparams_by_ifp(ifp) != NULL) {
- zlog_warn("ospf_mpls_te_new_if: ifp(%p) already in use?",
- (void *)ifp);
- rc = 0; /* Do nothing here. */
- return rc;
- }
+ if (lookup_linkparams_by_ifp(ifp) != NULL)
+ return 0;
new = XCALLOC(MTYPE_OSPF_MPLS_TE, sizeof(struct mpls_te_link));
ifp->name, new->flags, new->type);
/* Schedule Opaque-LSA refresh. */ /* XXX */
-
- rc = 0;
- return rc;
+ return 0;
}
static int ospf_mpls_te_del_if(struct interface *ifp)
/* Get Link context from interface */
if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s",
ifp->name);
return;
struct mpls_te_link *lp;
if ((lp = lookup_linkparams_by_ifp(oi->ifp)) == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?",
IF_NAME(oi));
return;
}
if (oi->area == NULL || oi->area->ospf == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",
IF_NAME(oi));
return;
&& !IPV4_ADDR_SAME(&lp->area->area_id, &oi->area->area_id))
|| (lp->area != NULL && oi->area == NULL)) {
/* How should we consider this case? */
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"MPLS-TE: Area for OI(%s) has changed to [%s], flush previous LSAs",
IF_NAME(oi),
oi->area ? inet_ntoa(oi->area->area_id) : "N/A");
uint16_t length;
/* Create a stream for LSA. */
- if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
- zlog_warn("ospf_mpls_te_lsa_new: stream_new() ?");
- return NULL;
- }
+ s = stream_new(OSPF_MAX_LSA_SIZE);
lsah = (struct lsa_header *)STREAM_DATA(s);
options = OSPF_OPTION_O; /* Don't forget this :-) */
/* Create new Opaque-LSA/MPLS-TE instance. */
new = ospf_mpls_te_lsa_new(area->ospf, area, lp);
if (new == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
return rc;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(area->ospf, NULL /*oi*/, new) == NULL) {
- zlog_warn("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
return rc;
}
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) {
if (CHECK_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH)) {
UNSET_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH);
- zlog_warn(
+ zlog_info(
"OSPF MPLS-TE (ospf_mpls_te_lsa_originate_area): Refresh instead of Originate");
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
}
}
if (!is_mandated_params_set(lp)) {
- zlog_warn(
+ zlog_info(
"ospf_mpls_te_lsa_originate_area: Link(%s) lacks some mandated MPLS-TE parameters.",
lp->ifp ? lp->ifp->name : "?");
continue;
/* Create new Opaque-LSA/Inter-AS instance. */
new = ospf_mpls_te_lsa_new(top, NULL, lp);
if (new == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_LSA_UNEXPECTED,
"ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
return rc;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
- zlog_warn("ospf_mpls_te_lsa_originate2: ospf_lsa_install() ?");
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "ospf_mpls_te_lsa_originate2: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
return rc;
}
}
if (!is_mandated_params_set(lp)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"ospf_mpls_te_lsa_originate_as: Link(%s) lacks some mandated MPLS-TE parameters.",
lp->ifp ? lp->ifp->name : "?");
continue;
/* At first, resolve lsa/lp relationship. */
if ((lp = lookup_linkparams_by_instance(lsa)) == NULL) {
- zlog_warn("ospf_mpls_te_lsa_refresh: Invalid parameter?");
+ flog_warn(EC_OSPF_TE_UNEXPECTED,
+ "ospf_mpls_te_lsa_refresh: Invalid parameter?");
lsa->data->ls_age =
htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */
ospf_opaque_lsa_flush_schedule(lsa);
/* Check if lp was not disable in the interval */
if (!CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE)) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"ospf_mpls_te_lsa_refresh: lp was disabled: Flush it!");
lsa->data->ls_age =
htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */
/* Create new Opaque-LSA/MPLS-TE instance. */
new = ospf_mpls_te_lsa_new(top, area, lp);
if (new == NULL) {
- zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
+ flog_warn(EC_OSPF_TE_UNEXPECTED,
+ "ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
top = area->ospf;
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
- zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
return NULL;
}
top, OspfMplsTE.interas_areaid);
/* Unable to set the area context. Abort! */
if (lp->area == NULL) {
- zlog_warn(
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
"MPLS-TE(ospf_mpls_te_lsa_schedule) Area context is null. Abort !");
return;
}
ospf_opaque_lsa_flush_schedule(&lsa);
break;
default:
- zlog_warn("ospf_mpls_te_lsa_schedule: Unknown opcode (%u)",
+ flog_warn(EC_OSPF_TE_UNEXPECTED,
+ "ospf_mpls_te_lsa_schedule: Unknown opcode (%u)",
opcode);
break;
}
return CMD_SUCCESS;
ospf_routemap_unset(red);
+ ospf_redist_del(ospf, source, 0);
+
return ospf_redistribute_unset(ospf, source, 0);
}
return CMD_SUCCESS;
ospf_routemap_unset(red);
+ ospf_redist_del(ospf, source, instance);
+
return ospf_redistribute_unset(ospf, source, instance);
}
return CMD_SUCCESS;
ospf_routemap_unset(red);
+ ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
+
return ospf_redistribute_default_unset(ospf);
}
if (ifp == NULL)
return 0;
- if (if_is_up(ifp))
- zlog_warn("Zebra: got delete of %s, but interface is still up",
- ifp->name);
-
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
"Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
ospf_redist_string(type), instance, ospf->vrf_id);
- ospf_redist_del(ospf, type, instance);
-
/* Remove the routes from OSPF table. */
ospf_redistribute_withdraw(ospf, type, instance);
int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
int mvalue)
{
- struct ospf_redist *red;
-
ospf->default_originate = originate;
- red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
- red->dmetric.type = mtype;
- red->dmetric.value = mvalue;
-
ospf_external_add(ospf, DEFAULT_ROUTE, 0);
- if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
- /* if ospf->default_originate changes value, is calling
- ospf_external_lsa_refresh_default sufficient to implement
- the change? */
- ospf_external_lsa_refresh_default(ospf);
-
+ if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug(
"Redistribute[%s]: Refresh Type[%d], Metric[%d]",
ospf_redist_string(DEFAULT_ROUTE),
metric_type(ospf, DEFAULT_ROUTE, 0),
metric_value(ospf, DEFAULT_ROUTE, 0));
- return CMD_SUCCESS;
- }
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
ospf->vrf_id);
metric_type(ospf, DEFAULT_ROUTE, 0),
metric_value(ospf, DEFAULT_ROUTE, 0));
+ ospf_external_lsa_refresh_default(ospf);
+
if (ospf->router_id.s_addr == 0)
ospf->external_origin |= (1 << DEFAULT_ROUTE);
else
return CMD_SUCCESS;
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
- ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
ospf->vrf_id);
/* Update distribute-list, and apply filter. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
- struct listnode *node;
struct ospf_redist *red;
red_list = ospf->redist[type];
*/
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;
- struct listnode *node;
struct ospf_redist *red;
red_list = ospf->redist[type];
new->lsa_refresh_interval, &new->t_lsa_refresher);
new->lsa_refresher_started = monotime(NULL);
- if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1)) == NULL) {
- zlog_err(
- "ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
- OSPF_MAX_PACKET_SIZE + 1);
- exit(1);
- }
+ new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1);
+
new->t_read = NULL;
new->oi_write_q = list_new();
new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
new->fd = -1;
if ((ospf_sock_init(new)) < 0) {
if (new->vrf_id != VRF_UNKNOWN)
- zlog_warn(
+ flog_err(
+ EC_LIB_SOCKET,
"%s: ospf_sock_init is unable to open a socket",
__func__);
return new;
ospf_lsdb_free(ospf->lsdb);
for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
- struct ospf_lsa *lsa;
-
if ((lsa = rn->info) != NULL) {
ospf_lsa_unlock(&lsa);
rn->info = NULL;
for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
struct list *ext_list;
- struct listnode *node;
struct ospf_external *ext;
ext_list = ospf->external[i];
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 = \
-!Makefile
-Makefile.in
-libpbr.a
pbrd
-tags
-TAGS
-.deps
-*.o
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
pnhgc);
for (ALL_NEXTHOPS(nhgc->nhg, nhop)) {
- struct pbr_nexthop_cache lookup;
+ struct pbr_nexthop_cache lookupc;
struct pbr_nexthop_cache *pnhc;
- lookup.nexthop = nhop;
- pnhc = hash_lookup(pnhgc->nhh, &lookup);
+ lookupc.nexthop = nhop;
+ pnhc = hash_lookup(pnhgc->nhh, &lookupc);
if (!pnhc) {
- pnhc = hash_get(pnhgc->nhh, &lookup, pbr_nh_alloc);
+ pnhc = hash_get(pnhgc->nhh, &lookupc, pbr_nh_alloc);
pnhc->parent = pnhgc;
}
}
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 = \
-!Makefile
-Makefile.in
-libpim.a
pimd
mtracebis
test_igmpv3_join
-tags
-TAGS
-.deps
-*.o
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
* 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"
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef __linux__
#include <stdio.h>
break; /* process next filter */
}
if (h->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr *err =
+ struct nlmsgerr *merr =
(struct nlmsgerr *)NLMSG_DATA(
h);
if (h->nlmsg_len
fprintf(stderr,
"ERROR truncated\n");
} else {
- errno = -err->error;
+ errno = -merr->error;
perror("RTNETLINK answers");
}
return -1;
}
if (h->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr *err =
+ struct nlmsgerr *merr =
(struct nlmsgerr *)NLMSG_DATA(h);
if (l < (int)sizeof(struct nlmsgerr)) {
fprintf(stderr, "ERROR truncated\n");
} else {
- errno = -err->error;
+ errno = -merr->error;
if (errno == 0) {
if (answer)
memcpy(answer, h,
* 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>
vty_out(vty, "Designated Router\n");
vty_out(vty, "-----------------\n");
vty_out(vty, "Address : %s\n", dr_str);
- vty_out(vty, "Priority : %d\n",
- pim_ifp->pim_dr_priority);
+ vty_out(vty, "Priority : %d(%d)\n",
+ pim_ifp->pim_dr_priority,
+ pim_ifp->pim_dr_num_nondrpri_neighbors);
vty_out(vty, "Uptime : %s\n", dr_uptime);
vty_out(vty, "Elections : %d\n",
pim_ifp->pim_dr_election_count);
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]",
pim_ifp = ifp->info;
if (!pim_ifp) {
- pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
+ pim_ifp = pim_if_new(ifp, true, false, false);
if (!pim_ifp) {
vty_out(vty, "Could not enable IGMP on interface %s\n",
ifp->name);
struct pim_interface *pim_ifp = ifp->info;
if (!pim_ifp) {
- pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
+ pim_ifp = pim_if_new(ifp, false, true, false);
if (!pim_ifp) {
return 0;
}
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;
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;
return 1;
}
-DEFUN_HIDDEN (interface_no_ip_pim_ssm,
- interface_no_ip_pim_ssm_cmd,
- "no ip pim ssm",
- NO_STR
- IP_STR
- PIM_STR
- IFACE_PIM_STR)
+static int interface_no_ip_pim_helper(struct vty *vty)
{
VTY_DECLVAR_CONTEXT(interface, ifp);
if (!pim_cmd_interface_delete(ifp)) {
return CMD_SUCCESS;
}
-DEFUN (interface_no_ip_pim_sm,
+DEFUN_HIDDEN (interface_no_ip_pim_ssm,
+ interface_no_ip_pim_ssm_cmd,
+ "no ip pim ssm",
+ NO_STR
+ IP_STR
+ PIM_STR
+ IFACE_PIM_STR)
+{
+ return interface_no_ip_pim_helper(vty);
+}
+
+DEFUN_HIDDEN (interface_no_ip_pim_sm,
interface_no_ip_pim_sm_cmd,
"no ip pim sm",
NO_STR
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 */
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")
{
"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")
{
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);
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);
/* clang-format off */
static struct log_ref ferr_pim_err[] = {
{
- .code = PIM_ERR_MSDP_PACKET,
+ .code = EC_PIM_MSDP_PACKET,
.title = "PIM MSDP Packet Error",
.description = "PIM has received a packet from a peer that does not correctly decode",
.suggestion = "Check MSDP peer and ensure it is correctly working"
},
{
- .code = PIM_ERR_CONFIG,
+ .code = EC_PIM_CONFIG,
.title = "PIM Configuration Error",
.description = "PIM has detected a configuration error",
.suggestion = "Ensure the configuration is correct and apply correct configuration"
#include "lib/ferr.h"
enum pim_log_refs {
- PIM_ERR_MSDP_PACKET = PIM_FERR_START,
- PIM_ERR_CONFIG,
+ EC_PIM_MSDP_PACKET = PIM_FERR_START,
+ EC_PIM_CONFIG,
};
extern void pim_error_init(void);
return 0;
}
-struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
+struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
+ bool ispimreg)
{
struct pim_interface *pim_ifp;
pim_sock_reset(ifp);
- pim_if_add_vif(ifp);
+ pim_if_add_vif(ifp, ispimreg);
return pim_ifp;
}
address assigned, then try to create a vif_index.
*/
if (pim_ifp->mroute_vif_index < 0) {
- pim_if_add_vif(ifp);
+ pim_if_add_vif(ifp, false);
}
pim_ifchannel_scan_forward_start(ifp);
}
* address assigned, then try to create a vif_index.
*/
if (pim_ifp->mroute_vif_index < 0) {
- pim_if_add_vif(ifp);
+ pim_if_add_vif(ifp, false);
}
pim_ifchannel_scan_forward_start(ifp);
see also pim_if_find_vifindex_by_ifindex()
*/
-int pim_if_add_vif(struct interface *ifp)
+int pim_if_add_vif(struct interface *ifp, bool ispimreg)
{
struct pim_interface *pim_ifp = ifp->info;
struct in_addr ifaddr;
}
ifaddr = pim_ifp->primary_address;
- if (ifp->ifindex != PIM_OIF_PIM_REGISTER_VIF
- && PIM_INADDR_IS_ANY(ifaddr)) {
+ if (!ispimreg && PIM_INADDR_IS_ANY(ifaddr)) {
zlog_warn(
"%s: could not get address for interface %s ifindex=%d",
__PRETTY_FUNCTION__, ifp->name, ifp->ifindex);
pim->regiface = if_create(pimreg_name, pim->vrf_id);
pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
- pim_if_new(pim->regiface, 0, 0);
+ pim_if_new(pim->regiface, false, false, true);
}
}
void pim_if_init(struct pim_instance *pim);
void pim_if_terminate(struct pim_instance *pim);
-struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim);
+struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
+ bool ispimreg);
void pim_if_delete(struct interface *ifp);
void pim_if_addr_add(struct connected *ifc);
void pim_if_addr_del(struct connected *ifc, int force_prim_as_any);
void pim_if_addr_del_all_igmp(struct interface *ifp);
void pim_if_addr_del_all_pim(struct interface *ifp);
-int pim_if_add_vif(struct interface *ifp);
+int pim_if_add_vif(struct interface *ifp, bool ispimreg);
int pim_if_del_vif(struct interface *ifp);
void pim_if_add_vif_all(struct pim_instance *pim);
void pim_if_del_vif_all(struct pim_instance *pim);
struct channel_oil *c_oil = child->channel_oil;
struct pim_ifchannel *chchannel =
pim_ifchannel_find(ifp, &child->sg);
- struct pim_interface *pim_ifp = ifp->info;
+
+ pim_ifp = ifp->info;
if (PIM_DEBUG_EVENTS)
zlog_debug("%s %s: Prune(S,G)=%s(%s) from %s",
if (!join) {
flog_err_sys(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"IGMP socket fd=%d could not join any group on interface address %s",
fd, inet_ntoa(ifaddr));
close(fd);
if (close(igmp->fd)) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s",
inet_ntoa(igmp->ifaddr), igmp->fd,
igmp->interface->name, errno, safe_strerror(errno));
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;
* 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)
msg_size = IGMP_V3_SOURCES_OFFSET + (num_sources << 2);
if (msg_size > query_buf_size) {
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"%s %s: unable to send: msg_size=%zd larger than query_buf_size=%d",
__FILE__, __PRETTY_FUNCTION__, msg_size,
query_buf_size);
* the Interface type is SSM we don't need to
* do anything here
*/
- if (!rpg || (pim_rpf_addr_is_inaddr_none(rpg))
- || (!(PIM_I_am_DR(pim_ifp)))) {
+ if (!rpg || pim_rpf_addr_is_inaddr_none(rpg)) {
if (PIM_DEBUG_MROUTE_DETAIL)
zlog_debug(
- "%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
+ "%s: Interface is not configured correctly to handle incoming packet: Could be !pim_ifp, !SM, !RP",
__PRETTY_FUNCTION__);
+
return 0;
}
sg.src = msg->im_src;
sg.grp = msg->im_dst;
+ if (!(PIM_I_am_DR(pim_ifp))) {
+ struct channel_oil *c_oil;
+
+ if (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug("%s: Interface is not the DR blackholing incoming traffic for %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+
+ /*
+ * We are not the DR, but we are still receiving packets
+ * Let's blackhole those packets for the moment
+ * As that they will be coming up to the cpu
+ * and causing us to consider them.
+ */
+ c_oil = pim_channel_oil_add(pim_ifp->pim, &sg,
+ pim_ifp->mroute_vif_index);
+ pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
+
+ return 0;
+ }
+
up = pim_upstream_find_or_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
__PRETTY_FUNCTION__);
if (!up) {
* changes; perhaps
* address this in the next release? - XXX */
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"MSDP sa %s SPT teardown is causing the local entry to be removed",
sa->sg_str);
return;
/* If getsockopt is fail, this is fatal error. */
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"can't get sockopt for nonblocking connect");
pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
return;
if (prefix_len != 32) {
/* ignore SA update if the prefix length is not 32 */
- flog_err(PIM_ERR_MSDP_PACKET,
- "rxed sa update with invalid prefix length %d",
- prefix_len);
+ flog_err(EC_PIM_MSDP_PACKET,
+ "rxed sa update with invalid prefix length %d",
+ prefix_len);
return;
}
if (PIM_DEBUG_MSDP_PACKETS) {
socklen_t optlen = sizeof(optval);
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"getsockopt of SO_SNDBUF failed %s\n",
safe_strerror(errno));
return;
if (optval < size) {
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size))
< 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"Couldn't increase send buffer: %s\n",
safe_strerror(errno));
}
/* re-register accept thread */
accept_sock = THREAD_FD(thread);
if (accept_sock < 0) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "accept_sock is negative value %d", accept_sock);
+ flog_err(EC_LIB_DEVELOPMENT, "accept_sock is negative value %d",
+ accept_sock);
return -1;
}
pim->msdp.listener.thread = NULL;
/* accept client connection. */
msdp_sock = sockunion_accept(accept_sock, &su);
if (msdp_sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_sock_accept failed (%s)",
+ flog_err_sys(EC_LIB_SOCKET, "pim_msdp_sock_accept failed (%s)",
safe_strerror(errno));
return -1;
}
if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) {
++pim->msdp.rejected_accepts;
if (PIM_DEBUG_MSDP_EVENTS) {
- flog_err(PIM_ERR_MSDP_PACKET,
- "msdp peer connection refused from %s",
- sockunion2str(&su, buf, SU_ADDRSTRLEN));
+ flog_err(EC_PIM_MSDP_PACKET,
+ "msdp peer connection refused from %s",
+ sockunion2str(&su, buf, SU_ADDRSTRLEN));
}
close(msdp_sock);
return -1;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "socket: %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "socket: %s", safe_strerror(errno));
return sock;
}
struct interface *ifp =
if_lookup_by_name(pim->vrf->name, pim->vrf_id);
if (!ifp) {
- flog_err(LIB_ERR_INTERFACE,
- "%s: Unable to lookup vrf interface: %s",
- __PRETTY_FUNCTION__, pim->vrf->name);
+ flog_err(EC_LIB_INTERFACE,
+ "%s: Unable to lookup vrf interface: %s",
+ __PRETTY_FUNCTION__, pim->vrf->name);
close(sock);
return -1;
}
if (pim_socket_bind(sock, ifp)) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: Unable to bind to socket: %s",
__PRETTY_FUNCTION__, safe_strerror(errno));
close(sock);
}
if (rc < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"pim_msdp_socket bind to port %d: %s",
ntohs(sin.sin_port), safe_strerror(errno));
close(sock);
rc = listen(sock, 3 /* backlog */);
if (rc < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_socket listen: %s",
+ flog_err_sys(EC_LIB_SOCKET, "pim_msdp_socket listen: %s",
safe_strerror(errno));
close(sock);
return rc;
/* Make socket for the peer. */
mp->fd = sockunion_socket(&mp->su_peer);
if (mp->fd < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"pim_msdp_socket socket failure: %s",
safe_strerror(errno));
return -1;
struct interface *ifp =
if_lookup_by_name(mp->pim->vrf->name, mp->pim->vrf_id);
if (!ifp) {
- flog_err(LIB_ERR_INTERFACE,
- "%s: Unable to lookup vrf interface: %s",
- __PRETTY_FUNCTION__, mp->pim->vrf->name);
+ flog_err(EC_LIB_INTERFACE,
+ "%s: Unable to lookup vrf interface: %s",
+ __PRETTY_FUNCTION__, mp->pim->vrf->name);
return -1;
}
if (pim_socket_bind(mp->fd, ifp)) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: Unable to bind to socket: %s",
__PRETTY_FUNCTION__, safe_strerror(errno));
close(mp->fd);
/* source bind */
rc = sockunion_bind(mp->fd, &mp->su_local, 0, &mp->su_local);
if (rc < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"pim_msdp_socket connect bind failure: %s",
safe_strerror(errno));
close(mp->fd);
if (neigh->prefix_list == addr_list) {
if (addr_list) {
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"%s: internal error: trying to replace same prefix list=%p",
__PRETTY_FUNCTION__, (void *)addr_list);
}
delete_message);
if (!ifp->info) {
- flog_err(PIM_ERR_CONFIG,
- "%s: %s: but PIM not enabled on interface %s (!)",
- __PRETTY_FUNCTION__, delete_message, ifp->name);
+ flog_err(EC_PIM_CONFIG,
+ "%s: %s: but PIM not enabled on interface %s (!)",
+ __PRETTY_FUNCTION__, delete_message, ifp->name);
return;
}
ip->ip_len = htons(sendlen);
if (PIM_DEBUG_PIM_PACKETS) {
- struct pim_msg_header *header =
- (struct pim_msg_header *)pim_msg;
char dst_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", dst, dst_str, sizeof(dst_str));
zlog_debug("%s: to %s on %s: msg_size=%d checksum=%x",
rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
if (!str2prefix("224.0.0.0/4", &rp_info->group)) {
- flog_err(LIB_ERR_DEVELOPMENT,
- "Unable to convert 224.0.0.0/4 to prefix");
+ flog_err(EC_LIB_DEVELOPMENT,
+ "Unable to convert 224.0.0.0/4 to prefix");
list_delete_and_null(&pim->rp_list);
route_table_finish(pim->rp_table);
XFREE(MTYPE_PIM_RP, rp_info);
rn = route_node_match(pim->rp_table, group);
if (!rn) {
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"%s: BUG We should have found default group information\n",
__PRETTY_FUNCTION__);
return best;
if (rn) {
if (rn->info != rp_info)
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"Expected rn->info to be equal to rp_info");
if (PIM_DEBUG_TRACE) {
}
#else
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"%s %s: Missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
__FILE__, __PRETTY_FUNCTION__);
close(fd);
sprintf(ifaddr_str, "<ifaddr?>");
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"Failure socket joining fd=%d group %s on interface address %s: errno=%d: %s",
fd, group_str, ifaddr_str, errno, safe_strerror(errno));
return ret;
if (first) {
if (!str2prefix(PIM_SSM_STANDARD_RANGE, &group_ssm))
- flog_err(LIB_ERR_DEVELOPMENT,
- "%s: Failure to Read Group Address: %s",
- __PRETTY_FUNCTION__, PIM_SSM_STANDARD_RANGE);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "%s: Failure to Read Group Address: %s",
+ __PRETTY_FUNCTION__, PIM_SSM_STANDARD_RANGE);
first = 0;
}
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: could not create socket: errno=%d: %s",
__PRETTY_FUNCTION__, errno, safe_strerror(errno));
return -1;
}
#else
flog_err(
- LIB_ERR_DEVELOPMENT,
+ EC_LIB_DEVELOPMENT,
"%s %s: missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
__FILE__, __PRETTY_FUNCTION__);
close(fd);
result = gettimeofday(tv, 0);
if (result) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: gettimeofday() failure: errno=%d: %s",
__PRETTY_FUNCTION__, errno, safe_strerror(errno));
}
struct timeval now_tv;
if (gettime_monotonic(&now_tv)) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: gettime_monotonic() failure: errno=%d: %s",
__PRETTY_FUNCTION__, errno, safe_strerror(errno));
return -1;
int64_t now_dsec;
if (gettime_monotonic(&now_tv)) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: gettime_monotonic() failure: errno=%d: %s",
__PRETTY_FUNCTION__, errno, safe_strerror(errno));
return -1;
int64_t now_dsec;
if (gettime_monotonic(&now_tv)) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: gettime_monotonic() failure: errno=%d: %s",
__PRETTY_FUNCTION__, errno, safe_strerror(errno));
return -1;
void pim_upstream_init(struct pim_instance *pim)
{
- char hash_name[64];
+ char name[64];
+ snprintf(name, 64, "PIM %s Timer Wheel",
+ pim->vrf->name);
pim->upstream_sg_wheel =
wheel_init(master, 31000, 100, pim_upstream_hash_key,
- pim_upstream_sg_running);
+ pim_upstream_sg_running, name);
- snprintf(hash_name, 64, "PIM %s Upstream Hash", pim->vrf->name);
+ snprintf(name, 64, "PIM %s Upstream Hash",
+ pim->vrf->name);
pim->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
- pim_upstream_equal, hash_name);
+ pim_upstream_equal, name);
pim->upstream_list = list_new();
pim->upstream_list->cmp = pim_upstream_compare;
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;
}
struct pim_interface *pim_ifp;
if (!ifp->info) {
- pim_ifp = pim_if_new(ifp, 0, 0);
+ pim_ifp = pim_if_new(ifp, false, false, false);
ifp->info = pim_ifp;
}
return;
}
- if (!(PIM_I_am_DR(pim_oif)))
+ if (!(PIM_I_am_DR(pim_oif))) {
+ if (PIM_DEBUG_IGMP_TRACE)
+ zlog_debug("%s: %s was received on %s interface but we are not DR for that interface",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&sg),
+ group->group_igmp_sock->interface->name);
return;
-
+ }
/*
Feed IGMPv3-gathered local membership information into PIM
per-interface (S,G) state.
{
zlookup = zclient_new_notify(master, &zclient_options_default);
if (!zlookup) {
- flog_err(LIB_ERR_ZAPI_SOCKET, "%s: zclient_new() failure",
- __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure",
+ __PRETTY_FUNCTION__);
return;
}
err = zclient_read_header(s, zlookup->sock, &length, &marker,
&version, &vrf_id, &command);
if (err < 0) {
- flog_err(LIB_ERR_ZAPI_MISSMATCH,
- "%s: zclient_read_header() failed",
- __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_ZAPI_MISSMATCH,
+ "%s: zclient_read_header() failed",
+ __PRETTY_FUNCTION__);
zclient_lookup_failed(zlookup);
return -1;
}
/* Check socket. */
if (zlookup->sock < 0) {
- flog_err(LIB_ERR_ZAPI_SOCKET,
- "%s: zclient lookup socket is not connected",
- __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_ZAPI_SOCKET,
+ "%s: zclient lookup socket is not connected",
+ __PRETTY_FUNCTION__);
zclient_lookup_failed(zlookup);
return -1;
}
ret = writen(zlookup->sock, s->data, stream_get_endp(s));
if (ret < 0) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%s: writen() failure: %d writing to zclient lookup socket",
__PRETTY_FUNCTION__, errno);
zclient_lookup_failed(zlookup);
return -2;
}
if (ret == 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s: connection closed on zclient lookup socket",
__PRETTY_FUNCTION__);
zclient_lookup_failed(zlookup);
ret = writen(zlookup->sock, s->data, count);
if (ret <= 0) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%s: writen() failure: %d writing to zclient lookup socket",
__PRETTY_FUNCTION__, errno);
return -1;
err = zclient_read_header(s, zlookup->sock, &length, &marker,
&version, &vrf_id, &command);
if (err < 0) {
- flog_err(LIB_ERR_ZAPI_MISSMATCH,
- "%s: zclient_read_header() failed",
- __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_ZAPI_MISSMATCH,
+ "%s: zclient_read_header() failed",
+ __PRETTY_FUNCTION__);
zclient_lookup_failed(zlookup);
return -1;
}
more.src = c_oil->oil.mfcc_origin;
more.grp = c_oil->oil.mfcc_mcastgrp;
flog_err(
- LIB_ERR_ZAPI_MISSMATCH,
+ EC_LIB_ZAPI_MISSMATCH,
"%s: Received wrong %s(%s) information requested",
__PRETTY_FUNCTION__, pim_str_sg_dump(&more),
c_oil->pim->vrf->name);
{
if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"%s %s: could not solve %s to group address: errno=%d: %s",
__FILE__, __PRETTY_FUNCTION__, PIM_ALL_PIM_ROUTERS,
errno, safe_strerror(errno));
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 = \
-Makefile
-Makefile.in
*.sh
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
+++ /dev/null
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-
+++ /dev/null
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-
+++ /dev/null
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-
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 *'
+++ /dev/null
-!Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
* 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"
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
zebra.spec
frr.spec
-Makefile
-Makefile.in
-.nfs*
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
(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)
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
pbrd=no
staticd=no
bfdd=no
+fabricd=no
#
# Command line options for the daemons
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
# 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
/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
+}
%{!?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
--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
%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
%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
%{_sbindir}/pbrd
%endif
%{_sbindir}/isisd
+%{_sbindir}/fabricd
%if %{with_ldpd}
%{_sbindir}/ldpd
%endif
-!Makefile
-Makefile.in
-*.o
ripd
ripd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
#include "rip_errors.h"
static struct log_ref ferr_rip_err[] = {
- {
- .code = RIP_ERR_PACKET,
- .title = "RIP Packet Error",
- .description = "RIP has detected a packet encode/decode issue",
- .suggestion = "Gather log files from both sides and open a Issue"
- },
+ {.code = EC_RIP_PACKET,
+ .title = "RIP Packet Error",
+ .description = "RIP has detected a packet encode/decode issue",
+ .suggestion = "Gather log files from both sides and open a Issue"},
{
.code = END_FERR,
- }
-};
+ }};
void rip_error_init(void)
{
#include "lib/ferr.h"
enum rip_log_refs {
- RIP_ERR_PACKET = RIP_FERR_START,
+ EC_RIP_PACKET = RIP_FERR_START,
RIP_ERR_CONFIG,
};
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
struct prefix *p;
- struct route_node *node;
+ struct route_node *n;
p = connected->address;
address.prefix = p->u.prefix4;
address.prefixlen = IPV4_MAX_BITLEN;
- node = route_node_match(rip_enable_network,
- (struct prefix *)&address);
- if (node) {
- route_unlock_node(node);
+ n = route_node_match(rip_enable_network,
+ (struct prefix *)&address);
+ if (n) {
+ route_unlock_node(n);
return 1;
}
}
/* Join to multicast group. */
if (rip_multicast_join(ifp, rip->sock) < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"multicast join failed, interface %s not running",
ifp->name);
return 0;
/* Modify entry according to the interface routemap. */
if (ri->routemap[RIP_FILTER_IN]) {
- int ret;
-
/* The object should be of the type of rip_info */
ret = route_map_apply(ri->routemap[RIP_FILTER_IN],
(struct prefix *)&p, RMAP_RIP, &newinfo);
/* Check packet length. */
if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE)) {
- flog_err(RIP_ERR_PACKET,
- "rip_auth_md5_set(): packet length %ld is less than minimum length.",
- len);
+ flog_err(
+ EC_RIP_PACKET,
+ "rip_auth_md5_set(): packet length %ld is less than minimum length.",
+ len);
return;
}
/* Make datagram socket. */
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "Cannot create UDP socket: %s",
+ flog_err_sys(EC_LIB_SOCKET, "Cannot create UDP socket: %s",
safe_strerror(errno));
exit(1);
}
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 = \
-!Makefile
-Makefile.in
-*.o
ripngd
ripngd.conf
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-*.a
/* Join to multicast group. */
if (ripng_multicast_join(ifp) < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"multicast join failed, interface %s not running",
ifp->name);
return 0;
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "Can't make ripng socket");
+ flog_err_sys(EC_LIB_SOCKET, "Can't make ripng socket");
return sock;
}
if (ret < 0) {
if (to)
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"RIPng send fail on %s to %s: %s",
ifp->name, inet6_ntoa(to->sin6_addr),
safe_strerror(errno));
else
- flog_err_sys(LIB_ERR_SOCKET,
- "RIPng send fail on %s: %s", ifp->name,
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "RIPng send fail on %s: %s",
+ ifp->name, safe_strerror(errno));
}
return ret;
/* Modify entry. */
if (ri->routemap[RIPNG_FILTER_IN]) {
- int ret;
-
ret = route_map_apply(ri->routemap[RIPNG_FILTER_IN],
(struct prefix *)&p, RMAP_RIPNG,
&newinfo);
/* Interface route-map */
if (ri->routemap[RIPNG_FILTER_OUT]) {
- int ret;
-
ret = route_map_apply(
ri->routemap[RIPNG_FILTER_OUT],
(struct prefix *)p, RMAP_RIPNG, rinfo);
/* Redistribute route-map. */
if (ripng->route_map[rinfo->type].name) {
- int ret;
-
ret = route_map_apply(
ripng->route_map[rinfo->type].map,
(struct prefix *)p, RMAP_RIPNG, rinfo);
/* Interface route-map */
if (ri->routemap[RIPNG_FILTER_OUT]) {
- int ret;
struct ripng_info newinfo;
/* let's cast the aggregate structure to
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 = \
-Makefile
-Makefile.in
-*.o
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.a
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
sharpd
sharpd.conf
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);
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;
}
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 = \
prime
stage
frr*.snap
-!*/Makefile
frr.init
*.pkg
*.pkg.gz
-*~
-*.loT
-*.a
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)
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);
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;
if (si->distance != si_changed->distance)
continue;
+ if (si->table_id != si_changed->table_id)
+ continue;
+
api_nh->vrf_id = si->nh_vrf_id;
switch (si->type) {
case STATIC_IFNAME:
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 = \
-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
--- /dev/null
+all: ALWAYS
+ @$(MAKE) -s -C .. check
+%: ALWAYS
+ @$(MAKE) -s -C .. tests/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
+++ /dev/null
-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
struct aspath *asp;
size_t datalen;
- bgp_pthreads_init();
- frr_pthread_get(PTHREAD_KEEPALIVES)->running = true;
-
asp = make_aspath(t->segment->asdata, t->segment->len, 0);
peer.curr = stream_new(BGP_MAX_PACKET_SIZE);
i = 0;
+ bgp_pthreads_init();
+ bgp_pth_ka->running = true;
+
while (aspath_tests[i].desc) {
printf("aspath_attr test %d\n", i);
attr_test(&aspath_tests[i++]);
bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_pthreads_init();
- frr_pthread_get(PTHREAD_KEEPALIVES)->running = true;
+ bgp_pth_ka->running = true;
if (fileno(stdout) >= 0)
tty = isatty(fileno(stdout));
bgp_master_init(master);
bgp_option_set(BGP_OPT_NO_LISTEN);
vrf_init(NULL, NULL, NULL, NULL, NULL);
- bgp_init();
+ bgp_init(0);
bgp_pthreads_run();
}
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):
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "test_fuzz_isis_tlv_tests.h"
#include <zebra.h>
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);
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++;
};
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}",
class TestCli(frrtest.TestRefOut):
program = './test_cli'
+ built_refout = True
if (descriptions != NULL) {
for (j = 0; j < vector_active(descriptions);
j++) {
- struct cmd_token *cmd =
+ struct cmd_token *ct =
vector_slot(descriptions, j);
- printf(" '%s' '%s'\n", cmd->text,
- cmd->desc);
+ printf(" '%s' '%s'\n", ct->text,
+ ct->desc);
}
vector_free(descriptions);
}
expected_lock++;
if (rn->lock != expected_lock) {
- const struct prefix_ipv6 *dst_p, *src_p;
srcdest_rnode_prefixes(
rn, (const struct prefix **)&dst_p,
(const struct prefix **)&src_p);
#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;
--- /dev/null
+#
+# 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
* 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"
printf("Connect to Label Manager\n");
- ret = lm_label_manager_connect(zclient);
+ ret = lm_label_manager_connect(zclient, 0);
printf("Label Manager connection result: %u \n", ret);
if (ret != 0) {
fprintf(stderr, "Error %d connecting to Label Manager %s\n",
-!Makefile
-.arch-inventory
-.arch-ids
-
-*~
-*.loT
-.libs
-*.o
/permutations
/ssd
# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
our $Attribute = qr{
const|
+ _Atomic|
__percpu|
__nocast|
__safe|
194 sharp
195 pbr
196 static
+197 openfabric
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
* 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"
fprintf(stdout, USAGE "\n");
exit(EXIT_SUCCESS);
}
- struct cmd_element *cmd = calloc(1, sizeof(struct cmd_element));
+ struct cmd_element *cmd = XCALLOC(MTYPE_TMP,
+ sizeof(struct cmd_element));
cmd->string = strdup(argv[1]);
struct graph *graph = graph_new();
* 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*/
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);
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);
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;
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));
DIR *procdir;
struct dirent *entry;
int foundany;
- pid_t pid;
+ long pid;
procdir = opendir("/proc");
if (!procdir)
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)
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);
/* change tty */
fd = open("/dev/tty", O_RDWR);
if (fd >= 0) {
- ioctl(fd, TIOCNOTTY, 0);
+ if (ioctl(fd, TIOCNOTTY, 0) < 0)
+ printf("ioctl TIOCNOTTY failed: %s\n",
+ strerror(errno));
close(fd);
}
chdir("/");
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();
-Makefile
-Makefile.in
-*.o
vtysh
-tags
-TAGS
-.deps
vtysh_cmd.c
-.nfs*
extract.pl
-.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
--- /dev/null
+all: ALWAYS
+ @$(MAKE) -s -C .. vtysh/vtysh
+%: ALWAYS
+ @$(MAKE) -s -C .. vtysh/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
+++ /dev/null
-## 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
#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);
$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";
}
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$/) {
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;
$ecmd =~ s/^\s+//g;
$ecmd =~ s/\s+$//g;
+ if ($fabricd) {
+ $ecmd = "fabricd_" . $ecmd;
+ }
+
# Register $ecmd
if (defined ($cmd2str{$ecmd})) {
my ($key);
}
}
+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.
--- /dev/null
+#
+# 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
{.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},
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;
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)# ",
};
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 = {
return CMD_SUCCESS;
}
-#if defined(HAVE_RPKI)
DEFUNSH(VTYSH_BGPD,
rpki,
rpki_cmd,
return CMD_SUCCESS;
}
-#endif
-
DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
"address-family <l2vpn evpn>",
"Enter Address Family command mode\n"
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"
case LDP_NODE:
case LDP_L2VPN_NODE:
case ISIS_NODE:
+ case OPENFABRIC_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
case VTY_NODE:
}
-#if defined(HAVE_RPKI)
DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit",
"Exit current mode and down to previous mode\n")
{
{
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")
"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")
{
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"
"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;
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"
"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;
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"
"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);
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)
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);
#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);
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);
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);
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);
#define VTYSH_PBRD 0x04000
#define VTYSH_STATICD 0x08000
#define VTYSH_BFDD 0x10000
+#define VTYSH_FABRICD 0x20000
#define VTYSH_WAS_ACTIVE (-2)
/* watchfrr is not in ALL since library CLI functions should not be
* run on it (logging & co. should stay in a fixed/frozen config, and
* things like prefix lists are not even initialised) */
-#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD
-#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD
-#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD
+#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD|VTYSH_FABRICD
+#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD|VTYSH_FABRICD
+#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD|VTYSH_FABRICD
#define VTYSH_NS VTYSH_ZEBRA
#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD
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)
#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"
vtysh_execute("enable");
while (cmd != NULL) {
- int ret;
char *eol;
while ((eol = strchr(cmd->line, '\n')) != NULL) {
/* Boot startup configuration file. */
if (boot_flag) {
vtysh_flock_config(frr_config);
- int ret = vtysh_read_config(frr_config);
+ ret = vtysh_read_config(frr_config);
vtysh_unflock_config();
if (ret) {
fprintf(stderr,
-!Makefile
-Makefile.in
-*.o
watchfrr
-tags
-TAGS
-.deps
-.nfs*
-*.lo
-*.la
-*.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
-
if WATCHFRR
sbin_PROGRAMS += watchfrr/watchfrr
+vtysh_scan += $(top_srcdir)/watchfrr/watchfrr_vty.c
+man8 += $(MANBUILD)/watchfrr.8
endif
noinst_HEADERS += \
switch (child = fork()) {
case -1:
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"fork failed, cannot run command [%s]: %s",
shell_cmd, safe_strerror(errno));
return -1;
char dashc[] = "-c";
char *const argv[4] = {shell, dashc, shell_cmd, NULL};
execv("/bin/sh", argv);
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"execv(/bin/sh -c '%s') failed: %s",
shell_cmd, safe_strerror(errno));
_exit(127);
}
default:
/* Parent process: we will reap the child later. */
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Forked background command [pid %d]: %s",
(int)child, shell_cmd);
return child;
switch (child = waitpid(-1, &status, WNOHANG)) {
case -1:
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "waitpid failed: %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "waitpid failed: %s",
safe_strerror(errno));
return;
case 0:
gettimeofday(&restart->time, NULL);
} else {
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"waitpid returned status for an unknown child process %d",
(int)child);
name = "(unknown)";
name, (int)child);
} else
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"cannot interpret %s %s process %d wait status 0x%x",
what, name, (int)child, status);
phase_check();
dmn->t_wakeup = NULL;
if (try_connect(dmn) < 0) {
SET_WAKEUP_DOWN(dmn);
- flog_err(WATCHFRR_ERR_CONNECTION,
- "%s state -> down : initial connection attempt failed",
- dmn->name);
+ flog_err(EC_WATCHFRR_CONNECTION,
+ "%s state -> down : initial connection attempt failed",
+ dmn->name);
dmn->state = DAEMON_DOWN;
}
return 0;
static void daemon_down(struct daemon *dmn, const char *why)
{
if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
- flog_err(WATCHFRR_ERR_CONNECTION,
- "%s state -> down : %s", dmn->name, why);
+ flog_err(EC_WATCHFRR_CONNECTION, "%s state -> down : %s",
+ dmn->name, why);
else if (gs.loglevel > LOG_DEBUG)
zlog_debug("%s still down : %s", dmn->name, why);
if (IS_UP(dmn))
of creating a socket. */
if (access(addr.sun_path, W_OK) < 0) {
if (errno != ENOENT)
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s: access to socket %s denied: %s",
dmn->name, addr.sun_path,
safe_strerror(errno));
}
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "%s(%s): cannot make socket: %s",
+ flog_err_sys(EC_LIB_SOCKET, "%s(%s): cannot make socket: %s",
__func__, addr.sun_path, safe_strerror(errno));
return -1;
}
if (set_nonblocking(sock) < 0 || set_cloexec(sock) < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"%s(%s): set_nonblocking/cloexec(%d) failed",
__func__, addr.sun_path, sock);
close(sock);
static int phase_hanging(struct thread *t_hanging)
{
gs.t_phase_hanging = NULL;
- flog_err(WATCHFRR_ERR_CONNECTION,
- "Phase [%s] hanging for %ld seconds, aborting phased restart",
- phase_str[gs.phase], PHASE_TIMEOUT);
+ flog_err(EC_WATCHFRR_CONNECTION,
+ "Phase [%s] hanging for %ld seconds, aborting phased restart",
+ phase_str[gs.phase], PHASE_TIMEOUT);
gs.phase = PHASE_NONE;
return 0;
}
dmn->t_wakeup = NULL;
if (dmn->state != DAEMON_UNRESPONSIVE)
- flog_err(WATCHFRR_ERR_CONNECTION,
- "%s: no longer unresponsive (now %s), "
- "wakeup should have been cancelled!",
- dmn->name, state_str[dmn->state]);
+ flog_err(EC_WATCHFRR_CONNECTION,
+ "%s: no longer unresponsive (now %s), "
+ "wakeup should have been cancelled!",
+ dmn->name, state_str[dmn->state]);
else {
SET_WAKEUP_UNRESPONSIVE(dmn);
try_restart(dmn);
dmn->t_wakeup = NULL;
dmn->state = DAEMON_UNRESPONSIVE;
- flog_err(WATCHFRR_ERR_CONNECTION,
- "%s state -> unresponsive : no response yet to ping "
- "sent %ld seconds ago",
- dmn->name, gs.timeout);
+ flog_err(EC_WATCHFRR_CONNECTION,
+ "%s state -> unresponsive : no response yet to ping "
+ "sent %ld seconds ago",
+ dmn->name, gs.timeout);
SET_WAKEUP_UNRESPONSIVE(dmn);
try_restart(dmn);
return 0;
/* clang-format off */
static struct log_ref ferr_watchfrr_err[] = {
{
- .code = WATCHFRR_ERR_CONNECTION,
+ .code = EC_WATCHFRR_CONNECTION,
.title = "WATCHFRR Connection Error",
.description = "WATCHFRR has detected a connectivity issue with one of the FRR daemons",
.suggestion = "Ensure that FRR is still running and if not please open an Issue"
#include "lib/ferr.h"
enum watchfrr_log_refs {
- WATCHFRR_ERR_CONNECTION = WATCHFRR_FERR_START,
+ EC_WATCHFRR_CONNECTION = WATCHFRR_FERR_START,
};
extern void watchfrr_error_init(void);
-!Makefile
-Makefile.in
-*.o
zebra
zebra.conf
client
-tags
-TAGS
-.deps
-.nfs*
-.libs
-.arch-inventory
-.arch-ids
-*~
-*.loT
#include "zebra/rtadv.h"
#include "zebra/zebra_mpls.h"
#include "zebra/debug.h"
+#include "zebra/zebra_errors.h"
/* communicate the withdrawal of a connected address */
static void connected_withdraw(struct connected *ifc)
#endif
break;
default:
- zlog_warn("Received unknown AFI: %s", afi2str(afi));
+ flog_warn(EC_ZEBRA_CONNECTED_AFI_UNKNOWN,
+ "Received unknown AFI: %s", afi2str(afi));
return;
break;
}
/* validate the destination address */
if (CONNECTED_PEER(ifc)) {
if (IPV4_ADDR_SAME(addr, broad))
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER,
"warning: interface %s has same local and peer "
"address %s, routing protocols may malfunction",
ifp->name, inet_ntoa(*addr));
struct in_addr bcalc;
bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,
prefixlen);
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_BCAST_ADDR_MISMATCH,
"warning: interface %s broadcast addr %s/%d != "
"calculated %s, routing protocols may malfunction",
ifp->name,
} else {
if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
- zlog_warn(
+ zlog_debug(
"warning: %s called for interface %s "
"with peer flag set, but no peer address supplied",
__func__, ifp->name);
/* no broadcast or destination address was supplied */
if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
- zlog_warn(
+ zlog_debug(
"warning: PtP interface %s with addr %s/%d needs a "
"peer address",
ifp->name, inet_ntoa(*addr), prefixlen);
ifc->destination = (struct prefix *)p;
} else {
if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
- zlog_warn("warning: %s called for interface %s with peer flag set, but no peer address supplied",
- __func__, ifp->name);
+ zlog_debug(
+ "warning: %s called for interface %s with peer flag set, but no peer address supplied",
+ __func__, ifp->name);
UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
}
}
#include "zebra/interface.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
+#include "zebra/zebra_errors.h"
#include <ifaddrs.h>
/* Normally SIOCGIFCONF works with AF_INET socket. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
- zlog_warn("Can't make AF_INET socket stream: %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET,
+ "Can't make AF_INET socket stream: %s",
+ safe_strerror(errno));
return -1;
}
ret = ioctl(sock, SIOCGIFCONF, &ifconf);
if (ret < 0) {
- zlog_warn("SIOCGIFCONF: %s", safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "SIOCGIFCONF: %s",
+ safe_strerror(errno));
goto end;
}
/* Repeatedly get info til buffer fails to grow. */
ret = getifaddrs(&ifap);
if (ret != 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "getifaddrs(): %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "getifaddrs(): %s",
safe_strerror(errno));
return -1;
}
for (ifapfree = ifap; ifap; ifap = ifap->ifa_next) {
if (ifap->ifa_addr == NULL) {
flog_err(
- LIB_ERR_INTERFACE,
+ EC_LIB_INTERFACE,
"%s: nonsensical ifaddr with NULL ifa_addr, ifname %s",
__func__,
(ifap->ifa_name ? ifap->ifa_name : "(null)"));
ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT);
if (ifp == NULL) {
- flog_err(LIB_ERR_INTERFACE,
- "if_getaddrs(): Can't lookup interface %s\n",
- ifap->ifa_name);
+ flog_err(EC_LIB_INTERFACE,
+ "if_getaddrs(): Can't lookup interface %s\n",
+ ifap->ifa_name);
continue;
}
#include "zebra/interface.h"
#include "zebra/ioctl_solaris.h"
#include "zebra/rib.h"
+#include "zebra/rt.h"
+#include "zebra/zebra_errors.h"
static int if_get_addr(struct interface *, struct sockaddr *, const char *);
static void interface_info_ioctl(struct interface *);
struct lifconf lifconf;
struct interface *ifp;
int n;
- int save_errno;
size_t needed, lastneeded = 0;
char *buf = NULL;
}
if (sock < 0) {
- zlog_warn("Can't make %s socket stream: %s",
- (af == AF_INET ? "AF_INET" : "AF_INET6"),
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "Can't make %s socket stream: %s",
+ (af == AF_INET ? "AF_INET" : "AF_INET6"),
+ safe_strerror(errno));
return -1;
}
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));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "interface_list_ioctl: SIOCGLIFNUM failed %s",
+ safe_strerror(errno));
close(sock);
return -1;
}
if (errno == EINVAL)
goto calculate_lifc_len;
- zlog_warn("SIOCGLIFCONF: %s", safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "SIOCGLIFCONF: %s",
+ safe_strerror(errno));
goto end;
}
ret = -1;
if (ret < 0) {
- zlog_warn("SIOCGLIFINDEX(%s) failed", ifp->name);
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "SIOCGLIFINDEX(%s) failed",
+ ifp->name);
return ret;
}
if (ret < 0) {
if (errno != EADDRNOTAVAIL) {
- zlog_warn("SIOCGLIFNETMASK (%s) fail: %s",
- ifp->name, safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "SIOCGLIFNETMASK (%s) fail: %s",
+ ifp->name, safe_strerror(errno));
return ret;
}
return 0;
if (ifp->flags & IFF_POINTOPOINT)
prefixlen = IPV6_MAX_BITLEN;
else
- zlog_warn("SIOCGLIFSUBNET (%s) fail: %s",
- ifp->name, safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "SIOCGLIFSUBNET (%s) fail: %s",
+ ifp->name, safe_strerror(errno));
} else {
prefixlen = lifreq.lifr_addrlen;
}
void interface_list(struct zebra_ns *zns)
{
if (zns->ns_id != NS_DEFAULT) {
- zlog_warn("interface_list: ignore NS %u", zns->ns_id);
+ zlog_debug("interface_list: ignore NS %u", zns->ns_id);
return;
}
interface_list_ioctl(AF_INET);
#include "zebra/zebra_mpls.h"
#include "zebra/kernel_netlink.h"
#include "zebra/if_netlink.h"
+#include "zebra/zebra_errors.h"
extern struct zebra_privs_t zserv_privs;
&& (oifp != ifp)) {
if (ifi_index == IFINDEX_INTERNAL)
flog_err(
- LIB_ERR_INTERFACE,
+ EC_LIB_INTERFACE,
"Netlink is setting interface %s ifindex to reserved internal value %u",
ifp->name, ifi_index);
else {
ifi_index, oifp->name, ifp->name);
if (if_is_up(oifp))
flog_err(
- LIB_ERR_INTERFACE,
+ EC_LIB_INTERFACE,
"interface rename detected on up interface: index %d was renamed from %s to %s, results are uncertain!",
ifi_index, oifp->name, ifp->name);
if_delete_update(oifp);
hw_addr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
if (hw_addr_len > INTERFACE_HWADDR_MAX)
- zlog_warn("Hardware address is too large: %d",
- hw_addr_len);
+ zlog_debug("Hardware address is too large: %d",
+ hw_addr_len);
else {
ifp->hw_addr_len = hw_addr_len;
memcpy(ifp->hw_addr, RTA_DATA(tb[IFLA_ADDRESS]),
vrf = vrf_get((vrf_id_t)ifi->ifi_index,
name); // It would create vrf
if (!vrf) {
- flog_err(LIB_ERR_INTERFACE, "VRF %s id %u not created",
- name, ifi->ifi_index);
+ flog_err(EC_LIB_INTERFACE, "VRF %s id %u not created",
+ name, ifi->ifi_index);
return;
}
/* Enable the created VRF. */
if (!vrf_enable(vrf)) {
- flog_err(LIB_ERR_INTERFACE,
- "Failed to enable VRF %s id %u", name,
- ifi->ifi_index);
+ flog_err(EC_LIB_INTERFACE,
+ "Failed to enable VRF %s id %u", name,
+ ifi->ifi_index);
return;
}
vrf = vrf_lookup_by_id((vrf_id_t)ifi->ifi_index);
if (!vrf) {
- zlog_warn("%s: vrf not found", __func__);
+ flog_warn(EC_ZEBRA_VRF_NOT_FOUND, "%s: vrf not found",
+ __func__);
return;
}
/* The interface should already be known, if not discard. */
ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), ifi->ifi_index);
if (!ifp) {
- zlog_warn("Cannot find bridge IF %s(%u)", name, ifi->ifi_index);
+ zlog_debug("Cannot find bridge IF %s(%u)", name,
+ ifi->ifi_index);
return 0;
}
if (!IS_ZEBRA_IF_VXLAN(ifp))
zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
ifindex_t link_ifindex = IFINDEX_INTERNAL;
+ struct zebra_if *zif;
zns = zebra_ns_lookup(ns_id);
ifi = NLMSG_DATA(h);
if (IS_ZEBRA_IF_VRF(ifp))
SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
- /* Update link. */
- zebra_if_update_link(ifp, link_ifindex, ns_id);
+ /*
+ * Just set the @link/lower-device ifindex. During nldump interfaces are
+ * not ordered in any fashion so we may end up getting upper devices
+ * before lower devices. We will setup the real linkage once the dump
+ * is complete.
+ */
+ zif = (struct zebra_if *)ifp->info;
+ zif->link_ifindex = link_ifindex;
/* Hardware type and address. */
ifp->ll_type = netlink_to_zebra_link_type(ifi->ifi_type);
if (ret < 0)
return ret;
+ /* fixup linkages */
+ zebra_if_update_all_links();
+
/* Get IPv4 address of the interfaces. */
ret = netlink_request_intf_addr(zns, AF_INET, RTM_GETADDR, 0);
if (ret < 0)
ifa = NLMSG_DATA(h);
if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6) {
- zlog_warn(
- "Invalid address family: %u received from kernel interface addr change: %u",
- ifa->ifa_family, h->nlmsg_type);
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_FAMILY,
+ "Invalid address family: %u received from kernel interface addr change: %s",
+ ifa->ifa_family, nl_msg_type_to_str(h->nlmsg_type));
return 0;
}
ifp = if_lookup_by_index_per_ns(zns, ifa->ifa_index);
if (ifp == NULL) {
flog_err(
- LIB_ERR_INTERFACE,
+ EC_LIB_INTERFACE,
"netlink_interface_addr can't find interface by index %d",
ifa->ifa_index);
return -1;
if (ifa->ifa_family == AF_INET) {
if (ifa->ifa_prefixlen > IPV4_MAX_BITLEN) {
zlog_err(
- "Invalid prefix length: %u received from kernel interface addr change: %u",
- ifa->ifa_prefixlen, h->nlmsg_type);
+ "Invalid prefix length: %u received from kernel interface addr change: %s",
+ ifa->ifa_prefixlen,
+ nl_msg_type_to_str(h->nlmsg_type));
return -1;
}
if (h->nlmsg_type == RTM_NEWADDR)
if (ifa->ifa_family == AF_INET6) {
if (ifa->ifa_prefixlen > IPV6_MAX_BITLEN) {
zlog_err(
- "Invalid prefix length: %u received from kernel interface addr change: %u",
- ifa->ifa_prefixlen, h->nlmsg_type);
+ "Invalid prefix length: %u received from kernel interface addr change: %s",
+ ifa->ifa_prefixlen,
+ nl_msg_type_to_str(h->nlmsg_type));
return -1;
}
if (h->nlmsg_type == RTM_NEWADDR) {
return 0;
}
-/* helper function called by if_netlink_change
- * to delete interfaces in case the interface moved
- * to an other netns
- */
-static void if_netlink_check_ifp_instance_consistency(uint16_t cmd,
- struct interface *ifp,
- ns_id_t ns_id)
-{
- struct interface *other_ifp;
-
- /*
- * look if interface name is also found on other netns
- * - only if vrf backend is netns
- * - do not concern lo interface
- * - then remove previous one
- * - for new link case, check found interface is not active
- */
- if (!vrf_is_backend_netns() ||
- !strcmp(ifp->name, "lo"))
- return;
- other_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name);
- if (!other_ifp)
- return;
- /* because previous interface may be inactive,
- * interface is moved back to default vrf
- * then one may find the same pointer; ignore
- */
- if (other_ifp == ifp)
- return;
- if ((cmd == RTM_NEWLINK)
- && (CHECK_FLAG(other_ifp->status, ZEBRA_INTERFACE_ACTIVE)))
- return;
- if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_NEWLINK) {
- zlog_debug("RTM_NEWLINK %s(%u, VRF %u) replaces %s(%u, VRF %u)\n",
- ifp->name,
- ifp->ifindex,
- ifp->vrf_id,
- other_ifp->name,
- other_ifp->ifindex,
- other_ifp->vrf_id);
- } else if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_DELLINK) {
- zlog_debug("RTM_DELLINK %s(%u, VRF %u) is replaced by %s(%u, VRF %u)\n",
- ifp->name,
- ifp->ifindex,
- ifp->vrf_id,
- other_ifp->name,
- other_ifp->ifindex,
- other_ifp->vrf_id);
- }
- /* the found interface replaces the current one
- * remove it
- */
- if (cmd == RTM_DELLINK)
- if_delete(ifp);
- else
- if_delete(other_ifp);
- /* the found interface is replaced by the current one
- * suppress it
- */
-}
-
int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
{
int len;
/* assume if not default zns, then new VRF */
if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) {
/* If this is not link add/delete message so print warning. */
- zlog_warn("netlink_link_change: wrong kernel message %d",
- h->nlmsg_type);
+ zlog_debug("netlink_link_change: wrong kernel message %s",
+ nl_msg_type_to_str(h->nlmsg_type));
return 0;
}
if (!(ifi->ifi_family == AF_UNSPEC || ifi->ifi_family == AF_BRIDGE
|| ifi->ifi_family == AF_INET6)) {
- zlog_warn(
- "Invalid address family: %u received from kernel link change: %u",
- ifi->ifi_family, h->nlmsg_type);
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_FAMILY,
+ "Invalid address family: %u received from kernel link change: %s",
+ ifi->ifi_family, nl_msg_type_to_str(h->nlmsg_type));
return 0;
}
set_ifindex(ifp, ifi->ifi_index, zns);
ifp->flags = ifi->ifi_flags & 0x0000fffff;
if (!tb[IFLA_MTU]) {
- zlog_warn(
+ zlog_debug(
"RTM_NEWLINK for interface %s(%u) without MTU set",
name, ifi->ifi_index);
return 0;
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);
- if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
- ifp, ns_id);
} else if (ifp->vrf_id != vrf_id) {
/* VRF change for an interface. */
if (IS_ZEBRA_DEBUG_KERNEL)
set_ifindex(ifp, ifi->ifi_index, zns);
if (!tb[IFLA_MTU]) {
- zlog_warn(
+ zlog_debug(
"RTM_NEWLINK for interface %s(%u) without MTU set",
name, ifi->ifi_index);
return 0;
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);
- if_netlink_check_ifp_instance_consistency(RTM_NEWLINK,
- ifp, ns_id);
}
} else {
/* Delete interface notification from kernel */
if (ifp == NULL) {
- zlog_warn("RTM_DELLINK for unknown interface %s(%u)",
- name, ifi->ifi_index);
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_DELLINK for unknown interface %s(%u)",
+ name, ifi->ifi_index);
return 0;
}
if (!IS_ZEBRA_IF_VRF(ifp))
if_delete_update(ifp);
- if_netlink_check_ifp_instance_consistency(RTM_DELLINK,
- ifp, ns_id);
}
return 0;
#include "zebra/rt.h"
#include "zebra/kernel_socket.h"
#include "zebra/rib.h"
+#include "zebra/zebra_errors.h"
void ifstat_update_sysctl(void)
{
/* Query buffer size. */
if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) {
- zlog_warn("sysctl() error by %s", safe_strerror(errno));
+ flog_warn(EC_ZEBRA_SYSCTL_FAILED, "sysctl() error by %s",
+ safe_strerror(errno));
return;
}
/* Fetch interface informations into allocated buffer. */
if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) {
- zlog_warn("sysctl error by %s", safe_strerror(errno));
+ flog_warn(EC_ZEBRA_SYSCTL_FAILED, "sysctl error by %s",
+ safe_strerror(errno));
XFREE(MTYPE_TMP, ref);
return;
}
NET_RT_IFLIST, 0};
if (zns->ns_id != NS_DEFAULT) {
- zlog_warn("interface_list: ignore NS %u", zns->ns_id);
+ zlog_debug("interface_list: ignore NS %u", zns->ns_id);
return;
}
/* Query buffer size. */
if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) {
- zlog_warn("sysctl() error by %s", safe_strerror(errno));
+ flog_err_sys(EC_ZEBRA_IFLIST_FAILED,
+ "Could not enumerate interfaces: %s",
+ safe_strerror(errno));
return;
}
/* Fetch interface informations into allocated buffer. */
if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) {
- zlog_warn("sysctl error by %s", safe_strerror(errno));
+ flog_err_sys(EC_ZEBRA_IFLIST_FAILED,
+ "Could not enumerate interfaces: %s",
+ safe_strerror(errno));
return;
}
#include "zebra/rt_netlink.h"
#include "zebra/interface.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_errors.h"
#define ZEBRA_PTM_SUPPORT
if (rn->info) {
ifp = (struct interface *)rn->info;
route_unlock_node(rn); /* get */
- ifp->node = rn;
return ifp;
}
return NULL;
}
-/* this function must be used only if the vrf backend
- * is a netns backend
- */
-struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id,
- const char *ifname)
-{
- struct interface *ifp;
- struct ns *ns;
-
- RB_FOREACH (ns, ns_head, &ns_tree) {
- if (ns->ns_id == ns_id)
- continue;
- /* if_delete_update has removed interface
- * from zns->if_table
- * so to look for interface, use the vrf list
- */
- ifp = if_lookup_by_name(ifname, (vrf_id_t)ns->ns_id);
- if (!ifp)
- continue;
- return ifp;
- }
- return NULL;
-}
-
const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
{
struct interface *ifp;
/* Get address derived subnet node. */
rn = route_node_lookup(zebra_if->ipv4_subnets, &cp);
if (!(rn && rn->info)) {
- zlog_warn(
- "Trying to remove an address from an unknown subnet."
- " (please report this bug)");
+ flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET,
+ "Trying to remove an address from an unknown subnet."
+ " (please report this bug)");
return -1;
}
route_unlock_node(rn);
* In any case, we shouldn't decrement the lock counter if the address
* is unknown. */
if (!listnode_lookup(addr_list, ifc)) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_REMOVE_UNREGISTERED_ADDR,
"Trying to remove an address from a subnet where it is not"
" currently registered. (please report this bug)");
return -1;
ret = if_set_prefix(ifp, ifc);
if (ret < 0) {
- zlog_warn(
+ flog_err_sys(
+ EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
"Can't set interface's address: %s",
safe_strerror(errno));
continue;
ret = if_prefix_add_ipv6(ifp, ifc);
if (ret < 0) {
- zlog_warn(
+ flog_err_sys(
+ EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
"Can't set interface's address: %s",
safe_strerror(errno));
continue;
if (if_is_up(ifp)) {
flog_err(
- LIB_ERR_INTERFACE,
+ EC_LIB_INTERFACE,
"interface %s vrf %u index %d is still up while being deleted.",
ifp->name, ifp->vrf_id, ifp->ifindex);
return;
ifp->node = NULL;
/* if the ifp is in a vrf, move it to default so vrf can be deleted if
- * desired */
- if (ifp->vrf_id)
+ * desired. This operation is not done for netns implementation to avoid
+ * collision with interface with the same name in the default vrf (can
+ * occur with this implementation whereas it is not possible with
+ * vrf-lite).
+ */
+ if (ifp->vrf_id && !vrf_is_backend_netns())
if_handle_vrf_change(ifp, VRF_DEFAULT);
/* Reset some zebra interface params to default values. */
/* Notify the protocol daemons. */
if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
- zlog_warn("%s: interface %s hasn't passed ptm check\n",
+ flog_warn(EC_ZEBRA_PTM_NOT_READY,
+ "%s: interface %s hasn't passed ptm check\n",
__func__, ifp->name);
return;
}
link_ifindex);
}
+/*
+ * during initial link dump kernel does not order lower devices before
+ * upper devices so we need to fixup link dependencies at the end of dump
+ */
+void zebra_if_update_all_links(void)
+{
+ struct route_node *rn;
+ struct interface *ifp;
+ struct zebra_if *zif;
+ struct zebra_ns *ns;
+
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_info("fixup link dependencies");
+
+ ns = zebra_ns_lookup(NS_DEFAULT);
+ for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) {
+ ifp = (struct interface *)rn->info;
+ if (!ifp)
+ continue;
+ zif = ifp->info;
+ if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
+ zif->link = if_lookup_by_index_per_ns(ns,
+ zif->link_ifindex);
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("interface %s/%d's lower fixup to %s/%d",
+ ifp->name, ifp->ifindex,
+ zif->link?zif->link->name:"unk",
+ zif->link_ifindex);
+ }
+ }
+}
+
+
/* Output prefix string to vty. */
static int prefix_vty_out(struct vty *vty, struct prefix *p)
static int if_config_write(struct vty *vty)
{
- struct vrf *vrf;
+ struct vrf *vrf0;
struct interface *ifp;
zebra_ptm_write(vty);
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
- FOR_ALL_INTERFACES (vrf, ifp) {
+ RB_FOREACH (vrf0, vrf_name_head, &vrfs_by_name)
+ FOR_ALL_INTERFACES (vrf0, ifp) {
struct zebra_if *if_data;
struct listnode *addrnode;
struct connected *ifc;
extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t);
extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *,
const char *);
-extern struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id,
- const char *ifname);
extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *);
extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int);
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,
ns_id_t ns_id);
+extern void zebra_if_update_all_links(void);
extern void vrf_add_update(struct vrf *vrfp);
#include "zebra/rib.h"
#include "zebra/rt.h"
#include "zebra/interface.h"
+#include "zebra/zebra_errors.h"
#ifndef SUNOS_5
ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"vrf_if_ioctl(SIOCGIFFLAGS) failed: %s",
safe_strerror(errno));
return;
/* Seems not all interfaces implement this ioctl */
if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"if_ioctl(SIOCGIFMEDIA) failed: %s",
safe_strerror(errno));
else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
#include "zebra/rt.h"
#include "zebra/interface.h"
#include "zebra/ioctl_solaris.h"
+#include "zebra/zebra_errors.h"
extern struct zebra_privs_t zserv_privs;
{
char addrbuf[PREFIX_STRLEN];
- zlog_warn("Can't set %s on interface %s",
+ flog_warn(EC_LIB_DEVELOPMENT, "Can't set %s on interface %s",
prefix2str(ifc->address, addrbuf, sizeof(addrbuf)),
ifp->name);
{
char addrbuf[PREFIX_STRLEN];
- zlog_warn("Can't delete %s on interface %s",
+ flog_warn(EC_LIB_DEVELOPMENT, "Can't delete %s on interface %s",
prefix2str(ifc->address, addrbuf, sizeof(addrbuf)),
ifp->name);
#include "log.h"
#include "privs.h"
-#include "lib_errors.h"
#include "zebra/ipforward.h"
#include "privs.h"
#include "zebra/ipforward.h"
+#include "zebra/zebra_errors.h"
/*
** Solaris should define IP_DEV_NAME in <inet/ip.h>, but we'll save
else if (cmd == ND_GET)
snprintf(nd_buf, ND_BUFFER_SIZE, "%s", parameter);
else {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"internal error - inappropriate command given to "
"solaris_nd()%s:%d",
__FILE__, __LINE__);
frr_elevate_privs(&zserv_privs) {
if ((fd = open(device, O_RDWR)) < 0) {
- zlog_warn("failed to open device %s - %s", device,
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "failed to open device %s - %s", device,
+ safe_strerror(errno));
return -1;
}
if (ioctl(fd, I_STR, &strioctl) < 0) {
close(fd);
- zlog_warn("ioctl I_STR failed on device %s - %s",
- device,
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "ioctl I_STR failed on device %s - %s",
+ device, safe_strerror(errno));
return -1;
}
close(fd);
errno = 0;
retval = atoi(nd_buf);
if (errno) {
- zlog_warn(
+ zlog_debug(
"failed to convert returned value to integer - %s",
safe_strerror(errno));
retval = -1;
#include "privs.h"
#include "zebra/ipforward.h"
+#include "zebra/zebra_errors.h"
#include "log.h"
#include "lib_errors.h"
len = sizeof ipforwarding;
if (sysctl(mib, MIB_SIZ, &ipforwarding, &len, 0, 0) < 0) {
- zlog_warn("Can't get ipforwarding value");
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "Can't get ipforwarding value");
return -1;
}
return ipforwarding;
len = sizeof ipforwarding;
frr_elevate_privs(&zserv_privs) {
if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) {
- zlog_warn("Can't set ipforwarding on");
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "Can't set ipforwarding on");
return -1;
}
}
len = sizeof ipforwarding;
frr_elevate_privs(&zserv_privs) {
if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) {
- zlog_warn("Can't set ipforwarding on");
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "Can't set ipforwarding on");
return -1;
}
}
len = sizeof ip6forwarding;
frr_elevate_privs(&zserv_privs) {
if (sysctl(mib_ipv6, MIB_SIZ, &ip6forwarding, &len, 0, 0) < 0) {
- zlog_warn("can't get ip6forwarding value");
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "can't get ip6forwarding value");
return -1;
}
}
frr_elevate_privs(&zserv_privs) {
if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len)
< 0) {
- zlog_warn("can't get ip6forwarding value");
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "can't get ip6forwarding value");
return -1;
}
}
frr_elevate_privs(&zserv_privs) {
if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len)
< 0) {
- zlog_warn("can't get ip6forwarding value");
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "can't get ip6forwarding value");
return -1;
}
}
#include "log.h"
#include "zclient.h"
#include "thread.h"
+#include "lib_errors.h"
#include "zebra/interface.h"
#include "zebra/rtadv.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
#include "zebra/redistribute.h"
#include "zebra/irdp.h"
+#include "zebra/zebra_errors.h"
#include <netinet/ip_icmp.h>
#include "if.h"
#include "sockunion.h"
p = irdp_get_prefix(ifp);
if (!p) {
- zlog_warn("IRDP: can't get address for %s", ifp->name);
+ flog_warn(EC_ZEBRA_NO_IFACE_ADDR,
+ "IRDP: can't get address for %s", ifp->name);
return 1;
}
ret = setsockopt(sock, IPPROTO_IP, add_leave, (char *)&m,
sizeof(struct ip_mreq));
if (ret < 0)
- zlog_warn("IRDP: %s can't setsockopt %s: %s",
- add_leave == IP_ADD_MEMBERSHIP ? "join group"
- : "leave group",
- inet_2a(group, b1), safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "IRDP: %s can't setsockopt %s: %s",
+ add_leave == IP_ADD_MEMBERSHIP ? "join group"
+ : "leave group",
+ inet_2a(group, b1), safe_strerror(errno));
return ret;
}
irdp->started = true;
if (irdp->flags & IF_ACTIVE) {
- zlog_warn("IRDP: Interface is already active %s", ifp->name);
+ zlog_debug("IRDP: Interface is already active %s", ifp->name);
return;
}
if ((irdp_sock < 0) && ((irdp_sock = irdp_sock_init()) < 0)) {
- zlog_warn(
- "IRDP: Cannot activate interface %s (cannot create "
- "IRDP socket)",
- ifp->name);
+ flog_warn(EC_ZEBRA_IRDP_CANNOT_ACTIVATE_IFACE,
+ "IRDP: Cannot activate interface %s (cannot create "
+ "IRDP socket)",
+ ifp->name);
return;
}
irdp->flags |= IF_ACTIVE;
if_add_update(ifp);
if (!(ifp->flags & IFF_UP)) {
- zlog_warn("IRDP: Interface is down %s", ifp->name);
+ flog_warn(EC_ZEBRA_IRDP_IFACE_DOWN,
+ "IRDP: Interface is down %s", ifp->name);
}
/* Shall we cancel if_start if if_add_group fails? */
if_add_group(ifp);
if (!(ifp->flags & (IFF_MULTICAST | IFF_ALLMULTI))) {
- zlog_warn("IRDP: Interface not multicast enabled %s",
+ flog_warn(EC_ZEBRA_IRDP_IFACE_MCAST_DISABLED,
+ "IRDP: Interface not multicast enabled %s",
ifp->name);
}
}
struct irdp_interface *irdp = zi->irdp;
if (irdp == NULL) {
- zlog_warn("Interface %s structure is NULL", ifp->name);
+ zlog_debug("Interface %s structure is NULL", ifp->name);
return;
}
if (!(irdp->flags & IF_ACTIVE)) {
- zlog_warn("Interface is not active %s", ifp->name);
+ zlog_debug("Interface is not active %s", ifp->name);
return;
}
return;
if (irdp->flags & IF_SHUTDOWN) {
- zlog_warn("IRDP: Interface is already shutdown %s", ifp->name);
+ zlog_debug("IRDP: Interface is already shutdown %s", ifp->name);
return;
}
return;
if (!(irdp->flags & IF_SHUTDOWN)) {
- zlog_warn("IRDP: Interface is not shutdown %s", ifp->name);
+ zlog_debug("IRDP: Interface is not shutdown %s", ifp->name);
return;
}
#include "zebra/zserv.h"
#include "zebra/redistribute.h"
#include "zebra/irdp.h"
+#include "zebra/zebra_errors.h"
#include <netinet/ip_icmp.h>
#include "checksum.h"
}
if (sock < 0) {
- zlog_warn("IRDP: can't create irdp socket %s",
- safe_strerror(save_errno));
+ flog_err_sys(EC_LIB_SOCKET, "IRDP: can't create irdp socket %s",
+ safe_strerror(save_errno));
return sock;
};
i = 1;
ret = setsockopt(sock, IPPROTO_IP, IP_TTL, (void *)&i, sizeof(i));
if (ret < 0) {
- zlog_warn("IRDP: can't do irdp sockopt %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "IRDP: can't do irdp sockopt %s",
+ safe_strerror(errno));
close(sock);
return ret;
};
ret = setsockopt_ifindex(AF_INET, sock, 1);
if (ret < 0) {
- zlog_warn("IRDP: can't do irdp sockopt %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "IRDP: can't do irdp sockopt %s",
+ safe_strerror(errno));
close(sock);
return ret;
};
#include "thread.h"
#include "vty.h"
#include "zclient.h"
+#include "lib_errors.h"
#include "zebra_memory.h"
#include "zebra/interface.h"
src = ip->ip_src;
if (len != iplen) {
- flog_err(ZEBRA_ERR_IRDP_LEN_MISMATCH,
- "IRDP: RX length doesnt match IP length");
+ flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH,
+ "IRDP: RX length doesnt match IP length");
return;
}
if (iplen < ICMP_MINLEN) {
- flog_err(ZEBRA_ERR_IRDP_LEN_MISMATCH,
- "IRDP: RX ICMP packet too short from %s\n",
- inet_ntoa(src));
+ flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH,
+ "IRDP: RX ICMP packet too short from %s\n",
+ inet_ntoa(src));
return;
}
+
len of IP-header) 14+20 */
if (iplen > IRDP_RX_BUF - 34) {
- flog_err(ZEBRA_ERR_IRDP_LEN_MISMATCH,
- "IRDP: RX ICMP packet too long from %s\n",
- inet_ntoa(src));
+ flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH,
+ "IRDP: RX ICMP packet too long from %s\n",
+ inet_ntoa(src));
return;
}
/* check icmp checksum */
if (in_cksum(icmp, datalen) != icmp->checksum) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_IRDP_BAD_CHECKSUM,
"IRDP: RX ICMP packet from %s. Bad checksum, silently ignored",
inet_ntoa(src));
return;
return;
if (icmp->code != 0) {
- zlog_warn(
- "IRDP: RX packet type %d from %s. Bad ICMP type code,"
- " silently ignored",
- icmp->type, inet_ntoa(src));
+ flog_warn(EC_ZEBRA_IRDP_BAD_TYPE_CODE,
+ "IRDP: RX packet type %d from %s. Bad ICMP type code,"
+ " silently ignored",
+ icmp->type, inet_ntoa(src));
return;
}
&& (irdp->flags & IF_BROADCAST))
|| (ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP
&& !(irdp->flags & IF_BROADCAST))) {
- zlog_warn(
- "IRDP: RX illegal from %s to %s while %s operates in %s\n",
+ flog_warn(
+ EC_ZEBRA_IRDP_BAD_RX_FLAGS,
+ "IRDP: RX illegal from %s to %s while %s operates in %s; Please correct settings\n",
inet_ntoa(src),
ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP
? "multicast"
: inet_ntoa(ip->ip_dst),
ifp->name,
irdp->flags & IF_BROADCAST ? "broadcast" : "multicast");
-
- zlog_warn("IRDP: Please correct settings\n");
return;
}
break;
default:
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_IRDP_BAD_TYPE,
"IRDP: RX type %d from %s. Bad ICMP type, silently ignored",
icmp->type, inet_ntoa(src));
}
ret = recvmsg(sock, &msg, 0);
if (ret < 0) {
- zlog_warn("IRDP: recvmsg: read error %s", safe_strerror(errno));
+ flog_warn(EC_LIB_SOCKET, "IRDP: recvmsg: read error %s",
+ safe_strerror(errno));
return ret;
}
if (msg.msg_flags & MSG_TRUNC) {
- zlog_warn("IRDP: recvmsg: truncated message");
+ flog_warn(EC_LIB_SOCKET, "IRDP: recvmsg: truncated message");
return ret;
}
if (msg.msg_flags & MSG_CTRUNC) {
- zlog_warn("IRDP: recvmsg: truncated control message");
+ flog_warn(EC_LIB_SOCKET,
+ "IRDP: recvmsg: truncated control message");
return ret;
}
ret = irdp_recvmsg(irdp_sock, (uint8_t *)buf, IRDP_RX_BUF, &ifindex);
if (ret < 0)
- zlog_warn("IRDP: RX Error length = %d", ret);
+ flog_warn(EC_LIB_SOCKET, "IRDP: RX Error length = %d", ret);
ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
if (!ifp)
if (setsockopt(irdp_sock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
sizeof(on))
< 0)
- zlog_warn("sendto %s", safe_strerror(errno));
+ zlog_debug("sendto %s", safe_strerror(errno));
if (dst == INADDR_BROADCAST) {
if (setsockopt(irdp_sock, SOL_SOCKET, SO_BROADCAST, (char *)&on,
sizeof(on))
< 0)
- zlog_warn("sendto %s", safe_strerror(errno));
+ zlog_debug("sendto %s", safe_strerror(errno));
}
if (dst != INADDR_BROADCAST)
sockopt_iphdrincl_swab_htosys(ip);
if (sendmsg(irdp_sock, msg, 0) < 0) {
- zlog_warn("sendto %s", safe_strerror(errno));
+ zlog_debug("sendto %s", safe_strerror(errno));
}
/* printf("TX on %s idx %d\n", ifp->name, ifp->ifindex); */
}
ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"Can't get %s receive buffer size: %s", nl->name,
safe_strerror(errno));
return -1;
ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF,
&nl_rcvbufsize, sizeof(nl_rcvbufsize));
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"Can't set %s receive buffer size: %s", nl->name,
safe_strerror(errno));
return -1;
ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"Can't get %s receive buffer size: %s", nl->name,
safe_strerror(errno));
return -1;
namelen = sizeof snl;
ret = getsockname(sock, (struct sockaddr *)&snl, (socklen_t *)&namelen);
if (ret < 0 || namelen != sizeof snl) {
- flog_err_sys(LIB_ERR_SOCKET, "Can't get %s socket name: %s",
+ flog_err_sys(EC_LIB_SOCKET, "Can't get %s socket name: %s",
nl->name, safe_strerror(errno));
close(sock);
return -1;
* this message type or not ask for
* it to be sent up to us
*/
- flog_err(ZEBRA_ERR_UNKNOWN_NLMSG,
- "Unknown netlink nlmsg_type %s(%d) vrf %u\n",
- nl_msg_type_to_str(h->nlmsg_type), h->nlmsg_type,
- ns_id);
+ flog_err(EC_ZEBRA_UNKNOWN_NLMSG,
+ "Unknown netlink nlmsg_type %s(%d) vrf %u\n",
+ nl_msg_type_to_str(h->nlmsg_type), h->nlmsg_type,
+ ns_id);
break;
}
return 0;
if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog))
< 0)
- zlog_warn("Can't install socket filter: %s\n",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "Can't install socket filter: %s\n",
+ safe_strerror(errno));
}
void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta,
* but noticing it for later.
*/
err_nlh = &err->msg;
- zlog_warn("%s: Received %d extended Ack",
- __PRETTY_FUNCTION__, err_nlh->nlmsg_type);
+ zlog_debug("%s: Received %s extended Ack",
+ __PRETTY_FUNCTION__,
+ nl_msg_type_to_str(err_nlh->nlmsg_type));
}
}
if (is_err)
zlog_err("Extended Error: %s", msg);
else
- zlog_warn("Extended Warning: %s", msg);
+ flog_warn(EC_ZEBRA_NETLINK_EXTENDED_WARNING,
+ "Extended Warning: %s", msg);
}
}
continue;
if (errno == EWOULDBLOCK || errno == EAGAIN)
break;
- flog_err(ZEBRA_ERR_RECVMSG_OVERRUN,
- "%s recvmsg overrun: %s", nl->name,
- safe_strerror(errno));
+ flog_err(EC_ZEBRA_RECVMSG_OVERRUN,
+ "%s recvmsg overrun: %s", nl->name,
+ safe_strerror(errno));
/*
* In this case we are screwed.
* There is no good way to
}
if (status == 0) {
- flog_err_sys(LIB_ERR_SOCKET, "%s EOF", nl->name);
+ flog_err_sys(EC_LIB_SOCKET, "%s EOF", nl->name);
return -1;
}
if (msg.msg_namelen != sizeof snl) {
- flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR,
- "%s sender address length error: length %d",
- nl->name, msg.msg_namelen);
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "%s sender address length error: length %d",
+ nl->name, msg.msg_namelen);
return -1;
}
if (h->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- flog_err(
- ZEBRA_ERR_NETLINK_LENGTH_ERROR,
- "%s error: message truncated",
- nl->name);
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "%s error: message truncated",
+ nl->name);
return -1;
}
err->msg.nlmsg_pid);
} else
flog_err(
- ZEBRA_ERR_UNEXPECTED_MESSAGE,
+ EC_ZEBRA_UNEXPECTED_MESSAGE,
"%s error: %s, type=%s(%u), seq=%u, pid=%u",
nl->name,
safe_strerror(-errnum),
error = (*filter)(h, zns->ns_id, startup);
if (error < 0) {
- zlog_warn("%s filter function error", nl->name);
+ zlog_debug("%s filter function error",
+ nl->name);
ret = error;
}
}
/* After error care. */
if (msg.msg_flags & MSG_TRUNC) {
- flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR,
- "%s error: message truncated", nl->name);
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "%s error: message truncated", nl->name);
continue;
}
if (status) {
- flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR,
- "%s error: data remnant size %d", nl->name,
- status);
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "%s error: data remnant size %d", nl->name,
+ status);
return -1;
}
}
}
if (status < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "netlink_talk sendmsg() error: %s",
+ flog_err_sys(EC_LIB_SOCKET, "netlink_talk sendmsg() error: %s",
safe_strerror(save_errno));
return -1;
}
/* Check netlink socket. */
if (nl->sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "%s socket isn't active.",
+ flog_err_sys(EC_LIB_SOCKET, "%s socket isn't active.",
nl->name);
return -1;
}
/* Register kernel socket. */
if (fcntl(zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
- flog_err_sys(LIB_ERR_SOCKET, "Can't set %s socket flags: %s",
+ flog_err_sys(EC_LIB_SOCKET, "Can't set %s socket flags: %s",
zns->netlink.name, safe_strerror(errno));
if (fcntl(zns->netlink_cmd.sock, F_SETFL, O_NONBLOCK) < 0)
/* paranoia: sanity check structure */
if (ifm->ifm_msglen < sizeof(struct if_msghdr)) {
- flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR,
- "ifm_read: ifm->ifm_msglen %d too short\n",
- ifm->ifm_msglen);
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "ifm_read: ifm->ifm_msglen %d too short\n",
+ ifm->ifm_msglen);
return -1;
}
* RTA_IFP) is required.
*/
if (!ifnlen) {
- zlog_warn("Interface index %d (new) missing ifname\n",
- ifm->ifm_index);
+ zlog_debug("Interface index %d (new) missing ifname\n",
+ ifm->ifm_index);
return -1;
}
*/
{
if (ifp->ifindex != ifm->ifm_index) {
- zlog_warn(
+ zlog_debug(
"%s: index mismatch, ifname %s, ifp index %d, "
"ifm index %d",
__func__, ifp->name, ifp->ifindex,
/* Assert read up end point matches to end point */
if (pnt != end)
- zlog_warn("ifam_read() doesn't read all socket data");
+ zlog_debug("ifam_read() doesn't read all socket data");
}
/* Interface's address information get. */
ifam_read_mesg(ifam, &addr, &mask, &brd, ifname, &ifnlen);
if ((ifp = if_lookup_by_index(ifam->ifam_index, VRF_DEFAULT)) == NULL) {
- zlog_warn("%s: no interface for ifname %s, index %d", __func__,
+ flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
+ "%s: no interface for ifname %s, index %d", __func__,
ifname, ifam->ifam_index);
return -1;
}
/* rt_msghdr version check. */
if (rtm->rtm_version != RTM_VERSION)
- zlog_warn(
- "Routing message version different %d should be %d."
- "This may cause problem\n",
- rtm->rtm_version, RTM_VERSION);
+ flog_warn(EC_ZEBRA_RTM_VERSION_MISMATCH,
+ "Routing message version different %d should be %d."
+ "This may cause problem\n",
+ rtm->rtm_version, RTM_VERSION);
/* Be sure structure is cleared */
memset(dest, 0, sizeof(union sockunion));
/* Assert read up to the end of pointer. */
if (pnt != end)
- zlog_warn("rtm_read() doesn't read all socket data.");
+ zlog_debug("rtm_read() doesn't read all socket data.");
return rtm->rtm_flags;
}
if (mask)
inet_ntop(AF_INET, &mask->sin.sin_addr,
mask_buf, INET_ADDRSTRLEN);
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_RTM_NO_GATEWAY,
"%s: %s/%s: gate == NULL and no gateway found for ifindex %d",
__func__, dest_buf, mask_buf, index);
return -1;
if (errno == ESRCH)
return ZEBRA_ERR_RTNOEXIST;
- zlog_warn("%s: write : %s (%d)", __func__, safe_strerror(errno),
- errno);
+ flog_err_sys(EC_LIB_SOCKET, "%s: write : %s (%d)", __func__,
+ safe_strerror(errno), errno);
return ZEBRA_ERR_KERNEL;
}
return ZEBRA_ERR_NOERROR;
if (nbytes <= 0) {
if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
- zlog_warn("routing socket error: %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s",
+ safe_strerror(errno));
return 0;
}
* can assume they have the whole message.
*/
if (rtm->rtm_msglen != nbytes) {
- zlog_warn(
+ zlog_debug(
"kernel_read: rtm->rtm_msglen %d, nbytes %d, type %d\n",
rtm->rtm_msglen, nbytes, rtm->rtm_type);
return -1;
}
if (routing_sock < 0) {
- zlog_warn("Can't init kernel routing socket");
+ flog_err_sys(EC_LIB_SOCKET, "Can't init kernel routing socket");
return;
}
ret = zclient_read_header(src, zclient->sock, &size, &marker, &version,
&vrf_id, &resp_cmd);
if (ret < 0 && errno != EAGAIN) {
- flog_err(ZEBRA_ERR_LM_RESPONSE,
- "Error reading Label Manager response: %s",
- strerror(errno));
+ flog_err(EC_ZEBRA_LM_RESPONSE,
+ "Error reading Label Manager response: %s",
+ strerror(errno));
return -1;
}
- zlog_debug("Label Manager response received, %d bytes", size);
+
+ /* do not relay a msg that has nothing to do with LM */
+ switch (resp_cmd) {
+ case ZEBRA_LABEL_MANAGER_CONNECT:
+ case ZEBRA_LABEL_MANAGER_CONNECT_ASYNC: /* should not be seen */
+ case ZEBRA_GET_LABEL_CHUNK:
+ case ZEBRA_RELEASE_LABEL_CHUNK:
+ break;
+ default:
+ zlog_debug("Not relaying '%s' response (size %d) from LM",
+ zserv_command_string(resp_cmd), size);
+ return -1;
+ }
+
+ zlog_debug("Received '%s' response (size %d) from LM",
+ zserv_command_string(resp_cmd), size);
+
if (size == 0)
return -1;
zserv = zserv_find_client(proto, instance);
if (!zserv) {
flog_err(
- ZEBRA_ERR_LM_NO_SUCH_CLIENT,
+ EC_ZEBRA_LM_NO_SUCH_CLIENT,
"Error relaying LM response: can't find client %s, instance %u",
proto_str, instance);
return -1;
/* send response back */
ret = writen(zserv->sock, dst->data, stream_get_endp(dst));
if (ret <= 0) {
- flog_err(ZEBRA_ERR_LM_RELAY_FAILED,
- "Error relaying LM response to %s instance %u: %s",
- proto_str, instance, strerror(errno));
+ flog_err(EC_ZEBRA_LM_RELAY_FAILED,
+ "Error relaying LM response to %s instance %u: %s",
+ proto_str, instance, strerror(errno));
return -1;
}
zlog_debug("Relayed LM response (%d bytes) to %s instance %u", ret,
/* read response and send it back */
ret = relay_response_back();
+ /* on error, schedule another read */
+ if (ret == -1)
+ if (!zclient->t_read)
+ thread_add_read(zclient->master, lm_zclient_read, NULL,
+ zclient->sock, &zclient->t_read);
return ret;
}
unsigned short instance;
if (zclient->sock < 0) {
- flog_err(ZEBRA_ERR_LM_NO_SOCKET,
- "Unable to relay LM request: no socket");
+ flog_err(EC_ZEBRA_LM_NO_SOCKET,
+ "Unable to relay LM request: no socket");
reply_error(cmd, zserv, vrf_id);
return -1;
}
/* check & set client proto if unset */
if (zserv->proto && zserv->proto != proto) {
- zlog_warn("Client proto(%u) != msg proto(%u)", zserv->proto,
+ flog_warn(EC_ZEBRAING_LM_PROTO_MISMATCH,
+ "Client proto(%u) != msg proto(%u)", zserv->proto,
proto);
return -1;
}
/* check & set client instance if unset */
if (zserv->instance && zserv->instance != instance) {
- flog_err(ZEBRA_ERR_LM_BAD_INSTANCE,
- "Client instance(%u) != msg instance(%u)",
- zserv->instance, instance);
+ flog_err(EC_ZEBRA_LM_BAD_INSTANCE,
+ "Client instance(%u) != msg instance(%u)",
+ zserv->instance, instance);
return -1;
}
zserv->proto = proto;
/* in case there's any incoming message enqueued, read and forward it */
- while (ret == 0)
- ret = relay_response_back();
+ if (zserv->is_synchronous)
+ while (ret == 0)
+ ret = relay_response_back();
/* get the msg buffer used toward the 'master' Label Manager */
dst = zclient->obuf;
/* Send request to external label manager */
ret = writen(zclient->sock, dst->data, stream_get_endp(dst));
if (ret <= 0) {
- flog_err(ZEBRA_ERR_LM_RELAY_FAILED,
- "Error relaying LM request from %s instance %u: %s",
- proto_str, instance, strerror(errno));
+ flog_err(EC_ZEBRA_LM_RELAY_FAILED,
+ "Error relaying LM request from %s instance %u: %s",
+ proto_str, instance, strerror(errno));
reply_error(cmd, zserv, vrf_id);
return -1;
}
return 0;
if (zclient_socket_connect(zclient) < 0) {
- flog_err(ZEBRA_ERR_LM_CLIENT_CONNECTION_FAILED,
- "Error connecting synchronous zclient!");
+ flog_err(EC_ZEBRA_LM_CLIENT_CONNECTION_FAILED,
+ "Error connecting synchronous zclient!");
thread_add_timer(zebrad.master, lm_zclient_connect, zclient,
CONNECTION_DELAY, &zclient->t_connect);
return -1;
}
/* make socket non-blocking */
- if (set_nonblocking(zclient->sock) < 0)
- zlog_warn("%s: set_nonblocking(%d) failed", __func__,
- zclient->sock);
+ (void)set_nonblocking(zclient->sock);
return 0;
}
->end
+ 1;
if (lmc->start > MPLS_LABEL_UNRESERVED_MAX - size + 1) {
- flog_err(ZEBRA_ERR_LM_EXHAUSTED_LABELS,
- "Reached max labels. Start: %u, size: %u", lmc->start,
- size);
+ flog_err(EC_ZEBRA_LM_EXHAUSTED_LABELS,
+ "Reached max labels. Start: %u, size: %u", lmc->start,
+ size);
XFREE(MTYPE_LM_CHUNK, lmc);
return NULL;
}
if (lmc->end != end)
continue;
if (lmc->proto != proto || lmc->instance != instance) {
- flog_err(ZEBRA_ERR_LM_DAEMON_MISMATCH,
- "%s: Daemon mismatch!!", __func__);
+ flog_err(EC_ZEBRA_LM_DAEMON_MISMATCH,
+ "%s: Daemon mismatch!!", __func__);
continue;
}
lmc->proto = NO_PROTO;
break;
}
if (ret != 0)
- flog_err(ZEBRA_ERR_LM_UNRELEASED_CHUNK,
- "%s: Label chunk not released!!", __func__);
+ flog_err(EC_ZEBRA_LM_UNRELEASED_CHUNK,
+ "%s: Label chunk not released!!", __func__);
return ret;
}
if (multipath_num > MULTIPATH_NUM
|| multipath_num <= 0) {
flog_err(
- ZEBRA_ERR_BAD_MULTIPATH_NUM,
+ EC_ZEBRA_BAD_MULTIPATH_NUM,
"Multipath Number specified must be less than %d and greater than 0",
MULTIPATH_NUM);
return 1;
#include "zebra/zapi_msg.h"
#include "zebra/zebra_memory.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_errors.h"
#define ZEBRA_PTM_SUPPORT
afi = family2afi(p->family);
if (!afi) {
- zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
+ flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+ "%s: Unknown AFI/SAFI prefix received\n",
__FUNCTION__);
return;
}
afi = family2afi(p->family);
if (!afi) {
- zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
+ flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+ "%s: Unknown AFI/SAFI prefix received\n",
__FUNCTION__);
return;
}
zebra_route_string(type), zvrf_id(zvrf), instance);
if (afi == 0 || afi >= AFI_MAX) {
- zlog_warn("%s: Specified afi %d does not exist",
+ flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+ "%s: Specified afi %d does not exist",
__PRETTY_FUNCTION__, afi);
return;
}
if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
- zlog_warn("%s: Specified Route Type %d does not exist",
- __PRETTY_FUNCTION__, type);
+ zlog_debug("%s: Specified Route Type %d does not exist",
+ __PRETTY_FUNCTION__, type);
return;
}
STREAM_GETW(msg, instance);
if (afi == 0 || afi >= AFI_MAX) {
- zlog_warn("%s: Specified afi %d does not exist",
+ flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+ "%s: Specified afi %d does not exist",
__PRETTY_FUNCTION__, afi);
return;
}
if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
- zlog_warn("%s: Specified Route Type %d does not exist",
- __PRETTY_FUNCTION__, type);
+ zlog_debug("%s: Specified Route Type %d does not exist",
+ __PRETTY_FUNCTION__, type);
return;
}
}
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
"WARNING: advertising address to clients that is not yet usable.");
zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
struct in_addr *vtep_ip);
extern int kernel_add_mac(struct interface *ifp, vlanid_t vid,
struct ethaddr *mac, struct in_addr vtep_ip,
- uint8_t sticky);
+ bool sticky);
extern int kernel_del_mac(struct interface *ifp, vlanid_t vid,
- struct ethaddr *mac, struct in_addr vtep_ip,
- int local);
+ struct ethaddr *mac, struct in_addr vtep_ip);
extern int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
struct ethaddr *mac, uint8_t flags);
#include "zebra/rt_netlink.h"
#include "zebra/zebra_mroute.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_errors.h"
#ifndef AF_MPLS
#define AF_MPLS 28
|| (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;
}
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
* is intentionally a warn because we should see
* this as part of development of a new protocol
*/
- zlog_warn("%s: Please add this protocol(%d) to proper rt_netlink.c handling",
- __PRETTY_FUNCTION__, proto);
+ zlog_debug(
+ "%s: Please add this protocol(%d) to proper rt_netlink.c handling",
+ __PRETTY_FUNCTION__, proto);
proto = RTPROT_ZEBRA;
break;
}
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
* is intentionally a warn because we should see
* this as part of development of a new protocol
*/
- zlog_warn("%s: Please add this protocol(%d) to proper rt_netlink.c handling",
- __PRETTY_FUNCTION__,
- proto);
+ zlog_debug(
+ "%s: Please add this protocol(%d) to proper rt_netlink.c handling",
+ __PRETTY_FUNCTION__, proto);
proto = ZEBRA_ROUTE_KERNEL;
break;
}
if (rtm->rtm_src_len != 0) {
char buf[PREFIX_STRLEN];
- zlog_warn("unsupported IPv4 sourcedest route (dest %s vrf %u)",
- prefix2str(&p, buf, sizeof(buf)), vrf_id);
+ flog_warn(
+ EC_ZEBRA_UNSUPPORTED_V4_SRCDEST,
+ "unsupported IPv4 sourcedest route (dest %s vrf %u)",
+ prefix2str(&p, buf, sizeof(buf)), vrf_id);
return 0;
}
for (;;) {
struct nexthop *nh = NULL;
- vrf_id_t nh_vrf_id;
+
if (len < (int)sizeof(*rtnh)
|| rtnh->rtnh_len > len)
break;
if (ifp)
nh_vrf_id = ifp->vrf_id;
else {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_INTERFACE,
"%s: Unknown interface %u specified, defaulting to VRF_DEFAULT",
__PRETTY_FUNCTION__,
index);
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)) {
/* If this is not route add/delete message print warning. */
- zlog_warn("Kernel message: %d NS %u\n", h->nlmsg_type, ns_id);
+ zlog_debug("Kernel message: %s NS %u\n",
+ nl_msg_type_to_str(h->nlmsg_type), ns_id);
return 0;
}
- if (!(rtm->rtm_family == AF_INET || rtm->rtm_family == AF_INET6)) {
- zlog_warn(
- "Invalid address family: %u received from kernel route change: %u",
- rtm->rtm_family, h->nlmsg_type);
+ if (!(rtm->rtm_family == AF_INET ||
+ rtm->rtm_family == AF_INET6 ||
+ rtm->rtm_family == RTNL_FAMILY_IPMR )) {
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_FAMILY,
+ "Invalid address family: %u received from kernel route change: %s",
+ rtm->rtm_family, nl_msg_type_to_str(h->nlmsg_type));
return 0;
}
int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
{
+ uint32_t actual_table;
int suc = 0;
struct mcast_route_data *mr = (struct mcast_route_data *)in;
struct {
addattr_l(&req.n, sizeof(req), RTA_OIF, &mroute->ifindex, 4);
addattr_l(&req.n, sizeof(req), RTA_SRC, &mroute->sg.src.s_addr, 4);
addattr_l(&req.n, sizeof(req), RTA_DST, &mroute->sg.grp.s_addr, 4);
- addattr_l(&req.n, sizeof(req), RTA_TABLE, &zvrf->table_id, 4);
+ /*
+ * What?
+ *
+ * So during the namespace cleanup we started storing
+ * the zvrf table_id for the default table as RT_TABLE_MAIN
+ * which is what the normal routing table for ip routing is.
+ * This change caused this to break our lookups of sg data
+ * because prior to this change the zvrf->table_id was 0
+ * and when the pim multicast kernel code saw a 0,
+ * it was auto-translated to RT_TABLE_DEFAULT. But since
+ * we are now passing in RT_TABLE_MAIN there is no auto-translation
+ * and the kernel goes screw you and the delicious cookies you
+ * are trying to give me. So now we have this little hack.
+ */
+ actual_table = (zvrf->table_id == RT_TABLE_MAIN) ? RT_TABLE_DEFAULT :
+ zvrf->table_id;
+ addattr_l(&req.n, sizeof(req), RTA_TABLE, &actual_table, 4);
suc = netlink_talk(netlink_route_change_read_multicast, &req.n,
&zns->netlink_cmd, zns, 0);
char buf[ETHER_ADDR_STRLEN];
char vid_buf[20];
char dst_buf[30];
- uint8_t sticky = 0;
+ bool sticky;
ndm = NLMSG_DATA(h);
zif = (struct zebra_if *)ifp->info;
if ((br_if = zif->brslave_info.br_if) == NULL) {
- zlog_warn("%s family %s IF %s(%u) brIF %u - no bridge master",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
+ zlog_debug("%s family %s IF %s(%u) brIF %u - no bridge master",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
return 0;
}
netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len);
if (!tb[NDA_LLADDR]) {
- zlog_warn("%s family %s IF %s(%u) brIF %u - no LLADDR",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
+ zlog_debug("%s family %s IF %s(%u) brIF %u - no LLADDR",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
return 0;
}
if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) {
- zlog_warn(
+ zlog_debug(
"%s family %s IF %s(%u) brIF %u - LLADDR is not MAC, len %lu",
nl_msg_type_to_str(h->nlmsg_type),
nl_family_to_str(ndm->ndm_family), ifp->name,
sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip.u.prefix4));
}
- sticky = (ndm->ndm_state & NUD_NOARP) ? 1 : 0;
+ sticky = !!(ndm->ndm_state & NUD_NOARP);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("Rx %s family %s IF %s(%u)%s %sMAC %s%s",
static int netlink_macfdb_update(struct interface *ifp, vlanid_t vid,
struct ethaddr *mac, struct in_addr vtep_ip,
- int local, int cmd, uint8_t sticky)
+ int cmd, bool sticky)
{
struct zebra_ns *zns;
struct {
zns = zvrf->zns;
zif = ifp->info;
if ((br_if = zif->brslave_info.br_if) == NULL) {
- zlog_warn("MAC %s on IF %s(%u) - no mapping to bridge",
- (cmd == RTM_NEWNEIGH) ? "add" : "del", ifp->name,
- ifp->ifindex);
+ zlog_debug("MAC %s on IF %s(%u) - no mapping to bridge",
+ (cmd == RTM_NEWNEIGH) ? "add" : "del", ifp->name,
+ ifp->ifindex);
return -1;
}
addattr_l(&req.n, sizeof(req), NDA_LLADDR, mac, 6);
req.ndm.ndm_ifindex = ifp->ifindex;
- if (!local) {
- dst_alen = 4; // TODO: hardcoded
- addattr_l(&req.n, sizeof(req), NDA_DST, &vtep_ip, dst_alen);
- dst_present = 1;
- sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip));
- }
+ dst_alen = 4; // TODO: hardcoded
+ addattr_l(&req.n, sizeof(req), NDA_DST, &vtep_ip, dst_alen);
+ dst_present = 1;
+ sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip));
br_zif = (struct zebra_if *)br_if->info;
if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif) && vid > 0) {
addattr16(&req.n, sizeof(req), NDA_VLAN, vid);
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
int mac_present = 0;
- uint8_t ext_learned;
- uint8_t router_flag;
+ bool is_ext;
+ bool is_router;
ndm = NLMSG_DATA(h);
netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len);
if (!tb[NDA_DST]) {
- zlog_warn("%s family %s IF %s(%u) - no DST",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex);
+ zlog_debug("%s family %s IF %s(%u) - no DST",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex);
return 0;
}
/* Drop some "permanent" entries. */
if (ndm->ndm_state & NUD_PERMANENT) {
- char buf[16] = "169.254.0.1";
+ char b[16] = "169.254.0.1";
struct in_addr ipv4_ll;
if (ndm->ndm_family != AF_INET)
if (h->nlmsg_type != RTM_DELNEIGH)
return 0;
- inet_pton(AF_INET, buf, &ipv4_ll);
+ inet_pton(AF_INET, b, &ipv4_ll);
if (ipv4_ll.s_addr != ip.ip._v4_addr.s_addr)
return 0;
if (h->nlmsg_type == RTM_NEWNEIGH) {
if (tb[NDA_LLADDR]) {
if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) {
- zlog_warn(
+ zlog_debug(
"%s family %s IF %s(%u) - LLADDR is not MAC, len %lu",
nl_msg_type_to_str(h->nlmsg_type),
nl_family_to_str(ndm->ndm_family),
memcpy(&mac, RTA_DATA(tb[NDA_LLADDR]), ETH_ALEN);
}
- ext_learned = (ndm->ndm_flags & NTF_EXT_LEARNED) ? 1 : 0;
- router_flag = (ndm->ndm_flags & NTF_ROUTER) ? 1 : 0;
+ is_ext = !!(ndm->ndm_flags & NTF_EXT_LEARNED);
+ is_router = !!(ndm->ndm_flags & NTF_ROUTER);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
if (ndm->ndm_state & NUD_VALID)
return zebra_vxlan_handle_kernel_neigh_update(
ifp, link_if, &ip, &mac, ndm->ndm_state,
- ext_learned, router_flag);
+ is_ext, is_router);
return zebra_vxlan_handle_kernel_neigh_del(ifp, link_if, &ip);
}
if (ndm->ndm_family == AF_INET || ndm->ndm_family == AF_INET6)
return netlink_ipneigh_change(h, len, ns_id);
else {
- zlog_warn(
- "Invalid address family: %u received from kernel neighbor change: %u",
- ndm->ndm_family, h->nlmsg_type);
+ flog_warn(
+ EC_ZEBRA_UNKNOWN_FAMILY,
+ "Invalid address family: %u received from kernel neighbor change: %s",
+ ndm->ndm_family, nl_msg_type_to_str(h->nlmsg_type));
return 0;
}
}
int kernel_add_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
- struct in_addr vtep_ip, uint8_t sticky)
+ struct in_addr vtep_ip, bool sticky)
{
- return netlink_macfdb_update(ifp, vid, mac, vtep_ip, 0, RTM_NEWNEIGH,
+ return netlink_macfdb_update(ifp, vid, mac, vtep_ip, RTM_NEWNEIGH,
sticky);
}
int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
- struct in_addr vtep_ip, int local)
+ struct in_addr vtep_ip)
{
- return netlink_macfdb_update(ifp, vid, mac, vtep_ip, local,
- RTM_DELNEIGH, 0);
+ return netlink_macfdb_update(ifp, vid, mac, vtep_ip, RTM_DELNEIGH, 0);
}
int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
#define RTPROT_SHARP 194
#define RTPROT_PBR 195
#define RTPROT_ZSTATIC 196
+#define RTPROT_OPENFABRIC 197
void rt_netlink_init(void);
#include "zebra/rt.h"
#include "zebra/kernel_socket.h"
#include "zebra/zebra_mpls.h"
+#include "zebra/zebra_errors.h"
extern struct zebra_privs_t zserv_privs;
struct sockaddr_mpls *smpls)
{
if (nh_label->num_labels > 1) {
- zlog_warn(
- "%s: can't push %u labels at "
- "once (maximum is 1)",
- __func__, nh_label->num_labels);
+ flog_warn(EC_ZEBRA_MAX_LABELS_PUSH,
+ "%s: can't push %u labels at "
+ "once (maximum is 1)",
+ __func__, nh_label->num_labels);
return -1;
}
case ZEBRA_ERR_RTEXIST:
if (cmd != RTM_ADD)
flog_err(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"%s: rtm_write() returned %d for command %d",
__func__, error, cmd);
continue;
case ZEBRA_ERR_RTUNREACH:
default:
flog_err(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"%s: %s: rtm_write() unexpectedly returned %d for command %s",
__func__,
prefix2str(p, prefix_buf,
int route = 0;
if (src_p && src_p->prefixlen) {
- zlog_warn("%s: IPv6 sourcedest routes unsupported!", __func__);
+ flog_warn(EC_ZEBRA_UNSUPPORTED_V6_SRCDEST,
+ "%s: IPv6 sourcedest routes unsupported!", __func__);
return DP_REQUEST_FAILURE;
}
}
int kernel_add_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
- struct in_addr vtep_ip, uint8_t sticky)
+ struct in_addr vtep_ip, bool sticky)
{
return 0;
}
int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
- struct in_addr vtep_ip, int local)
+ struct in_addr vtep_ip)
{
return 0;
}
#include "zebra/zapi_msg.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
+#include "zebra/zebra_errors.h"
extern struct zebra_privs_t zserv_privs;
adata = calloc(1, CMSG_SPACE(sizeof(struct in6_pktinfo)));
if (adata == NULL) {
- zlog_warn(
+ zlog_debug(
"rtadv_send_packet: can't malloc control data");
exit(-1);
}
ret = sendmsg(sock, &msg, 0);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"%s(%u): Tx RA failed, socket %u error %d (%s)",
ifp->name, ifp->ifindex, sock, errno,
safe_strerror(errno));
inet_ntop(AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
if (len < sizeof(struct nd_router_advert)) {
- zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
- ifp->name, ifp->ifindex, len, addr_str);
+ zlog_debug("%s(%u): Rx RA with invalid length %d from %s",
+ ifp->name, ifp->ifindex, len, addr_str);
return;
}
if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
- zlog_warn(
+ zlog_debug(
"%s(%u): Rx RA with non-linklocal source address from %s",
ifp->name, ifp->ifindex, addr_str);
return;
if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit)
&& (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit)) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str);
}
if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
&& !zif->rtadv.AdvManagedFlag) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str);
}
if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
&& !zif->rtadv.AdvOtherConfigFlag) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str);
}
if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime)
&& (ntohl(radvert->nd_ra_reachable)
!= zif->rtadv.AdvReachableTime)) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str);
}
if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer)
&& (ntohl(radvert->nd_ra_retransmit)
!= (unsigned int)zif->rtadv.AdvRetransTimer)) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str);
}
/* Interface search. */
ifp = if_lookup_by_index_per_ns(zns, ifindex);
if (ifp == NULL) {
- zlog_warn("RA/RS received on unknown IF %u from %s", ifindex,
+ flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
+ "RA/RS received on unknown IF %u from %s", ifindex,
addr_str);
return;
}
/* ICMP message length check. */
if (len < sizeof(struct icmp6_hdr)) {
- zlog_warn("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
- ifp->name, ifp->ifindex, len);
+ zlog_debug("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
+ ifp->name, ifp->ifindex, len);
return;
}
/* ICMP message type check. */
if (icmph->icmp6_type != ND_ROUTER_SOLICIT
&& icmph->icmp6_type != ND_ROUTER_ADVERT) {
- zlog_warn("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
- ifp->name, ifp->ifindex, icmph->icmp6_type);
+ zlog_debug("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
+ ifp->name, ifp->ifindex, icmph->icmp6_type);
return;
}
/* Hoplimit check. */
if (hoplimit >= 0 && hoplimit != 255) {
- zlog_warn("%s(%u): Rx RA - Invalid hoplimit %d", ifp->name,
- ifp->ifindex, hoplimit);
+ zlog_debug("%s(%u): Rx RA - Invalid hoplimit %d", ifp->name,
+ ifp->ifindex, hoplimit);
return;
}
&hoplimit);
if (len < 0) {
- zlog_warn("RA/RS recv failed, socket %u error %s", sock,
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET,
+ "RA/RS recv failed, socket %u error %s", sock,
+ safe_strerror(errno));
return len;
}
/* Locate interface and check VRF match. */
ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifindex);
if (!ifp) {
- zlog_warn("%u: IF %u RA %s client %s - interface unknown",
+ flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
+ "%u: IF %u RA %s client %s - interface unknown",
zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
zebra_route_string(client->proto));
return;
}
if (ifp->vrf_id != zvrf_id(zvrf)) {
- zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
- zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
- zebra_route_string(client->proto), ifp->vrf_id);
+ zlog_debug(
+ "%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
+ zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
+ zebra_route_string(client->proto), ifp->vrf_id);
return;
}
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq,
sizeof mreq);
if (ret < 0)
- zlog_warn("%s(%u): Failed to join group, socket %u error %s",
- ifp->name, ifp->ifindex, sock, safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET,
+ "%s(%u): Failed to join group, socket %u error %s",
+ ifp->name, ifp->ifindex, sock,
+ safe_strerror(errno));
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug(
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *)&mreq,
sizeof mreq);
if (ret < 0)
- zlog_warn("%s(%u): Failed to leave group, socket %u error %s",
- ifp->name, ifp->ifindex, sock, safe_strerror(errno));
+ flog_err_sys(
+ EC_LIB_SOCKET,
+ "%s(%u): Failed to leave group, socket %u error %s",
+ ifp->name, ifp->ifindex, sock, safe_strerror(errno));
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug(
#include "if.h"
#include "vrf.h"
#include "vty.h"
+#include "lib_errors.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
+#include "zebra/zebra_pbr.h"
+#include "zebra/zebra_errors.h"
/* Thank you, Solaris, for polluting application symbol namespace. */
#undef hook_register
int flags, dev, retval, process;
if ((dev = open(_PATH_GETMSG_ROUTE, O_RDWR)) == -1) {
- zlog_warn("can't open %s: %s", _PATH_GETMSG_ROUTE,
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "can't open %s: %s",
+ _PATH_GETMSG_ROUTE, safe_strerror(errno));
return;
}
flags = 0;
if (putmsg(dev, &msgdata, NULL, flags) == -1) {
- zlog_warn("putmsg failed: %s", safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "putmsg failed: %s",
+ safe_strerror(errno));
goto exit;
}
retval = getmsg(dev, &msgdata, NULL, &flags);
if (retval == -1) {
- zlog_warn("getmsg(ctl) failed: %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "getmsg(ctl) failed: %s",
+ safe_strerror(errno));
goto exit;
}
if ((size_t)msgdata.len >= sizeof(struct T_error_ack)
&& TLIerr->PRIM_type == T_ERROR_ACK) {
- zlog_warn("getmsg(ctl) returned T_ERROR_ACK: %s",
- safe_strerror((TLIerr->TLI_error == TSYSERR)
- ? TLIerr->UNIX_error
- : EPROTO));
+ zlog_debug("getmsg(ctl) returned T_ERROR_ACK: %s",
+ safe_strerror((TLIerr->TLI_error == TSYSERR)
+ ? TLIerr->UNIX_error
+ : EPROTO));
break;
}
|| TLIack->PRIM_type != T_OPTMGMT_ACK
|| TLIack->MGMT_flags != T_SUCCESS) {
errno = ENOMSG;
- zlog_warn("getmsg(ctl) returned bizarreness");
+ zlog_debug("getmsg(ctl) returned bizarreness");
break;
}
retval = getmsg(dev, NULL, &msgdata, &flags);
if (retval == -1) {
- zlog_warn("getmsg(data) failed: %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "getmsg(data) failed: %s",
+ safe_strerror(errno));
goto exit;
}
if (!(retval == 0 || retval == MOREDATA)) {
- zlog_warn("getmsg(data) returned %d", retval);
+ zlog_debug("getmsg(data) returned %d", retval);
goto exit;
}
if (process) {
if (msgdata.len % sizeof(mib2_ipRouteEntry_t)
!= 0) {
- zlog_warn(
+ zlog_debug(
"getmsg(data) returned "
"msgdata.len = %d (%% sizeof (mib2_ipRouteEntry_t) != 0)",
msgdata.len);
#include "zebra/rt.h"
#include "zebra/kernel_socket.h"
#include "zebra/zebra_pbr.h"
+#include "zebra/zebra_errors.h"
/* Kernel routing table read up by sysctl function. */
void route_read(struct zebra_ns *zns)
/* Get buffer size. */
if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) {
- zlog_warn("sysctl fail: %s", safe_strerror(errno));
+ flog_warn(EC_ZEBRA_SYSCTL_FAILED, "sysctl fail: %s",
+ safe_strerror(errno));
return;
}
/* Read routing table information by calling sysctl(). */
if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) {
- zlog_warn("sysctl() fail by %s", safe_strerror(errno));
+ flog_warn(EC_ZEBRA_SYSCTL_FAILED, "sysctl() fail by %s",
+ safe_strerror(errno));
XFREE(MTYPE_TMP, ref);
return;
}
#include "zebra/kernel_netlink.h"
#include "zebra/rule_netlink.h"
#include "zebra/zebra_pbr.h"
+#include "zebra/zebra_errors.h"
/* definitions */
frh = NLMSG_DATA(h);
if (frh->family != AF_INET && frh->family != AF_INET6) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_NETLINK_INVALID_AF,
"Invalid address family: %u received from kernel rule change: %u",
frh->family, h->nlmsg_type);
return 0;
#include "zebra/kernel_netlink.h"
#include "zebra/rule_netlink.h"
#include "zebra/zebra_pbr.h"
+#include "zebra/zebra_errors.h"
enum dp_req_result kernel_add_pbr_rule(struct zebra_pbr_rule *rule)
{
- flog_err(LIB_ERR_UNAVAILABLE, "%s not Implemented for this platform",
- __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_UNAVAILABLE, "%s not Implemented for this platform",
+ __PRETTY_FUNCTION__);
return DP_REQUEST_FAILURE;
}
enum dp_req_result kernel_del_pbr_rule(struct zebra_pbr_rule *rule)
{
- flog_err(LIB_ERR_UNAVAILABLE, "%s not Implemented for this platform",
- __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_UNAVAILABLE, "%s not Implemented for this platform",
+ __PRETTY_FUNCTION__);
return DP_REQUEST_FAILURE;
}
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
module_LTLIBRARIES += zebra/zebra_fpm.la
endif
+man8 += $(MANBUILD)/zebra.8
## endif ZEBRA
endif
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
#endif /* SUNOS_5 */
tmc->start = start;
if (RT_TABLE_ID_UNRESERVED_MAX - size + 1 < start) {
- flog_err(ZEBRA_ERR_TM_EXHAUSTED_IDS,
- "Reached max table id. Start/Size %u/%u", start,
- size);
+ flog_err(EC_ZEBRA_TM_EXHAUSTED_IDS,
+ "Reached max table id. Start/Size %u/%u", start, size);
XFREE(MTYPE_TM_CHUNK, tmc);
return NULL;
}
if (tmc->end != end)
continue;
if (tmc->proto != proto || tmc->instance != instance) {
- flog_err(ZEBRA_ERR_TM_DAEMON_MISMATCH,
- "%s: Daemon mismatch!!", __func__);
+ flog_err(EC_ZEBRA_TM_DAEMON_MISMATCH,
+ "%s: Daemon mismatch!!", __func__);
continue;
}
tmc->proto = NO_PROTO;
break;
}
if (ret != 0)
- flog_err(ZEBRA_ERR_TM_UNRELEASED_CHUNK,
- "%s: Table chunk not released!!", __func__);
+ flog_err(EC_ZEBRA_TM_UNRELEASED_CHUNK,
+ "%s: Table chunk not released!!", __func__);
return ret;
}
#include "zebra/zebra_pbr.h"
#include "zebra/table_manager.h"
#include "zebra/zapi_msg.h"
+#include "zebra/zebra_errors.h"
/* Encoding helpers -------------------------------------------------------- */
l += 4;
if (p.family == AF_INET) {
if (p.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is too large for a v4 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
l += IPV4_MAX_BYTELEN;
} else if (p.family == AF_INET6) {
if (p.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is to large for a v6 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
l += IPV6_MAX_BYTELEN;
} else {
flog_err(
- ZEBRA_ERR_UNKNOWN_FAMILY,
+ EC_ZEBRA_UNKNOWN_FAMILY,
"rnh_register: Received unknown family type %d\n",
p.family);
return;
l += 4;
if (p.family == AF_INET) {
if (p.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is to large for a v4 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
l += IPV4_MAX_BYTELEN;
} else if (p.family == AF_INET6) {
if (p.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is to large for a v6 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
l += IPV6_MAX_BYTELEN;
} else {
flog_err(
- ZEBRA_ERR_UNKNOWN_FAMILY,
+ EC_ZEBRA_UNKNOWN_FAMILY,
"rnh_register: Received unknown family type %d\n",
p.family);
return;
*/
if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
flog_err(
- ZEBRA_ERR_IRDP_LEN_MISMATCH,
+ EC_ZEBRA_IRDP_LEN_MISMATCH,
"fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode",
hdr->length);
return;
STREAM_GETW(s, p.family);
if (p.family != AF_INET && p.family != AF_INET6) {
flog_err(
- ZEBRA_ERR_UNKNOWN_FAMILY,
+ EC_ZEBRA_UNKNOWN_FAMILY,
"fec_register: Received unknown family type %d\n",
p.family);
return;
if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
|| (p.family == AF_INET6
&& p.prefixlen > IPV6_MAX_BITLEN)) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length: %d is to long for %d",
__PRETTY_FUNCTION__, p.prefixlen, p.family);
return;
*/
if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
flog_err(
- ZEBRA_ERR_IRDP_LEN_MISMATCH,
+ EC_ZEBRA_IRDP_LEN_MISMATCH,
"fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode",
hdr->length);
return;
STREAM_GETW(s, p.family);
if (p.family != AF_INET && p.family != AF_INET6) {
flog_err(
- ZEBRA_ERR_UNKNOWN_FAMILY,
+ EC_ZEBRA_UNKNOWN_FAMILY,
"fec_unregister: Received unknown family type %d\n",
p.family);
return;
if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
|| (p.family == AF_INET6
&& p.prefixlen > IPV6_MAX_BITLEN)) {
- zlog_warn(
+ zlog_debug(
"%s: Received prefix hdr->length %d which is greater than %d can support",
__PRETTY_FUNCTION__, p.prefixlen, p.family);
return;
char buff[PREFIX2STR_BUFFER];
prefix2str(p, buff, sizeof(buff));
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
"%s: Prefix %s has %d nexthops, but we can only use the first %d",
caller, buff, nexthop_num, multipath_num);
}
}
if (!nexthop) {
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_NEXTHOP_CREATION_FAILED,
"%s: Nexthops Specified: %d but we failed to properly create one",
__PRETTY_FUNCTION__, api.nexthop_num);
nexthops_free(re->ng.nexthop);
afi = family2afi(api.prefix.family);
if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
- zlog_warn("%s: Received SRC Prefix but afi is not v6",
+ flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+ "%s: Received SRC Prefix but afi is not v6",
__PRETTY_FUNCTION__);
nexthops_free(re->ng.nexthop);
XFREE(MTYPE_RE, re);
afi = family2afi(api.prefix.family);
if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
- zlog_warn("%s: Received a src prefix while afi is not v6",
+ flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+ "%s: Received a src prefix while afi is not v6",
__PRETTY_FUNCTION__);
return;
}
STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
STREAM_GETC(s, prefix.prefixlen);
if (prefix.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix length %d is greater than a v4 address can support",
__PRETTY_FUNCTION__, prefix.prefixlen);
return;
STREAM_GET(&prefix.u.prefix6, s, 16);
STREAM_GETC(s, prefix.prefixlen);
if (prefix.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix length %d is greater than a v6 address can support",
__PRETTY_FUNCTION__, prefix.prefixlen);
return;
STREAM_GET(&gate.ipv6, s, 16);
break;
default:
- zlog_warn("%s: Specified AF %d is not supported for this call",
- __PRETTY_FUNCTION__, prefix.family);
+ zlog_debug("%s: Specified AF %d is not supported for this call",
+ __PRETTY_FUNCTION__, prefix.family);
return;
}
STREAM_GETL(s, ifindex);
/* accept only dynamic routing protocols */
if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
- flog_err(ZEBRA_ERR_TM_WRONG_PROTO,
- "client %d has wrong protocol %s", client->sock,
- zebra_route_string(proto));
+ flog_err(EC_ZEBRA_TM_WRONG_PROTO,
+ "client %d has wrong protocol %s", client->sock,
+ zebra_route_string(proto));
zsend_table_manager_connect_response(client, vrf_id, 1);
return;
}
/* accept only dynamic routing protocols */
if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
- flog_err(ZEBRA_ERR_TM_WRONG_PROTO,
- "client %d has wrong protocol %s", client->sock,
- zebra_route_string(proto));
- zsend_label_manager_connect_response(client, vrf_id, 1);
+ flog_err(EC_ZEBRA_TM_WRONG_PROTO,
+ "client %d has wrong protocol %s", client->sock,
+ zebra_route_string(proto));
+ if (client->is_synchronous)
+ zsend_label_manager_connect_response(client, vrf_id, 1);
return;
}
zlog_notice("client %d with vrf %u instance %u connected as %s",
" Label Manager client connected: sock %d, proto %s, vrf %u instance %u",
client->sock, zebra_route_string(proto), vrf_id, instance);
/* send response back */
- zsend_label_manager_connect_response(client, vrf_id, 0);
+ if (client->is_synchronous)
+ zsend_label_manager_connect_response(client, vrf_id, 0);
stream_failure:
return;
}
-static int msg_client_id_mismatch(const char *op, struct zserv *client,
- uint8_t proto, unsigned int instance)
-{
- if (proto != client->proto) {
- flog_err(ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH,
- "%s: msg vs client proto mismatch, client=%u msg=%u",
- op, client->proto, proto);
- /* TODO: fail when BGP sets proto and instance */
- /* return 1; */
- }
-
- if (instance != client->instance) {
- flog_err(
- ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH,
- "%s: msg vs client instance mismatch, client=%u msg=%u",
- op, client->instance, instance);
- /* TODO: fail when BGP sets proto and instance */
- /* return 1; */
- }
-
- return 0;
-}
static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
vrf_id_t vrf_id)
STREAM_GETC(s, keep);
STREAM_GETL(s, size);
- /* detect client vs message (proto,instance) mismatch */
- if (msg_client_id_mismatch("Get-label-chunk", client, proto, instance))
- return;
-
- lmc = assign_label_chunk(client->proto, client->instance, keep, size);
+ lmc = assign_label_chunk(proto, instance, keep, size);
if (!lmc)
flog_err(
- ZEBRA_ERR_LM_CANNOT_ASSIGN_CHUNK,
+ EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK,
"Unable to assign Label Chunk of size %u to %s instance %u",
- size, zebra_route_string(client->proto),
- client->instance);
+ size, zebra_route_string(proto), instance);
else
zlog_debug("Assigned Label Chunk %u - %u to %s instance %u",
lmc->start, lmc->end,
- zebra_route_string(client->proto), client->instance);
+ zebra_route_string(proto), instance);
/* send response back */
zsend_assign_label_chunk_response(client, vrf_id, lmc);
STREAM_GETL(s, start);
STREAM_GETL(s, end);
- /* detect client vs message (proto,instance) mismatch */
- if (msg_client_id_mismatch("Release-label-chunk", client, proto,
- instance))
- return;
-
- release_label_chunk(client->proto, client->instance, start, end);
+ release_label_chunk(proto, instance, start, end);
stream_failure:
return;
static void zread_label_manager_request(ZAPI_HANDLER_ARGS)
{
/* to avoid sending other messages like ZERBA_INTERFACE_UP */
- if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT)
- client->is_synchronous = 1;
+ client->is_synchronous = hdr->command ==
+ ZEBRA_LABEL_MANAGER_CONNECT;
/* external label manager */
if (lm_is_external)
zvrf_id(zvrf));
/* this is a label manager */
else {
- if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT)
+ if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT ||
+ hdr->command == ZEBRA_LABEL_MANAGER_CONNECT_ASYNC)
zread_label_manager_connect(client, msg, zvrf_id(zvrf));
else {
- /* Sanity: don't allow 'unidentified' requests */
- if (!client->proto) {
- flog_err(
- ZEBRA_ERR_LM_ALIENS,
- "Got label request from an unidentified client");
- return;
- }
if (hdr->command == ZEBRA_GET_LABEL_CHUNK)
zread_get_label_chunk(client, msg,
zvrf_id(zvrf));
tmc = assign_table_chunk(client->proto, client->instance, size);
if (!tmc)
- flog_err(ZEBRA_ERR_TM_CANNOT_ASSIGN_CHUNK,
- "%s: Unable to assign Table Chunk of size %u",
- __func__, size);
+ flog_err(EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
+ "%s: Unable to assign Table Chunk of size %u",
+ __func__, size);
else
zlog_debug("Assigned Table Chunk %u - %u", tmc->start,
tmc->end);
/* Sanity: don't allow 'unidentified' requests */
if (!client->proto) {
flog_err(
- ZEBRA_ERR_TM_ALIENS,
+ EC_ZEBRA_TM_ALIENS,
"Got table request from an unidentified client");
return;
}
switch (hdr->command) {
case ZEBRA_PW_ADD:
if (pw) {
- zlog_warn("%s: pseudowire %s already exists [%s]",
+ flog_warn(EC_ZEBRA_PSEUDOWIRE_EXISTS,
+ "%s: pseudowire %s already exists [%s]",
__func__, ifname,
zserv_command_string(hdr->command));
return;
break;
case ZEBRA_PW_DELETE:
if (!pw) {
- zlog_warn("%s: pseudowire %s not found [%s]", __func__,
+ flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+ "%s: pseudowire %s not found [%s]", __func__,
ifname, zserv_command_string(hdr->command));
return;
}
case ZEBRA_PW_SET:
case ZEBRA_PW_UNSET:
if (!pw) {
- zlog_warn("%s: pseudowire %s not found [%s]", __func__,
+ flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+ "%s: pseudowire %s not found [%s]", __func__,
ifname, zserv_command_string(hdr->command));
return;
}
[ZEBRA_MPLS_LABELS_DELETE] = zread_mpls_labels,
[ZEBRA_IPMR_ROUTE_STATS] = zebra_ipmr_route_stats,
[ZEBRA_LABEL_MANAGER_CONNECT] = zread_label_manager_request,
+ [ZEBRA_LABEL_MANAGER_CONNECT_ASYNC] = zread_label_manager_request,
[ZEBRA_GET_LABEL_CHUNK] = zread_label_manager_request,
[ZEBRA_RELEASE_LABEL_CHUNK] = zread_label_manager_request,
[ZEBRA_FEC_REGISTER] = zread_fec_register,
zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
if (!zvrf) {
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
- zlog_warn("ZAPI message specifies unknown VRF: %d",
- hdr.vrf_id);
+ zlog_debug("ZAPI message specifies unknown VRF: %d",
+ hdr.vrf_id);
return;
}
/* clang-format off */
static struct log_ref ferr_zebra_err[] = {
{
- .code = ZEBRA_ERR_LM_RESPONSE,
+ .code = EC_ZEBRA_LM_RESPONSE,
.title = "Error reading response from label manager",
.description = "Zebra could not read the ZAPI header from the label manager",
.suggestion = "Wait for the error to resolve on its own. If it does not resolve, restart Zebra.",
},
{
- .code = ZEBRA_ERR_LM_NO_SUCH_CLIENT,
+ .code = EC_ZEBRA_LM_NO_SUCH_CLIENT,
.title = "Label manager could not find ZAPI client",
.description = "Zebra was unable to find a ZAPI client matching the given protocol and instance number.",
.suggestion = "Ensure clients which use the label manager are properly configured and running.",
},
{
- .code = ZEBRA_ERR_LM_RELAY_FAILED,
+ .code = EC_ZEBRA_LM_RELAY_FAILED,
.title = "Zebra could not relay label manager response",
.description = "Zebra found the client and instance to relay the label manager response or request to, but was not able to do so, possibly because the connection was closed.",
.suggestion = "Ensure clients which use the label manager are properly configured and running.",
},
{
- .code = ZEBRA_ERR_LM_BAD_INSTANCE,
+ .code = EC_ZEBRA_LM_BAD_INSTANCE,
.title = "Mismatch between ZAPI instance and encoded message instance",
.description = "While relaying a request to the external label manager, Zebra noticed that the instance number encoded in the message did not match the client instance number.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_LM_EXHAUSTED_LABELS,
+ .code = EC_ZEBRA_LM_EXHAUSTED_LABELS,
.title = "Zebra label manager used all available labels",
.description = "Zebra is unable to assign additional label chunks because it has exhausted its assigned label range.",
.suggestion = "Make the label range bigger and restart Zebra.",
},
{
- .code = ZEBRA_ERR_LM_DAEMON_MISMATCH,
+ .code = EC_ZEBRA_LM_DAEMON_MISMATCH,
.title = "Daemon mismatch when releasing label chunks",
.description = "Zebra noticed a mismatch between a label chunk and a protocol daemon number or instance when releasing unused label chunks.",
.suggestion = "Ignore this error.",
},
{
- .code = ZEBRA_ERR_LM_UNRELEASED_CHUNK,
+ .code = EC_ZEBRA_LM_UNRELEASED_CHUNK,
.title = "Zebra did not free any label chunks",
.description = "Zebra's chunk cleanup procedure ran, but no label chunks were released.",
.suggestion = "Ignore this error.",
},
{
- .code = ZEBRA_ERR_DP_INVALID_RC,
+ .code = EC_ZEBRA_DP_INVALID_RC,
.title = "Dataplane returned invalid status code",
.description = "The underlying dataplane responded to a Zebra message or other interaction with an unrecognized, unknown or invalid status code.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_WQ_NONEXISTENT,
+ .code = EC_ZEBRA_WQ_NONEXISTENT,
.title = "A necessary work queue does not exist.",
.description = "A necessary work queue does not exist.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_FEC_ADD_FAILED,
+ .code = EC_ZEBRA_FEC_ADD_FAILED,
.title = "Failed to add FEC for MPLS client",
.description = "A client requested a label binding for a new FEC, but Zebra was unable to add the FEC to its internal table.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_FEC_RM_FAILED,
+ .code = EC_ZEBRA_FEC_RM_FAILED,
.title = "Failed to remove FEC for MPLS client",
.description = "Zebra was unable to find and remove a FEC in its internal table.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_IRDP_LEN_MISMATCH,
+ .code = EC_ZEBRA_IRDP_LEN_MISMATCH,
.title = "IRDP message length mismatch",
.description = "The length encoded in the IP TLV does not match the length of the packet received.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_RNH_UNKNOWN_FAMILY,
+ .code = EC_ZEBRA_RNH_UNKNOWN_FAMILY,
.title = "Attempted to perform nexthop update for unknown address family",
.description = "Zebra attempted to perform a nexthop update for unknown address family",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_DP_INSTALL_FAIL,
+ .code = EC_ZEBRA_DP_INSTALL_FAIL,
.title = "Dataplane installation failure",
.description = "Installation of routes to underlying dataplane failed.",
.suggestion = "Check all configuration parameters for correctness.",
},
{
- .code = ZEBRA_ERR_TABLE_LOOKUP_FAILED,
+ .code = EC_ZEBRA_DP_DELETE_FAIL,
+ .title = "Dataplane deletion failure",
+ .description = "Deletion of routes from underlying dataplane failed.",
+ .suggestion = "Check all configuration parameters for correctness.",
+ },
+ {
+ .code = EC_ZEBRA_TABLE_LOOKUP_FAILED,
.title = "Zebra table lookup failed",
.description = "Zebra attempted to look up a table for a particular address family and subsequent address family, but didn't find anything.",
.suggestion = "If you entered a command to trigger this error, make sure you entered the arguments correctly. Check your config file for any potential errors. If these look correct, seek help.",
},
{
- .code = ZEBRA_ERR_NETLINK_NOT_AVAILABLE,
+ .code = EC_ZEBRA_NETLINK_NOT_AVAILABLE,
.title = "Netlink backend not available",
.description = "FRR was not compiled with support for Netlink. Any operations that require Netlink will fail.",
.suggestion = "Recompile FRR with Netlink, or install a package that supports this feature.",
},
{
- .code = ZEBRA_ERR_PROTOBUF_NOT_AVAILABLE,
+ .code = EC_ZEBRA_PROTOBUF_NOT_AVAILABLE,
.title = "Protocol Buffers backend not available",
.description = "FRR was not compiled with support for Protocol Buffers. Any operations that require Protobuf will fail.",
.suggestion = "Recompile FRR with Protobuf support, or install a package that supports this feature.",
},
{
- .code = ZEBRA_ERR_TM_EXHAUSTED_IDS,
+ .code = EC_ZEBRA_TM_EXHAUSTED_IDS,
.title = "Table manager used all available IDs",
.description = "Zebra's table manager used up all IDs available to it and can't assign any more.",
.suggestion = "Reconfigure Zebra with a larger range of table IDs.",
},
{
- .code = ZEBRA_ERR_TM_DAEMON_MISMATCH,
+ .code = EC_ZEBRA_TM_DAEMON_MISMATCH,
.title = "Daemon mismatch when releasing table chunks",
.description = "Zebra noticed a mismatch between a table ID chunk and a protocol daemon number instance when releasing unused table chunks.",
.suggestion = "Ignore this error.",
},
{
- .code = ZEBRA_ERR_TM_UNRELEASED_CHUNK,
+ .code = EC_ZEBRA_TM_UNRELEASED_CHUNK,
.title = "Zebra did not free any table chunks",
.description = "Zebra's table chunk cleanup procedure ran, but no table chunks were released.",
.suggestion = "Ignore this error.",
},
{
- .code = ZEBRA_ERR_UNKNOWN_FAMILY,
+ .code = EC_ZEBRA_UNKNOWN_FAMILY,
.title = "Address family specifier unrecognized",
.description = "Zebra attempted to process information from somewhere that included an address family specifier, but did not recognize the provided specifier.",
.suggestion = "Ensure that your configuration is correct. If it is, notify a developer.",
},
{
- .code = ZEBRA_ERR_TM_WRONG_PROTO,
+ .code = EC_ZEBRA_TM_WRONG_PROTO,
.title = "Incorrect protocol for table manager client",
.description = "Zebra's table manager only accepts connections from daemons managing dynamic routing protocols, but received a connection attempt from a daemon that does not meet this criterion.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH,
+ .code = EC_ZEBRA_PROTO_OR_INSTANCE_MISMATCH,
.title = "Mismatch between message and client protocol and/or instance",
.description = "Zebra detected a mismatch between a client's protocol and/or instance numbers versus those stored in a message transiting its socket.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_LM_CANNOT_ASSIGN_CHUNK,
+ .code = EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK,
.title = "Label manager unable to assign label chunk",
.description = "Zebra's label manager was unable to assign a label chunk to client.",
.suggestion = "Ensure that Zebra has a sufficient label range available and that there is not a range collision.",
},
{
- .code = ZEBRA_ERR_LM_ALIENS,
+ .code = EC_ZEBRA_LM_ALIENS,
.title = "Label request from unidentified client",
.description = "Zebra's label manager received a label request from an unidentified client.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_TM_CANNOT_ASSIGN_CHUNK,
+ .code = EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
.title = "Table manager unable to assign table chunk",
.description = "Zebra's table manager was unable to assign a table chunk to a client.",
.suggestion = "Ensure that Zebra has sufficient table ID range available and that there is not a range collision.",
},
{
- .code = ZEBRA_ERR_TM_ALIENS,
+ .code = EC_ZEBRA_TM_ALIENS,
.title = "Table request from unidentified client",
.description = "Zebra's table manager received a table request from an unidentified client.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_RECVBUF,
+ .code = EC_ZEBRA_RECVBUF,
.title = "Cannot set receive buffer size",
.description = "Socket receive buffer size could not be set in the kernel",
.suggestion = "Ignore this error.",
},
{
- .code = ZEBRA_ERR_UNKNOWN_NLMSG,
+ .code = EC_ZEBRA_UNKNOWN_NLMSG,
.title = "Unknown Netlink message type",
.description = "Zebra received a Netlink message with an unrecognized type field.",
.suggestion = "Verify that you are running the latest version of FRR to ensure kernel compatibility. If the problem persists, notify a developer.",
},
{
- .code = ZEBRA_ERR_RECVMSG_OVERRUN,
+ .code = EC_ZEBRA_RECVMSG_OVERRUN,
.title = "Receive buffer overrun",
.description = "The kernel's buffer for a socket has been overrun, rendering the socket invalid.",
.suggestion = "Zebra will restart itself. Notify a developer if this issue shows up frequently.",
},
{
- .code = ZEBRA_ERR_NETLINK_LENGTH_ERROR,
+ .code = EC_ZEBRA_NETLINK_LENGTH_ERROR,
.title = "Netlink message length mismatch",
.description = "Zebra received a Netlink message with incorrect length fields.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_NETLINK_LENGTH_ERROR,
+ .code = EC_ZEBRA_NETLINK_LENGTH_ERROR,
.title = "Netlink message length mismatch",
.description = "Zebra received a Netlink message with incorrect length fields.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_UNEXPECTED_MESSAGE,
+ .code = EC_ZEBRA_UNEXPECTED_MESSAGE,
.title = "Received unexpected response from kernel",
.description = "Received unexpected response from the kernel via Netlink.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_NETLINK_BAD_SEQUENCE,
+ .code = EC_ZEBRA_NETLINK_BAD_SEQUENCE,
.title = "Bad sequence number in Netlink message",
.description = "Zebra received a Netlink message with a bad sequence number.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_BAD_MULTIPATH_NUM,
+ .code = EC_ZEBRA_BAD_MULTIPATH_NUM,
.title = "Multipath number was out of valid range",
.description = "Multipath number specified to Zebra must be in the appropriate range",
.suggestion = "Provide a multipath number that is within its accepted range",
},
{
- .code = ZEBRA_ERR_PREFIX_PARSE_ERROR,
+ .code = EC_ZEBRA_PREFIX_PARSE_ERROR,
.title = "String could not be parsed as IP prefix",
.description = "There was an attempt to parse a string as an IPv4 or IPv6 prefix, but the string could not be parsed and this operation failed.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_MAC_ADD_FAILED,
+ .code = EC_ZEBRA_MAC_ADD_FAILED,
.title = "Failed to add MAC address to interface",
.description = "Zebra attempted to assign a MAC address to a vxlan interface but failed",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_VNI_DEL_FAILED,
+ .code = EC_ZEBRA_VNI_DEL_FAILED,
.title = "Failed to delete VNI",
.description = "Zebra attempted to delete a VNI entry and failed",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_VTEP_ADD_FAILED,
+ .code = EC_ZEBRA_VTEP_ADD_FAILED,
.title = "Adding remote VTEP failed",
.description = "Zebra attempted to add a remote VTEP and failed.",
.suggestion = "Notify a developer.",
},
{
- .code = ZEBRA_ERR_VNI_ADD_FAILED,
+ .code = EC_ZEBRA_VNI_ADD_FAILED,
.title = "Adding VNI failed",
.description = "Zebra attempted to add a VNI hash to an interface and failed",
.suggestion = "Notify a developer.",
},
+ {
+ .code = EC_ZEBRA_NS_NOTIFY_READ,
+ .title = "Zebra failed to read namespace inotify information",
+ .description = "Zebra received an event from inotify, but failed to read what it was.",
+ .suggestion = "Notify a developer.",
+ },
+ /* Warnings */
+ {
+ .code = EC_ZEBRAING_LM_PROTO_MISMATCH,
+ .title =
+ "Zebra label manager received malformed label request",
+ .description =
+ "Zebra's label manager received a label request from a client whose protocol type does not match the protocol field received in the message.",
+ .suggestion =
+ "This is a bug. Please report it.",
+ },
+ {
+ .code = EC_ZEBRA_LSP_INSTALL_FAILURE,
+ .title =
+ "Zebra failed to install LSP into the kernel",
+ .description =
+ "Zebra made an attempt to install a label switched path, but the kernel indicated that the installation was not successful.",
+ .suggestion =
+ "Wait for Zebra to reattempt installation.",
+ },
+ {
+ .code = EC_ZEBRA_LSP_DELETE_FAILURE,
+ .title =
+ "Zebra failed to remove LSP from the kernel",
+ .description =
+ "Zebra made an attempt to remove a label switched path, but the kernel indicated that the deletion was not successful.",
+ .suggestion =
+ "Wait for Zebra to reattempt deletion.",
+ },
+ {
+ .code = EC_ZEBRA_MPLS_SUPPORT_DISABLED,
+ .title =
+ "Zebra will not run with MPLS support",
+ .description =
+ "Zebra noticed that the running kernel does not support MPLS, so it disabled MPLS support.",
+ .suggestion =
+ "If you want MPLS support, upgrade the kernel to a version that provides MPLS support.",
+ },
+ {
+ .code = EC_ZEBRA_SYSCTL_FAILED,
+ .title = "A call to sysctl() failed",
+ .description =
+ "sysctl() returned a nonzero exit code, indicating an error.",
+ .suggestion =
+ "The log message should contain further details on the specific error that occurred; investigate the reported error.",
+ },
+ {
+ .code = EC_ZEBRA_NS_VRF_CREATION_FAILED,
+ .title =
+ "Zebra failed to create namespace VRF",
+ .description =
+ "Zebra failed to create namespace VRF",
+ .suggestion = "",
+ },
+ {
+ .code = EC_ZEBRA_NS_DELETION_FAILED_NO_VRF,
+ .title =
+ "Zebra attempted to delete nonexistent namespace",
+ .description =
+ "Zebra attempted to delete a particular namespace, but no VRF associated with that namespace could be found to delete.",
+ .suggestion = "Please report this bug.",
+ },
+ {
+ .code = EC_ZEBRA_IFLIST_FAILED,
+ .title =
+ "Zebra interface listing failed",
+ .description =
+ "Zebra encountered an error attempting to query sysctl for a list of interfaces on the system.",
+ .suggestion =
+ "Check that Zebra is running with the appropriate permissions. If it is, please report this as a bug.",
+ },
+ {
+ .code = EC_ZEBRA_IRDP_BAD_CHECKSUM,
+ .title =
+ "Zebra received ICMP packet with invalid checksum",
+ .description =
+ "Zebra received an ICMP packet with a bad checksum and has silently ignored it.",
+ .suggestion =
+ "If the problem continues to occur, investigate the source of the bad ICMP packets.",
+ },
+ {
+ .code = EC_ZEBRA_IRDP_BAD_TYPE_CODE,
+ .title =
+ "Zebra received ICMP packet with bad type code",
+ .description =
+ "Zebra received an ICMP packet with a bad code for the message type and has silently ignored it.",
+ .suggestion =
+ "If the problem continues to occur, investigate the source of the bad ICMP packets.",
+ },
+ {
+ .code = EC_ZEBRA_IRDP_BAD_RX_FLAGS,
+ .title =
+ "Zebra received IRDP packet while operating in wrong mode",
+ .description =
+ "Zebra received a multicast IRDP packet while operating in unicast mode, or vice versa.",
+ .suggestion =
+ "If you wish to receive the messages, change your IRDP settings accordingly.",
+ },
+ {
+ .code = EC_ZEBRA_IRDP_BAD_TYPE,
+ .title =
+ "Zebra received IRDP packet with bad type",
+ .description =
+ "THIS IS BULLSHIT REMOVE ME",
+ .suggestion = "asdf",
+ },
+ {
+ .code = EC_ZEBRA_RNH_NO_TABLE,
+ .title =
+ "Zebra could not find table for next hop",
+ .description =
+ "Zebra attempted to add a next hop but could not find the appropriate table to install it in.",
+ .suggestion = "Please report this bug.",
+ },
+ {
+ .code = EC_ZEBRA_FPM_FORMAT_UNKNOWN,
+ .title =
+ "Unknown message format for Zebra's FPM module",
+ .description =
+ "Zebra's FPM module takes an argument which specifies the message format to use, but the format was either not provided or was not a valid format. The FPM interface will be disabled.",
+ .suggestion =
+ "Provide or correct the module argument to provide a valid format. See documentation for further information.",
+ },
+ {
+ .code = EC_ZEBRA_CLIENT_IO_ERROR,
+ .title =
+ "Zebra client connection failed",
+ .description =
+ "A Zebra client encountered an I/O error and is shutting down. This can occur under normal circumstances, such as when FRR is restarting or shutting down; it can also happen if the daemon crashed. Usually this warning can be ignored.",
+ .suggestion =
+ "Ignore this warning, it is mostly informational.",
+ },
+ {
+ .code = EC_ZEBRA_CLIENT_WRITE_FAILED,
+ .title =
+ "Zebra failed to send message to client",
+ .description =
+ "Zebra attempted to send a message to one of its clients, but the write operation failed. The connection will be closed.",
+ .suggestion =
+ "Ignore this warning, it is mostly informational.",
+ },
+ {
+ .code = EC_ZEBRA_NETLINK_INVALID_AF,
+ .title =
+ "Zebra received Netlink message with invalid family",
+ .description =
+ "Zebra received a Netlink message with an invalid address family.",
+ .suggestion =
+ "Inspect the logged address family and submit it with a bug report.",
+ },
+ {
+ .code = EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET,
+ .title =
+ "Zebra tried to remove address from unknown subnet",
+ .description =
+ "Zebra attempted to remove an address from an unknown subnet.",
+ .suggestion =
+ "This is a bug, please report it.",
+ },
+ {
+ .code = EC_ZEBRA_REMOVE_UNREGISTERED_ADDR,
+ .title =
+ "Zebra tried to remove unregistered address",
+ .description =
+ "Zebra attempted to remove an address from a subnet it was not registered on.",
+ .suggestion =
+ "This is a bug, please report it.",
+ },
+ {
+ .code = EC_ZEBRA_PTM_NOT_READY,
+ .title =
+ "Interface is up but PTM check has not completed",
+ .description =
+ "Zebra noticed that an interface came up and attempted to perform its usual setup procedures, but the PTM check failed and the operation was aborted.",
+ .suggestion =
+ "If the problem persists, ensure that the interface is actually up and that PTM is functioning properly.",
+ },
+ {
+ .code = EC_ZEBRA_UNSUPPORTED_V4_SRCDEST,
+ .title =
+ "Kernel rejected sourcedest route",
+ .description =
+ "Zebra attempted to install a sourcedest route into the kernel, but the kernel did not acknowledge its installation. The route is unsupported.",
+ .suggestion =
+ "Check configuration values for correctness",
+ },
+ {
+ .code = EC_ZEBRA_UNKNOWN_INTERFACE,
+ .title =
+ "Zebra encountered an unknown interface specifier",
+ .description =
+ "Zebra was asked to look up an interface with a given name or index, but could not find the interface corresponding to the given name or index.",
+ .suggestion =
+ "Check configuration values for correctness.",
+ },
+ {
+ .code = EC_ZEBRA_VRF_NOT_FOUND,
+ .title =
+ "Zebra could not find the specified VRF",
+ .description =
+ "Zebra tried to look up a VRF, either by name or ID, and could not find it. This could be due to internal inconsistency (a bug) or a configuration error.",
+ .suggestion =
+ "Check configuration values for correctness. If values are correct, please file a bug report.",
+ },
+ {
+ .code = EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
+ .title =
+ "More nexthops were provided than the configured multipath limit",
+ .description =
+ "A route with multiple nexthops was given, but the number of nexthops exceeded the configured multipath limit.",
+ .suggestion =
+ "Reduce the number of nexthops, or increase the multipath limit.",
+ },
+ {
+ .code = EC_ZEBRA_NEXTHOP_CREATION_FAILED,
+ .title =
+ "Zebra failed to create one or more nexthops",
+ .description =
+ "While attempting to create nexthops for a route installation operation, Zebra found that it was unable to create one or more of the given nexthops.",
+ .suggestion =
+ "Check configuration values for correctness. If they are correct, report this as a bug.",
+ },
+ {
+ .code = EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+ .title =
+ "Zebra received sourcedest route install without IPv6 address family",
+ .description =
+ "Zebra received a message from a client requesting a sourcedest route installation, but the address family was not set to IPv6. Only IPv6 is supported for sourcedest routing.",
+ .suggestion =
+ "This is a bug; please report it.",
+ },
+ {
+ .code = EC_ZEBRA_PSEUDOWIRE_EXISTS,
+ .title =
+ "Zebra received an installation / creation request for a pseudowire that already exists",
+ .description =
+ "Zebra received an installation or creation request for a pseudowire that already exists, so the installation / creation has been skipped.",
+ .suggestion =
+ "This message is informational.",
+ },
+ {
+ .code = EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+ .title =
+ "Zebra received an uninstallation / deletion request for a pseudowire that already exists",
+ .description =
+ "Zebra received an uninstallation / deletion request for a pseudowire that doesn't exist, so the uninstallation / deletion has been skipped.",
+ .suggestion =
+ "This message is informational.",
+ },
+ {
+ .code = EC_ZEBRA_PSEUDOWIRE_UNINSTALL_NOT_FOUND,
+ .title =
+ "Zebra received uninstall request for a pseudowire that doesn't exist",
+ .description =
+ "Zebra received an uninstall request for a pseudowire that doesn't exist, so the uninstallation has been skipped.",
+ .suggestion =
+ "This message is informational.",
+ },
+ {
+ .code = EC_ZEBRA_NO_IFACE_ADDR,
+ .title = "No address on interface",
+ .description =
+ "Zebra attempted to retrieve a connected address for an interface, but the interface had no connected addresses.",
+ .suggestion =
+ "This warning is situational; it is usually informative but can indicate a misconfiguration.",
+ },
+ {
+ .code = EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
+ .title =
+ "Zebra failed to add address to interface",
+ .description =
+ "Zebra attempted to add an address to an interface but was unsuccessful.",
+ .suggestion =
+ "Check configuration values for correctness.",
+ },
+ {
+ .code = EC_ZEBRA_IRDP_CANNOT_ACTIVATE_IFACE,
+ .title =
+ "Zebra could not enable IRDP on interface",
+ .description =
+ "Zebra attempted to enable IRDP on an interface, but could not create the IRDP socket. The system may be out of socket resources, or privilege elevation may have failed.",
+ .suggestion =
+ "Verify that Zebra has the appropriate privileges and that the system has sufficient socket resources.",
+ },
+ {
+ .code = EC_ZEBRA_IRDP_IFACE_DOWN,
+ .title =
+ "Zebra attempted to enable IRDP on an interface, but the interface was down",
+ .description = "Zebra attempted to enable IRDP on an interface, but the interface was down.",
+ .suggestion =
+ "Bring up the interface that IRDP is desired on.",
+ },
+ {
+ .code = EC_ZEBRA_IRDP_IFACE_MCAST_DISABLED,
+ .title =
+ "Zebra cannot enable IRDP on interface because multicast is disabled",
+ .description =
+ "Zebra attempted to enable IRDP on an interface, but multicast functionality was not enabled on the interface.",
+ .suggestion =
+ "Enable multicast on the interface.",
+ },
+ {
+ .code = EC_ZEBRA_NETLINK_EXTENDED_WARNING,
+ .title =
+ "Zebra received warning message from Netlink",
+ .description =
+ "Zebra received a warning message from Netlink",
+ .suggestion =
+ "This message is informational. See the Netlink error message for details.",
+ },
+ {
+ .code = EC_ZEBRA_NAMESPACE_DIR_INACCESSIBLE,
+ .title =
+ "Zebra could not access /var/run/netns",
+ .description =
+ "Zebra tried to verify that the run directory for Linux network namespaces existed, but this test failed.",
+ .suggestion =
+ "Ensure that Zebra has the proper privileges to access this directory.",
+ },
+ {
+ .code = EC_ZEBRA_CONNECTED_AFI_UNKNOWN,
+ .title =
+ "Zebra received unknown address family on interface",
+ .description =
+ "Zebra received a notification of a connected prefix on an interface but did not recognize the address family as IPv4 or IPv6",
+ .suggestion =
+ "This message is informational.",
+ },
+ {
+ .code = EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER,
+ .title =
+ "Zebra route has same destination address as local interface",
+ .description =
+ "Zebra noticed that a route on an interface has the same destination address as an address on the interface itself, which may cause issues with routing protocols.",
+ .suggestion =
+ "Investigate the source of the route to determine why the destination and interface addresses are the same.",
+ },
+ {
+ .code = EC_ZEBRA_BCAST_ADDR_MISMATCH,
+ .title =
+ "Zebra broadcast address sanity check failed",
+ .description =
+ "Zebra computed the broadcast address for a connected prefix based on the netmask and found that it did not match the broadcast address it received for the prefix on that interface",
+ .suggestion =
+ "Investigate the source of the broadcast address to determine why it does not match the computed address.",
+ },
+ {
+ .code = EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+ .title =
+ "Zebra encountered unknown address family during redistribution",
+ .description =
+ "During a redistribution operation Zebra encountered an unknown address family.",
+ .suggestion =
+ "This warning can be ignored; the redistribution operation will skip the unknown address family.",
+ },
+ {
+ .code = EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
+ .title =
+ "Zebra advertising unusable interface address",
+ .description =
+ "Zebra is advertising an address on an interface that is not yet fully installed on the interface.",
+ .suggestion =
+ "This message is informational. The address should show up on the interface shortly after advertisement.",
+ },
+ {
+ .code = EC_ZEBRA_RA_PARAM_MISMATCH,
+ .title =
+ "Zebra received route advertisement with parameter mismatch",
+ .description =
+ "Zebra received a router advertisement, but one of the non-critical parameters (AdvCurHopLimit, AdvManagedFlag, AdvOtherConfigFlag, AdvReachableTime or AdvRetransTimer) does not match Zebra's local settings.",
+ .suggestion =
+ "This message is informational; the route advertisement will be processed as normal. If issues arise due to the parameter mismatch, check Zebra's router advertisement configuration.",
+ },
+ {
+ .code = EC_ZEBRA_RTM_VERSION_MISMATCH,
+ .title =
+ "Zebra received kernel message with uknown version",
+ .description =
+ "Zebra received a message from the kernel with a message version that does not match Zebra's internal version. Depending on version compatibility, this may cause issues sending and receiving messages to the kernel.",
+ .suggestion =
+ "If issues arise, check if there is a version of FRR available for your kernel version.",
+ },
+ {
+ .code = EC_ZEBRA_RTM_NO_GATEWAY,
+ .title =
+ "Zebra could not determine proper gateway for kernel route",
+ .description =
+ "Zebra attempted to install a route into the kernel, but noticed it had no gateway and no interface with a gateway could be located.",
+ .suggestion =
+ "Check configuration values for correctness.",
+ },
+ {
+ .code = EC_ZEBRA_MAX_LABELS_PUSH,
+ .title =
+ "Zebra exceeded maximum LSP labels for a single rtmsg",
+ .description =
+ "Zebra attempted to push more than one label into the kernel; the maximum on OpenBSD is 1 label.",
+ .suggestion =
+ "This message is informational.",
+ },
+ {
+ .code = EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
+ .title =
+ "EVPN MAC already learnt as remote sticky MAC",
+ .description =
+ "Zebra tried to handle a local MAC addition but noticed that it had already learnt the MAC from a remote peer.",
+ .suggestion =
+ "Check configuration values for correctness.",
+ },
+ {
+ .code = EC_ZEBRA_UNSUPPORTED_V6_SRCDEST,
+ .title =
+ "Kernel does not support IPv6 sourcedest routes",
+ .description =
+ "Zebra attempted to install a sourcedest route into the kernel, but IPv6 sourcedest routes are not supported on the current kernel.",
+ .suggestion =
+ "Do not use v6 sourcedest routes, or upgrade your kernel.",
+ },
{
.code = END_FERR,
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef __ZEBRA_ERRORS_H__
-#define __ZEBRA_ERRORS_H__
+#ifndef __EC_ZEBRAORS_H__
+#define __EC_ZEBRAORS_H__
#include "lib/ferr.h"
enum zebra_log_refs {
- ZEBRA_ERR_LM_RESPONSE = ZEBRA_FERR_START,
- ZEBRA_ERR_LM_NO_SUCH_CLIENT,
- ZEBRA_ERR_LM_RELAY_FAILED,
- ZEBRA_ERR_LM_NO_SOCKET,
- ZEBRA_ERR_LM_BAD_INSTANCE,
- ZEBRA_ERR_LM_RELAY_REQUEST_FAILED,
- ZEBRA_ERR_LM_CLIENT_CONNECTION_FAILED,
- ZEBRA_ERR_LM_EXHAUSTED_LABELS,
- ZEBRA_ERR_LM_DAEMON_MISMATCH,
- ZEBRA_ERR_LM_UNRELEASED_CHUNK,
- ZEBRA_ERR_DP_INVALID_RC,
- ZEBRA_ERR_WQ_NONEXISTENT,
- ZEBRA_ERR_FEC_ADD_FAILED,
- ZEBRA_ERR_FEC_RM_FAILED,
- ZEBRA_ERR_IRDP_LEN_MISMATCH,
- ZEBRA_ERR_RNH_UNKNOWN_FAMILY,
- ZEBRA_ERR_DP_INSTALL_FAIL,
- ZEBRA_ERR_TABLE_LOOKUP_FAILED,
- ZEBRA_ERR_NETLINK_NOT_AVAILABLE,
- ZEBRA_ERR_PROTOBUF_NOT_AVAILABLE,
- ZEBRA_ERR_TM_EXHAUSTED_IDS,
- ZEBRA_ERR_TM_DAEMON_MISMATCH,
- ZEBRA_ERR_TM_UNRELEASED_CHUNK,
- ZEBRA_ERR_UNKNOWN_FAMILY,
- ZEBRA_ERR_TM_WRONG_PROTO,
- ZEBRA_ERR_PROTO_OR_INSTANCE_MISMATCH,
- ZEBRA_ERR_LM_CANNOT_ASSIGN_CHUNK,
- ZEBRA_ERR_LM_ALIENS,
- ZEBRA_ERR_TM_CANNOT_ASSIGN_CHUNK,
- ZEBRA_ERR_TM_ALIENS,
- ZEBRA_ERR_RECVBUF,
- ZEBRA_ERR_UNKNOWN_NLMSG,
- ZEBRA_ERR_RECVMSG_OVERRUN,
- ZEBRA_ERR_NETLINK_LENGTH_ERROR,
- ZEBRA_ERR_UNEXPECTED_MESSAGE,
- ZEBRA_ERR_NETLINK_BAD_SEQUENCE,
- ZEBRA_ERR_BAD_MULTIPATH_NUM,
- ZEBRA_ERR_PREFIX_PARSE_ERROR,
- ZEBRA_ERR_MAC_ADD_FAILED,
- ZEBRA_ERR_VNI_DEL_FAILED,
- ZEBRA_ERR_VTEP_ADD_FAILED,
- ZEBRA_ERR_VNI_ADD_FAILED,
+ EC_ZEBRA_LM_RESPONSE = ZEBRA_FERR_START,
+ EC_ZEBRA_LM_NO_SUCH_CLIENT,
+ EC_ZEBRA_LM_RELAY_FAILED,
+ EC_ZEBRA_LM_NO_SOCKET,
+ EC_ZEBRA_LM_BAD_INSTANCE,
+ EC_ZEBRA_LM_RELAY_REQUEST_FAILED,
+ EC_ZEBRA_LM_CLIENT_CONNECTION_FAILED,
+ EC_ZEBRA_LM_EXHAUSTED_LABELS,
+ EC_ZEBRA_LM_DAEMON_MISMATCH,
+ EC_ZEBRA_LM_UNRELEASED_CHUNK,
+ EC_ZEBRA_DP_INVALID_RC,
+ EC_ZEBRA_WQ_NONEXISTENT,
+ EC_ZEBRA_FEC_ADD_FAILED,
+ EC_ZEBRA_FEC_RM_FAILED,
+ EC_ZEBRA_IRDP_LEN_MISMATCH,
+ EC_ZEBRA_RNH_UNKNOWN_FAMILY,
+ EC_ZEBRA_DP_INSTALL_FAIL,
+ EC_ZEBRA_DP_DELETE_FAIL,
+ EC_ZEBRA_TABLE_LOOKUP_FAILED,
+ EC_ZEBRA_NETLINK_NOT_AVAILABLE,
+ EC_ZEBRA_PROTOBUF_NOT_AVAILABLE,
+ EC_ZEBRA_TM_EXHAUSTED_IDS,
+ EC_ZEBRA_TM_DAEMON_MISMATCH,
+ EC_ZEBRA_TM_UNRELEASED_CHUNK,
+ EC_ZEBRA_UNKNOWN_FAMILY,
+ EC_ZEBRA_TM_WRONG_PROTO,
+ EC_ZEBRA_PROTO_OR_INSTANCE_MISMATCH,
+ EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK,
+ EC_ZEBRA_LM_ALIENS,
+ EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
+ EC_ZEBRA_TM_ALIENS,
+ EC_ZEBRA_RECVBUF,
+ EC_ZEBRA_UNKNOWN_NLMSG,
+ EC_ZEBRA_RECVMSG_OVERRUN,
+ EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ EC_ZEBRA_UNEXPECTED_MESSAGE,
+ EC_ZEBRA_NETLINK_BAD_SEQUENCE,
+ EC_ZEBRA_BAD_MULTIPATH_NUM,
+ EC_ZEBRA_PREFIX_PARSE_ERROR,
+ EC_ZEBRA_MAC_ADD_FAILED,
+ EC_ZEBRA_VNI_DEL_FAILED,
+ EC_ZEBRA_VTEP_ADD_FAILED,
+ EC_ZEBRA_VNI_ADD_FAILED,
+ /* warnings */
+ EC_ZEBRA_NS_NOTIFY_READ,
+ EC_ZEBRAING_LM_PROTO_MISMATCH,
+ EC_ZEBRA_LSP_INSTALL_FAILURE,
+ EC_ZEBRA_LSP_DELETE_FAILURE,
+ EC_ZEBRA_MPLS_SUPPORT_DISABLED,
+ EC_ZEBRA_SYSCTL_FAILED,
+ EC_ZEBRA_CONVERT_TO_DEBUG,
+ EC_ZEBRA_NS_VRF_CREATION_FAILED,
+ EC_ZEBRA_NS_DELETION_FAILED_NO_VRF,
+ EC_ZEBRA_IRDP_BAD_CHECKSUM,
+ EC_ZEBRA_IRDP_BAD_TYPE_CODE,
+ EC_ZEBRA_IRDP_BAD_RX_FLAGS,
+ EC_ZEBRA_IRDP_BAD_TYPE,
+ EC_ZEBRA_RNH_NO_TABLE,
+ EC_ZEBRA_IFLIST_FAILED,
+ EC_ZEBRA_FPM_FORMAT_UNKNOWN,
+ EC_ZEBRA_CLIENT_IO_ERROR,
+ EC_ZEBRA_CLIENT_WRITE_FAILED,
+ EC_ZEBRA_NETLINK_INVALID_AF,
+ EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET,
+ EC_ZEBRA_REMOVE_UNREGISTERED_ADDR,
+ EC_ZEBRA_PTM_NOT_READY,
+ EC_ZEBRA_UNSUPPORTED_V4_SRCDEST,
+ EC_ZEBRA_UNKNOWN_INTERFACE,
+ EC_ZEBRA_VRF_NOT_FOUND,
+ EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
+ EC_ZEBRA_NEXTHOP_CREATION_FAILED,
+ EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+ EC_ZEBRA_PSEUDOWIRE_EXISTS,
+ EC_ZEBRA_PSEUDOWIRE_UNINSTALL_NOT_FOUND,
+ EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+ EC_ZEBRA_NO_IFACE_ADDR,
+ EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
+ EC_ZEBRA_IRDP_CANNOT_ACTIVATE_IFACE,
+ EC_ZEBRA_IRDP_IFACE_DOWN,
+ EC_ZEBRA_IRDP_IFACE_MCAST_DISABLED,
+ EC_ZEBRA_NETLINK_EXTENDED_WARNING,
+ EC_ZEBRA_NAMESPACE_DIR_INACCESSIBLE,
+ EC_ZEBRA_CONNECTED_AFI_UNKNOWN,
+ EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER,
+ EC_ZEBRA_BCAST_ADDR_MISMATCH,
+ EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+ EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
+ EC_ZEBRA_RA_PARAM_MISMATCH,
+ EC_ZEBRA_RTM_VERSION_MISMATCH,
+ EC_ZEBRA_RTM_NO_GATEWAY,
+ EC_ZEBRA_MAX_LABELS_PUSH,
+ EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
+ EC_ZEBRA_UNSUPPORTED_V6_SRCDEST,
};
void zebra_error_init(void);
-#endif /* __ZEBRA_ERRORS_H__ */
+#endif /* __EC_ZEBRAORS_H__ */
if (!strcmp("netlink", format)) {
if (!have_netlink) {
- flog_err(
- ZEBRA_ERR_NETLINK_NOT_AVAILABLE,
- "FPM netlink message format is not available");
+ flog_err(EC_ZEBRA_NETLINK_NOT_AVAILABLE,
+ "FPM netlink message format is not available");
return;
}
zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK;
if (!strcmp("protobuf", format)) {
if (!have_protobuf) {
flog_err(
- ZEBRA_ERR_PROTOBUF_NOT_AVAILABLE,
+ EC_ZEBRA_PROTOBUF_NOT_AVAILABLE,
"FPM protobuf message format is not available");
return;
}
return;
}
- zlog_warn("Unknown fpm format '%s'", format);
+ flog_warn(EC_ZEBRA_FPM_FORMAT_UNKNOWN, "Unknown fpm format '%s'",
+ format);
}
/**
}
// TODO: Use src.
+ (void)src;
return 1;
}
switch (kernel_add_lsp(lsp)) {
case DP_REQUEST_QUEUED:
flog_err(
- ZEBRA_ERR_DP_INVALID_RC,
+ EC_ZEBRA_DP_INVALID_RC,
"No current DataPlane interfaces can return this, please fix");
break;
case DP_REQUEST_FAILURE:
switch (kernel_del_lsp(lsp)) {
case DP_REQUEST_QUEUED:
flog_err(
- ZEBRA_ERR_DP_INVALID_RC,
+ EC_ZEBRA_DP_INVALID_RC,
"No current DataPlane interfaces can return this, please fix");
break;
case DP_REQUEST_FAILURE:
switch (kernel_upd_lsp(lsp)) {
case DP_REQUEST_QUEUED:
flog_err(
- ZEBRA_ERR_DP_INVALID_RC,
+ EC_ZEBRA_DP_INVALID_RC,
"No current DataPlane interfaces can return this, please fix");
break;
case DP_REQUEST_FAILURE:
return 0;
if (zebrad.lsp_process_q == NULL) {
- flog_err(ZEBRA_ERR_WQ_NONEXISTENT,
- "%s: work_queue does not exist!", __func__);
+ flog_err(EC_ZEBRA_WQ_NONEXISTENT,
+ "%s: work_queue does not exist!", __func__);
return -1;
}
{
zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing");
if (!zebra->lsp_process_q) {
- flog_err(ZEBRA_ERR_WQ_NONEXISTENT,
- "%s: could not initialise work queue!", __func__);
+ flog_err(EC_ZEBRA_WQ_NONEXISTENT,
+ "%s: could not initialise work queue!", __func__);
return -1;
}
case DP_INSTALL_FAILURE:
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
clear_nhlfe_installed(lsp);
- zlog_warn("LSP Install Failure: %u", lsp->ile.in_label);
+ flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE,
+ "LSP Install Failure: %u", lsp->ile.in_label);
break;
case DP_INSTALL_SUCCESS:
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
clear_nhlfe_installed(lsp);
break;
case DP_DELETE_FAILURE:
- zlog_warn("LSP Deletion Failure: %u", lsp->ile.in_label);
+ flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE,
+ "LSP Deletion Failure: %u", lsp->ile.in_label);
break;
}
}
if (!fec) {
prefix2str(p, buf, BUFSIZ);
flog_err(
- ZEBRA_ERR_FEC_ADD_FAILED,
+ EC_ZEBRA_FEC_ADD_FAILED,
"Failed to add FEC %s upon register, client %s",
buf, zebra_route_string(client->proto));
return -1;
fec = fec_find(table, p);
if (!fec) {
prefix2str(p, buf, BUFSIZ);
- flog_err(ZEBRA_ERR_FEC_RM_FAILED,
- "Failed to find FEC %s upon unregister, client %s",
- buf, zebra_route_string(client->proto));
+ flog_err(EC_ZEBRA_FEC_RM_FAILED,
+ "Failed to find FEC %s upon unregister, client %s",
+ buf, zebra_route_string(client->proto));
return -1;
}
MPLS_INVALID_LABEL_INDEX);
if (!fec) {
prefix2str(p, buf, BUFSIZ);
- flog_err(ZEBRA_ERR_FEC_ADD_FAILED,
- "Failed to add FEC %s upon config", buf);
+ flog_err(EC_ZEBRA_FEC_ADD_FAILED,
+ "Failed to add FEC %s upon config", buf);
return -1;
}
fec = fec_find(table, p);
if (!fec) {
prefix2str(p, buf, BUFSIZ);
- flog_err(ZEBRA_ERR_FEC_RM_FAILED,
- "Failed to find FEC %s upon delete", buf);
+ flog_err(EC_ZEBRA_FEC_RM_FAILED,
+ "Failed to find FEC %s upon delete", buf);
return -1;
}
mpls_enabled = 0;
if (mpls_kernel_init() < 0) {
- zlog_warn("Disabling MPLS support (no kernel support)");
+ flog_warn(EC_ZEBRA_MPLS_SUPPORT_DISABLED,
+ "Disabling MPLS support (no kernel support)");
return;
}
#include "zebra/rt.h"
#include "zebra/zebra_mpls.h"
#include "zebra/debug.h"
+#include "zebra/zebra_errors.h"
#include "privs.h"
#include "prefix.h"
}
if (ret == -1)
- flog_err_sys(LIB_ERR_SOCKET, "%s: %s", __func__,
+ flog_err_sys(EC_LIB_SOCKET, "%s: %s", __func__,
safe_strerror(errno));
return ret;
}
if (ret == -1)
- flog_err_sys(LIB_ERR_SOCKET, "%s: %s", __func__,
+ flog_err_sys(EC_LIB_SOCKET, "%s: %s", __func__,
safe_strerror(errno));
return ret;
&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)
&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)))) {
if (nhlfe->nexthop->nh_label->num_labels > 1) {
- zlog_warn(
- "%s: can't push %u labels at once "
- "(maximum is 1)",
- __func__,
- nhlfe->nexthop->nh_label->num_labels);
+ flog_warn(EC_ZEBRA_MAX_LABELS_PUSH,
+ "%s: can't push %u labels at once "
+ "(maximum is 1)",
+ __func__,
+ nhlfe->nexthop->nh_label->num_labels);
continue;
}
imr.imr_type = IMR_TYPE_ETHERNET_TAGGED;
break;
default:
- zlog_warn("%s: unhandled pseudowire type (%#X)", __func__,
- pw->type);
+ zlog_debug("%s: unhandled pseudowire type (%#X)", __func__,
+ pw->type);
return -1;
}
sa_in6->sin6_addr = pw->nexthop.ipv6;
break;
default:
- zlog_warn("%s: unhandled pseudowire address-family (%u)",
- __func__, pw->af);
+ zlog_debug("%s: unhandled pseudowire address-family (%u)",
+ __func__, pw->af);
return -1;
}
memcpy(&imr.imr_nexthop, (struct sockaddr *)&ss,
strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name));
ifr.ifr_data = (caddr_t)&imr;
if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s",
safe_strerror(errno));
return -1;
}
strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name));
ifr.ifr_data = (caddr_t)&imr;
if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s",
+ flog_err_sys(EC_LIB_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s",
safe_strerror(errno));
return -1;
}
socklen_t optlen;
if ((kr_state.fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
- zlog_warn("%s: socket", __func__);
+ flog_err_sys(EC_LIB_SOCKET, "%s: socket", __func__);
return -1;
}
if ((kr_state.ioctl_fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0))
== -1) {
- zlog_warn("%s: ioctl socket", __func__);
+ flog_err_sys(EC_LIB_SOCKET, "%s: ioctl socket", __func__);
return -1;
}
if (getsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF, &default_rcvbuf,
&optlen)
== -1)
- zlog_warn("kr_init getsockopt SOL_SOCKET SO_RCVBUF");
+ flog_err_sys(EC_LIB_SOCKET,
+ "kr_init getsockopt SOL_SOCKET SO_RCVBUF");
else
for (rcvbuf = MAX_RTSOCK_BUF;
rcvbuf > default_rcvbuf
strlcpy(sbuf, inet_ntoa(mroute.sg.src), sizeof(sbuf));
strlcpy(gbuf, inet_ntoa(mroute.sg.grp), sizeof(gbuf));
- zlog_debug("Asking for (%s,%s) mroute information", sbuf, gbuf);
+ zlog_debug("Asking for (%s,%s)[%s(%u)] mroute information",
+ sbuf, gbuf, zvrf->vrf->name, zvrf->vrf->vrf_id);
}
suc = kernel_get_ipmr_sg_stats(zvrf, &mroute);
ret = sendto(sock, (const void *)nlh, (size_t)nlh->nlmsg_len, 0,
(struct sockaddr *)&snl, (socklen_t)sizeof(snl));
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "netlink( %u) sendmsg() error: %s",
+ flog_err_sys(EC_LIB_SOCKET, "netlink( %u) sendmsg() error: %s",
sock, safe_strerror(errno));
return -1;
}
};
ret = recvmsg(sock, &msg, 0);
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"netlink recvmsg: error %d (errno %u)", ret,
errno);
return -1;
}
if (msg.msg_flags & MSG_TRUNC) {
- flog_err(ZEBRA_ERR_NETLINK_LENGTH_ERROR,
- "netlink recvmsg : error message truncated");
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "netlink recvmsg : error message truncated");
return -1;
}
/* nlh already points to buf */
if (nlh->nlmsg_seq != seq) {
flog_err(
- ZEBRA_ERR_NETLINK_BAD_SEQUENCE,
+ EC_ZEBRA_NETLINK_BAD_SEQUENCE,
"netlink recvmsg: bad sequence number %x (expected %x)",
seq, nlh->nlmsg_seq);
return -1;
/* netlink socket */
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sock < 0) {
- flog_err_sys(LIB_ERR_SOCKET, "netlink( %u) socket() error: %s",
+ flog_err_sys(EC_LIB_SOCKET, "netlink( %u) socket() error: %s",
sock, safe_strerror(errno));
close(fd);
return NS_UNKNOWN;
snl.nl_pid = 0; /* AUTO PID */
ret = bind(sock, (struct sockaddr *)&snl, sizeof(snl));
if (ret < 0) {
- flog_err_sys(LIB_ERR_SOCKET,
+ flog_err_sys(EC_LIB_SOCKET,
"netlink( %u) socket() bind error: %s", sock,
safe_strerror(errno));
close(sock);
if (ret <= 0) {
if (errno != EEXIST && ret != 0) {
flog_err(
- LIB_ERR_SOCKET,
+ EC_LIB_SOCKET,
"netlink( %u) recvfrom() error 2 when reading: %s",
fd, safe_strerror(errno));
close(sock);
close(fd);
if (errno == ENOTSUP) {
- zlog_warn("NEWNSID locally generated");
+ zlog_debug("NEWNSID locally generated");
return zebra_ns_id_get_fallback(netnspath);
}
return NS_UNKNOWN;
/* S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH */
if (mkdir(NS_RUN_DIR, 0755)) {
if (errno != EEXIST) {
- zlog_warn("NS check: failed to access %s", NS_RUN_DIR);
+ flog_warn(EC_ZEBRA_NAMESPACE_DIR_INACCESSIBLE,
+ "NS check: failed to access %s", NS_RUN_DIR);
return;
}
}
#include "zebra_netns_notify.h"
#include "zebra_netns_id.h"
+#include "zebra_errors.h"
#ifdef HAVE_NETLINK
/* if VRF with NS ID already present */
vrf = vrf_lookup_by_id((vrf_id_t)ns_id_external);
if (vrf) {
- zlog_warn(
+ zlog_debug(
"NS notify : same NSID used by VRF %s. Ignore NS %s creation",
vrf->name, netnspath);
return;
}
if (vrf_handler_create(NULL, name, &vrf) != CMD_SUCCESS) {
- zlog_warn("NS notify : failed to create VRF %s", name);
+ flog_warn(EC_ZEBRA_NS_VRF_CREATION_FAILED,
+ "NS notify : failed to create VRF %s", name);
ns_map_nsid_with_external(ns_id, false);
return;
}
ns_id_external, ns_id);
}
if (ret != CMD_SUCCESS) {
- zlog_warn("NS notify : failed to create NS %s", netnspath);
+ flog_warn(EC_ZEBRA_NS_VRF_CREATION_FAILED,
+ "NS notify : failed to create NS %s", netnspath);
ns_map_nsid_with_external(ns_id, false);
vrf_delete(vrf);
return;
struct ns *ns;
if (!vrf) {
- zlog_warn(
- "NS notify : no VRF found using NS %s",
- name);
+ flog_warn(EC_ZEBRA_NS_DELETION_FAILED_NO_VRF,
+ "NS notify : no VRF found using NS %s", name);
return 0;
}
/* Clear configured flag and invoke delete. */
zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);
len = read(fd_monitor, buf, sizeof(buf));
if (len < 0) {
- zlog_warn("NS notify read: failed to read (%s)",
- safe_strerror(errno));
+ flog_err_sys(EC_ZEBRA_NS_NOTIFY_READ,
+ "NS notify read: failed to read (%s)",
+ safe_strerror(errno));
return 0;
}
for (event = (struct inotify_event *)buf; (char *)event < &buf[len];
if (offsetof(struct inotify_event, name) + event->len
>= sizeof(buf)) {
- zlog_err("NS notify read: buffer underflow");
+ flog_err(EC_ZEBRA_NS_NOTIFY_READ,
+ "NS notify read: buffer underflow");
break;
}
if (strnlen(event->name, event->len) == event->len) {
- zlog_err("NS notify error: bad event name");
+ flog_err(EC_ZEBRA_NS_NOTIFY_READ,
+ "NS notify error: bad event name");
break;
}
DIR *srcdir = opendir(NS_RUN_DIR);
if (srcdir == NULL) {
- zlog_warn("NS parsing init: failed to parse %s", NS_RUN_DIR);
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "NS parsing init: failed to parse %s", NS_RUN_DIR);
return;
}
while ((dent = readdir(srcdir)) != NULL) {
|| strcmp(dent->d_name, "..") == 0)
continue;
if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) {
- zlog_warn("NS parsing init: failed to parse entry %s",
- dent->d_name);
+ flog_err_sys(
+ EC_LIB_SYSTEM_CALL,
+ "NS parsing init: failed to parse entry %s",
+ dent->d_name);
continue;
}
if (S_ISDIR(st.st_mode)) {
- zlog_warn("NS parsing init: %s is not a NS",
- dent->d_name);
+ zlog_debug("NS parsing init: %s is not a NS",
+ dent->d_name);
continue;
}
if (zebra_ns_notify_is_default_netns(dent->d_name)) {
zebra_netns_notify_current = NULL;
fd_monitor = inotify_init();
if (fd_monitor < 0) {
- zlog_warn("NS notify init: failed to initialize inotify (%s)",
- safe_strerror(errno));
+ flog_err_sys(
+ EC_LIB_SYSTEM_CALL,
+ "NS notify init: failed to initialize inotify (%s)",
+ safe_strerror(errno));
}
if (inotify_add_watch(fd_monitor, NS_RUN_DIR,
IN_CREATE | IN_DELETE) < 0) {
- zlog_warn("NS notify watch: failed to add watch (%s)",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "NS notify watch: failed to add watch (%s)",
+ safe_strerror(errno));
}
zebra_netns_notify_current = thread_add_read(
zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);
#include "lib/logicalrouter.h"
#include "lib/prefix.h"
#include "lib/memory.h"
-#include "lib/lib_errors.h"
#include "rtadv.h"
#include "zebra_ns.h"
hash_clean(zns->rules_hash, zebra_pbr_rules_free);
hash_free(zns->rules_hash);
- hash_clean(zns->ipset_entry_hash,
- zebra_pbr_ipset_entry_free),
+ hash_clean(zns->ipset_entry_hash, zebra_pbr_ipset_entry_free);
hash_clean(zns->ipset_hash, zebra_pbr_ipset_free);
hash_free(zns->ipset_hash);
hash_free(zns->ipset_entry_hash);
hash_release(zns->rules_hash, lookup);
XFREE(MTYPE_TMP, lookup);
} else
- zlog_warn("%s: Rule being deleted we know nothing about",
- __PRETTY_FUNCTION__);
+ zlog_debug("%s: Rule being deleted we know nothing about",
+ __PRETTY_FUNCTION__);
}
static void zebra_pbr_cleanup_rules(struct hash_backet *b, void *data)
hash_release(zns->ipset_hash, lookup);
XFREE(MTYPE_TMP, lookup);
} else
- zlog_warn("%s: IPSet Entry being deleted we know nothing about",
- __PRETTY_FUNCTION__);
+ zlog_debug(
+ "%s: IPSet Entry being deleted we know nothing about",
+ __PRETTY_FUNCTION__);
}
struct pbr_ipset_name_lookup {
hash_release(zns->ipset_entry_hash, lookup);
XFREE(MTYPE_TMP, lookup);
} else
- zlog_warn("%s: IPSet being deleted we know nothing about",
- __PRETTY_FUNCTION__);
+ zlog_debug("%s: IPSet being deleted we know nothing about",
+ __PRETTY_FUNCTION__);
}
static void *pbr_iptable_alloc_intern(void *arg)
}
XFREE(MTYPE_TMP, lookup);
} else
- zlog_warn("%s: IPTable being deleted we know nothing about",
- __PRETTY_FUNCTION__);
+ zlog_debug("%s: IPTable being deleted we know nothing about",
+ __PRETTY_FUNCTION__);
}
/*
*/
extern void kernel_read_pbr_rules(struct zebra_ns *zns);
-enum dp_results;
/*
* Handle success or failure of rule (un)install in the kernel.
*/
#include "version.h"
#include "vrf.h"
#include "vty.h"
+#include "lib_errors.h"
#include "zebra/debug.h"
#include "zebra/interface.h"
ptm_cb.out_data = calloc(1, ZEBRA_PTM_SEND_MAX_SOCKBUF);
if (!ptm_cb.out_data) {
- zlog_warn("%s: Allocation of send data failed", __func__);
+ zlog_debug("%s: Allocation of send data failed", __func__);
return;
}
ptm_cb.in_data = calloc(1, ZEBRA_PTM_MAX_SOCKBUF);
if (!ptm_cb.in_data) {
- zlog_warn("%s: Allocation of recv data failed", __func__);
+ zlog_debug("%s: Allocation of recv data failed", __func__);
free(ptm_cb.out_data);
return;
}
switch (buffer_flush_available(ptm_cb.wb, ptm_cb.ptm_sock)) {
case BUFFER_ERROR:
- zlog_warn("%s ptm socket error: %s", __func__,
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "%s ptm socket error: %s", __func__,
+ safe_strerror(errno));
close(ptm_cb.ptm_sock);
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
errno = 0;
switch (buffer_write(ptm_cb.wb, ptm_cb.ptm_sock, data, size)) {
case BUFFER_ERROR:
- zlog_warn("%s ptm socket error: %s", __func__,
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "%s ptm socket error: %s", __func__,
+ safe_strerror(errno));
close(ptm_cb.ptm_sock);
ptm_cb.ptm_sock = -1;
zebra_ptm_reset_status(0);
dest_str, src_str);
if (str2prefix(dest_str, &dest_prefix) == 0) {
- flog_err(ZEBRA_ERR_PREFIX_PARSE_ERROR,
- "%s: Peer addr %s not found", __func__, dest_str);
+ flog_err(EC_ZEBRA_PREFIX_PARSE_ERROR,
+ "%s: Peer addr %s not found", __func__, dest_str);
return -1;
}
memset(&src_prefix, 0, sizeof(struct prefix));
if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) {
if (str2prefix(src_str, &src_prefix) == 0) {
- flog_err(ZEBRA_ERR_PREFIX_PARSE_ERROR,
- "%s: Local addr %s not found", __func__,
- src_str);
+ flog_err(EC_ZEBRA_PREFIX_PARSE_ERROR,
+ "%s: Local addr %s not found", __func__,
+ src_str);
return -1;
}
}
ifp = if_lookup_by_name_all_vrf(port_str);
if (!ifp) {
- zlog_warn("%s: %s not found in interface list",
+ flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
+ "%s: %s not found in interface list",
__func__, port_str);
return -1;
}
if (((rc == 0) && !errno)
|| (errno && (errno != EWOULDBLOCK) && (errno != EAGAIN))) {
- zlog_warn("%s routing socket error: %s(%d) bytes %d",
- __func__, safe_strerror(errno), errno, rc);
+ flog_err_sys(EC_LIB_SOCKET,
+ "%s routing socket error: %s(%d) bytes %d",
+ __func__, safe_strerror(errno), errno, rc);
close(ptm_cb.ptm_sock);
ptm_cb.ptm_sock = -1;
return 0;
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_warn("bfd_client_deregister msg for client %s",
- zebra_route_string(proto));
+ zlog_debug("bfd_client_deregister msg for client %s",
+ zebra_route_string(proto));
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
/* Create copy for replication. */
msgc = stream_dup(msg);
if (msgc == NULL) {
- zlog_warn("%s: not enough memory", __func__);
+ zlog_debug("%s: not enough memory", __func__);
return;
}
/* Allocate more messages. */
msg = stream_dup(msgc);
if (msg == NULL) {
- zlog_warn("%s: not enough memory", __func__);
+ zlog_debug("%s: not enough memory", __func__);
return;
}
}
/* Create copy for replication. */
msgc = stream_dup(msg);
if (msgc == NULL) {
- zlog_warn("%s: not enough memory", __func__);
+ zlog_debug("%s: not enough memory", __func__);
return;
}
/* Allocate more messages. */
msg = stream_dup(msgc);
if (msg == NULL) {
- zlog_warn("%s: not enough memory", __func__);
+ zlog_debug("%s: not enough memory", __func__);
return;
}
}
/* Generate, send message and free() daemon related data. */
msg = stream_new(ZEBRA_MAX_PACKET_SIZ);
if (msg == NULL) {
- zlog_warn("%s: not enough memory", __func__);
+ zlog_debug("%s: not enough memory", __func__);
return 0;
}
*/
msgc = stream_new(ZEBRA_MAX_PACKET_SIZ);
if (msgc == NULL) {
- zlog_warn("%s: not enough memory", __func__);
+ zlog_debug("%s: not enough memory", __func__);
return;
}
*/
msgc = stream_new(ZEBRA_MAX_PACKET_SIZ);
if (msgc == NULL) {
- zlog_warn("%s: not enough memory", __func__);
+ zlog_debug("%s: not enough memory", __func__);
return;
}
&pw->nexthop, NULL);
if (!re) {
if (IS_ZEBRA_DEBUG_PW)
- zlog_warn("%s: no route found for %s", __func__,
- pw->ifname);
+ zlog_debug("%s: no route found for %s", __func__,
+ pw->ifname);
return -1;
}
for (ALL_NEXTHOPS(re->ng, nexthop)) {
if (!nexthop->nh_label) {
if (IS_ZEBRA_DEBUG_PW)
- zlog_warn("%s: unlabeled route for %s",
- __func__, pw->ifname);
+ zlog_debug("%s: unlabeled route for %s",
+ __func__, pw->ifname);
return -1;
}
}
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);
}
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);
/* 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
*/
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. */
}
/* 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) {
*/
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
}
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;
}
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;
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? */
dest->selected_fib = re;
zsend_route_notify_owner(re, p, ZAPI_ROUTE_FAIL_INSTALL);
- zlog_warn("%u:%s: Route install failed", re->vrf_id,
- prefix2str(p, buf, sizeof(buf)));
+ flog_err(EC_ZEBRA_DP_INSTALL_FAIL,
+ "%u:%s: Route install failed", re->vrf_id,
+ prefix2str(p, buf, sizeof(buf)));
break;
case DP_DELETE_SUCCESS:
/*
* delete fails?
*/
dest->selected_fib = NULL;
- zlog_warn("%u:%s: Route Deletion failure", re->vrf_id,
- prefix2str(p, buf, sizeof(buf)));
+ flog_err(EC_ZEBRA_DP_DELETE_FAIL,
+ "%u:%s: Route Deletion failure", re->vrf_id,
+ prefix2str(p, buf, sizeof(buf)));
zsend_route_notify_owner(re, p, ZAPI_ROUTE_REMOVE_FAIL);
break;
switch (kernel_route_rib(rn, p, src_p, old, re)) {
case DP_REQUEST_QUEUED:
flog_err(
- ZEBRA_ERR_DP_INVALID_RC,
+ EC_ZEBRA_DP_INVALID_RC,
"No current known DataPlane interfaces can return this, please fix");
break;
case DP_REQUEST_FAILURE:
flog_err(
- ZEBRA_ERR_DP_INSTALL_FAIL,
+ EC_ZEBRA_DP_INSTALL_FAIL,
"No current known Rib Install Failure cases, please fix");
break;
case DP_REQUEST_SUCCESS:
switch (kernel_route_rib(rn, p, src_p, re, NULL)) {
case DP_REQUEST_QUEUED:
flog_err(
- ZEBRA_ERR_DP_INVALID_RC,
+ EC_ZEBRA_DP_INVALID_RC,
"No current known DataPlane interfaces can return this, please fix");
break;
case DP_REQUEST_FAILURE:
flog_err(
- ZEBRA_ERR_DP_INSTALL_FAIL,
+ EC_ZEBRA_DP_INSTALL_FAIL,
"No current known RIB Install Failure cases, please fix");
break;
case DP_REQUEST_SUCCESS:
}
if (zebrad.ribq == NULL) {
- flog_err(ZEBRA_ERR_WQ_NONEXISTENT,
- "%s: work_queue does not exist!", __func__);
+ flog_err(EC_ZEBRA_WQ_NONEXISTENT,
+ "%s: work_queue does not exist!", __func__);
return;
}
if (!(zebra->ribq =
work_queue_new(zebra->master, "route_node processing"))) {
- flog_err(ZEBRA_ERR_WQ_NONEXISTENT,
- "%s: could not initialise work queue!", __func__);
+ flog_err(EC_ZEBRA_WQ_NONEXISTENT,
+ "%s: could not initialise work queue!", __func__);
return;
}
zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
if (!(zebra->mq = meta_queue_new())) {
- flog_err(ZEBRA_ERR_WQ_NONEXISTENT,
- "%s: could not initialise meta queue!", __func__);
+ flog_err(EC_ZEBRA_WQ_NONEXISTENT,
+ "%s: could not initialise meta queue!", __func__);
return;
}
return;
/* Lookup table. */
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
if (!table) {
- flog_err(ZEBRA_ERR_TABLE_LOOKUP_FAILED,
- "%s:%u zebra_vrf_table() returned NULL", __func__,
- vrf_id);
+ flog_err(EC_ZEBRA_TABLE_LOOKUP_FAILED,
+ "%s:%u zebra_vrf_table() returned NULL", __func__,
+ vrf_id);
return;
}
rib_dest_t *dest;
if (NULL == (table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id))) {
- flog_err(ZEBRA_ERR_TABLE_LOOKUP_FAILED,
- "%s:%u zebra_vrf_table() returned NULL", __func__,
- vrf_id);
+ flog_err(EC_ZEBRA_TABLE_LOOKUP_FAILED,
+ "%s:%u zebra_vrf_table() returned NULL", __func__,
+ vrf_id);
return;
}
table = get_rnh_table(vrfid, PREFIX_FAMILY(p), type);
if (!table) {
prefix2str(p, buf, sizeof(buf));
- zlog_warn("%u: Add RNH %s type %d - table not found", vrfid,
+ flog_warn(EC_ZEBRA_RNH_NO_TABLE,
+ "%u: Add RNH %s type %d - table not found", vrfid,
buf, type);
exists = false;
return NULL;
break;
default:
memset(prefix, 0, sizeof(*prefix));
- zlog_warn("%s: unknown address family %d", __func__, af);
+ zlog_debug("%s: unknown address family %d", __func__, af);
break;
}
}
stream_put(s, &rn->p.u.prefix6, IPV6_MAX_BYTELEN);
break;
default:
- flog_err(ZEBRA_ERR_RNH_UNKNOWN_FAMILY,
- "%s: Unknown family (%d) notification attempted\n",
- __FUNCTION__, rn->p.family);
+ flog_err(EC_ZEBRA_RNH_UNKNOWN_FAMILY,
+ "%s: Unknown family (%d) notification attempted\n",
+ __FUNCTION__, rn->p.family);
break;
}
if (re) {
static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid);
static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
-static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local);
+static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac);
static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
static unsigned int vni_hash_keymake(void *p);
struct ipaddr *ip);
struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
static int advertise_gw_macip_enabled(zebra_vni_t *zvni);
-static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
- int uninstall);
+static int remote_neigh_count(zebra_mac_t *zmac);
+static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac);
/* Private functions */
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);
+ zlog_debug("%s: Unexpected family type: %d",
+ __PRETTY_FUNCTION__, hle1->p.family);
return 0;
}
}
n = (zebra_neigh_t *)backet->data;
- ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
+ ipaddr2str(&n->ip, buf, sizeof(buf));
+ width = strlen(buf);
if (width > wctx->addr_width)
wctx->addr_width = width;
return 0;
if (!zvni->vxlan_if) {
- zlog_warn("VNI %u hash %p couldn't be uninstalled - no intf",
- zvni->vni, zvni);
+ zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
+ zvni->vni, zvni);
return -1;
}
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, vxl->access_vlan);
+ flog_err(EC_ZEBRA_MAC_ADD_FAILED,
+ "Failed to add MAC %s intf %s(%u) VID %u",
+ prefix_mac2str(macaddr, buf, sizeof(buf)),
+ ifp->name, ifp->ifindex, vxl->access_vlan);
return -1;
}
}
n = zvni_neigh_add(zvni, ip, macaddr);
if (!n) {
flog_err(
- ZEBRA_ERR_MAC_ADD_FAILED,
+ EC_ZEBRA_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)),
/* mac entry should be present */
mac = zvni_mac_lookup(zvni, &n->emac);
if (!mac) {
- zlog_warn("MAC %s doesnt exists for neigh %s on VNI %u",
- prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
- ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
+ zlog_debug("MAC %s doesnt exists for neigh %s on VNI %u",
+ prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
+ ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
return -1;
}
/* see if the mac needs to be deleted as well*/
if (mac)
- zvni_deref_ip2mac(zvni, mac, 0);
+ zvni_deref_ip2mac(zvni, mac);
return 0;
}
struct interface *ifp,
struct ipaddr *ip,
struct ethaddr *macaddr,
- uint8_t router_flag)
+ bool is_router)
{
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
zmac = zvni_mac_add(zvni, macaddr);
if (!zmac) {
- zlog_warn("Failed to add MAC %s VNI %u",
- prefix_mac2str(macaddr, buf, sizeof(buf)),
- zvni->vni);
+ zlog_debug("Failed to add MAC %s VNI %u",
+ prefix_mac2str(macaddr, buf, sizeof(buf)),
+ zvni->vni);
return -1;
}
n = zvni_neigh_add(zvni, ip, macaddr);
if (!n) {
flog_err(
- ZEBRA_ERR_MAC_ADD_FAILED,
+ EC_ZEBRA_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)),
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))
- check_rbit = true;
-
- if (memcmp(n->emac.octet, macaddr->octet,
- ETH_ALEN) == 0) {
- /* Update any params and return - client doesn't
- * care about a purely local change.
- */
+ bool mac_different;
+ bool cur_is_router;
+
+ /* Note any changes and see if of interest to BGP. */
+ mac_different = (memcmp(n->emac.octet,
+ macaddr->octet, ETH_ALEN) != 0) ? 1 : 0;
+ cur_is_router = !!CHECK_FLAG(n->flags,
+ ZEBRA_NEIGH_ROUTER_FLAG);
+ if (!mac_different && is_router == cur_is_router) {
n->ifindex = ifp->ifindex;
- } else {
+ return 0;
+ }
- /* 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.
- */
- 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) {
- 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);
- }
+ if (!mac_different) {
+ /* Only the router flag has changed. */
+ if (is_router)
+ SET_FLAG(n->flags,
+ ZEBRA_NEIGH_ROUTER_FLAG);
+ else
+ UNSET_FLAG(n->flags,
+ ZEBRA_NEIGH_ROUTER_FLAG);
- /* Update the forwarding info. */
- n->ifindex = ifp->ifindex;
- memcpy(&n->emac, macaddr, ETH_ALEN);
+ if (IS_ZEBRA_NEIGH_ACTIVE(n))
+ return zvni_neigh_send_add_to_client(
+ zvni->vni, ip, macaddr,
+ n->flags, n->loc_seq);
+ return 0;
+ }
- /* Link to new MAC */
- listnode_add_sort(zmac->neigh_list, n);
+ /* 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.
+ */
+ 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) {
+ 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);
}
+ /* Update the forwarding info. */
+ n->ifindex = ifp->ifindex;
+ memcpy(&n->emac, macaddr, ETH_ALEN);
+
+ /* Link to new MAC */
+ listnode_add_sort(zmac->neigh_list, n);
} else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
/*
* Neighbor has moved from remote to local. Its
neigh_mac_change = upd_mac_seq = true;
listnode_delete(old_zmac->neigh_list,
n);
- zvni_deref_ip2mac(zvni, old_zmac, 0);
+ zvni_deref_ip2mac(zvni, old_zmac);
}
/* Link to new MAC */
}
/*Mark Router flag (R-bit) */
- if (router_flag)
+ if (is_router)
SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
else
UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
*/
zmac = zvni_mac_lookup(zvni, macaddr);
if (!zmac || !CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
- zlog_warn(
+ zlog_debug(
"Ignore remote neigh %s (MAC %s) on L2-VNI %u - MAC unknown or local",
ipaddr2str(&n->ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
}
if (wctx->uninstall)
- zvni_mac_uninstall(wctx->zvni, mac, 0);
+ zvni_mac_uninstall(wctx->zvni, mac);
zvni_mac_del(wctx->zvni, mac);
}
{
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
- uint8_t sticky;
+ bool sticky;
if (!(mac->flags & ZEBRA_MAC_REMOTE))
return 0;
return -1;
vxl = &zif->l2info.vxl;
- sticky = CHECK_FLAG(mac->flags,
- (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)) ? 1 : 0;
+ sticky = !!CHECK_FLAG(mac->flags,
+ (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
mac->fwd_info.r_vtep_ip, sticky);
}
/*
- * Uninstall remote MAC from the kernel. In the scenario where the MAC
- * moves to remote, we have to uninstall any existing local entry first.
+ * Uninstall remote MAC from the kernel.
*/
-static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local)
+static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac)
{
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
- struct in_addr vtep_ip = {.s_addr = 0};
- struct zebra_ns *zns;
+ struct in_addr vtep_ip;
struct interface *ifp;
- if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
+ if (!(mac->flags & ZEBRA_MAC_REMOTE))
return 0;
if (!zvni->vxlan_if) {
- zlog_warn("VNI %u hash %p couldn't be uninstalled - no intf",
- zvni->vni, zvni);
+ zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
+ zvni->vni, zvni);
return -1;
}
return -1;
vxl = &zif->l2info.vxl;
- if (local) {
- zns = zebra_ns_lookup(NS_DEFAULT);
- ifp = if_lookup_by_index_per_ns(zns,
- mac->fwd_info.local.ifindex);
- if (!ifp) // unexpected
- return -1;
- } else {
- ifp = zvni->vxlan_if;
- vtep_ip = mac->fwd_info.r_vtep_ip;
- }
+ ifp = zvni->vxlan_if;
+ vtep_ip = mac->fwd_info.r_vtep_ip;
- return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip,
- local);
+ return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip);
}
/*
zvni_mac_install(wctx->zvni, mac);
}
+/*
+ * Count of remote neighbors referencing this MAC.
+ */
+static int remote_neigh_count(zebra_mac_t *zmac)
+{
+ zebra_neigh_t *n = NULL;
+ struct listnode *node = NULL;
+ int count = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
+ if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
+ count++;
+ }
+
+ return count;
+}
+
/*
* Decrement neighbor refcount of MAC; uninstall and free it if
* appropriate.
*/
-static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
- int uninstall)
+static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac)
{
- if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)
- || !list_isempty(mac->neigh_list))
+ if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
return;
- if (uninstall)
- zvni_mac_uninstall(zvni, mac, 0);
+ /* If all remote neighbors referencing a remote MAC go away,
+ * we need to uninstall the MAC.
+ */
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) &&
+ remote_neigh_count(mac) == 0) {
+ zvni_mac_uninstall(zvni, mac);
+ UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
+ }
- zvni_mac_del(zvni, mac);
+ /* If no neighbors, delete the MAC. */
+ if (list_isempty(mac->neigh_list))
+ zvni_mac_del(zvni, mac);
}
/*
/* VNI hash entry is not expected to exist. */
zvni = zvni_lookup(vni);
if (zvni) {
- zlog_warn(
+ zlog_debug(
"VNI hash already present for IF %s(%u) L2-VNI %u",
ifp->name, ifp->ifindex, vni);
continue;
zvni = zvni_add(vni);
if (!zvni) {
- zlog_warn(
+ zlog_debug(
"Failed to add VNI hash, IF %s(%u) L2-VNI %u",
ifp->name, ifp->ifindex, vni);
return;
static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
{
if (!zvni->vxlan_if) {
- zlog_warn("VNI %u hash %p couldn't be uninstalled - no intf",
- zvni->vni, zvni);
+ zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
+ zvni->vni, zvni);
return -1;
}
return 0;
if (!zl3vni->vxlan_if) {
- zlog_warn(
+ zlog_debug(
"RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
zl3vni->vni, zl3vni);
vxl = &zif->l2info.vxl;
return kernel_del_mac(zl3vni->vxlan_if, vxl->access_vlan,
- &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0);
+ &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip);
}
/* handle rmac add */
zrmac = zl3vni_rmac_add(zl3vni, rmac);
if (!zrmac) {
- zlog_warn(
+ zlog_debug(
"Failed to add RMAC %s L3VNI %u Remote VTEP %s",
prefix_mac2str(rmac, buf, sizeof(buf)),
zl3vni->vni,
nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
if (!nh) {
- zlog_warn(
+ zlog_debug(
"Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
ipaddr2str(vtep_ip, buf1, sizeof(buf1)),
prefix_mac2str(rmac, buf, sizeof(buf)),
/* Delete the hash entry. */
if (zvni_del(zvni)) {
- flog_err(ZEBRA_ERR_VNI_DEL_FAILED,
- "Failed to del VNI hash %p, VNI %u", zvni,
- zvni->vni);
+ flog_err(EC_ZEBRA_VNI_DEL_FAILED,
+ "Failed to del VNI hash %p, VNI %u", zvni,
+ zvni->vni);
return -1;
}
} else {
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;
+ bool sticky;
+ bool remote_gw;
+ bool is_router;
/* Locate VNI hash entry - expected to exist. */
zvni = zvni_lookup(vni);
if (!zvtep) {
if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
flog_err(
- ZEBRA_ERR_VTEP_ADD_FAILED,
+ EC_ZEBRA_VTEP_ADD_FAILED,
"Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD",
vni, zvni);
return;
zvni_vtep_install(zvni, &vtep_ip);
}
- 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);
+ sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+ remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+ is_router = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
mac = zvni_mac_lookup(zvni, macaddr);
*/
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
+ || sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
+ || remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW)
|| !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)
|| seq != mac->rem_seq)
update_mac = 1;
n = zvni_neigh_lookup(zvni, ipaddr);
if (!n
|| !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
+ || is_router != !!CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
|| (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;
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);
+ zvni_deref_ip2mac(zvni, old_mac);
}
listnode_add_sort(mac->neigh_list, n);
memcpy(&n->emac, macaddr, ETH_ALEN);
&& (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);
+ zvni_deref_ip2mac(zvni, mac);
}
} 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);
+ /* If all remote neighbors referencing a remote MAC
+ * go away, we need to uninstall the MAC.
+ */
+ if (remote_neigh_count(mac) == 0) {
+ zvni_mac_uninstall(zvni, mac);
+ UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
+ }
+ if (list_isempty(mac->neigh_list))
zvni_mac_del(zvni, mac);
- } else
+ else
SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
}
}
return 0;
if (!zvni->vxlan_if) {
- zlog_warn(
+ zlog_debug(
"VNI %u hash %p doesn't have intf upon local neighbor DEL",
zvni->vni, zvni);
return -1;
zmac = zvni_mac_lookup(zvni, &n->emac);
if (!zmac) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_warn(
+ zlog_debug(
"Trying to del a neigh %s without a mac %s on VNI %u",
ipaddr2str(ip, buf, sizeof(buf)),
prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
struct ipaddr *ip,
struct ethaddr *macaddr,
uint16_t state,
- uint8_t ext_learned,
- uint8_t router_flag)
+ bool is_ext,
+ bool is_router)
{
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
"Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s %s-> L2-VNI %u",
ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
- ifp->ifindex, state, ext_learned ? "ext-learned " : "",
- router_flag ? "router " : "",
+ ifp->ifindex, state, is_ext ? "ext-learned " : "",
+ is_router ? "router " : "",
zvni->vni);
/* Is this about a local neighbor or a remote one? */
- if (!ext_learned)
+ if (!is_ext)
return zvni_local_neigh_update(zvni, ifp, ip, macaddr,
- router_flag);
+ is_router);
return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
}
zebra_route_string(client->proto));
process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
-
}
stream_failure:
memset(&vtep_ip, 0, sizeof(struct in_addr));
if (!EVPN_ENABLED(zvrf)) {
- zlog_warn("EVPN not enabled, ignoring remote MACIP ADD");
+ zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
return;
}
if (!zvni)
return 0;
if (!zvni->vxlan_if) {
- zlog_warn("VNI %u hash %p doesn't have intf upon local MAC DEL",
- zvni->vni, zvni);
+ zlog_debug(
+ "VNI %u hash %p doesn't have intf upon local MAC DEL",
+ zvni->vni, zvni);
return -1;
}
int zebra_vxlan_local_mac_add_update(struct interface *ifp,
struct interface *br_if,
struct ethaddr *macaddr, vlanid_t vid,
- uint8_t sticky)
+ bool sticky)
{
zebra_vni_t *zvni;
zebra_mac_t *mac;
}
if (!zvni->vxlan_if) {
- zlog_warn("VNI %u hash %p doesn't have intf upon local MAC ADD",
- zvni->vni, zvni);
+ zlog_debug(
+ "VNI %u hash %p doesn't have intf upon local MAC ADD",
+ zvni->vni, zvni);
return -1;
}
mac = zvni_mac_add(zvni, macaddr);
if (!mac) {
flog_err(
- ZEBRA_ERR_MAC_ADD_FAILED,
+ EC_ZEBRA_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);
* operator error.
*/
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
- zlog_warn(
- "MAC %s already learnt as remote sticky behind VTEP %s VNI %u",
+ flog_warn(
+ EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
+ "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
prefix_mac2str(macaddr, buf,
sizeof(buf)),
inet_ntoa(mac->fwd_info.r_vtep_ip),
struct zebra_if *zif;
if (!is_evpn_enabled()) {
- zlog_warn(
+ zlog_debug(
"%s: EVPN is not enabled yet we have received a vtep del command",
__PRETTY_FUNCTION__);
return;
}
if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_warn("Recv MACIP DEL for non-default VRF %u",
- zvrf_id(zvrf));
+ zlog_debug("Recv MACIP DEL for non-default VRF %u",
+ zvrf_id(zvrf));
return;
}
ifp = zvni->vxlan_if;
if (!ifp) {
- zlog_warn(
+ zlog_debug(
"VNI %u hash %p doesn't have intf upon remote VTEP DEL",
zvni->vni, zvni);
continue;
struct zebra_if *zif;
if (!is_evpn_enabled()) {
- zlog_warn(
+ zlog_debug(
"%s: EVPN not enabled yet we received a vtep_add zapi call",
__PRETTY_FUNCTION__);
return;
}
if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_warn("Recv MACIP ADD for non-default VRF %u",
- zvrf_id(zvrf));
+ zlog_debug("Recv MACIP ADD for non-default VRF %u",
+ zvrf_id(zvrf));
return;
}
zvni = zvni_lookup(vni);
if (!zvni) {
flog_err(
- ZEBRA_ERR_VTEP_ADD_FAILED,
+ EC_ZEBRA_VTEP_ADD_FAILED,
"Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
vni);
continue;
ifp = zvni->vxlan_if;
if (!ifp) {
flog_err(
- ZEBRA_ERR_VTEP_ADD_FAILED,
+ EC_ZEBRA_VTEP_ADD_FAILED,
"VNI %u hash %p doesn't have intf upon remote VTEP ADD",
zvni->vni, zvni);
continue;
continue;
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);
+ flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
+ "Failed to add remote VTEP, VNI %u zvni %p",
+ vni, zvni);
continue;
}
svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
ifp_zif->link_ifindex);
if (!svi_if) {
- zlog_warn("MACVLAN %s(%u) without link information",
- ifp->name, ifp->ifindex);
+ zlog_debug("MACVLAN %s(%u) without link information",
+ ifp->name, ifp->ifindex);
return -1;
}
return 0;
if (!zvni->vxlan_if) {
- zlog_warn("VNI %u hash %p doesn't have intf upon MACVLAN up",
- zvni->vni, zvni);
+ zlog_debug("VNI %u hash %p doesn't have intf upon MACVLAN up",
+ zvni->vni, zvni);
return -1;
}
return 0;
if (!zvni->vxlan_if) {
- zlog_warn(
+ zlog_debug(
"VNI %u hash %p doesn't have intf upon SVI up",
zvni->vni, zvni);
return -1;
/* Locate hash entry; it is expected to exist. */
zvni = zvni_lookup(vni);
if (!zvni) {
- zlog_warn(
+ zlog_debug(
"Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
/* Locate hash entry; it is expected to exist. */
zvni = zvni_lookup(vni);
if (!zvni) {
- zlog_warn(
+ zlog_debug(
"Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
/* Locate hash entry; it is expected to exist. */
zvni = zvni_lookup(vni);
if (!zvni) {
- zlog_warn(
+ zlog_debug(
"Failed to locate VNI hash at del, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return 0;
/* Delete the hash entry. */
if (zvni_del(zvni)) {
- flog_err(ZEBRA_ERR_VNI_DEL_FAILED,
- "Failed to del VNI hash %p, IF %s(%u) VNI %u",
- zvni, ifp->name, ifp->ifindex, zvni->vni);
+ flog_err(EC_ZEBRA_VNI_DEL_FAILED,
+ "Failed to del VNI hash %p, IF %s(%u) VNI %u",
+ zvni, ifp->name, ifp->ifindex, zvni->vni);
return -1;
}
}
/* Update VNI hash. */
zvni = zvni_lookup(vni);
if (!zvni) {
- zlog_warn(
+ zlog_debug(
"Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
zvni = zvni_add(vni);
if (!zvni) {
flog_err(
- ZEBRA_ERR_VNI_ADD_FAILED,
+ EC_ZEBRA_VNI_ADD_FAILED,
"Failed to add VNI hash, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
struct interface *vlan_if = NULL;
if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_warn("EVPN GW-MACIP Adv for non-default VRF %u",
- zvrf_id(zvrf));
+ zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
+ zvrf_id(zvrf));
return;
}
struct interface *ifp = NULL;
if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_warn("EVPN GW-MACIP Adv for non-default VRF %u",
- zvrf_id(zvrf));
+ zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
+ zvrf_id(zvrf));
return;
}
struct zebra_ns *zns = NULL;
if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_warn("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf));
+ zlog_debug("EVPN VNI Adv for non-default VRF %u",
+ zvrf_id(zvrf));
return;
}
struct interface *link_if);
extern int zebra_vxlan_handle_kernel_neigh_update(
struct interface *ifp, struct interface *link_if, struct ipaddr *ip,
- struct ethaddr *macaddr, uint16_t state, uint8_t ext_learned,
- uint8_t router_flag);
+ struct ethaddr *macaddr, uint16_t state, bool is_ext,
+ bool is_router);
extern int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
struct interface *link_if,
struct ipaddr *ip);
extern int zebra_vxlan_local_mac_add_update(struct interface *ifp,
struct interface *br_if,
struct ethaddr *mac, vlanid_t vid,
- uint8_t sticky);
+ bool sticky);
extern int zebra_vxlan_local_mac_del(struct interface *ifp,
struct interface *br_if,
struct ethaddr *mac, vlanid_t vid);
#include "zebra/zapi_msg.h" /* for zserv_handle_commands */
#include "zebra/zebra_vrf.h" /* for zebra_vrf_lookup_by_id, zvrf */
#include "zebra/zserv.h" /* for zserv */
+#include "zebra/zebra_errors.h" /* for error messages */
/* clang-format on */
/* privileges */
*/
static void zserv_client_fail(struct zserv *client)
{
- zlog_warn("Client '%s' encountered an error and is shutting down.",
+ flog_warn(EC_ZEBRA_CLIENT_IO_ERROR,
+ "Client '%s' encountered an error and is shutting down.",
zebra_route_string(client->proto));
atomic_store_explicit(&client->pthread->running, false,
return 0;
zwrite_fail:
- zlog_warn("%s: could not write to %s [fd = %d], closing.", __func__,
+ flog_warn(EC_ZEBRA_CLIENT_WRITE_FAILED,
+ "%s: could not write to %s [fd = %d], closing.", __func__,
zebra_route_string(client->proto), client->sock);
zserv_client_fail(client);
return 0;
listnode_add(zebrad.client_list, client);
struct frr_pthread_attr zclient_pthr_attrs = {
- .id = frr_pthread_get_id(),
.start = frr_pthread_attr_default.start,
.stop = frr_pthread_attr_default.stop
};
client_sock = accept(accept_sock, (struct sockaddr *)&client, &len);
if (client_sock < 0) {
- zlog_warn("Can't accept zebra socket: %s",
- safe_strerror(errno));
+ flog_err_sys(EC_LIB_SOCKET, "Can't accept zebra socket: %s",
+ safe_strerror(errno));
return -1;
}
/* Make UNIX domain socket. */
zebrad.sock = socket(sa.ss_family, SOCK_STREAM, 0);
if (zebrad.sock < 0) {
- zlog_warn("Can't create zserv socket: %s",
- safe_strerror(errno));
- zlog_warn(
- "zebra can't provide full functionality due to above error");
+ flog_err_sys(EC_LIB_SOCKET, "Can't create zserv socket: %s",
+ safe_strerror(errno));
return;
}
ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len);
}
if (ret < 0) {
- zlog_warn("Can't bind zserv socket on %s: %s", path,
- safe_strerror(errno));
- zlog_warn(
- "zebra can't provide full functionality due to above error");
+ flog_err_sys(EC_LIB_SOCKET, "Can't bind zserv socket on %s: %s",
+ path, safe_strerror(errno));
close(zebrad.sock);
zebrad.sock = -1;
return;
ret = listen(zebrad.sock, 5);
if (ret < 0) {
- zlog_warn("Can't listen to zserv socket %s: %s", path,
- safe_strerror(errno));
- zlog_warn(
- "zebra can't provide full functionality due to above error");
+ flog_err_sys(EC_LIB_SOCKET,
+ "Can't listen to zserv socket %s: %s", path,
+ safe_strerror(errno));
close(zebrad.sock);
zebrad.sock = -1;
return;