diff options
458 files changed, 12356 insertions, 12070 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..cedca17729 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,43 @@ +### How to submit an issue +Please use this text as a template and replace text in the sections or remove +the entire section if it does not apply to your issue. For example in case of +a question or feature request, just a description with some example is probably +fine. Also remember to use GitHub Flavored Markdown properly, especially if +posting output or code listings. + +### Things you may try first +(put "x" in "[ ]" if you already tried following) +* [ ] Did you check if this is a duplicate issue? +* [ ] Did you test it on the latest FRRouting/frr master branch? + +**Related Issue:** +[fill here if applicable] + +### Description +[Description of the bug or feature] + +### Steps to Reproduce +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected behavior:** +[What you expected to happen] + +**Actual behavior:** +[What actually happened] + +### Components +[bgpd, build, doc, isisd, ospfd, etc.] + +### Versions +* OS: [name] [version] +* Kernel: [Linux/BSD] [version] +* FRR: [version] + +### Attachments +[Attach if applicable. For example log-files, log-lines. etc. etc.] + +You're also welcomed to provide us with any other data you think may be useful. + +Thanks! diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..0a8aa03c8d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,12 @@ +### Summary +[fill here] + +### Related Issue +[fill here if applicable] + +### Components +[bgpd, build, doc, ripd, ospfd, eigrpd, isisd, etc. etc.] + +Always remember to follow proper coding style etc. as +described in the FRRouting Dev Guide. +http://docs.frrouting.org/projects/dev-guide/en/latest/workflow.html diff --git a/.gitignore b/.gitignore index c5fd0ced9b..8c62f05539 100644 --- a/.gitignore +++ b/.gitignore @@ -1,87 +1,87 @@ -compile -config.log -config.h -config.cache -config.status -config.guess -config.sub -ltmain.sh -stamp-h -stamp-h[0-9]* +### autoconf/automake root stuff + +/compile +/config.log +/config.h +/config.cache +/config.status +/config.guess +/config.sub +/ltmain.sh +/stamp-h +/stamp-h[0-9]* *-stamp -Makefile -INSTALL +/INSTALL +/depcomp +/missing +/install-sh +/mkinstalldirs +/ylwrap +/autom4te*.cache +/configure.lineno +/configure +/config.h.in +/confdefs.h +/conftest +/conftest.err +/aclocal.m4 +/libtool + +/Makefile +/Makefile.in + +### autoconf/automake subdir stuff + .deps -depcomp -missing -install-sh -mkinstalldirs -ylwrap -autom4te*.cache -configure.lineno -configure -config.h.in -confdefs.h -conftest -conftest.err -aclocal.m4 -Makefile.in -*.tar.gz -*.tar.gz.asc +.libs + +### build outputs + +*.o +*.lo +*.a +*.la +*.so +*.loT +*.pb.h +*.pb-c.h +*.pb-c.c +*_clippy.c + +### dist + *.tar.?z +*.tar.?z.asc +*.tar.asc +*.deb +*.ddeb +*.dsc +*.changes + +### other garbage + .nfs* -libtool -.libs .arch-inventory .arch-ids {arch} build +.cache .msg .rebase-* *~ -*.o -*.loT -m4/*.m4 -!m4/ax_sys_weak_alias.m4 -!m4/ax_compare_version.m4 -!m4/ax_prog_perl_modules.m4 -!m4/pkg.m4 -debian/autoreconf.after -debian/autoreconf.before -debian/files -debian/frr-dbg.debhelper.log -debian/frr-dbg.substvars -debian/frr-dbg/ -debian/frr-doc.debhelper.log -debian/frr-doc.substvars -debian/frr-doc/ -debian/frr.debhelper.log -debian/frr.postinst.debhelper -debian/frr.postrm.debhelper -debian/frr.prerm.debhelper -debian/frr.substvars -debian/frr/ -debian/tmp/ -*.deb -*.ddeb -*.dsc -*.changes -*.pyc +*.bak *.swp +*.pyc +__pycache__ +*.patch +*.diff cscope.* -*.pb.h -*.pb-c.h -*.pb-c.c TAGS tags GTAGS GSYMS GRTAGS GPATH -*.la -*.lo compile_commands.json .dirstamp - -# clippy generated source -*_clippy.c +refix diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 61867a860c..0000000000 --- a/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -Kunihiro Ishiguro <kunihiro@zebra.org> -Toshiaki Takada <takada@zebra.org> -Yasuhiro Ohara <yasu@sfc.wide.ad.jp> -Alex D. Zinin <azinin@hotmail.com> -Gleb Natapov <gleb@nbase.co.il> -Akihiro Mizutani <mizutani@dml.com> diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index ec7e6cdde8..0000000000 --- a/ChangeLog +++ /dev/null @@ -1,4 +0,0 @@ -ChangeLog information for FRRouting is for now recorded in source-code -management system. Please see: - - http://www.frrouting.org/ diff --git a/Makefile.am b/Makefile.am index b9003b8358..fb052a8dea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,19 @@ ## Process this file with automake to produce Makefile.in. AUTOMAKE_OPTIONS = subdir-objects 1.12 -include common.am +ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \ - -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib +AM_CFLAGS = \ + $(SAN_FLAGS) \ + $(WERROR) \ + # end +AM_CPPFLAGS = \ + -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \ + -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib +AM_LDFLAGS = \ + -export-dynamic \ + $(SAN_FLAGS) \ + # end DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE) LIBCAP = @LIBCAP@ @@ -83,6 +92,7 @@ pkginclude_HEADERS = nodist_pkginclude_HEADERS = dist_examples_DATA = man_MANS = +vtysh_scan = ## libtool, the self-made GNU scourge ## ... this should fix relinking @@ -106,6 +116,9 @@ include tools/subdir.am include debianpkg/subdir.am include solaris/subdir.am +include bgpd/subdir.am +include bgpd/rfp-example/librfp/subdir.am +include bgpd/rfp-example/rfptest/subdir.am include ripd/subdir.am include ripngd/subdir.am include ospfd/subdir.am @@ -122,16 +135,8 @@ include pbrd/subdir.am include staticd/subdir.am include bfdd/subdir.am -SUBDIRS = . @LIBRFP@ @RFPTEST@ \ - @BGPD@ \ - @VTYSH@ \ - tests - -DIST_SUBDIRS = . bgpd \ - vtysh tests \ - bgpd/rfp-example/librfp \ - bgpd/rfp-example/rfptest \ - # end +include vtysh/subdir.am +include tests/subdir.am if PKGSRC rcdir=@pkgsrcrcdir@ @@ -147,6 +152,7 @@ endif EXTRA_DIST += \ aclocal.m4 \ + README.md \ m4/README.txt \ \ python/clidef.py \ @@ -169,17 +175,37 @@ EXTRA_DIST += \ snapcraft/helpers \ snapcraft/snap \ \ - vtysh/Makefile.am \ - vtysh/Makefile.in \ - \ + babeld/Makefile \ + bgpd/Makefile \ + bgpd/rfp-example/librfp/Makefile \ + bgpd/rfp-example/rfptest/Makefile \ doc/Makefile \ doc/developer/Makefile \ doc/manpages/Makefile \ doc/user/Makefile \ + eigrpd/Makefile \ + fpm/Makefile \ + isisd/Makefile \ + ldpd/Makefile \ + lib/Makefile \ + nhrpd/Makefile \ + ospf6d/Makefile \ + ospfclient/Makefile \ + ospfd/Makefile \ + pbrd/Makefile \ + pimd/Makefile \ + ports/Makefile \ + qpb/Makefile \ + ripd/Makefile \ + ripngd/Makefile \ + staticd/Makefile \ + tests/Makefile \ + tools/Makefile \ + vtysh/Makefile \ + watchfrr/Makefile \ + zebra/Makefile \ # end -ACLOCAL_AMFLAGS = -I m4 - noinst_HEADERS += defaults.h indent: @@ -1,2574 +0,0 @@ -Note: this file lists major user-visible changes only. - -* Changes in Quagga 0.99.24 - -User-visible changes: -- [pimd] New daemon: pimd provides IPv4 PIM-SSM multicast routing. -- [bgpd] New feature: "next-hop-self all" to override nexthop on iBGP route - reflector setups. -- [bgpd] route-maps have a new action "set ipv6 next-hop peer-address" -- [bgpd] route-maps have a new action "set as-path prepend last-as" -- [bgpd] Update validity checking (particularly MP-BGP / IPv6 routes) was - touched up significantly. Please report possible bugs. -- [ripd] New feature: RIP for IPv4 now supports equal-cost multipath (ECMP) -- [zebra] Multicast RIB support has been extended. It still is IPv4 only. -- [zebra] "no link-detect" is now printed in configurations since it won't - be the default anymore soon. To retain current behaviour, re-save your - configuration after updating to 0.99.24. - -Distributor-visible changes: -- --enable-pimd is added to enable pimd. It is considered experimental, though - unless the distribution target is embedded systems with little flash, there - is no reason to not include it in packages. -- --disable-ipv6 no longer exists as an option. It's 2015, your C library - really needs to have IPv6 support by now. -- --disable-netlink no longer exists as an option. It didn't work anyway. -- --disable-solaris no longer exists as an option. It only controlled some - init scripts. -- --enable-isisd is now the default. -- mrlg.cgi is no longer included (it was severely outdated). It can be found - independently at http://mrlg.op-sec.us/ -- build on Linux with the musl C library should now work - -* Changes in Quagga 0.99.23 - -Known issues: -- [bgpd] setting an extcommunity in a route map on a route that already has - an extcommunity attribute will cause bgpd to crash. This issue will be - fixed in a followup minor release. - -User-visible changes: -- [lib] Performance enhancements on hashes and timers. -- [bgpd] New feature: iBGP TTL security. -- [bgpd] New feature: relaxed bestpath criteria for multipath and improved - display of multipath routes in "show ip bgp". Scripts parsing this output - may need to be updated. -- [bgpd] Multiprotocol peerings over IPv6 now try to find a more appropriate - IPv4 nexthop by looking at the interface. -- [ospf6d] A large amount of changes has been merged for ospf6d. Careful - evaluation prior to deployment is recommended. -- [zebra] Recursive route support has been overhauled. Scripts parsing - "show ip route" output may need adaptation. -- [zebra] IPv6 address management has been improved regarding tentative - addresses. This is visible in that a freshly configured address will not - immediately be marked as usable. -- [*] a lot of bugs have been fixed, please refer to the git log - -* Changes in Quagga 0.99.22 - -- [bgpd] The semantics of default-originate route-map have changed. - The route-map is now used to advertise the default route conditionally. - The old behaviour which allowed to set attributes on the originated - default route is no longer supported. -- [bgpd] There is now a replace-as option to neighbor ... local-as ... - no-prepend. For details, refer to the user documentation. -- [zebra] An FPM interface has been added. This provides an alternate - interface to routing information and is geared at OpenFlow & co. -- [snmp] AgentX is now supported; the old smux backend is considered - deprecated. ospf6d has also had OSPFV3-MIB added. -- [*] several issues with configuration save/load/apply have been fixed, - in particular on ospf "max-metric router-lsa administrative" and - "distribute-list", bgpd "no neighbor activate", isisd "metric-style", -- [*] a lot of bugs have been fixed, please refer to the git log - -* Changes in Quagga 0.99.21 - -- [bgpd] BGP multipath support has been merged -- [bgpd] SAFI (Multicast topology) support has been extended to propagate - the topology to zebra. -- [bgpd] AS path limit functionality has been removed -- [babeld] a new routing daemon implementing the BABEL ad-hoc mesh routing - protocol has been merged. -- [isisd] a major overhaul has been picked up. Please note that isisd is - STILL NOT SUITABLE FOR PRODUCTION USE. -- [*] a lot of bugs have been fixed, please refer to the git log - -* Changes in Quagga 0.99.10 - -- [bgpd] 4-byte AS support added -- [bgpd] MRT format changes to version 2. Those relying on - bgpd MRT table dumps may need to update their tools. -- [bgpd] Added new route-map set statement: "as-path exclude" -- Zebra RIB updates queue has evolved into a multi-level - structure to address RIB consistency issues. - -* Changes in Quagga 0.99.2 - -- [bgpd] Work queues added to bgpd to split up update processing, - particularly beneficial when a peer session goes down. AS_PATH - parsing rewritten to be clearer, more robust and ready for 4-byte. - -- [ripd] Simple authentication is no longer the default authentication - mode for ripd. The default is now no-authentication. Any setups which - used simple authentication will probably need to update their - configuration manually. - -- [ospfd] 1s dead-interval with sub-second Hellos feature added. - SPF timers now specified in milliseconds, and with adaptive - hold-time support. RFC3137 Stub-router support added. Default ABR - type is now 'cisco'. - -- Solaris least privileges support added. - -* Changes in Quagga 0.99.1 - -- Zserv is now buffered via threads and non-blocking in most cases for both - clients and zebra, which should improve responsiveness of daemons when - they must send many messages to zebra. - -- 'show thread cpu' now displays both cpu+system and wall-clock time, - where getrusage() is available. - -- Background threads added and workqueue API added, with a - 'show work-queues' command. Thread scheduling improved slightly. - -- Zebra now has a work-queue for RIB processing. See 'show work-queues' in - the zebra daemon vty. - -- Support for interface renaming on Linux netlink systems. - -- GNU Zebra bgpd merges, including BGP Graceful-restart and "match ip - route-source" command. - -- Automatic logging of backtraces should daemons crash to assist in - diagnosis. See the documentation for more information on configuring - logging correctly, and set --enable-gcc-rdynamic if compiling with gcc. - -* Changes in Quagga 0.98.0 - -- Logging facilities upgraded. One can now specify a severity level - for each logging destination. And a new "show logging" command gives - thorough information on the current logging system configuration. - -- Watchquagga daemon added. This is not well tested yet. Please try - monitor mode first before enabling restart features. It is important - to make sure that the various timers are configured with appropriate - values for your site. - -- BGP route-server support added. See the texinfo documentation. - -- OSPF API initialisation is disabled by default even if compiled in. You - can enable it with -a/--apiserver command line switch. - -- "write-config integrated" vtysh command replaced with "service - integrated-vtysh-config" command. - -- Router id is now handled by zebra daemon and all daemons receive changes - from it. Router id can be overriden in daemons' configurations of course. - To fix common router id in zebra daemon you can either install non-127 - address on loopback or use "router-id x.x.x.x" command. - -- "secondary" keyword is removed from ip address configuration. All - supported OS'es have their own vision what's secondary address and - how to handle it. - -- Zebra no longer enables forwarding by default. If you rely on zebra to - enable forwarding make sure to add '<ip|ip6> forwarding' statements - to your zebra configuration file. - -- All libraries are built and used shared, on platforms where libtool - supports shared libraries. - -- Router advertisement syntax is changed. In usual cases (if you didn't do - any fancy stuff) it's enough to change lines in configuration from: - "ipv6 nd prefix-advertisement X:X:X:X::/X 2592000 604800 autoconfig on-link" - to: - "ipv6 nd prefix X:X:X:X::/X" - - All router advertisement options are documented in texi documentation. - -- --enable-nssa configure switch is removed. NSSA support is stable enough. - -- Daemons don't look at current directory for config file any more. - -* Changes in Quagga 0.96.5 - -- include files are installed in $(prefix)/include/quagga. Programs - building against these includes should -I$(prefix)/include and e.g. - #include <quagga/routemap.h> - -- New option --enable-exampledir puts example files in a separate - directory from $(sysconfdir), easing NetBSD pkgsrc hierarchy rules - compliance. - -- New configure options --enable-configfile-mask and - --enable-logfile-mask to set umask values for config and log - values. Masks default to 0600, matching previous behavior. - -- Import current CVS isisd from SourceForge, then merge it with - the Quagga's Framework. - -* Changes in Quagga 0.96.4 - -- Further fixes to ospfd, some relating to the PtP revert. Interface -lookups should be a lot more robust now. - -- Fix for a remote triggerable crash in vty layer. - -- Improvements to ripd, and addition of split horizon support. - -- Improved bgpd table support, now dumps at time of day intervals rather -than time from startup intervals. Much improved support for IPv6 table -dumps. show commands for views improved. - -* Changes in Quagga 0.96.3 - -- revert the 'generic PtP' patch. Means Quagga will no longer work with -FreeSWAN, however, on the plus side this gets rid of a lot of niggly bugs -which the PtP patch introduced. - -* Changes in Quagga 0.96.2 - -- Fix crash in ospfd - -* Changes in Quagga 0.96.1 - -- Iron out problem with the privileges definitions - -* Changes in Quagga 0.96 - -- Privilege support, daemons now run with the minimal privileges needed, see - the documentation for details. - -- NSSA ABR support in ospfd. - -- OSPF-API support merged in. - -- 6WIND patch merged in. - -* Changes in zebra-0.93 - -* Changes in bgpd - -** Configuration is changed to new format. - -* Changes in ospfd - -** Crush bugs which reported on Zebra ML is fixed. - -** Opaque LSA and TE LSA support is added by KDD R&D Laboratories, - Inc. - -* Chages in ospf6d - -** Many bugs are fixed. - -* Changes in zebra-0.92a - -* Changes in bgpd - -** Fix "^$" community list bug. - -** Below command's Address Family specific configurations are added - - nexthop-self - route-reflector-client - route-server-client - soft-reconfiguration inbound - -* Changes in zebra - -** Treat kernel type routes as EGP routes. - -* Changes in zebra-0.92 - -** Overall security is improved. Default umask is 0077. - -* Changes in ripd - -** If output interface is in simple password authentication mode, -substruct one from rtemax. - -* Changes in bgpd - -** IPv4 multicast and IPv6 unicast configuration is changed to so -called new config. All of AFI and SAFI specific configuration is -moved to "address-family" node. When you have many IPv6 only -configuration, you will see many "no neighbor X:X::X:X activate" line -in your configuration to disable IPv4 unicast NLRI exchange. In that -case please use "no bgp default ipv4-unicast" command to suppress the -output. Until zebra-0.93, old config is still left for compatibility. - -Old config -========== -router bgp 7675 - bgp router-id 10.0.0.1 - redistribute connected - network 192.168.0.0/24 - neighbor 10.0.0.2 remote-as 7675 - ipv6 bgp network 3ffe:506::/33 - ipv6 bgp network 3ffe:1800:e800::/40 - ipv6 bgp aggregate-address 3ffe:506::/32 - ipv6 bgp redistribute connected - ipv6 bgp neighbor 3ffe:506:1000::2 remote-as 1 - -New config -========== -router bgp 7675 - bgp router-id 10.0.0.1 - network 192.168.0.0/24 - redistribute connected - neighbor 10.0.0.2 remote-as 7675 - neighbor 3ffe:506:1000::2 remote-as 1 - no neighbor 3ffe:506:1000::2 activate -! - address-family ipv6 - network 3ffe:506::/33 - network 3ffe:1800:e800::/40 - aggregate-address 3ffe:506::/32 - redistribute connected - neighbor 3ffe:506:1000::2 activate - exit-address-family - -* Changes in ospfd - -** Internal interface treatment is changed. Now ospfd can handle -multiple IP address for an interface. - -** Redistribution of loopback interface's address works fine. - -* Changes in zebra-0.91 - -** --enable-oldrib configure option is removed. - -** HAVE_IF_PSEUDO part is removed. Same feature is now supported by -default. - -* Changes in ripd - -** When redistributed route is withdrawn, perform poisoned reverse. - -* Changes in zebra - -** When interface's address is removed, kernel route pointing out to -the address is removed. - -** IPv6 RIB is now based upon new RIB code. - -** zebra can handle same connected route to one interface. - -** New command for interface address. Currently this commands are -only supported on GNU/Linux with netlink interface. - -"ip address A.B.C.D secondary" -"ip address A.B.C.D label LABEL" - -* Changes in bgpd - -** BGP flap dampening bugs are fixed. - -** BGP non-blocking TCP connection bug is fixed. - -** "show ip bgp summary" shows AS path and community entry number. - -** New commands have been added. - "show ip bgp cidr-only" - "show ip bgp ipv4 (unicast|multicast) cidr-only" - "show ip bgp A.B.C.D/M longer-prefixes" - "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M longer-prefixes" - "show ipv6 bgp X:X::X:X/M longer-prefixes" - "show ipv6 mbgp X:X::X:X/M longer-prefixes" - -** IPv6 IBGP nexthop change is monitored. - -** Unknown transitive attribute is passed with partial flag bit on. - -* Changes in ospfd - -** Fix bug of LSA MaxAge flood. - -** Fix bug of NSSA codes. - -* Changes in zebra-0.90 - -** From this beta release, --enable-unixdomain and --enable-newrib -becomes default. So both options are removed from configure.in. To -revert old behavior please specify below option. - ---enable-tcp-zebra # TCP/IP socket is used for protocol daemon and zebra. ---enable-oldrib # Turn on old RIB implementation. - -Old RIB implementation will be removed in zebra-0.91. - -** From this beta release --enable-multipath is supported. This -option is only effective on GNU/Linux kernel with -CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_ROUTE_MULTIPATH is set. - ---enable-multipath=ARG # ARG must be digit. When ARG is 0 unlimit multipath number. - -** From this release we do not include guile files. - -* Changes in lib - -** newlist.[ch] is merged with linklist.[ch]. - -** Now Zebra works on MacOS X public beta. - -** Access-list can have remark. "access-list WORD remark LINE" define -remark for specified access-list. - -** Key of key-chain is sorted by it's idetifier value. - -** prefix-list rule is slightly changed. The rule of "len <= ge-value -<= le-value" is changed to "len < ge-value <= le-value". - -** According to above prefix-list rule change, add automatic -conversion function of an old rule. ex.) 10.0.0.0/8 ge 8 -> 10.0.0.0/8 -le 32 - -** SMUX can handle SNMP trap. - -** In our event library, event thread is executed before any other -thread like timer, read and write event. - -** Robust method for writing configuration file and recover from -backing up config file. - -** Display "end" at the end of configuration. - -** Fix memory leak in vtysh_read(). - -** Fix memroy leak about access-list and prefix-list name. - -* Changes in zebra - -** UNIX domain socket server of zebra protocol is added. - -** Fix PointoPoint interface network bug. The destination network -should be installed into routing table instead of local network. - -** Metric value is reflected to kernel routing table. - -** "show ip route" display uptime of RIP,OSPF,BGP routes. - -** New RIB implementation is added. - -Now we have enhanced RIB (routing information base) implementation in -zebra. New RIB has many new features and fixed some bugs which exist -in old RIB code. - -*** Static route with distance value - - Static route can be specified with administrative distance. The - distance value 255 means it is not installed into the kernel. - Default value of distance for static route is 1. - - ip route A.B.C.D/M A.B.C.D <1-255> - ip route A.B.C.D/M IFNAME <1-255> - - If the least distance value's route's nexthop are unreachable, - select the least distance value route which has reachable nexthop is - selected. - - ip route 0.0.0.0/0 10.0.0.1 - ip route 0.0.0.0/0 11.0.0.1 2 - - In this case, when 10.0.0.1 is unreachable and 11.0.0.1 is - reachable. The route with nexthop 11.0.0.1 will be installed into - forwarding table. - - zebra> show ip route - S>* 0.0.0.0/0 [2/0] via 11.0.0.1 - S 0.0.0.0/0 [1/0] via 10.0.0.1 inactive - - If the nexthop is unreachable "inactive" is displayed. You can - specify any string to IFNAME. There is no need of the interface is - there when you configure the route. - - ip route 1.1.1.1/32 ppp0 - - When ppp0 comes up, the route is installed properly. - -*** Multiple nexthop routes for one prefix - - Multiple nexthop routes can be specified for one prefix. Even the - kernel support only one nexthop for one prefix user can configure - multiple nexthop. - - When you configure routes like below, prefix 10.0.0.1 has three - nexthop. - - ip route 10.0.0.1/32 10.0.0.2 - ip route 10.0.0.1/32 10.0.0.3 - ip route 10.0.0.1/32 eth0 - - If there is no route to 10.0.0.2 and 10.0.0.3. And interface eth0 - is reachable, then the last route is installed into the kernel. - - zebra> show ip route - S> 10.0.0.1/32 [1/0] via 10.0.0.2 inactive - via 10.0.0.3 inactive - * is directly connected, eth0 - - '*' means this nexthop is installed into the kernel. - -*** Multipath (more than one nexthop for one prefix) can be installed into the kernel. - - When the kernel support multipath, zebra can install multipath - routes into the kernel. Before doing that please make it sure that - setting --enable-multipath=ARG to configure script. ARG must be digit - value. When specify 0 to ARG, there is no limitation of the number - of the multipath. Currently only GNU/Linux with netlink interface is - supported. - - ip route 10.0.0.1/32 10.0.0.2 - ip route 10.0.0.1/32 10.0.0.3 - ip route 10.0.0.1/32 eth0 - - zebra> show ip route - S>* 10.0.0.1/32 [1/0] via 10.0.0.2 - * via 10.0.0.3 - is directly connected, eth0 - -*** Kernel message delete installed route. - - After zebra install static or dynamic route into the kernel. - - R>* 0.0.0.0/0 [120/3] via 10.0.0.1 - - If you delete this route outside zebra, old zebra does not reinstall - route again. Now the route is re-processed and properly reinstall the - static or dynamic route into the kernel. - -** GNU/Linux netlink socket handling is improved to fix race condition -between kernel message and user command responce. - -* Changes in bgpd - -** Add show neighbor's routes command. - - "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes" - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) routes" - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) routes" - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) routes" - -** BGP passive peer support problem is fixed. - -** Redistributed IGP nexthop is passed to BGP nexthop. - -** On multiaccess media, if the nexthop is reachable nexthop is passed -as it is. - -** Remove zebra-0.88 compatibility commands. - - "match ip prefix-list WORD" - "match ipv6 prefix-list WORD" - - Instead of above please use below commands. - - "match ip address prefix-list WORD" - "match ipv6 address prefix-list WORD" - -** Fix bug of holdtimer is not reset when bgp cleared. - -** "show ip bgp summary" display peer establish/drop count. - -** Change "match ip next-hop" argument from IP address to access-list -name. - -** When "bgp enforce-first-as" is enabled, check EBGP peer's update -has it's AS number in the first AS number in AS sequence. - -** New route-map command "set community-delete COMMUNITY-LIST" is -added. Community matched the CoMMUNITY-LIST is removed from the -community. - -** BGP-MIB implementation is finished. - -** When BGP connection comes from unconfigured IP address, close -socket immediately. - -** Do not compare router ID when the routes comes from EBGP peer. -When originator ID is same, take shorter cluster-list route. If -cluster-list is same take smaller IP address neighbor's route. - -** Add "bgp bestpath as-path ignore" command. When this option is -set, do not concider AS path length when route selection. - -** Add "bgp bestpath compare-routerid". When this option is set, -compare router ID when the routes comes from EBGP peer. - -** Add "bgp deterministic-med" process. - -** BGP flap dampening feature is added. - -** When IBGP nexthop is changed, it is reflected to RIB. - -** Change "neighbor route-refresh" command to "neighbor capability -route-refresh". - -* Changes in ripd - -** Change "match ip next-hop" argument from IP address to access-list -name. - -** "no ip rip (send|receive)" command accept version number argument. - -** Memory leak related classfull network generation is fixed. - -** When a route is in garbage collection process (invalid with metric -16) and a router receives the same route with valid metric then route -was not installed into zebra rib, but only into ripd rib. Moreover , -it will never get into zebra rib, because ripd wrongly assumes it's -already there. - -* Change in ospfd - -** Fix bug of refreshing default route. - -** --enable-nssa turn on undergoing NSSA feature. - -** Fix bug of Hello packet's option is not properly set when interface -comes up. - -** Reduce unconditional logging. - -** Add nexthop to OSPF path only when it is not there. - -** When there is no DR on network (suppose you have only one router -with interface priority 0). It's router LSA does not contain the link -information about this network. - -** When you change a priority of interface from/to 0 -ISM_NeighborChange event should be scheduled in order to elect new -DR/BDR on the network. - -** When we add some LSA into retransmit list we need to check whether -the present old LSA in retransmit list is not more recent than the new -one. - -** In states Loading and Full the slave must resend its last Database -Description packet in response to duplicate Database Description -packets received from the master. For this reason the slave must wait -RouterDeadInterval seconds before freeing the last Database -Description packet. Reception of a Database Description packet from -the master after this interval will generate a SeqNumberMismatch -neighbor event. RFC2328 Section 10.8 - -** Virtual link can not configured in stub area. - -** Clear a ls_upd_queue queue of the interface when interface goes -down. - -** "no router ospf" unregister redistribution requests from zebra. - -** New command for virtual-link configuration is added. - - "area A.B.C.D virtual-link A.B.C.D" - "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535>" - "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535> authentication-key AUTH_KEY" - "area A.B.C.D virtual-link A.B.C.D authentication-key AUTH_KEY" - "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535> message-digest-key <1-255> md5 KEY" - "area A.B.C.D virtual-link A.B.C.D message-digest-key <1-255> md5 KEY" - -** Clear cryptographic sequence number when neighbor status is changed -to NSM down. - -** Make Summary LSA's origination and refreshment as same as other -type of LSA. - -** New OSPF pakcet read method. Now maximum packet length may be 65535 -bytes (maximum IP packet length). - -** Checking the age of the found LSA and if the LSA is MAXAGE we -should call refresh instead of originate. - -** Install multipath information to zebra. - -** Fix socket descriptor leak when system call failed. - -* Changes in ospf6d - -** Whole functionality has been rewritten as new code. new command -"show ipv6 ospf6 spf node", "show ipv6 ospf6 spf tree", "show ipv6 -ospf6 spf table" has been added. - -** Change to do not send garbage route whose nexthop is not linklocal -address. - -** "redistribute ospf6" was generated in "router ospf6" in config -file. It is fixed. - -** LSDB sync bug is fixed. - -** Fix bug of using unavailable route. - -* Changes in vtysh - -** route-map and access-list configuration is merged into one -configuration. - -** /usr/local/etc/Zebra.conf is integrated configuration file. "write -memory" in vtysh will write whole configuration to this file. - -** When -b option is specified to vtysh, vtysh read -/usr/local/etc/Zebra.conf file then pass the confuguration to proper -protocol daemon. So make all protocol daemon's configuration file -empty then invoke all daemon. After that vtysh -b will setup saved -configuration. - -zebrastart.sh -============= -/usr/local/sbin/zebra -d -/usr/local/sbin/ripd -d -/usr/local/sbin/ospfd -d -/usr/local/sbin/bgpd -d -/usr/local/bin/vtysh -b - -* Changes in zebra-0.89 - -* Changes in lib - -** distribute-list can set all interface's access-list and prefix-list -configuration. - -* Changes in ripd - -** "show ip protocols" display proper distribute-list settings and -distance settings. - -** When metric infinity route received withdraw the route from kernel -immediately it used to be wait garbage collection. - -** key-chain can be used for simple password authentication. - -** RIPv2 MIB getnext interface bug is fixed. - -* Changes in vtysh - -** --with-libpam enable PAM authentication for vtysh. - -** Now vtysh read vtysh.conf. This file should be -${SYSCONFDIR}/etc/vtysh.conf for security reason. Usually it is -/usr/local/etc/vtysh.conf. - -** "username WORD nopassword" command is added to vtysh. - -* Chagees in ospfd - -** NBMA interface support is added. - -** OSPF area is sorted by area ID. - -** New implementation of OSPF refreesh. - -** OSPF-MIB read function is partly added. - -* Changes in bgpd - -** When the peering is done by ebgp-multihop, nexthop is looked up -like IBGP routes. - -** "show ip mbgp" commands are changed to "show ip bgp ipv4 -multicast". - -** New terminal commands are added. - "show ip bgp ipv4 (unicast|multicast) filter-list WORD" - "show ip bgp ipv4 (unicast|multicast) community" - "show ip bgp ipv4 (unicast|multicast) community-list WORD" - "show ip bgp ipv4 (unicast|multicast) community-list WORD exact-match" - -** MBGP soft-reconfiguration command is added. - "clear ip bgp x.x.x.x ipv4 (unicast|multicast) in" - "clear ip bgp x.x.x.x ipv4 (unicast|multicast) out" - "clear ip bgp x.x.x.x ipv4 (unicast|multicast) soft" - "clear ip bgp <1-65535> ipv4 (unicast|multicast) in" - "clear ip bgp <1-65535> ipv4 (unicast|multicast) out" - "clear ip bgp <1-65535> ipv4 (unicast|multicast) soft" - "clear ip bgp * ipv4 (unicast|multicast) in" - "clear ip bgp * ipv4 (unicast|multicast) out" - "clear ip bgp * ipv4 (unicast|multicast) soft" - -** MED related commands are added. - "bgp deterministic-med" - "bgp bestpath med confed" - "bgp bestpath med missing-as-worst" - -** "bgp default local-preference" command is added. - -** BGP confederation peer's routes are passed to zebra like IBGP route. - -** Community match command is added. - "show ip bgp community <val>" - "show ip bgp community <val> exact-match" - -** EBGP multihop route treatment bug is fixed. Now nexthop is -resolved by IGP routes. - -** Some commands are added to show routes by filter-list and community -value. - "show ip bgp ipv4 (unicast|multicast) filter-list WORD" - "show ip bgp ipv4 (unicast|multicast) community" - "show ip bgp ipv4 (unicast|multicast) community-list WORD" - "show ip bgp ipv4 (unicast|multicast) community-list WORD exact-match" - -* Changes in zebra - -** zebra read interface's address information using getifaddrs() when -it is available. - -** Reflect IPv6 interface's address change to protocol daemons. - -* Changes in zebra-0.88 - -* Changes in lib - -** "exact-match" option is added to "access-list" and "ipv6 -access-list" command. If this option is specified, the prefix and -prefix length is compared as exact match mode. - -* Changes in zebra - -** New Zebra message ZEBRA_REDISTRIBUTE_DEFAULT_ADD and -ZEBRA_REDISTRIBUTE_DEFAULT_DELTE are added. - -** Default administrative distance value is changed. - - Old New ------------------------------------------- -system 10 0 -kernel 20 0 -connected 30 0 -static 40 1 -rip 50 120 -ripng 50 120 -ospf 60 110 -ospf6 49 110 -bgp 70 200(iBGP) 20(eBGP) ------------------------------------------- - -** Distance value can be passed from protocol daemon to zebra. - -** "show ip route" shows [metric/distance] value pair. - -** Zebra Protocol is changed to support multi-path route and distance -value. - -* Changes in ospfd - -** "default-information originate [always]" command is added. - -** "default-metric <0-16777214>" command is added. - -** "show ip ospf database" command is integrated. LS-ID and AdvRouter can - be specifed. The commands are - - show ip ospf database TYPE LS-ID - show ip ospf database TYPE LS-ID ADV-ROUTER - show ip ospf database TYPE LS-ID self-originate - show ip ospf database TYPE self-originate - -** route-map support for `redistribute' command are added. - Supported `match' statements are - - match interface - match ip address - match next-hop - - Supported `set' statements are - - set metric - set metric-type - -** Pass OSPF metric value to zebra daemon. - -* Changes in ripd - -** When specified route-map does not exist, it means all deny. - -** "default-metric <1-16>" command is added. - -** "offset-list ACCESS-LIST-NAME <0-16>" and "offset-list -ACCESS-LIST-NAME <0-16> IFNAME" commands are added. - -** "redistribute ROUTE-TYPE metric <0-16>" command is added. - -** "default-information originate" command is added. - -** "ip split-horizon" and "no ip split-horizon" is added to interface -configuration. - -** "no router rip" command is added. - -** "ip rip authentication mode (md5|text)" is added to interface -configuration. - -** "ip rip authentication key-chain KEY-CHAIN" is added to interface -configuration. - -** Pass RIP metric value to zebra daemon. - -** Distance manipulation functions are added. - -* Changes in bgpd - -** Fix bug of next hop treatment for MPLS-VPN route exchange. - -** BGP peer MIB is updated. - -** Aggregated route has origin IGP, atomic-aggregate and proper -aggregator attribute. - -** Suppressed route now installed into BGP table. It is only -suppressed from announcement. - -** BGP router-id is properly set after "no router bgp ASN" and "router -bgp ASN". - -** Add check for nexthop is accessible or not for IBGP routes. - -** Add cehck for nexthop is on connected or not for EBGP routes. - -** "dump bgp route" command is changed to "dump bgp route-mrt" for -generating MRT compatible dump output. - -** Soft reconfiguration inbound and outbound is supported. - -** Route refresh feature is supported. - -* Changes in vtysh - -** VTY shell is now included into the distribution. - -* Changes in zebra-0.87 - -* Changes in lib - -** "show startup-config" command is added. - -** "show history" command is added. - -** Memory statistics command is changed. New command - - show memory all - show memory lib - show memory rip - show memory ospf - show memory bgp - -are added. - -** Filters can be removed only specify it's name. New command - - no access-list NAME - no ip community-list NAME - no ip as-path access-list NAME - no route-map NAME - -are added. - -** At any node, user can view/save user configuration. - - write terminal - write file - wirte memory - -are added to every node in default. - -** LCD completion is added. For example both "ip" and "ipv6" command -are exist, "i" then press TAB will be expanded to "ip". - -* Changes in bgpd - -** "show ip bgp" family shows total number of prefixes. - -** "no bgp default ipv4-unicast" command is added. - -** Extended Communities support is added. - -** "no neighbor PEER send-community extended" command is added. - -** MPLS-VPN PE-RR support is added. - - New address family vpnv4 unicast is introduced. - - ! - address-family vpnv4 unicast - neighobr PEER activate - network A.B.C.D rd RD tag TAG - exit-address-family - ! - - To make it route-reflector, please configure it under normal router -bgp ASN. - - ! - router bgp 7675 - no bgp default ipv4-unicast - bgp router-id 10.0.0.100 - bgp cluster-id 10.0.0.100 - neighbor 10.0.0.1 remote-as 65535 - neighbor 10.0.0.1 route-reflector-client - neighbor 10.0.0.2 remote-as 65535 - neighbor 10.0.0.2 route-reflector-client - neighbor 10.0.0.3 remote-as 65535 - neighbor 10.0.0.3 route-reflector-client - ! - address-family vpnv4 unicast - neighbor 10.0.0.1 activate - neighbor 10.0.0.2 activate - neighbor 10.0.0.3 activate - exit-address-family - ! - -* Changes in ospfd - -** Many many bugs are fixed. - -* Changes in ripd - -** Better interface up/down event handle. - -* Changes in zebra - -** Better interface up/down event handle. - -* Changes in zebra-0.86 - -* Changes in lib - -** Fix bug of exec-timeout command which may cause crush. - -** Multiple same policy for "access-list", "ip prefix-list, "as-path -access-list", "ip community-list" is not duplicated. - -** It used to be "ip prefix-list A.B.C.D/M" match routes which mask >= -M. Now default behavior is exact match so it only match routes which -mask == M. - -* Changes in bgpd - -** "match ip address prefix-list" is added to route-map. - -** A route without local preference is evaluated as 100 local preference. - -** Select smaller router-id route when other values are same. - -** Compare MED only both routes comes from same neighboring AS. - -** "bgp always-compare-med" command is added. - -** Now MED value is passed to IBGP peer. - -** When neighbor's filter is configured with non-existent access-list, -as-path access-list, ip prefix-list, route-map. The behavior is -changed from all permit to all deny. - -* Changes in ospfd - -** Fix bug of external route tag byte order. - -** OSPF Neighbor deletion bug which cause crush is fixed. - -** Some route calculation bug are fixed. - -** Add sanity check with router routing table. - -** Fix bug of memory leak about linklist. - -** Fix bug of 1-WayReceived in NSM. - -** Take care of BIGENDIAN architecture. - -** Fix bug of NSM state flapping between ExStart and Exchange. - -** Fix bug of Network-LSA originated in stub network. - -** Fix bug of MS flag unset. - -** Add to schedule router_lsa origination when the interface cost -changes. - -** Increment LS age by configured interface transmit_delay. - -** distribute-list is reimplemented. - -** Fix bug of refresh never occurs. - -** Fix bug of summary-LSAs reorigination. Correctly copy -OSPF_LSA_APPROVED flag to new LSA. when summary-LSA is reoriginatd. - -** Fix bug of re-origination when a neighbor disappears. - -** Fix bug of segmentation fault with DD retransmission. - -** Fix network-LSA re-origination problem. - -** Fix problem of remaining withdrawn routes on zebra. - -* Changes in ripd - -** Do not leave from multicast group when interface goes down bug is -fixed. - -* Changes in zebra - -** Remove client structure when client dies. - -** Take care static route when interface goes up/down. - -* Changes in zebra-0.85 - -* Changes in bgpd - -** "transparent-nexthop" and "transparenet-as" commands are added. - -** Route reflector's originator-id bug is fixed. - -* Changes in ospfd - -** Fix bug of OSPF LSA memory leak. - -** Fix bug of OSPF external route memory leak. - -** AS-external-LSA origination bug was fixed. - -** LS request treatment is completely rewritten. Now performance is -drastically improved. - -* Changes in ripd - -** RIPv1 update is done by class-full manner. - -* Changes in zebra-0.84b - -* Changes in lib - -** Fix bug of inet_pton return value handling - -* Changes in bgpd - -** Fix bug of BGP-4+ link-local address nexthop check for IBGP peer. - -** Don't allocate whole buffer for displaying "show ip bgp". Now it -consume only one screen size memory. - -* Changes in ripd - -** Fix debug output string. - -** Add RIP peer handling. RIP peer are shown by "show ip protocols". - -* Changes in zebra-0.84a - -* Changes in bgpd - -** Fix serious bug of BGP-4+ peering under IPv6 link-local address. - Due to the bug BGP-4+ peering may not be established. - -* Changes in zebra-0.84 - -* Changes in lib - -** IPv6 address and prefix parser is added to VTY by Toshiaki Takada - <takada@zebra.org>. DEFUN string is "X:X::X:X" for IPv6 address, - "X:X::X:X/M" for IPv6 prefix. You can use it like this. - - DEFUN (func, cmd, "neighbor (A.B.C.D|X:X::X:X) remote-as <1-65535>") - -** VTY configuration is locked during configuration. This is for - avoiding unconditional crush from two terminals modify the - configuration at the same time. "who" command shows which termnal - lock the configuration. VTY which has '*' character at the head of - line is locking the configuration. - -** Old logging functions are removed. Functions like - log_open,log_close,openlog are deleted. Instead of that please use - zlog_* functions. zvlog_* used in ospf6d are deleted also. - -** "terminal monitor" command is added. "no terminal monitor" is for - disabling. This command simply display logging information to the - VTY. - -** dropline.[ch] files are deleted. - -* Changes in bgpd - -** BGP neighbor configuration are sorted by it's IP address. - -** BGP peer configuration and actual peer is separated. This is - preparation for Route Server support. - -** "no neighbor PEER" command is added. You can delete neighbor - without specifying AS number. - -** "no neighbor ebgp-multihop" command is added. - -** "no neighbor port PORT" command is added. - -** To conform RFC1771, "neighbor PEER send-community" is default - behavior. If you want to disable sending community attribute, - please specify "no neighbor PEER send-community" to the peer. - -** "neighbor maximum-prefix NUMBER" command is added. - -** Multi-protocol extention NLRI is proceeded only when the peer is - configured proper Address Family and Subsequent Address Family. If - not, those NLRI are simply ignored. - -** Aggregate-address support is improved. Currently below commands - works. - - "aggregate-address" - "aggregate-address summary-only" - "no aggregate-address" - "no aggregate-address summary-only" - - "ipv6 bgp aggregate-address" - "ipv6 bgp aggregate-address summary-only" - "no ipv6 bgp aggregate-address" - "no ipv6 bgp aggregate-address summary-only" - -** redistribute route-map bug is fixed. - -** MBGP support becomes default. "configure" option --enable-mbgp is - removed. - -** New command "neighbor PEER timers connect <1-65535>" is added. - -** New command "neighbor PEER override-capability" is added. - -** New command "show ip bgp neighbor A.B.C.D advertised-route" is added. - -** New command "show ip bgp neighbor A.B.C.D routes" is added. To use - this command, you have to configure neighbor with - "neighbor A.B.C.D soft-reconfiguration inbound" beforehand. - - -* Changes in zebra-0.83 - -* bgpd - -** Serious bug fix about fetching global and link-local address at the -same time. Due to this bug, corrupted IPv6 prefix is generated. If -you uses bgpd for BGP-4+ please update to this version. The bug is -introduced in zebra-0.82. - -** When bgpd send Notify message, don't use thread manager. It is now -send to neighbor immediately. - -* Changes in zebra-0.82 - -** Solaris 2.6 support is added by Michael Handler -<handler@sub-rosa.com>. - -** MBGP support is added by Robert Olsson <Robert.Olsson@data.slu.se>. -Please specify --enable-mbgp to configure script. This option will be -removed in the future and MBGP support will be default. - -* Changes in zebra - -** When interface goes down, withdraw connected routes from routing -table. When interface goes up, restore the routes to the routing -table. - -** `show interface' show interface's statistics on Linux and BSD with -routing socket. - -** Now zebra can get MTU value on BSDI/OS. - -* Changes in bgpd - -** Add capability option support based upon -draft-ietf-idr-bgp4-cap-neg-04.txt. - -** Add `show ipv6 bgp prefix-list' command. - -** Check self AS appeared in received routes. - -** redistribute route-map support is added. - -** BGP packet dump feature compatible with MRT. - -* Changes in ripd - -** Fix bug of `timers basic' command's argument format. - -* Changes in ripngd - -** Calculate max RTE using interface's MTU value. - -* Changes in ospfd - -** Some correction to LSU processing. - -** Add check for lsa->refresh_list. - -* Changes in ospf6d - -** Many debug feature is added. - -* Changes in zebra-0.81 - -** SNMP support is disabled in default.--enable-snmp option is added -to configure script. - -* Changes in bgpd - -** Fix FSM bug which introduced in zebra-0.80. - -* Changes in zebra-0.80 - -* access-list - - New access-list name space `ipv6 access-list' is added. At the same - time, `access-list' statemant only accepts IPv4 prefix. Please be - careful if you use IPv6 filtering. You will need to change your - configuration. For IPv6 filtering please use `ipv6 access-list'. - - As of zebra-0.7x, user can use `access-list' for both IPv4 and IPv6 - filtering. - - ! zebra-0.7x - access-list DML-net permit 203.181.89.0/24 - access-list DML-net permit 3ffe:506::0/32 - access-list DML-net deny any - ! - - Above configuration is not valid for zebra-08x. Please add `ipv6' - before 'access-list' when you configure IPv6 filtering. - - ! zebra-0.8x - access-list DML-net permit 203.181.89.0/24 - access-list DML-net deny any - ! - ipv6 access-list DML-net permit 3ffe:506::0/32 - ipv6 access-list DML-net deny any - ! - -* prefix-list - - And also new prefix-list name space `ipv6 prefix-list' is added. It - is the same as the change of `access-list'. `ip prefix-list' now only - accept IPv4 prefix. It was source of confusion that `ip prefix-list' - can be used both IPv4 and IPv6 filtering. Now name space is separated - to clear the meaning of the filter. - - If you use `ip prefix-list' for IPv6 filtering, please change the - stetement. - - ! zebra-0.7x - ip prefix-list 6bone-filter seq 5 permit 3ffe::/17 le 24 ge 24 - ip prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 le 28 ge 28 - ip prefix-list 6bone-filter seq 12 deny 3ffe::/16 - ip prefix-list 6bone-filter seq 15 permit 2000::/3 le 16 ge 16 - ip prefix-list 6bone-filter seq 20 permit 2001::/16 le 35 ge 35 - ip prefix-list 6bone-filter seq 30 deny any - ! - - Now user can explicitly configure it as IPv6 prefix-list. - - ! zebra-0.8x - ipv6 prefix-list 6bone-filter seq 5 permit 3ffe::/17 le 24 ge 24 - ipv6 prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 le 28 ge 28 - ipv6 prefix-list 6bone-filter seq 12 deny 3ffe::/16 - ipv6 prefix-list 6bone-filter seq 15 permit 2000::/3 le 16 ge 16 - ipv6 prefix-list 6bone-filter seq 20 permit 2001::/16 le 35 ge 35 - ipv6 prefix-list 6bone-filter seq 30 deny any - ! - -* RIP configuration - - If you want to filter only default route (0.0.0.0/0) and permit other - routes, it was hard to do that. Now `ip prefix-list' can be used for - RIP route filtering. - - New statement: - - `distribute-list prefix PLIST_NAME (in|out) IFNAME' - - is added to ripd. So you can configure on eth0 interface accept all - routes other than default routes. - - ! - router rip - distribute-list prefix filter-default in eth0 - ! - ip prefix-list filter-default deny 0.0.0.0/0 le 0 - ip prefix-list filter-default permit any - ! - -* RIPng configuration - - Same change is done for ripngd. You can use `ipv6 prefix-list' for - filtering. - - ! - router ripng - distribute-list prefix filter-default in eth0 - ! - ipv6 prefix-list filter-default deny ::/0 le 0 - ipv6 prefix-list filter-default permit any - ! - -* BGP configuration - - So far, Multiprotocol Extensions for BGP-4 (RFC2283) configuration is - done with traditional IPv4 peering statement like blow. - - ! - router bgp 7675 - neighbor 3ffe:506::1 remote-as 2500 - neighbor 3ffe:506::1 prefix-list 6bone-filter out - ! - - For separating configuration IPv4 and IPv6, and for retaining Cisco - configuration compatibility, now IPv6 configuration is done by IPv6 - specific statement. IPv6 BGP configuration is done by statement which - start from `ipv6 bgp'. - - ! - router bgp 7675 - ! - ipv6 bgp neighbor 3ffe:506::1 remote-as 2500 - ipv6 bgp neighbor 3ffe:506::1 prefix-list 6bone-filter out - ! - - At the same time some IPv6 specific commands are deleted from IPv4 - configuration. - - o redistribute ripng - o redistribute ospf6 - o neighbor PEER version BGP_VERSION - o neighbor PEER interface IFNAME - - Those commands are only accepted as like below. - - o ipv6 bgp redistribute ripng - o ipv6 bgp redistribute ospf6 - o ipv6 bgp neighbor PEER version BGP_VERSION - o ipv6 bgp neighbor PEER interface IFNAME - - And below new commands are added. - - o ipv6 bgp network IPV6_PREFIX - o ipv6 bgp redistribute static - o ipv6 bgp redistribute connected - o ipv6 bgp neighbor PEER remote-as <1-65535> [passive] - o ipv6 bgp neighbor PEER ebgp-multihop [TTL] - o ipv6 bgp neighbor PEER description DESCRIPTION - o ipv6 bgp neighbor PEER shutdown - o ipv6 bgp neighbor PEER route-reflector-client - o ipv6 bgp neighbor PEER update-source IFNAME - o ipv6 bgp neighbor PEER next-hop-self - o ipv6 bgp neighbor PEER timers holdtime <0-65535> - o ipv6 bgp neighbor PEER timers keepalive <0-65535> - o ipv6 bgp neighbor PEER send-community - o ipv6 bgp neighbor PEER weight <0-65535> - o ipv6 bgp neighbor PEER default-originate - o ipv6 bgp neighbor PEER filter-list FILTER_LIST_NAME (in|out) - o ipv6 bgp neighbor PEER prefix-list PREFIX_LIST_NAME (in|out) - o ipv6 bgp neighbor PEER distribute-list AS_LIST_NAME (in|out) - o ipv6 bgp neighbor PEER route-map ROUTE_MAP_NAME (in|out) - - And some utility commands are introduced. - - o clear ipv6 bgp [PEER] - o show ipv6 bgp neighbors [PEER] - o show ipv6 bgp summary - - I hope these changes are easy to understand for current Zebra users... - -* To restrict connection to VTY interface. - - It used to be both IPv4 and IPv6 filter can be specified with one - access-list. Then the access-list can be appried to VTY interface - with `access-class' stetement in `line vty' node. Below is example in - zebra-0.7x. - - ! - access-list local-only permit 127.0.0.1/32 - access-list local-only permit ::1/128 - access-list local-only deny any - ! - line vty - access-class local-only - ! - - Now IPv4 and IPv6 filter have each name space. It is not possible to - specify IPv4 and IPv6 filter with one access-list. For setting IPv6 - access-list in `line vty', `ipv6 access-class' statement is - introduced. Let me show the configuration in zebra-0.8x. - - ! - access-list local-only permit 127.0.0.1/32 - access-list local-only deny any - ! - ipv6 access-list local-only permit ::1/128 - ipv6 access-list local-only dny any - ! - line vty - access-class local-only - ipv6 access-class local-only - ! - -* route-map - - New IPv6 related route-map match commands are added. - - o match ipv6 address - o match ipv6 next-hop - - Please change your configuration if you use IP match statement for - IPv6 route. - - zebra-0.7x config - ================= - ! - access-list all permit any - ! - route-map set-nexthop permit 10 - match ip address all - set ipv6 next-hop global 3ffe:506::1 - set ipv6 next-hop local fe80::cbb5:591a - ! - - zebra-0.8x config - ================= - ! - ipv6 access-list all permit any - ! - route-map set-nexthop permit 10 - match ipv6 address all - set ipv6 next-hop global 3ffe:506::1 - set ipv6 next-hop local fe80::cbb5:591a - ! - -* zebra connection - - Protocol daemon such as ripd, bgpd, ospfd will reconnect zebra daemon - when the connection fail. Those daemons try to connect zebra every 10 - seconds first three trial, then the interval changed to 60 seconds. - After all, if ten connections are fail, protocol daemon give up the - connection to the zebra daemon. - -* SNMP support (is not yet finished) - - Zebra uses SMUX protocol (RFC1227) for making communication with SNMP - agent. Currently lib/smux.c can be compiled only with ucd-snmp-4.0.1 - and http://ucd-snmp.ucdavis.edu/patches/012.patch. It can not be - compiled with ucd-snmp-3.6.2. - - After applying the patch to ucd-snmp-4.0.1, please configure it with - SMUX module. - - % configure --with-mib-modules=smux - - After compile & install ucd-snmp-4.0.1, you will need to configure - smuxpeer. I'm now using below configuration. - - /usr/local/share/snmp/snmpd.conf - ================================ - smuxpeer 1.3.6.1.6.3.1 test - - Above 1.3.6.1.6.3.1 and test is temporary configuration which is hard - coded in lib/smux.c. Yes, I know it is bad, I'll change it ASAP. - -* HUP signal treatment - - From zebra-0.80, ripd will reload it's configuration file when ripd - receives HUP signal. Other daemon such as bgpd, ospfd will support - HUP signal treatment soon. - -* Changes in zebra-0.79 - -* Changes in zebra - -** Broadcast address setting on Linux box bug is fixed. - -** Protocol daemon can install connected IPv6 route into the kernel. - -** Now zebra can handle blackhole route. - -* Changes in ripd - -** Add route-map feature for RIP protocol. - -** In case of RIP version 2 routing table entry has IPv4 address and -netmask pair which host part bit is on, ignore the entry. - -* Changes in ripngd - -** Change CMSG_DATA cast from (u_char *) to (int *). (u_char *) does -not work for NetBSD-currnet on SparcStation 10. - -* Changes in ospfd - -** MaxAge LSA treatment is added. - -** ABR/ASBR functionality is added. - -** Virtual Link funtionality is added. - -** ABR behaviors IBM/Cisco/Shortcut is added. - -* Changes in ospf6d - -** Enclosed KAME specific part with #ifdef #endif - -* Changes in zebra-0.78 - -* Changes in lib - -** SNMP support is started. - -** Now Zebra can work on BSD/OS 4.X. - -** Now Zebra can compiled on vanilla OpenBSD 2.5 but not yet working correcltly. - -* Changes in zebra - -** Interface index detection using ioctl() bug is fixed. - -** Interface information protocol is changed. Now interface -addition/deletion and interface's address addition/deletion is -separated. - -* Changes in bgpd - -** BGP hold timer bug is fixed. - -** BGP keepavlie timer becomes configurable. - -* Changes in ripd - -** When making reply to rip's REQUEST message, fill in -RIP_METRIC_INFINITY with network byte order using htonl (). - -** Pass host byte order address to IN_CLASSC and IN_CLASSB macro. - -* Changes in ospfd - -** LSA flooding works. - -** Fix bug of DD processing. - -** Fix bug of originating router-LSA bug is fixed. - -** LSA structure is changed to support LSA aging. - -* Changes in ospf6d - -** `ip6' statement in configuration is changed to `ipv6'. - -* Changes in zebra-0.77 - -* Changes in lib - -** SIGUSR1 reopen logging file. - -** route-map is extended to support multi-protocol routing -information. - -** When compiling under GNU libc 2.1 environment don't use inet6-apps. - -* Changes in zebra - -** Basic IPv6 router advertisement codes added. It is not yet usable. - -** Fix IPv6 route addition/deletion bug is fixed. - -** `show ip route A.B.C.D' works - -* Changes in bgpd - -** When invalid unfeasible routes length comes, bgpd send notify then -continue to process the packet. Now bgpd stop parsing invalid packet -then return to main loop. - -** BGP-4+ withdrawn routes parse bug is fixed. - -** When BGP-4+ information passed to non shared network's peer, trim -link-local next-hop information. - -** `no redistribute ROUTE_TYPE' withdraw installed routes from BGP -routing information. - -** `show ipv6 route IPV6ADDR' command added. - -** BGP start timer has jitter. - -** Holdtimer configuration bug is fixed. Now configuration does not -show unconfigured hold time value. - -* Changes in ripngd - -** Now update timer (default 30 seconds) has +/- 50% jitter value. - -** Add timers basic command. - -** `network' configuration is dynamically reflected. - -** `timers basic <update> <timeout> <garbage>' added. - -* Changes in ripd - -** Reconstruct almost codes. - -** `network' configuration is dynamically reflected. - -** RIP timers now conforms to RFC2453. So user can configure update, -timeout, garbage timer. - -** `timers basic <update> <timeout> <garbage>' works. - -* Changes in ospfd - -** Bug of originating network LSA is fixed. - -** `no router ospf' core dump bug is fixed. - -* Changes in ospf6d - -** Redistribute route works. - -* Changes in zebra-0.76 - -* Changes in lib - -** configure.in Linux IPv6 detection problem is fixed. - -** Include SERVICES file to the distribution - -** Update zebra.texi to zebra-0.76. - -* Changes in zebra-0.75 - -* Changes in lib - -** `termnal length 0' bug is fixed. - -* Changes in zebra - -** When zebra starts up, sweep all zebra installed routes. If -k or ---keep_kernel option is specified to zebra dameon. This function is -not performed. - -* Changes in ripngd - -** Aggreagte address command supported. In router ripngd, -`aggregate-address IPV6PREFIX' works. - -* Changes in bgpd - -** Input route-map's bug which cause segmentation violation is fixed. - -** route-map method improved. - -** BGP-4+ nexthop detection improved. - -** BGP-4+ route re-selection bug is fixed. - -** BGP-4+ iBGP route's nexthop calculation works. - -** After connection Established `show ip bgp neighbor' display BGP TCP -connection's source and destination address. - -** In case of BGP-4+ `show ip bgp neighbor' display BGP-4+ global and -local nexthop which used for originated route. This address will be -used when `next-hop-self'. - -* Changes in ospfd - -** Fix bug of DR election. - -** Set IP precedence field with IPTOS_PREC_INTERNET_CONTROL. - -** Schedule NeighborChange event if NSM status change. - -** Never include a neighbor in Hello packet, when the neighbor goes -down. - -* Changes in zebra-0.74 - -* Changes in lib - -** Now `terminal length 0' means no line output control. - -** `line LINES' command deleted. Instead of this please use `terminal -length <0-512>'. - -** `terminal length <0-512>' is each vty specific configuration so it -can not be configured in the configuration file. If you want to -configure system wide line control, please use `service -terminal-length <0-512>'. This configuration affects to the all vty -interface. - -* Changes in zebra - -** Installation of IPv6 route bug is fixed. - -* Changes in bgpd - -** Very serious bug of bgp_stop () is fixed. When multiple route to -the same destination exist, bgpd try to announce the information to -stopped peer. Then add orphan write thread is added. This cause -many strange behavior of bgpd. - -** Router-id parsing bug is fixed. - -** With BGP-4+ nexthop installation was done with global address but -it should be link-local address. This bug is fixed now. - -** When incoming route-map prepend AS, old AS path remained. Now bgpd -free old AS path. - -** `neighbor PEER weight <0-65535>' command added. - -* Changes in ripngd - -** Almost codes are rewritten to conform to RFC2080. - -* Changes in ospfd - -** SPF calculation timer is added. Currently it is set to 30 seconds. - -** SPF calculation works now. - -** OSPF routing table codes are added. - -** OSPF's internal routes installed into the kernel routing table. - -** Now `ospfd' works as non-area, non-external route support OSPF -router. - -** Call of log_rotate() is removed. - -* Changes in ospf6d - -** LSA data structure is changed. - -** Call of log_rotate() is removed. - -* Changes in zebra-0.73 - -* Changes in lib - -** `config terminal' is changed to `configure terminal'. - -** `terminal length <0-512>' command is added. - -** Variable length argument was specified by `...'. Now all strings -started with character `.' is variable length argument. - -* Changes in zebra - -** Internal route (such as iBGP, internal OSPF route) handling works -correctly. - -** In interface node, `ipv6 address' and `no ipv6 address' works. - -** Interface's address remain after `no ip address' bug is fixed. - -** Host route such as IPv4 with /32 mask and IPv6 with /128 mask -didn't set RTF_GATEWAY even it has gateway. This bug if fixed now. - -* Changes in bgpd - -** `match as-path' argument is used to be specify AS PATH value itself -directly (e.g. ^$). But it is changed to specify `ip as-apth -access-list' name. - -** iBGP route handle works without getting error from the kernel. - -** `set aggregator as AS A.B.C.D' command is added to route-map. - -** `set atomic-aggregate' command is added to bgpd's routemap. - -** Announcement of atomic aggregate attribute and aggregator attribute -works. - -** `update-source' bug is fixed. - -** When a route learned from eBGP is announced to iBGP, local -preference was set to zero. But now it set to -DEFAULT_LOCAL_PREF(100). - -* Changes in ripd - -** RIPv1 route filter bug is fixed. - -** Some memory leak is fixed. - -* Changes in ospfd - -** Fix bug of DR Election. - -** Fix bug of adjacency forming. - -* Changes in ospf6d - -** Clean up logging message. - -** Reflect routing information to zebra daemon. - -* Changes in zebra-0.72 - -* Changes in lib - -** When getsockname return IPv4 mapped IPv6 address. Convert it to -IPv4 address. - -* Changes in bgpd - -** Change route-map's next-hop related settings. - -set ip nexthop -> set ip next-hop -set ipv6 nexthop global -> set ipv6 next-hop global -set ipv6 nexthop local -> set ipv6 next-hop local - -** Add `next-hop-self' command. - -* Changes in ospfd - -** Fix bug of multiple `network area' directive crashes. - -* Changes in zebra-0.71 - -* Changes in lib - -** `log syslog' command is added. - -** Use getaddrinfo function to bind IPv4/IPv6 server socket. - -** `no banner motd' will suppress motd output when user connect to VTY. - -** Bind `quit' command to major nodes. - -* Changes in zebra - -** Point-to-point link address handling bug is fixed. - -* Changes in bgpd - -** AS path validity check is added. If malformed AS path is received -NOTIFY Malformed AS path is send to the peer. - -** Use getaddrinfo function to bind IPv4/IPv6 server socket. - -* Changes in ripd - -** Connected network announcement bug is fixed. - -** `broadcast' command is deleted. - -** `network' command is added. - -** `neighbor' command is added. - -** `redistribute' command is added. - -** `timers basic' command is added. - -** `route' command is added. - -* Changes in ripngd - -** Fix metric calculation bug. - -* Changes in ospfd - -** Check sum bug is fixed. - -* Chanegs in ospf6d - -** Routing table code is rewritten. - -* Changes in zebra-0.70 - -* Changes in zebra - -** Critical routing information base calculation bug check is fixed. - -** zebra ipv4 message is extended to support external/internal route -flavor. - -** Now if internal route doesn't has direct connected nexthop, then -nexthop is calculated by looking up IGP routing table. - -* Changes in bgpd - -** `neighbor PEER update-source IFNAME' command added as ALIAS to -`neighbor PEER interface IFNAME'. - -* Changes in ospfd - -** DD null pointer bug is fixed. - -* Changes in zebra-0.69 - -* Changes in zebra - -** zebra redistirbution supports dynamic notification of the route -change. If you add static route while running zebra, it will be -reflected to other protocol daemon which set `redistribute static'. - -** If static route installation is failed due to the error. The -static route is not added to the configuration and zebra routing -table. - -** zebra sets forwarding flag to on when it starts up. - -** `no ip forwarding' turn off IPv4 forwarding. - -** `no ipv6 forwarding' turn off IPv6 forwarding. - -** Change `show ipforward' command to `show ip forwarding'. - -** Change `show ipv6forward' command to `show ipv6 forwarding'. - -** `ip route A.B.C.D/M INTERFACE' works. So you can set `ip route -10.0.0.0/8 eth0'. - -* Changes in bgpd - -** `neighbor PEER send-community' command is added. If the option is -set, bgpd will send community attribute to the peer. - -** When a BGP route has no-export community attribute and -send-community is set to the peer, the route is not announced to the -peer. - -* Changes in ripngd - -** When ripngd terminates, delete all installed route. - -** `redistribute static', `redistribute connected' works. - -** Change `debug ripng event' to `debug ripng events'. - -** Change `show debug ripng' to `show debugging ripng'. - -** Bug of static route deletion is fixed. - -* Changes in ospfd - -** LS request and LS update can be send and received. - -* Changes in zebra-0.68 - -* Changes in lib - -** DEFUN() is extended to support (a|b|c) statement. - -** Input buffer overflow bug is fixed. - -* Changes in bgpd - -** `ip community-list' is added. - -** set community and match community is added to route-map statement. - -** aggregate-address A.B.C.D/M partly works. Now it works only -summary-only mode. - -* Changes in zebra - -** IPv6 network address delete bug is fixed. - -* Changes in ospfd - -** DR election bug fixed. - -** Now Database Description can be send or received. - -** Neighbor State Machine goes to Full state. - -* Changes in ospf6d - -** router zebra related bug is fixed. - -* Changes in zebra-0.67 - -* Changes in lib - -** `service password-encryption' is added for encrypted password. - -* Changes in bgpd - -** `set as-path prepend ASPATH' is added to route-map command. - -** `set weight WEIGHT' is added to route-map command. - -** `no set ipv6 nexthop global' and `no set ipv6 nexthop local' -command is added to route-map. - -** `neighbor IP_ADDR version BGP_VERSION' command's BGP_VERSION -argument changed. - -Old New -===================== -bgp4 4 -bgp4+ 4+ -bgp4+-draft-00 4- -===================== - -If you want to peer with old draft version of BGP-4+, please configure -like below: - -router bgp ASN - neighbor PEER version 4- - -** Some AS path isn't correctly compared during route selection. Now -it is fixed. - -* Changes in ospfd - -** `router zebra' is default behavior. - -* Changes in ospf6d - -** `router zebra' is default behavior. - -* Changes in zebra-0.66 - -* Changes in zebra - -** When other daemon such as gated install routes into the kernel then -zebra blocks. This is only occur with netlink socket. Now socket is -set as NONBLOCKING and problem is fixed. Reported and fixed by -Patrick Koppen <koppen@rhrk.uni-kl.de> - -* Changes in bgpd - -** Now `router zebra' is not needed to insert BGP routes into the -kernel. It is default behavior. If you don't want to install the BGP -routes to the kernel, please configure like below: - -! -router zebra - no redistribute bgp -! - -** redistribute connected works. - -** redistribute static now filter local loopback routes and link local -network. - -* Changes in ripd - -** Some network check is added. Patch is done by Carlos Alberto -Barcenilla <barce@frlp.utn.edu.ar> - -* Changes in ripngd - -** Sometimes ripngd install wrong nexthop into the kernel. This bug -is fixed now. - -** Now `router zebra' is not needed to insert RIPng routes into the -kernel. It is default behavior. If you don't want to install the BGP -routes to the kernel, please configure like below: - -! -router zebra - no redistribute ripng -! - -* Changes in zebra-0.65 - -* Changes in lib - -** `C-c' changes current node to ENABLE_NODE. Previously it doesn't. - -** In ENABLE_NODE, `exit' command close vty connection. - -** `service advanced-vty' enable advanced vty function. If this -service is specified one can directly connect to ENABLE_NODE when -enable password is not set. - -** `lines LINES' command is added by Stephen R. van den Berg -<srb@cuci.nl>. - -* Changes in zebra - -** Basic Linux policy based routing table support is added by Stephen -R. van den Berg <srb@cuci.nl>. - -* Changes in bgpd - -** route-map command is improved: - `match ip next-hop': New command. - `match metric': New command. - `set metric': Doc fixed. - `set local-preference': DEFUN added. - -* Changes in ripd - -** Check of announced network is added. Now multicast address is -filtered. Reported by Carlos Alberto Barcenilla -<barce@frlp.utn.edu.ar> - -** Check of network 127 is added. Reported by Carlos Alberto -Barcenilla <barce@frlp.utn.edu.ar> - -* Changes in ripngd - -** Aging route bug is fixed. - -** `router zebra' semantics changed. ripngd automatically connect to -zebra. - -* Changes in ospfd - -** `no router ospf' works. - -* Changes in ospf6d - -** Bug fix about network vertex. - -* Changes in zebra-0.64.1. - -This is bug fix release. - -* Changes in lib - -** Add check of sin6_scope_id in struct sockaddr_in6. For compilation -on implementation which doesn't have sin6_scope_id. Reported by Wim -Biemolt <Wim.Biemolt@ipv6.surfnet.nl>. - -* Changes in zebra - -** Fix bug of display BGP routes as "O" instead of "B". Reported by -"William F. Maton" <wmaton@enterprise.ic.gc.ca> and Dave Hartzell -<hartzell@greatplains.net>. - -* Changes in bgpd - -** `no network IPV6_NETWORK' statement and `no neighbor IP_ADDR timers -holdtime [TIMER]' statement doesn't work. Reported by Georg Hitsch -<georg@atnet.at>. Now both statement work. - -* Changes in ospfd - -** Last interface is not updated by ospf_if_update(). Reported by -Dave Hartzell <hartzell@greatplains.net>. - -* Changes in ospf6d - -** Byte order of ifid is changed. Due to this change, this code will -not work with previous version, sorry. - -** Fix `show ip route' route type mismatch. - -** Fix bug of no network IPV6_NETWORK. - -** Important bug fix about intra-area-prefix-lsa. - -* Changes in zebra-0.64. - -* Changes in lib - -** prefix-list based filtering routine is added. Currently used in -bgpd but it will be in other daemons. - -* Changes in bgpd - -** `no router bgp' works. But network statement is not cleared. This -should be fixed in next beta. - -** Route reflector related statement is added. - - router bgp ASN - bgp cluster-id a.b.c.d - neighbor a.b.c.d route-reflector-client - - is added. - -** Prefix list based filtering is added. - - router bgp ASN - neighbor a.b.c.d prefix-list PREFIX_LIST_NAME - -** Prefix list based routing display works. - - show ip bgp prefix-list PREFIX_LIST_NAME - -* Changes in ripd - -** Fix route metric check bug. Reported from Mr. Carlos Alberto -Barcenilla. - -* Changes in ospf6d - -** There are many changes. If you have interested in ospf6d please -visit ospf6d/README file. - -* Changes in zebra-0.63 first beta package. - -* Changes in lib - -** `copy running-config stgartup-config' command is added. - -** prefix length check bug is fixed. Thanks Marlos Barcenilla -<barce@frip.utn.edu.ar>. - -* Changes in ospfd - -** DR and BDR election works. - -** OSPF Hello simple authentication works. - -* Changes in ospf6d - -** Now ospf6d can be compiled on both Linux and *BSD system. - -* Changes in zebra-19990420 snapshot - -** `make dist' at top directory works now. - -* Changes in lib - -** VTY has now access-class to restrict remote connection. -Implemented by Alex Bligh <amb@gxn.net>. - -! -line vty - access-class ACCESS-LIST-NAME -! - -** `show version' command added. Implemented by Carlos Alberto -Barcenilla <barce@frlp.utn.edu.ar> - -* Changes in zebra - -** `ip address' command on *BSD bug is fixed. - -** `no ip address' works now for IPv4 address. - -** Now `write terminal' display `ip address' configuration. - -* Changes in bgpd - -** Redistribute static works now. Please run both zebra and bgpd. -bgpd.conf should be like this: - -! -router zebra -! -router bgp ASN - redisitribute static -! - -* Changes in guile - -** configure --enable-guile turns on zebra-guile build. - -** (router-bgp ASN) allocates real bgp structre. - -* Changes in zebra-19990416 snapshot - -** Set version to 0.60 for preparation of beta release. - -** New directory guile is added for linking with guile interpreter. - -* Changes in zebra - -** On GNU/Linux Kernel 2.2.x (with netlink support), zebra detects -asynchronous routing updates. *BSD support is not yet finished. - -* Changes in bgpd - -** `show ip bgp regexp ASPATH_REGEX' uses CISCO like regular expression -instead of RPSL like regular expression. I'm planing to provide RPSL -like regular expression with `show ip bgp rpsl' or something. - -* Changes in lib - -** Press '?' at variable mandatory argument, vty prints nothing. Now -vty outputs description about the argument. Fixed by Alex Bligh -<amb@gxn.net> - -** buffer.c has some ugly bugs. Due to the bug, vty interface hangs -when large output date exists. This bug is fixed. Reported by Alex -Bligh <amb@gxn.net>. - -* Changes in ospfd - -** DR and BDR information is shown by `show ip ospf interface' command. - -* Changes in zebra-19990408 snapshot - -* Changes in bgpd - -** Old BGP-4+ specification (described in old draft) treatment bug is -fixed. It seems that mrtd uses this format as default. So if you -have problem peering with mrtd and want to use old draft format please -use version statement like this. - -neighbor PEER_ADDRESS remote-as ASN -neighbor PEER_ADDRESS version bgp4+-draft-00 - -** When AS path is epmty (routes generated by bgpd), SEGV is occur -when announce the routes to eBGP peer. Reported by -kad@gibson.skif.net. - -** ip as-path access-list command is added. - -** neighbor PEER_ADDRESS filter-list AS_LIST [in|out] command is added. - -** neighbor PEER_ADDRESS timers holdtimer TIMER command is added. - -* Changes in all daemons - -** With KAME stack, terminal interface is now bind AF_INET socket -instead of AF_INET6 one. - -* Changes in zebra-19990403 snapshot - -* Changes in bgpd - -** When bgpd has 'router zebra', bgpd automatically select it's router -ID as most highest interface's IP Address. - -** When AS path is empty (in case of iBGP), it doesn't include any AS -segment. This change is for announcement to gated under iBGP. - -* Changes in ospfd - -** OSPF hello packet send/receive works. - -* Changes in ospf6d - -** Yasuhiro Ohara's ospf6d codes is imported. It is under development -and can't be compiled on any platform. - -* Changes in zebra-19990327 snapshot - -* Changes in bgpd - -** When BGP-4+ connection is done by IPv6 link-local address. One -have to specify interface index for the connection. So I've added -interface statement to the neighbor commmand. Please specify -interface name for getting interface index like below. This statement -only works on GNU/Linux. I'll support BSD ASAP. - -router bgp 7675 - neighbor fe80::200:f8ff:fe01:5fd3 remote-as 2500 - neighbor fe80::200:f8ff:fe01:5fd3 interface sit3 - -** For disable BGP peering `shutdown' command is added. - -router bgp 7675 - neighbor 10.0.0.1 shutdown - -** `description' command is added to neighbor statement. - -router bgp 7675 - neighbor 10.0.0.1 description peering with Norway. - -** `show ip bgp regexp AS-REGEXP' works again. - -show ip bgp regexp AS7675 - -will show routes which include AS7675. - -** When a route which is made from `network' statement is send to -neighbor. Set it's nexthop to self. So 10.0.0.0/8 is announced to -the peer A with source address 192.168.1.1. The routes nexthop is set -to 192.168.1.1. - -* Changes in zebra - -** In zebra/rtread_sysctl.c, function rtm_read() may overrun allocated -buffer when the address family is not supported and the length is big -(i.e link address). Reported Achim Patzner <ap@bnc.net>. - -* Changes in ospfd - -** Now ospfd receive OSPF packet. - -* Changes in zebra-19990319 snapshot - -* Changes in configuration and libraries - -** User can disable IPv6 feature and/or pthread feature by configure - option. - - To disable IPv6: configure --disable-ipv6 - To disable pthread: configure --disable-pthread - -** User can disable specified daemon by configure option. - - Don't make zebra: configure --disable-zebra - Don't make bgpd: configure --disable-bgpd - Don't make ripd: configure --disable-ripd - Don't make ripngd: configure --disable-ripngd - Don't make ospfd: configure --disable-ospfd - Don't make ospf6d: configure --disable-ospf6d - -** Sample configuration files are installed as 600 file flag. - Suggested by Jeroen Ruigrok/Asmodai <asmodai@wxs.nl>. - -** syslog logging feature is added by Peter Galbavy - <Peter.Galbavy@knowledge.com> - -** Inclusion of standard header files is reworked by Peter Galbavy - <Peter.Galbavy@knowledge.com> - -** Change description from GNU/Linux 2.1.X to GNU/Linux 2.2.X - -** If daemon function exists in standard C library use it. - -** To generate configure script we upgrade autoconf to 2.13. To -generate Makefile.in we upgrade automake to 1.4. - -** doc/texinfo.tex is added to distribution. - -** Update ports/pkg/DESCR description. - -** Update doc/zebra.texi. - -** logfile FILENAME statement deleted. Instead of that please use log -file FILENAME. - -* Changes in zebra - -* Changes in bgpd - -** Communication between zebra and bgpd works now. So if there is - `router zebra' line in bgpd.conf, selected route is installed - into kernel routing table. - -** Delete all routes which inserted by bgpd when bgpd dies. If you -want to retain routes even bgpd dies please specify [-r|--retain] -option to bgpd. - -** BGP announcement code is reworked. Now bgpd announce selected - routes to other peer. - -** All output bgp packet is buffered. It's written to the socket when - it gets ready. - -** Output route-map works now. You can specify output route-map by: - - neighbor IP_ADDR route-map ROUTE_MAP_NAME out - -** New route-map command added. - - set ip nexthop IP_ADDR - set ipv6 nexthop global IP_ADDR - -** Fix bug about unlock of the route_node structure. - -** BGP-4+ support is added. bgpd can listen and speak BGP-4+ packet -specified in RFC2283. You can view IPv6 bgp table by: `show ipv6 bgp'. - -** Meny packet overflow check is added. - -* Changes in ripd - -* Changes in ripngd - -* Changes in ospfd - -** ospfd work is started by Toshiaki Takada <takada@zebra.org>. Now -several files are included in ospfd directory. - -** ospf6d codes are merged from Yasuhiro Ohara <yasu@sfc.wide.ad.jp>'s -ospfd work. Now codes are located in ospf6d directory. - - -Local variables: -mode: outline -paragraph-separate: "[ ]*$" -end: diff --git a/README b/README deleted file mode 100644 index 7600ec54cc..0000000000 --- a/README +++ /dev/null @@ -1,16 +0,0 @@ -FRRouting is free software that implements and manages various IPv4 and IPv6 -routing protocols. - -Currently FRRouting supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1, RIPv2, RIPng, -IS-IS, PIM-SM/MSDP, LDP and Babel as well as very early support for EIGRP and -NHRP. - -See doc/user/bugs.rst for information on how to report bugs. - -See doc/developer/workflow.rst for information on contributing. - -See the file COPYING for copying conditions. - -Public email discussion can be found at https://lists.frrouting.org/listinfo - -Our public slack channel is at https://frrouting.slack.com diff --git a/README.md b/README.md new file mode 100644 index 0000000000..48142f21b7 --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +FRRouting +========= + +FRR is free software that implements and manages various IPv4 and IPv6 routing +protocols. It runs on nearly all distributions of Linux and BSD as well as +Solaris and supports all modern CPU architectures. + +FRR currently supports the following protocols: + +* BGP +* OSPFv2 +* OSPFv3 +* RIPv1 +* RIPv2 +* RIPng +* IS-IS +* PIM-SM/MSDP +* LDP +* BFD +* Babel +* EIGRP (alpha) +* NHRP (alpha) + +Installation & Use +------------------ + +Packages are available for various distributions on our +[releases page](https://github.com/FRRouting/frr/releases). + +Snaps are also available [here](https://snapcraft.io/frr). + +Instructions on building and installing from source for supported platforms may +be found +[here](http://docs.frrouting.org/projects/dev-guide/en/latest/building.html). + +Once installed, please refer to the [user guide](http://docs.frrouting.org/) +for instructions on use. + +Community +--------- + +The FRRouting email list server is located +[here](https://lists.frrouting.org/listinfo) and offers the following public +lists: + +| Topic | List | +|-------------------|------------------------------| +| Development | dev@lists.frrouting.org | +| Users & Operators | frog@lists.frrouting.org | +| Announcements | announce@lists.frrouting.org | + +For chat, we currently use [Slack](https://frrouting.slack.com). Please email +the mailing list to request an invite as we do not issue automatic invites. + + +Contributing +------------ + +FRR maintains [developer's documentation](http://docs.frrouting.org/projects/dev-guide/en/latest/index.html) +which contains the [project workflow](http://docs.frrouting.org/projects/dev-guide/en/latest/workflow.html) +and expectations for contributors. Some technical documentation on project +internals is also available. + +We welcome and appreciate all contributions, no matter how small! + + +Security +-------- + +To report security issues, please use our security mailing list: + +``` +security [at] lists.frrouting.org +``` diff --git a/babeld/babel_errors.c b/babeld/babel_errors.c index e03cace379..b22b1d5cbf 100644 --- a/babeld/babel_errors.c +++ b/babeld/babel_errors.c @@ -26,25 +26,25 @@ /* 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" diff --git a/babeld/babel_errors.h b/babeld/babel_errors.h index 19adc63f04..629b6604be 100644 --- a/babeld/babel_errors.h +++ b/babeld/babel_errors.h @@ -24,10 +24,10 @@ #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); diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c index ff5cca42a0..31778901a6 100644 --- a/babeld/babel_filter.c +++ b/babeld/babel_filter.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "babel_filter.h" #include "vty.h" #include "filter.h" diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index b7c01e73dc..7121ca28d4 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -169,7 +169,7 @@ babel_interface_address_add (int cmd, struct zclient *client, 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); } @@ -709,7 +709,7 @@ interface_recalculate(struct interface *ifp) 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; @@ -729,7 +729,7 @@ interface_recalculate(struct interface *ifp) 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, @@ -793,7 +793,7 @@ interface_reset(struct interface *ifp) 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)); } @@ -1060,7 +1060,7 @@ DEFUN (show_babel_route, } 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) { @@ -1072,7 +1072,7 @@ DEFUN (show_babel_route, } 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; } @@ -1107,7 +1107,7 @@ DEFUN (show_babel_route_prefix, } 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) { @@ -1119,7 +1119,7 @@ DEFUN (show_babel_route_prefix, } 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; } @@ -1165,7 +1165,7 @@ DEFUN (show_babel_route_addr, } 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) { @@ -1177,7 +1177,7 @@ DEFUN (show_babel_route_addr, } 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; } @@ -1224,7 +1224,7 @@ DEFUN (show_babel_route_addr6, } 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) { @@ -1236,7 +1236,7 @@ DEFUN (show_babel_route_addr6, } 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; } diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 31a3fb5b4d..d02d86f77b 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -225,7 +225,7 @@ babel_init_random(void) 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; } @@ -246,13 +246,13 @@ babel_replace_by_null(int fd) 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); } @@ -272,11 +272,11 @@ babel_load_state_file(void) 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; @@ -288,7 +288,7 @@ babel_load_state_file(void) 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'; @@ -297,7 +297,7 @@ babel_load_state_file(void) 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, @@ -307,13 +307,13 @@ babel_load_state_file(void) 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; @@ -353,7 +353,7 @@ babel_save_state_file(void) 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 { @@ -364,12 +364,12 @@ babel_save_state_file(void) 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); } diff --git a/babeld/babeld.c b/babeld/babeld.c index 54692cdf2e..0517cbea6d 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -145,7 +145,7 @@ babel_create_routing_process (void) /* 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; } @@ -179,7 +179,7 @@ babel_read_protocol (struct thread *thread) (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) { @@ -255,12 +255,12 @@ babel_get_myid(void) 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); } @@ -519,7 +519,7 @@ resize_receive_buffer(int size) 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; } @@ -528,7 +528,7 @@ resize_receive_buffer(int size) 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; } diff --git a/babeld/kernel.c b/babeld/kernel.c index ba2b58131c..d4c962af3b 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -21,6 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <sys/time.h> #include <sys/param.h> #include <time.h> diff --git a/babeld/message.c b/babeld/message.c index 09eaca7a48..f85a08ac3a 100644 --- a/babeld/message.c +++ b/babeld/message.c @@ -141,12 +141,12 @@ parse_update_subtlv(const unsigned char *a, int alen, } 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; } @@ -154,14 +154,14 @@ parse_update_subtlv(const unsigned char *a, int alen, /* 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); @@ -189,13 +189,13 @@ parse_hello_subtlv(const unsigned char *a, int alen, } 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; } @@ -207,7 +207,7 @@ parse_hello_subtlv(const unsigned char *a, int alen, 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 { @@ -235,13 +235,13 @@ parse_ihu_subtlv(const unsigned char *a, int alen, } 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; } @@ -255,7 +255,7 @@ parse_ihu_subtlv(const unsigned char *a, int alen, ret = 1; } else { - flog_err(BABEL_ERR_PACKET, + flog_err(EC_BABEL_PACKET, "Received incorrect RTT sub-TLV on IHU message."); } } else { @@ -345,14 +345,14 @@ parse_packet(const unsigned char *from, struct interface *ifp, } 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; @@ -360,14 +360,14 @@ parse_packet(const unsigned char *from, struct interface *ifp, 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; } @@ -516,7 +516,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, 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; } @@ -528,7 +528,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, 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; } @@ -621,7 +621,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, 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; @@ -710,7 +710,7 @@ fill_rtt_message(struct interface *ifp) 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; } @@ -745,9 +745,9 @@ flushbuf(struct interface *ifp) 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); } @@ -870,7 +870,7 @@ start_unicast_message(struct neighbour *neigh, int type, int len) 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; } @@ -1007,10 +1007,10 @@ flush_unicast(int dofree) 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); @@ -1318,7 +1318,7 @@ buffer_update(struct interface *ifp, 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. */ @@ -1382,7 +1382,7 @@ send_update(struct interface *ifp, int urgent, } 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; @@ -1460,7 +1460,7 @@ send_self_update(struct interface *ifp) } 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."); } } diff --git a/babeld/neighbour.c b/babeld/neighbour.c index c1592fb18a..83f05bb5cf 100644 --- a/babeld/neighbour.c +++ b/babeld/neighbour.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -90,7 +94,7 @@ find_neighbour(const unsigned char *address, struct interface *ifp) 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; } diff --git a/babeld/net.c b/babeld/net.c index ad9a6bad92..d1f6a44142 100644 --- a/babeld/net.c +++ b/babeld/net.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <unistd.h> #include <fcntl.h> #include <string.h> diff --git a/babeld/resend.c b/babeld/resend.c index 1f21977442..8949075f67 100644 --- a/babeld/resend.c +++ b/babeld/resend.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <sys/time.h> #include <time.h> #include <string.h> diff --git a/babeld/route.c b/babeld/route.c index ceeaa10577..76f038cda5 100644 --- a/babeld/route.c +++ b/babeld/route.c @@ -399,14 +399,14 @@ install_route(struct babel_route *route) 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; @@ -418,7 +418,7 @@ install_route(struct babel_route *route) 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; @@ -441,7 +441,7 @@ uninstall_route(struct babel_route *route) 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; @@ -465,7 +465,7 @@ switch_routes(struct babel_route *old, struct babel_route *new) 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, @@ -474,7 +474,7 @@ switch_routes(struct babel_route *old, struct babel_route *new) 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; } @@ -503,7 +503,7 @@ change_route_metric(struct babel_route *route, 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; } @@ -798,7 +798,7 @@ update_route(const unsigned char *router_id, 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; } @@ -906,7 +906,7 @@ update_route(const unsigned char *router_id, 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; } diff --git a/babeld/source.c b/babeld/source.c index d6dd848952..ed165b41b4 100644 --- a/babeld/source.c +++ b/babeld/source.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -59,7 +63,7 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen, 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; } diff --git a/babeld/subdir.am b/babeld/subdir.am index 6f91f73930..e1f2cb0a00 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -6,6 +6,11 @@ if BABELD noinst_LIBRARIES += babeld/libbabel.a sbin_PROGRAMS += babeld/babeld dist_examples_DATA += babeld/babeld.conf.sample +vtysh_scan += \ + $(top_srcdir)/babeld/babel_interface.c \ + $(top_srcdir)/babeld/babel_zebra.c \ + $(top_srcdir)/babeld/babeld.c \ + # end endif babeld_libbabel_a_SOURCES = \ diff --git a/babeld/util.c b/babeld/util.c index 4a3ecace0c..880cda2fce 100644 --- a/babeld/util.c +++ b/babeld/util.c @@ -21,6 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <stdarg.h> #include <string.h> diff --git a/bfdd/.gitignore b/bfdd/.gitignore index e554d1b33f..2b020911fb 100644 --- a/bfdd/.gitignore +++ b/bfdd/.gitignore @@ -1,3 +1,2 @@ # ignore binary files -*.a bfdd diff --git a/bfdd/bfd.c b/bfdd/bfd.c index b3253a14d7..cf7c027db5 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -78,7 +78,7 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc) } else { memset(&shop, 0, sizeof(shop)); shop.peer = bpc->bpc_peer; - if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) + if (bpc->bpc_has_localif) strlcpy(shop.port_name, bpc->bpc_localif, sizeof(shop.port_name)); @@ -311,33 +311,6 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name, return l_bfd; } -#if 0 /* TODO VxLAN Support */ -static void -_update_vxlan_sess_parms(struct bfd_session *bfd, bfd_sess_parms *sess_parms) -{ - struct bfd_session_vxlan_info *vxlan_info = &bfd->vxlan_info; - bfd_parms_list *parms = &sess_parms->parms; - - vxlan_info->vnid = parms->vnid; - vxlan_info->check_tnl_key = parms->check_tnl_key; - vxlan_info->forwarding_if_rx = parms->forwarding_if_rx; - vxlan_info->cpath_down = parms->cpath_down; - vxlan_info->decay_min_rx = parms->decay_min_rx; - - inet_aton(parms->local_dst_ip, &vxlan_info->local_dst_ip); - inet_aton(parms->remote_dst_ip, &vxlan_info->peer_dst_ip); - - memcpy(vxlan_info->local_dst_mac, parms->local_dst_mac, ETH_ALEN); - memcpy(vxlan_info->peer_dst_mac, parms->remote_dst_mac, ETH_ALEN); - - /* The interface may change for Vxlan BFD sessions, so update - * the local mac and ifindex - */ - bfd->ifindex = sess_parms->ifindex; - memcpy(bfd->local_mac, sess_parms->local_mac, sizeof(bfd->local_mac)); -} -#endif /* VxLAN support */ - int bfd_xmt_cb(struct thread *t) { struct bfd_session *bs = THREAD_ARG(t); @@ -364,7 +337,7 @@ int bfd_recvtimer_cb(struct thread *t) switch (bs->ses_state) { case PTM_BFD_INIT: case PTM_BFD_UP: - ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME); + ptm_bfd_ses_dn(bs, BD_CONTROL_EXPIRED); bfd_recvtimer_update(bs); break; @@ -387,7 +360,7 @@ int bfd_echo_recvtimer_cb(struct thread *t) switch (bs->ses_state) { case PTM_BFD_INIT: case PTM_BFD_UP: - ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME); + ptm_bfd_ses_dn(bs, BD_ECHO_FAILED); break; } @@ -535,8 +508,6 @@ static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc) _bfd_session_update(bs, bpc); - /* TODO add VxLAN support. */ - control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs); return 0; @@ -606,9 +577,6 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc) ptm_bfd_fetch_local_mac(bpc->bpc_localif, bfd->local_mac); } - if (bpc->bpc_has_vxlan) - BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN); - if (bpc->bpc_ipv4 == false) { BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6); @@ -644,30 +612,13 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc) bfd_mhop_insert(bfd); } else { bfd->shop.peer = bpc->bpc_peer; - if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) + if (bpc->bpc_has_localif) strlcpy(bfd->shop.port_name, bpc->bpc_localif, sizeof(bfd->shop.port_name)); bfd_shop_insert(bfd); } - if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) { - static uint8_t bfd_def_vxlan_dmac[] = {0x00, 0x23, 0x20, - 0x00, 0x00, 0x01}; - memcpy(bfd->peer_mac, bfd_def_vxlan_dmac, - sizeof(bfd_def_vxlan_dmac)); - } -#if 0 /* TODO */ - else if (event->rmac) { - if (sscanf(event->rmac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &bfd->peer_mac[0], &bfd->peer_mac[1], &bfd->peer_mac[2], - &bfd->peer_mac[3], &bfd->peer_mac[4], &bfd->peer_mac[5]) - != 6) - DLOG("%s: Assigning remote mac = %s", __func__, - event->rmac); - } -#endif - /* * XXX: session update triggers echo start, so we must have our * discriminator ID set first. diff --git a/bfdd/bfd.h b/bfdd/bfd.h index d665448abf..3a58a8d53c 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -105,9 +105,6 @@ struct bfd_echo_pkt { #define BFD_CBIT 0x08 #define BFD_ABIT 0x04 #define BFD_DEMANDBIT 0x02 -#define BFD_DIAGNEIGHDOWN 3 -#define BFD_DIAGDETECTTIME 1 -#define BFD_DIAGADMINDOWN 7 #define BFD_SETDEMANDBIT(flags, val) \ { \ if ((val)) \ @@ -133,18 +130,27 @@ struct bfd_echo_pkt { #define BFD_GETSTATE(flags) ((flags >> 6) & 0x3) #define BFD_ECHO_VERSION 1 #define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt) -#define BFD_CTRL_PKT_LEN sizeof(struct bfd_pkt) -#define IP_HDR_LEN 20 -#define UDP_HDR_LEN 8 -#define ETH_HDR_LEN 14 -#define VXLAN_HDR_LEN 8 -#define HEADERS_MIN_LEN (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN) -#define BFD_ECHO_PKT_TOT_LEN \ - ((int)(ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN)) -#define BFD_VXLAN_PKT_TOT_LEN \ - ((int)(VXLAN_HDR_LEN + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN \ - + BFD_CTRL_PKT_LEN)) -#define BFD_RX_BUF_LEN 160 + +enum bfd_diagnosticis { + BD_OK = 0, + /* Control Detection Time Expired. */ + BD_CONTROL_EXPIRED = 1, + /* Echo Function Failed. */ + BD_ECHO_FAILED = 2, + /* Neighbor Signaled Session Down. */ + BD_NEIGHBOR_DOWN = 3, + /* Forwarding Plane Reset. */ + BD_FORWARDING_RESET = 4, + /* Path Down. */ + BD_PATH_DOWN = 5, + /* Concatenated Path Down. */ + BD_CONCATPATH_DOWN = 6, + /* Administratively Down. */ + BD_ADMIN_DOWN = 7, + /* Reverse Concatenated Path Down. */ + BD_REVCONCATPATH_DOWN = 8, + /* 9..31: reserved. */ +}; /* BFD session flags */ enum bfd_session_flags { @@ -154,9 +160,6 @@ enum bfd_session_flags { * actively */ BFD_SESS_FLAG_MH = 1 << 2, /* BFD Multi-hop session */ - BFD_SESS_FLAG_VXLAN = 1 << 3, /* BFD Multi-hop session which is - * used to monitor vxlan tunnel - */ BFD_SESS_FLAG_IPV6 = 1 << 4, /* BFD IPv6 session */ BFD_SESS_FLAG_SEND_EVT_ACTIVE = 1 << 5, /* send event timer active */ BFD_SESS_FLAG_SEND_EVT_IGNORE = 1 << 6, /* ignore send event when timer @@ -191,18 +194,6 @@ struct bfd_session_stats { uint64_t znotification; }; -struct bfd_session_vxlan_info { - uint32_t vnid; - uint32_t decay_min_rx; - uint8_t forwarding_if_rx; - uint8_t cpath_down; - uint8_t check_tnl_key; - uint8_t local_dst_mac[ETHERNET_ADDRESS_LENGTH]; - uint8_t peer_dst_mac[ETHERNET_ADDRESS_LENGTH]; - struct in_addr local_dst_ip; - struct in_addr peer_dst_ip; -}; - /* bfd_session shortcut label forwarding. */ struct peer_label; @@ -249,16 +240,11 @@ struct bfd_session { int ifindex; uint8_t local_mac[ETHERNET_ADDRESS_LENGTH]; uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH]; - uint16_t ip_id; /* BFD session flags */ enum bfd_session_flags flags; - uint8_t echo_pkt[BFD_ECHO_PKT_TOT_LEN]; /* Save the Echo Packet - * which will be transmitted - */ struct bfd_session_stats stats; - struct bfd_session_vxlan_info vxlan_info; struct timeval uptime; /* last up time */ struct timeval downtime; /* last down time */ @@ -407,7 +393,7 @@ struct bfd_global { int bg_shop6; int bg_mhop6; int bg_echo; - int bg_vxlan; + int bg_echov6; struct thread *bg_ev[6]; int bg_csock; @@ -473,10 +459,10 @@ void log_fatal(const char *fmt, ...); * * Contains the code related with receiving/seding, packing/unpacking BFD data. */ -int bp_set_ttlv6(int sd); -int bp_set_ttl(int sd); -int bp_set_tosv6(int sd); -int bp_set_tos(int sd); +int bp_set_ttlv6(int sd, uint8_t value); +int bp_set_ttl(int sd, uint8_t value); +int bp_set_tosv6(int sd, uint8_t value); +int bp_set_tos(int sd, uint8_t value); int bp_bind_dev(int sd, const char *dev); int bp_udp_shop(void); @@ -485,14 +471,14 @@ int bp_udp6_shop(void); int bp_udp6_mhop(void); int bp_peer_socket(struct bfd_peer_cfg *bpc); int bp_peer_socketv6(struct bfd_peer_cfg *bpc); +int bp_echo_socket(void); +int bp_echov6_socket(void); void ptm_bfd_snd(struct bfd_session *bfd, int fbit); void ptm_bfd_echo_snd(struct bfd_session *bfd); int bfd_recv_cb(struct thread *t); -uint16_t checksum(uint16_t *buf, int len); - /* * event.c @@ -602,30 +588,13 @@ int ptm_bfd_notify(struct bfd_session *bs); /* * OS compatibility functions. */ -struct udp_psuedo_header { - uint32_t saddr; - uint32_t daddr; - uint8_t reserved; - uint8_t protocol; - uint16_t len; -}; - -#define UDP_PSUEDO_HDR_LEN sizeof(struct udp_psuedo_header) - #if defined(BFD_LINUX) || defined(BFD_BSD) int ptm_bfd_fetch_ifindex(const char *ifname); void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac); void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen); -int ptm_bfd_echo_sock_init(void); -int ptm_bfd_vxlan_sock_init(void); #endif /* BFD_LINUX || BFD_BSD */ -#ifdef BFD_LINUX -uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len); -#endif /* BFD_LINUX */ - #ifdef BFD_BSD -uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len); ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen, struct sockaddr_storage *ss, socklen_t *sslen, uint8_t *ttl, uint32_t *id); diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 543181a12a..8acb9438c5 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -37,74 +37,26 @@ #include "bfd.h" -/* - * Definitions - */ - -/* iov for BFD control frames */ -#define CMSG_HDR_LEN sizeof(struct cmsghdr) -#define CMSG_TTL_LEN (CMSG_HDR_LEN + sizeof(uint32_t)) -#define CMSG_IN_PKT_INFO_LEN (CMSG_HDR_LEN + sizeof(struct in_pktinfo) + 4) -#define CMSG_IN6_PKT_INFO_LEN \ - (CMSG_HDR_LEN + sizeof(struct in6_addr) + sizeof(int) + 4) - -struct bfd_raw_echo_pkt { -#ifdef BFD_LINUX - struct iphdr ip; -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - struct ip ip; -#endif /* BFD_BSD */ - struct udphdr udp; - struct bfd_echo_pkt data; -}; - -#if 0 /* TODO: VxLAN support. */ -struct bfd_raw_ctrl_pkt { - struct iphdr ip; - struct udphdr udp; - struct bfd_pkt data; -}; -#endif - -struct vxlan_hdr { - uint32_t flags; - uint32_t vnid; -}; - -#define IP_ECHO_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN) -#define UDP_ECHO_PKT_LEN (UDP_HDR_LEN + BFD_ECHO_PKT_LEN) -#define IP_CTRL_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_PKT_LEN) -#define UDP_CTRL_PKT_LEN (UDP_HDR_LEN + BFD_PKT_LEN) - -static uint8_t msgbuf[BFD_PKT_LEN]; - -static int ttlval = BFD_TTL_VAL; -static int tosval = BFD_TOS_VAL; -static int rcvttl = BFD_RCV_TTL_VAL; /* * Prototypes */ -static uint16_t ptm_bfd_gen_IP_ID(struct bfd_session *bfd); -static void ptm_bfd_echo_pkt_create(struct bfd_session *bfd); -static int ptm_bfd_echo_loopback(uint8_t *pkt, int pkt_len, struct sockaddr *ss, - socklen_t sslen); -static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd, int fbit); static int ptm_bfd_process_echo_pkt(int s); -static bool -ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd, - struct bfd_session_vxlan_info *vxlan_info); +int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data, + size_t datalen); static void bfd_sd_reschedule(int sd); -static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, - struct sockaddr_any *peer); -static ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, - struct sockaddr_any *peer); +ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer); +ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer); +int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen, + struct sockaddr *to, socklen_t tolen); +int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr); /* socket related prototypes */ static void bp_set_ipopts(int sd); @@ -116,68 +68,17 @@ static void bp_bind_ipv6(int sd, uint16_t port); /* * Functions */ -uint16_t checksum(uint16_t *buf, int len) -{ - int nbytes = len; - int sum = 0; - uint16_t csum = 0; - int size = sizeof(uint16_t); - - while (nbytes > 1) { - sum += *buf++; - nbytes -= size; - } - - if (nbytes == 1) { - *(uint8_t *)(&csum) = *(uint8_t *)buf; - sum += csum; - } - - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - csum = ~sum; - return csum; -} - -static uint16_t ptm_bfd_gen_IP_ID(struct bfd_session *bfd) -{ - return (++bfd->ip_id); -} - -static int _ptm_bfd_send(struct bfd_session *bs, bool use_layer2, - uint16_t *port, const void *data, size_t datalen) +int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data, + size_t datalen) { struct sockaddr *sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; -#ifdef BFD_LINUX - struct sockaddr_ll dll; -#endif /* BFD_LINUX */ socklen_t slen; ssize_t rv; int sd = -1; - if (use_layer2) { -#ifdef BFD_LINUX - memset(&dll, 0, sizeof(dll)); - dll.sll_family = AF_PACKET; - dll.sll_protocol = htons(ETH_P_IP); - memcpy(dll.sll_addr, bs->peer_mac, ETHERNET_ADDRESS_LENGTH); - dll.sll_halen = htons(ETHERNET_ADDRESS_LENGTH); - dll.sll_ifindex = bs->ifindex; - - sd = bglobal.bg_echo; - sa = (struct sockaddr *)&dll; - slen = sizeof(dll); -#else - /* - * TODO: implement layer 2 send for *BSDs. This is - * needed for VxLAN. - */ - log_warning("packet-send: not implemented"); - return -1; -#endif - } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) { + if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) { memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_addr = bs->shop.peer.sa_sin6.sin6_addr; @@ -219,332 +120,63 @@ static int _ptm_bfd_send(struct bfd_session *bs, bool use_layer2, return 0; } -static void ptm_bfd_echo_pkt_create(struct bfd_session *bfd) -{ - struct bfd_raw_echo_pkt ep; - uint8_t *pkt = bfd->echo_pkt; - - memset(&ep, 0, sizeof(ep)); - memset(bfd->echo_pkt, 0, sizeof(bfd->echo_pkt)); - - /* Construct ethernet header information */ - memcpy(pkt, bfd->peer_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; - memcpy(pkt, bfd->local_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; -#ifdef BFD_LINUX - pkt[0] = ETH_P_IP / 256; - pkt[1] = ETH_P_IP % 256; -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - pkt[0] = ETHERTYPE_IP / 256; - pkt[1] = ETHERTYPE_IP % 256; -#endif /* BFD_BSD */ - pkt += 2; - - /* Construct IP header information */ -#ifdef BFD_LINUX - ep.ip.version = 4; - ep.ip.ihl = 5; - ep.ip.tos = 0; - ep.ip.tot_len = htons(IP_ECHO_PKT_LEN); - ep.ip.id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep.ip.frag_off = 0; - ep.ip.ttl = BFD_TTL_VAL; - ep.ip.protocol = IPPROTO_UDP; - ep.ip.saddr = bfd->local_ip.sa_sin.sin_addr.s_addr; - ep.ip.daddr = bfd->shop.peer.sa_sin.sin_addr.s_addr; - ep.ip.check = checksum((uint16_t *)&ep.ip, IP_HDR_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep.ip.ip_v = 4; - ep.ip.ip_hl = 5; - ep.ip.ip_tos = 0; - ep.ip.ip_len = htons(IP_ECHO_PKT_LEN); - ep.ip.ip_id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep.ip.ip_off = 0; - ep.ip.ip_ttl = BFD_TTL_VAL; - ep.ip.ip_p = IPPROTO_UDP; - ep.ip.ip_src = bfd->local_ip.sa_sin.sin_addr; - ep.ip.ip_dst = bfd->shop.peer.sa_sin.sin_addr; - ep.ip.ip_sum = checksum((uint16_t *)&ep.ip, IP_HDR_LEN); -#endif /* BFD_BSD */ - - /* Construct UDP header information */ -#ifdef BFD_LINUX - ep.udp.source = htons(BFD_DEF_ECHO_PORT); - ep.udp.dest = htons(BFD_DEF_ECHO_PORT); - ep.udp.len = htons(UDP_ECHO_PKT_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep.udp.uh_sport = htons(BFD_DEF_ECHO_PORT); - ep.udp.uh_dport = htons(BFD_DEF_ECHO_PORT); - ep.udp.uh_ulen = htons(UDP_ECHO_PKT_LEN); -#endif /* BFD_BSD */ - - /* Construct Echo packet information */ - ep.data.ver = BFD_ECHO_VERSION; - ep.data.len = BFD_ECHO_PKT_LEN; - ep.data.my_discr = htonl(bfd->discrs.my_discr); -#ifdef BFD_LINUX - ep.udp.check = -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep.udp.uh_sum = -#endif /* BFD_BSD */ - udp4_checksum(&ep.ip, (uint8_t *)&ep.udp, - UDP_ECHO_PKT_LEN); - - memcpy(pkt, &ep, sizeof(ep)); -} - void ptm_bfd_echo_snd(struct bfd_session *bfd) { - struct bfd_raw_echo_pkt *ep; - bool use_layer2 = false; - const void *pkt; - size_t pktlen; - uint16_t port = htons(BFD_DEF_ECHO_PORT); + struct sockaddr_any *sa; + socklen_t salen; + int sd; + struct bfd_echo_pkt bep; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; - if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) { - ptm_bfd_echo_pkt_create(bfd); + if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE); - } else { - /* just update the checksum and ip Id */ - ep = (struct bfd_raw_echo_pkt *)(bfd->echo_pkt + ETH_HDR_LEN); -#ifdef BFD_LINUX - ep->ip.id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep->ip.check = 0; - ep->ip.check = checksum((uint16_t *)&ep->ip, IP_HDR_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep->ip.ip_id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep->ip.ip_sum = 0; - ep->ip.ip_sum = checksum((uint16_t *)&ep->ip, IP_HDR_LEN); -#endif /* BFD_BSD */ - } - if (use_layer2) { - pkt = bfd->echo_pkt; - pktlen = BFD_ECHO_PKT_TOT_LEN; + memset(&bep, 0, sizeof(bep)); + bep.ver = BFD_ECHO_VERSION; + bep.len = BFD_ECHO_PKT_LEN; + bep.my_discr = htonl(bfd->discrs.my_discr); + + sa = BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_MH) ? &bfd->mhop.peer + : &bfd->shop.peer; + if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6)) { + sd = bglobal.bg_echov6; + sin6 = sa->sa_sin6; + sin6.sin6_port = htons(BFD_DEF_ECHO_PORT); +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + sin6.sin6_len = sizeof(sin6); +#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ + + sa = (struct sockaddr_any *)&sin6; + salen = sizeof(sin6); } else { - pkt = &bfd->echo_pkt[ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN]; - pktlen = BFD_ECHO_PKT_TOT_LEN - - (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN); - } + sd = bglobal.bg_echo; + sin = sa->sa_sin; + sin.sin_port = htons(BFD_DEF_ECHO_PORT); +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + sin.sin_len = sizeof(sin); +#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - if (_ptm_bfd_send(bfd, use_layer2, &port, pkt, pktlen) != 0) { - log_debug("echo-packet: send failure: %s", strerror(errno)); - return; + sa = (struct sockaddr_any *)&sin; + salen = sizeof(sin); } + if (bp_udp_send(sd, BFD_TTL_VAL, (uint8_t *)&bep, sizeof(bep), + (struct sockaddr *)sa, salen) + == -1) + return; bfd->stats.tx_echo_pkt++; } -static int ptm_bfd_echo_loopback(uint8_t *pkt, int pkt_len, struct sockaddr *ss, - socklen_t sslen) -{ -#ifdef BFD_LINUX - struct bfd_raw_echo_pkt *ep = - (struct bfd_raw_echo_pkt *)(pkt + ETH_HDR_LEN); - uint8_t temp_mac[ETHERNET_ADDRESS_LENGTH]; - uint32_t temp_ip; - struct ethhdr *eth = (struct ethhdr *)pkt; - - /* swap the mac addresses */ - memcpy(temp_mac, eth->h_source, ETHERNET_ADDRESS_LENGTH); - memcpy(eth->h_source, eth->h_dest, ETHERNET_ADDRESS_LENGTH); - memcpy(eth->h_dest, temp_mac, ETHERNET_ADDRESS_LENGTH); - - /* swap ip addresses */ - temp_ip = ep->ip.saddr; - ep->ip.saddr = ep->ip.daddr; - ep->ip.daddr = temp_ip; - - ep->ip.ttl = ep->ip.ttl - 1; - ep->ip.check = 0; - ep->ip.check = checksum((uint16_t *)ep, IP_HDR_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD_FILTER - struct bfd_raw_echo_pkt_t *ep = - (struct bfd_raw_echo_pkt *)(pkt + ETH_HDR_LEN); - uint8_t temp_mac[ETHERNET_ADDRESS_LENGTH]; - struct in_addr temp_ip; - struct ether_header *ether = (struct ether_header *)pkt; - - /* - * TODO: this is not yet implemented and requires BPF code for - * OmniOS, NetBSD and FreeBSD9. - */ - - /* swap the mac addresses */ - memcpy(temp_mac, ether->ether_shost, ETHERNET_ADDRESS_LENGTH); - memcpy(ether->ether_shost, ether->ether_dhost, ETHERNET_ADDRESS_LENGTH); - memcpy(ether->ether_dhost, temp_mac, ETHERNET_ADDRESS_LENGTH); - - /* swap ip addresses */ - temp_ip = ep->ip.ip_src; - ep->ip.ip_src = ep->ip.ip_dst; - ep->ip.ip_dst = temp_ip; - - ep->ip.ip_ttl = ep->ip.ip_ttl - 1; - ep->ip.ip_sum = 0; - ep->ip.ip_sum = checksum((uint16_t *)ep, IP_HDR_LEN); -#endif /* BFD_BSD_FILTER */ - - if (sendto(bglobal.bg_echo, pkt, pkt_len, 0, ss, sslen) < 0) { - log_debug("echo-loopback: send failure: %s", strerror(errno)); - return -1; - } - - return 0; -} - -static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd - __attribute__((__unused__)), - int fbit __attribute__((__unused__))) -{ -#if 0 /* TODO: VxLAN support. */ - struct bfd_raw_ctrl_pkt cp; - uint8_t vxlan_pkt[BFD_VXLAN_PKT_TOT_LEN]; - uint8_t *pkt = vxlan_pkt; - struct sockaddr_in sin; - struct vxlan_hdr *vhdr; - - memset(vxlan_pkt, 0, sizeof(vxlan_pkt)); - memset(&cp, 0, sizeof(cp)); - - /* Construct VxLAN header information */ - vhdr = (struct vxlan_hdr *)pkt; - vhdr->flags = htonl(0x08000000); - vhdr->vnid = htonl(bfd->vxlan_info.vnid << 8); - pkt += VXLAN_HDR_LEN; - - /* Construct ethernet header information */ - memcpy(pkt, bfd->vxlan_info.peer_dst_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; - memcpy(pkt, bfd->vxlan_info.local_dst_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; - pkt[0] = ETH_P_IP / 256; - pkt[1] = ETH_P_IP % 256; - pkt += 2; - - /* Construct IP header information */ - cp.ip.version = 4; - cp.ip.ihl = 5; - cp.ip.tos = 0; - cp.ip.tot_len = htons(IP_CTRL_PKT_LEN); - cp.ip.id = ptm_bfd_gen_IP_ID(bfd); - cp.ip.frag_off = 0; - cp.ip.ttl = BFD_TTL_VAL; - cp.ip.protocol = IPPROTO_UDP; - cp.ip.daddr = bfd->vxlan_info.peer_dst_ip.s_addr; - cp.ip.saddr = bfd->vxlan_info.local_dst_ip.s_addr; - cp.ip.check = checksum((uint16_t *)&cp.ip, IP_HDR_LEN); - - /* Construct UDP header information */ - cp.udp.source = htons(BFD_DEFDESTPORT); - cp.udp.dest = htons(BFD_DEFDESTPORT); - cp.udp.len = htons(UDP_CTRL_PKT_LEN); - - /* Construct BFD control packet information */ - cp.data.diag = bfd->local_diag; - BFD_SETVER(cp.data.diag, BFD_VERSION); - BFD_SETSTATE(cp.data.flags, bfd->ses_state); - BFD_SETDEMANDBIT(cp.data.flags, BFD_DEF_DEMAND); - BFD_SETPBIT(cp.data.flags, bfd->polling); - BFD_SETFBIT(cp.data.flags, fbit); - cp.data.detect_mult = bfd->detect_mult; - cp.data.len = BFD_PKT_LEN; - cp.data.discrs.my_discr = htonl(bfd->discrs.my_discr); - cp.data.discrs.remote_discr = htonl(bfd->discrs.remote_discr); - cp.data.timers.desired_min_tx = htonl(bfd->timers.desired_min_tx); - cp.data.timers.required_min_rx = htonl(bfd->timers.required_min_rx); - cp.data.timers.required_min_echo = htonl(bfd->timers.required_min_echo); - - cp.udp.check = - udp4_checksum(&cp.ip, (uint8_t *)&cp.udp, UDP_CTRL_PKT_LEN); - - memcpy(pkt, &cp, sizeof(cp)); - sin.sin_family = AF_INET; - sin.sin_addr = bfd->shop.peer.sa_sin.sin_addr; - sin.sin_port = htons(4789); - - if (sendto(bfd->sock, vxlan_pkt, BFD_VXLAN_PKT_TOT_LEN, 0, - (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) - < 0) { - ERRLOG("Error sending vxlan bfd pkt: %s", strerror(errno)); - } else { - bfd->stats.tx_ctrl_pkt++; - } -#endif -} - static int ptm_bfd_process_echo_pkt(int s) { - uint32_t my_discr = 0; - struct sockaddr_storage ss; - socklen_t sslen = sizeof(ss); - uint8_t rx_pkt[BFD_RX_BUF_LEN]; - ssize_t pkt_len = sizeof(rx_pkt); struct bfd_session *bfd; -#ifdef BFD_LINUX - struct bfd_raw_echo_pkt *ep; - - /* - * valgrind: memset() ss so valgrind doesn't complain about - * uninitialized memory. - */ - memset(&ss, 0, sizeof(ss)); - pkt_len = recvfrom(s, rx_pkt, sizeof(rx_pkt), MSG_DONTWAIT, - (struct sockaddr *)&ss, &sslen); - if (pkt_len <= 0) { - if (errno != EAGAIN) - log_error("echo-packet: read failure: %s", - strerror(errno)); - - return -1; - } - - /* Check if we have at least the basic headers to send back. */ - if (pkt_len < BFD_ECHO_PKT_TOT_LEN) { - log_debug("echo-packet: too short (got %ld, expected %d)", - pkt_len, BFD_ECHO_PKT_TOT_LEN); - return -1; - } - - ep = (struct bfd_raw_echo_pkt *)(rx_pkt + ETH_HDR_LEN); - /* if TTL = 255, assume that the received echo packet has - * to be looped back - */ - if (ep->ip.ttl == BFD_TTL_VAL) - return ptm_bfd_echo_loopback(rx_pkt, pkt_len, - (struct sockaddr *)&ss, - sizeof(struct sockaddr_ll)); - - my_discr = ntohl(ep->data.my_discr); - if (ep->data.my_discr == 0) { - log_debug("echo-packet: 'my discriminator' is zero"); - return -1; - } -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - int rv; - uint8_t ttl; - - /* - * bsd_echo_sock_read() already treats invalid TTL values and - * zeroed discriminators. - */ - rv = bsd_echo_sock_read(s, rx_pkt, &pkt_len, &ss, &sslen, &ttl, - &my_discr); - if (rv == -1) - return -1; + uint32_t my_discr = 0; + uint8_t ttl = 0; - if (ttl == BFD_TTL_VAL) - return ptm_bfd_echo_loopback(rx_pkt, pkt_len, - (struct sockaddr *)&ss, sslen); -#endif /* BFD_BSD */ + /* Receive and parse echo packet. */ + if (bp_bfd_echo_in(s, &ttl, &my_discr) == -1) + return 0; /* Your discriminator not zero - use it to find session */ bfd = bfd_id_lookup(my_discr); @@ -554,8 +186,8 @@ static int ptm_bfd_process_echo_pkt(int s) } if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) { - log_debug("echo-packet: echo disabled [%s]", my_discr, - bs_to_string(bfd)); + log_debug("echo-packet: echo disabled [%s] (id:%u)", + bs_to_string(bfd), my_discr); return -1; } @@ -574,14 +206,6 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit) { struct bfd_pkt cp; - /* if the BFD session is for VxLAN tunnel, then construct and - * send bfd raw packet - */ - if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) { - ptm_bfd_vxlan_pkt_snd(bfd, fbit); - return; - } - /* Set fields according to section 6.5.7 */ cp.diag = bfd->local_diag; BFD_SETVER(cp.diag, BFD_VERSION); @@ -605,98 +229,16 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit) } cp.timers.required_min_echo = htonl(bfd->timers.required_min_echo); - if (_ptm_bfd_send(bfd, false, NULL, &cp, BFD_PKT_LEN) != 0) + if (_ptm_bfd_send(bfd, NULL, &cp, BFD_PKT_LEN) != 0) return; bfd->stats.tx_ctrl_pkt++; } -#if 0 /* TODO VxLAN Support */ -static struct bfd_pkt * -ptm_bfd_process_vxlan_pkt(int s, ptm_sockevent_e se, void *udata, int *ifindex, - struct sockaddr_in *sin, - struct bfd_session_vxlan_info_t *vxlan_info, - uint8_t *rx_pkt, int *mlen) -{ - struct sockaddr_ll sll; - uint32_t from_len = sizeof(struct sockaddr_ll); - struct bfd_raw_ctrl_pkt *cp; - uint8_t *pkt = rx_pkt; - struct iphdr *iph; - struct ethhdr *inner_ethh; - - *mlen = recvfrom(s, rx_pkt, BFD_RX_BUF_LEN, MSG_DONTWAIT, - (struct sockaddr *)&sll, &from_len); - - if (*mlen < 0) { - if (errno != EAGAIN) - ERRLOG("Error receiving from BFD Vxlan socket %d: %m", - s); - return NULL; - } - - iph = (struct iphdr *)(pkt + ETH_HDR_LEN); - pkt = pkt + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN; - vxlan_info->vnid = ntohl(*((int *)(pkt + 4))); - vxlan_info->vnid = vxlan_info->vnid >> 8; - - pkt = pkt + VXLAN_HDR_LEN; - inner_ethh = (struct ethhdr *)pkt; - - cp = (struct bfd_raw_ctrl_pkt *)(pkt + ETH_HDR_LEN); - - /* Discard the non BFD packets */ - if (ntohs(cp->udp.dest) != BFD_DEFDESTPORT) - return NULL; - - *ifindex = sll.sll_ifindex; - sin->sin_addr.s_addr = iph->saddr; - sin->sin_port = ntohs(cp->udp.dest); - - vxlan_info->local_dst_ip.s_addr = cp->ip.daddr; - memcpy(vxlan_info->local_dst_mac, inner_ethh->h_dest, - ETHERNET_ADDRESS_LENGTH); - - return &cp->data; -} -#endif /* VxLAN */ - -static bool -ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd, - struct bfd_session_vxlan_info *vxlan_info) -{ - if (bfd->vxlan_info.check_tnl_key && (vxlan_info->vnid != 0)) { - log_error("vxlan-packet: vnid not zero: %d", vxlan_info->vnid); - return false; - } - - if (bfd->vxlan_info.local_dst_ip.s_addr - != vxlan_info->local_dst_ip.s_addr) { - log_error("vxlan-packet: wrong inner destination", - inet_ntoa(vxlan_info->local_dst_ip)); - return false; - } - - if (memcmp(bfd->vxlan_info.local_dst_mac, vxlan_info->local_dst_mac, - ETHERNET_ADDRESS_LENGTH)) { - log_error( - "vxlan-packet: wrong inner mac: %02x:%02x:%02x:%02x:%02x:%02x", - vxlan_info->local_dst_mac[0], - vxlan_info->local_dst_mac[1], - vxlan_info->local_dst_mac[2], - vxlan_info->local_dst_mac[3], - vxlan_info->local_dst_mac[4], - vxlan_info->local_dst_mac[5]); - return false; - } - - return true; -} - -static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, - struct sockaddr_any *peer) +ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer) { struct cmsghdr *cm; int ifindex; @@ -706,9 +248,11 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, struct iovec iov[1]; uint8_t cmsgbuf[255]; + port[0] = '\0'; + /* Prepare the recvmsg params. */ iov[0].iov_base = msgbuf; - iov[0].iov_len = sizeof(msgbuf); + iov[0].iov_len = msgbuflen; memset(&msghdr, 0, sizeof(msghdr)); msghdr.msg_name = &msgaddr; @@ -739,16 +283,14 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, switch (cm->cmsg_type) { #ifdef BFD_LINUX case IP_TTL: { - uint32_t ttl; - - memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl)); - if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) { - log_debug( - "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)", - satostr(peer), ttl, BFD_TTL_VAL, - msghdr.msg_flags); + uint32_t ttlval; + + memcpy(&ttlval, CMSG_DATA(cm), sizeof(ttlval)); + if (ttlval > 255) { + log_debug("ipv4-recv: invalid TTL: %u", ttlval); return -1; } + *ttl = ttlval; break; } @@ -768,16 +310,7 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, #endif /* BFD_LINUX */ #ifdef BFD_BSD case IP_RECVTTL: { - uint8_t ttl; - - memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl)); - if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) { - log_debug( - "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)", - satostr(peer), ttl, BFD_TTL_VAL, - msghdr.msg_flags); - return -1; - } + memcpy(ttl, CMSG_DATA(cm), sizeof(*ttl)); break; } @@ -812,14 +345,16 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, return mlen; } -ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, struct sockaddr_any *peer) +ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer) { struct cmsghdr *cm; struct in6_pktinfo *pi6 = NULL; int ifindex = 0; ssize_t mlen; + uint32_t ttlval; struct sockaddr_in6 msgaddr6; struct msghdr msghdr6; struct iovec iov[1]; @@ -827,7 +362,7 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, /* Prepare the recvmsg params. */ iov[0].iov_base = msgbuf; - iov[0].iov_len = sizeof(msgbuf); + iov[0].iov_len = msgbuflen; memset(&msghdr6, 0, sizeof(msghdr6)); msghdr6.msg_name = &msgaddr6; @@ -840,7 +375,7 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, mlen = recvmsg(sd, &msghdr6, MSG_DONTWAIT); if (mlen == -1) { if (errno != EAGAIN) - log_error("ipv4-recv: recv failed: %s", + log_error("ipv6-recv: recv failed: %s", strerror(errno)); return -1; @@ -856,14 +391,13 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, continue; if (cm->cmsg_type == IPV6_HOPLIMIT) { - memcpy(&ttlval, CMSG_DATA(cm), 4); - if ((is_mhop == false) && (ttlval != BFD_TTL_VAL)) { - log_debug( - "ipv6-recv: invalid TTL from %s (expected %d, got %d flags %d)", - satostr(peer), ttlval, BFD_TTL_VAL, - msghdr6.msg_flags); + memcpy(&ttlval, CMSG_DATA(cm), sizeof(ttlval)); + if (ttlval > 255) { + log_debug("ipv6-recv: invalid TTL: %u", ttlval); return -1; } + + *ttl = ttlval; } else if (cm->cmsg_type == IPV6_PKTINFO) { pi6 = (struct in6_pktinfo *)CMSG_DATA(cm); if (pi6) { @@ -888,28 +422,28 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, static void bfd_sd_reschedule(int sd) { if (sd == bglobal.bg_shop) { - bglobal.bg_ev[0] = NULL; + THREAD_OFF(bglobal.bg_ev[0]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop, &bglobal.bg_ev[0]); } else if (sd == bglobal.bg_mhop) { - bglobal.bg_ev[1] = NULL; + THREAD_OFF(bglobal.bg_ev[1]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop, &bglobal.bg_ev[1]); } else if (sd == bglobal.bg_shop6) { - bglobal.bg_ev[2] = NULL; + THREAD_OFF(bglobal.bg_ev[2]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop6, &bglobal.bg_ev[2]); } else if (sd == bglobal.bg_mhop6) { - bglobal.bg_ev[3] = NULL; + THREAD_OFF(bglobal.bg_ev[3]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop6, &bglobal.bg_ev[3]); } else if (sd == bglobal.bg_echo) { - bglobal.bg_ev[4] = NULL; + THREAD_OFF(bglobal.bg_ev[4]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo, &bglobal.bg_ev[4]); - } else if (sd == bglobal.bg_vxlan) { - bglobal.bg_ev[5] = NULL; - thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan, + } else if (sd == bglobal.bg_echov6) { + THREAD_OFF(bglobal.bg_ev[5]); + thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6, &bglobal.bg_ev[5]); } } @@ -955,18 +489,19 @@ int bfd_recv_cb(struct thread *t) int sd = THREAD_FD(t); struct bfd_session *bfd; struct bfd_pkt *cp; - bool is_mhop, is_vxlan; + bool is_mhop; ssize_t mlen = 0; uint32_t oldEchoXmt_TO, oldXmtTime; + uint8_t ttl; struct sockaddr_any local, peer; char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1]; - struct bfd_session_vxlan_info vxlan_info; + uint8_t msgbuf[1516]; /* Schedule next read. */ bfd_sd_reschedule(sd); /* Handle echo packets. */ - if (sd == bglobal.bg_echo) { + if (sd == bglobal.bg_echo || sd == bglobal.bg_echov6) { ptm_bfd_process_echo_pkt(sd); return 0; } @@ -978,28 +513,18 @@ int bfd_recv_cb(struct thread *t) memset(&peer, 0, sizeof(peer)); /* Handle control packets. */ - is_mhop = is_vxlan = false; + is_mhop = false; if (sd == bglobal.bg_shop || sd == bglobal.bg_mhop) { is_mhop = sd == bglobal.bg_mhop; - mlen = bfd_recv_ipv4(sd, is_mhop, port, sizeof(port), vrfname, - sizeof(vrfname), &local, &peer); + mlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), &ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); } else if (sd == bglobal.bg_shop6 || sd == bglobal.bg_mhop6) { is_mhop = sd == bglobal.bg_mhop6; - mlen = bfd_recv_ipv6(sd, is_mhop, port, sizeof(port), vrfname, - sizeof(vrfname), &local, &peer); + mlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), &ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); } -#if 0 /* TODO vxlan handling */ - cp = ptm_bfd_process_vxlan_pkt(s, se, udata, &local_ifindex, - &sin, &vxlan_info, rx_pkt, &mlen); - if (!cp) - return -1; - - is_vxlan = true; - /* keep in network-byte order */ - peer.ip4_addr.s_addr = sin.sin_addr.s_addr; - peer.family = AF_INET; - strcpy(peer_addr, inet_ntoa(sin.sin_addr)); -#endif /* Implement RFC 5880 6.8.6 */ if (mlen < BFD_PKT_LEN) { @@ -1008,6 +533,13 @@ int bfd_recv_cb(struct thread *t) return 0; } + /* Validate packet TTL. */ + if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) { + cp_debug(is_mhop, &peer, &local, port, vrfname, + "invalid TTL: %d expected %d", ttl, BFD_TTL_VAL); + return 0; + } + /* * Parse the control header for inconsistencies: * - Invalid version; @@ -1047,10 +579,6 @@ int bfd_recv_cb(struct thread *t) return 0; } - /* Handle VxLAN cases. */ - if (is_vxlan && !ptm_bfd_validate_vxlan_pkt(bfd, &vxlan_info)) - return 0; - bfd->stats.rx_ctrl_pkt++; /* @@ -1058,10 +586,10 @@ int bfd_recv_cb(struct thread *t) * Single hop: set local address that received the packet. */ if (is_mhop) { - if ((BFD_TTL_VAL - bfd->mh_ttl) > ttlval) { + if ((BFD_TTL_VAL - bfd->mh_ttl) > BFD_TTL_VAL) { cp_debug(is_mhop, &peer, &local, port, vrfname, "exceeded max hop count (expected %d, got %d)", - bfd->mh_ttl, ttlval); + bfd->mh_ttl, BFD_TTL_VAL); return 0; } } else if (bfd->local_ip.sa_sin.sin_family == AF_UNSPEC) { @@ -1111,7 +639,7 @@ int bfd_recv_cb(struct thread *t) /* State switch from section 6.8.6 */ if (BFD_GETSTATE(cp->flags) == PTM_BFD_ADM_DOWN) { if (bfd->ses_state != PTM_BFD_DOWN) - ptm_bfd_ses_dn(bfd, BFD_DIAGNEIGHDOWN); + ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN); } else { switch (bfd->ses_state) { case (PTM_BFD_DOWN): @@ -1127,7 +655,7 @@ int bfd_recv_cb(struct thread *t) break; case (PTM_BFD_UP): if (BFD_GETSTATE(cp->flags) == PTM_BFD_DOWN) - ptm_bfd_ses_dn(bfd, BFD_DIAGNEIGHDOWN); + ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN); break; } } @@ -1209,6 +737,121 @@ int bfd_recv_cb(struct thread *t) return 0; } +/* + * bp_bfd_echo_in: proccesses an BFD echo packet. On TTL == BFD_TTL_VAL + * the packet is looped back or returns the my discriminator ID along + * with the TTL. + * + * Returns -1 on error or loopback or 0 on success. + */ +int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr) +{ + struct bfd_echo_pkt *bep; + ssize_t rlen; + struct sockaddr_any local, peer; + char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1]; + uint8_t msgbuf[1516]; + + if (sd == bglobal.bg_echo) + rlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); + else + rlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); + + /* Short packet, better not risk reading it. */ + if (rlen < (ssize_t)sizeof(*bep)) { + cp_debug(false, &peer, &local, port, vrfname, + "small echo packet"); + return -1; + } + + /* Test for loopback. */ + if (*ttl == BFD_TTL_VAL) { + bp_udp_send(sd, *ttl - 1, msgbuf, rlen, + (struct sockaddr *)&peer, + (sd == bglobal.bg_echo) ? sizeof(peer.sa_sin) + : sizeof(peer.sa_sin6)); + return -1; + } + + /* Read my discriminator from BFD Echo packet. */ + bep = (struct bfd_echo_pkt *)msgbuf; + *my_discr = ntohl(bep->my_discr); + if (*my_discr == 0) { + cp_debug(false, &peer, &local, port, vrfname, + "invalid echo packet discriminator (zero)"); + return -1; + } + + return 0; +} + +int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen, + struct sockaddr *to, socklen_t tolen) +{ + struct cmsghdr *cmsg; + ssize_t wlen; + int ttlval = ttl; + bool is_ipv6 = to->sa_family == AF_INET6; + struct msghdr msg; + struct iovec iov[1]; + uint8_t msgctl[255]; + + /* Prepare message data. */ + iov[0].iov_base = data; + iov[0].iov_len = datalen; + + memset(&msg, 0, sizeof(msg)); + memset(msgctl, 0, sizeof(msgctl)); + msg.msg_name = to; + msg.msg_namelen = tolen; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + /* Prepare the packet TTL information. */ + if (ttl > 0) { + /* Use ancillary data. */ + msg.msg_control = msgctl; + msg.msg_controllen = CMSG_LEN(sizeof(ttlval)); + + /* Configure the ancillary data. */ + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(ttlval)); + if (is_ipv6) { + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_HOPLIMIT; + } else { +#if BFD_LINUX + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_TTL; +#else + /* FreeBSD does not support TTL in ancillary data. */ + msg.msg_control = NULL; + msg.msg_controllen = 0; + + bp_set_ttl(sd, ttl); +#endif /* BFD_BSD */ + } + memcpy(CMSG_DATA(cmsg), &ttlval, sizeof(ttlval)); + } + + /* Send echo back. */ + wlen = sendmsg(sd, &msg, 0); + if (wlen <= 0) { + log_debug("udp-send: loopback failure: (%d) %s", errno, strerror(errno)); + return -1; + } else if (wlen < (ssize_t)datalen) { + log_debug("udp-send: partial send: %ld expected %ld", wlen, + datalen); + return -1; + } + + return 0; +} + /* * Sockets creation. @@ -1218,10 +861,12 @@ int bfd_recv_cb(struct thread *t) /* * IPv4 sockets */ -int bp_set_ttl(int sd) +int bp_set_ttl(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IP, IP_TTL, &ttlval, sizeof(ttlval)) == -1) { - log_warning("%s: setsockopt(IP_TTL): %s", __func__, + int ttl = value; + + if (setsockopt(sd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) { + log_warning("set-ttl: setsockopt(IP_TTL, %d): %s", value, strerror(errno)); return -1; } @@ -1229,10 +874,12 @@ int bp_set_ttl(int sd) return 0; } -int bp_set_tos(int sd) +int bp_set_tos(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IP, IP_TOS, &tosval, sizeof(tosval)) == -1) { - log_warning("%s: setsockopt(IP_TOS): %s", __func__, + int tos = value; + + if (setsockopt(sd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1) { + log_warning("set-tos: setsockopt(IP_TOS, %d): %s", value, strerror(errno)); return -1; } @@ -1242,20 +889,23 @@ int bp_set_tos(int sd) static void bp_set_ipopts(int sd) { - if (bp_set_ttl(sd) != 0) - log_fatal("%s: TTL configuration failed", __func__); + int rcvttl = BFD_RCV_TTL_VAL; + + if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) + log_fatal("set-ipopts: TTL configuration failed"); if (setsockopt(sd, IPPROTO_IP, IP_RECVTTL, &rcvttl, sizeof(rcvttl)) == -1) - log_fatal("%s: setsockopt(IP_RECVTTL): %s", __func__, + log_fatal("set-ipopts: setsockopt(IP_RECVTTL, %d): %s", rcvttl, strerror(errno)); #ifdef BFD_LINUX int pktinfo = BFD_PKT_INFO_VAL; + /* Figure out address and interface to do the peer matching. */ if (setsockopt(sd, IPPROTO_IP, IP_PKTINFO, &pktinfo, sizeof(pktinfo)) == -1) - log_fatal("%s: setsockopt(IP_PKTINFO): %s", __func__, + log_fatal("set-ipopts: setsockopt(IP_PKTINFO, %d): %s", pktinfo, strerror(errno)); #endif /* BFD_LINUX */ #ifdef BFD_BSD @@ -1263,12 +913,12 @@ static void bp_set_ipopts(int sd) /* Find out our address for peer matching. */ if (setsockopt(sd, IPPROTO_IP, IP_RECVDSTADDR, &yes, sizeof(yes)) == -1) - log_fatal("%s: setsockopt(IP_RECVDSTADDR): %s", __func__, + log_fatal("set-ipopts: setsockopt(IP_RECVDSTADDR, %d): %s", yes, strerror(errno)); /* Find out interface where the packet came in. */ if (setsockopt_ifindex(AF_INET, sd, yes) == -1) - log_fatal("%s: setsockopt_ipv4_ifindex: %s", __func__, + log_fatal("set-ipopts: setsockopt_ipv4_ifindex(%d): %s", yes, strerror(errno)); #endif /* BFD_BSD */ } @@ -1282,7 +932,7 @@ static void bp_bind_ip(int sd, uint16_t port) sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(port); if (bind(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) - log_fatal("%s: bind: %s", __func__, strerror(errno)); + log_fatal("bind-ip: bind: %s", strerror(errno)); } int bp_udp_shop(void) @@ -1291,7 +941,7 @@ int bp_udp_shop(void) sd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp-shop: socket: %s", strerror(errno)); bp_set_ipopts(sd); bp_bind_ip(sd, BFD_DEFDESTPORT); @@ -1305,7 +955,7 @@ int bp_udp_mhop(void) sd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp-mhop: socket: %s", strerror(errno)); bp_set_ipopts(sd); bp_bind_ip(sd, BFD_DEF_MHOP_DEST_PORT); @@ -1326,22 +976,19 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc) return -1; } - if (!bpc->bpc_has_vxlan) { - /* Set TTL to 255 for all transmitted packets */ - if (bp_set_ttl(sd) != 0) { - close(sd); - return -1; - } + /* Set TTL to 255 for all transmitted packets */ + if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) { + close(sd); + return -1; } /* Set TOS to CS6 for all transmitted packets */ - if (bp_set_tos(sd) != 0) { + if (bp_set_tos(sd, BFD_TOS_VAL) != 0) { close(sd); return -1; } - /* dont bind-to-device incase of vxlan */ - if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) { + if (bpc->bpc_has_localif) { if (bp_bind_dev(sd, bpc->bpc_localif) != 0) { close(sd); return -1; @@ -1360,7 +1007,7 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc) #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN sin.sin_len = sizeof(sin); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - if (bpc->bpc_mhop || bpc->bpc_has_vxlan) + if (bpc->bpc_mhop) sin.sin_addr = bpc->bpc_local.sa_sin.sin_addr; else sin.sin_addr.s_addr = INADDR_ANY; @@ -1400,16 +1047,14 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc) return -1; } - if (!bpc->bpc_has_vxlan) { - /* Set TTL to 255 for all transmitted packets */ - if (bp_set_ttlv6(sd) != 0) { - close(sd); - return -1; - } + /* Set TTL to 255 for all transmitted packets */ + if (bp_set_ttlv6(sd, BFD_TTL_VAL) != 0) { + close(sd); + return -1; } /* Set TOS to CS6 for all transmitted packets */ - if (bp_set_tosv6(sd) != 0) { + if (bp_set_tosv6(sd, BFD_TOS_VAL) != 0) { close(sd); return -1; } @@ -1454,24 +1099,27 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc) return sd; } -int bp_set_ttlv6(int sd) +int bp_set_ttlv6(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttlval, - sizeof(ttlval)) + int ttl = value; + + if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) == -1) { - log_warning("%s: setsockopt(IPV6_UNICAST_HOPS): %s", __func__, - strerror(errno)); + log_warning("set-ttlv6: setsockopt(IPV6_UNICAST_HOPS, %d): %s", + value, strerror(errno)); return -1; } return 0; } -int bp_set_tosv6(int sd) +int bp_set_tosv6(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IPV6, IPV6_TCLASS, &tosval, sizeof(tosval)) + int tos = value; + + if (setsockopt(sd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) == -1) { - log_warning("%s: setsockopt(IPV6_TCLASS): %s", __func__, + log_warning("set-tosv6: setsockopt(IPV6_TCLASS, %d): %s", value, strerror(errno)); return -1; } @@ -1481,28 +1129,26 @@ int bp_set_tosv6(int sd) static void bp_set_ipv6opts(int sd) { - static int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL; - static int ipv6_only = BFD_IPV6_ONLY_VAL; + int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL; + int ipv6_only = BFD_IPV6_ONLY_VAL; - if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttlval, - sizeof(ttlval)) - == -1) - log_fatal("%s: setsockopt(IPV6_UNICAST_HOPS): %s", __func__, - strerror(errno)); + if (bp_set_ttlv6(sd, BFD_TTL_VAL) == -1) + log_fatal("set-ipv6opts: setsockopt(IPV6_UNICAST_HOPS, %d): %s", + BFD_TTL_VAL, strerror(errno)); - if (setsockopt_ipv6_hoplimit(sd, rcvttl) == -1) - log_fatal("%s: setsockopt(IPV6_HOPLIMIT): %s", __func__, - strerror(errno)); + if (setsockopt_ipv6_hoplimit(sd, BFD_RCV_TTL_VAL) == -1) + log_fatal("set-ipv6opts: setsockopt(IPV6_HOPLIMIT, %d): %s", + BFD_RCV_TTL_VAL, strerror(errno)); if (setsockopt_ipv6_pktinfo(sd, ipv6_pktinfo) == -1) - log_fatal("%s: setsockopt(IPV6_PKTINFO): %s", __func__, - strerror(errno)); + log_fatal("set-ipv6opts: setsockopt(IPV6_PKTINFO, %d): %s", + ipv6_pktinfo, strerror(errno)); if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6_only, sizeof(ipv6_only)) == -1) - log_fatal("%s: setsockopt(IPV6_V6ONLY): %s", __func__, - strerror(errno)); + log_fatal("set-ipv6opts: setsockopt(IPV6_V6ONLY, %d): %s", + ipv6_only, strerror(errno)); } static void bp_bind_ipv6(int sd, uint16_t port) @@ -1517,7 +1163,7 @@ static void bp_bind_ipv6(int sd, uint16_t port) sin6.sin6_len = sizeof(sin6); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ if (bind(sd, (struct sockaddr *)&sin6, sizeof(sin6)) == -1) - log_fatal("%s: bind: %s", __func__, strerror(errno)); + log_fatal("bind-ipv6: bind: %s", strerror(errno)); } int bp_udp6_shop(void) @@ -1526,7 +1172,7 @@ int bp_udp6_shop(void) sd = socket(AF_INET6, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp6-shop: socket: %s", strerror(errno)); bp_set_ipv6opts(sd); bp_bind_ipv6(sd, BFD_DEFDESTPORT); @@ -1540,10 +1186,38 @@ int bp_udp6_mhop(void) sd = socket(AF_INET6, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp6-mhop: socket: %s", strerror(errno)); bp_set_ipv6opts(sd); bp_bind_ipv6(sd, BFD_DEF_MHOP_DEST_PORT); return sd; } + +int bp_echo_socket(void) +{ + int s; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + log_fatal("echo-socket: socket: %s", strerror(errno)); + + bp_set_ipopts(s); + bp_bind_ip(s, BFD_DEF_ECHO_PORT); + + return s; +} + +int bp_echov6_socket(void) +{ + int s; + + s = socket(AF_INET6, SOCK_DGRAM, 0); + if (s == -1) + log_fatal("echov6-socket: socket: %s", strerror(errno)); + + bp_set_ipv6opts(s); + bp_bind_ipv6(s, BFD_DEF_ECHO_PORT); + + return s; +} diff --git a/bfdd/bfdctl.h b/bfdd/bfdctl.h index 940efd1614..0da1ca8df6 100644 --- a/bfdd/bfdctl.h +++ b/bfdd/bfdctl.h @@ -66,9 +66,6 @@ struct bfd_peer_cfg { bool bpc_has_label; char bpc_label[MAXNAMELEN]; - bool bpc_has_vxlan; - unsigned int bpc_vxlan; - bool bpc_has_localif; char bpc_localif[MAXNAMELEN + 1]; diff --git a/bfdd/bfdd.c b/bfdd/bfdd.c index 144619088d..250f8d21c0 100644 --- a/bfdd/bfdd.c +++ b/bfdd/bfdd.c @@ -90,7 +90,6 @@ static void sigterm_handler(void) socket_close(&bglobal.bg_mhop); socket_close(&bglobal.bg_shop6); socket_close(&bglobal.bg_mhop6); - socket_close(&bglobal.bg_vxlan); /* Terminate and free() FRR related memory. */ frr_fini(); @@ -131,17 +130,22 @@ static struct option longopts[] = { struct bfd_global bglobal; struct bfd_diag_str_list diag_list[] = { - {.str = "NeighDown", .type = BFD_DIAGNEIGHDOWN}, - {.str = "DetectTime", .type = BFD_DIAGDETECTTIME}, - {.str = "AdminDown", .type = BFD_DIAGADMINDOWN}, + {.str = "control-expired", .type = BD_CONTROL_EXPIRED}, + {.str = "echo-failed", .type = BD_ECHO_FAILED}, + {.str = "neighbor-down", .type = BD_NEIGHBOR_DOWN}, + {.str = "forwarding-reset", .type = BD_FORWARDING_RESET}, + {.str = "path-down", .type = BD_PATH_DOWN}, + {.str = "concatenated-path-down", .type = BD_CONCATPATH_DOWN}, + {.str = "administratively-down", .type = BD_ADMIN_DOWN}, + {.str = "reverse-concat-path-down", .type = BD_REVCONCATPATH_DOWN}, {.str = NULL}, }; struct bfd_state_str_list state_list[] = { - {.str = "AdminDown", .type = PTM_BFD_ADM_DOWN}, - {.str = "Down", .type = PTM_BFD_DOWN}, - {.str = "Init", .type = PTM_BFD_INIT}, - {.str = "Up", .type = PTM_BFD_UP}, + {.str = "admin-down", .type = PTM_BFD_ADM_DOWN}, + {.str = "down", .type = PTM_BFD_DOWN}, + {.str = "init", .type = PTM_BFD_INIT}, + {.str = "up", .type = PTM_BFD_UP}, {.str = NULL}, }; @@ -154,8 +158,8 @@ static void bg_init(void) bglobal.bg_mhop = bp_udp_mhop(); bglobal.bg_shop6 = bp_udp6_shop(); bglobal.bg_mhop6 = bp_udp6_mhop(); - bglobal.bg_echo = ptm_bfd_echo_sock_init(); - bglobal.bg_vxlan = ptm_bfd_vxlan_sock_init(); + bglobal.bg_echo = bp_echo_socket(); + bglobal.bg_echov6 = bp_echov6_socket(); } int main(int argc, char *argv[]) @@ -216,10 +220,8 @@ int main(int argc, char *argv[]) &bglobal.bg_ev[3]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo, &bglobal.bg_ev[4]); -#if 0 /* TODO VxLAN support. */ - thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan, + thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6, &bglobal.bg_ev[5]); -#endif thread_add_read(master, control_accept, NULL, bglobal.bg_csock, &bglobal.bg_csockev); diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index ae6081f01a..1c6d03195c 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -827,7 +827,7 @@ DEFPY(bfd_show_peers_counters, bfd_show_peers_counters_cmd, * Configuration rules: * * Single hop: - * peer + (optional vxlan or interface name) + * peer + (interface name) * * Multi hop: * peer + local + (optional vrf) @@ -896,23 +896,6 @@ static int bfd_configure_peer(struct bfd_peer_cfg *bpc, bool mhop, bpc->bpc_mhop = mhop; -#if 0 - /* Handle VxLAN configuration. */ - if (vxlan >= 0) { - if (vxlan > ((1 << 24) - 1)) { - snprintf(ebuf, ebuflen, "invalid VxLAN %d", vxlan); - return -1; - } - if (bpc->bpc_mhop) { - snprintf(ebuf, ebuflen, - "multihop doesn't accept VxLAN"); - return -1; - } - - bpc->bpc_vxlan = vxlan; - } -#endif /* VxLAN */ - /* Handle interface specification configuration. */ if (ifname) { if (bpc->bpc_mhop) { diff --git a/bfdd/bsd.c b/bfdd/bsd.c index 34a3a1a801..e0fb340e30 100644 --- a/bfdd/bsd.c +++ b/bfdd/bsd.c @@ -33,38 +33,8 @@ #include "bfd.h" /* - * Prototypes - */ -static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen); - -/* * Definitions. */ -static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen) -{ - const struct sockaddr *sa = sv; - const struct sockaddr_in *sin = sv; - const struct sockaddr_in6 *sin6 = sv; - int unknown = 1; - - switch (sa->sa_family) { - case AF_INET: - if (inet_ntop(AF_INET, &sin->sin_addr, buf, buflen) != NULL) - unknown = 0; - break; - - case AF_INET6: - if (inet_ntop(AF_INET6, &sin6->sin6_addr, buf, buflen) != NULL) - unknown = 0; - break; - } - if (unknown == 0) - return buf; - - snprintf(buf, buflen, "unknown (af=%d)", sa->sa_family); - return buf; -} - int ptm_bfd_fetch_ifindex(const char *ifname) { return if_nametoindex(ifname); @@ -129,133 +99,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen) __LINE__); } -int ptm_bfd_echo_sock_init(void) -{ - int s, ttl, yes = 1; - struct sockaddr_in sin; - - s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); - if (s == -1) { - log_error("echo-socket: creation failed: %s", strerror(errno)); - return -1; - } - - memset(&sin, 0, sizeof(sin)); -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - /* OmniOS doesn't have this field, but uses this code. */ - sin.sin_len = sizeof(sin); -#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - sin.sin_family = AF_INET; - sin.sin_port = htons(3785); - if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { - log_error("echo-socket: bind failure: %s", strerror(errno)); - close(s); - return -1; - } - - if (setsockopt(s, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) == -1) { - log_error("echo-socket: setsockopt(IP_RECVTTL): %s", - strerror(errno)); - close(s); - return -1; - } - - ttl = BFD_TTL_VAL; - if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) { - log_error("echo-socket: setsockopt(IP_TTL): %s", - strerror(errno)); - close(s); - return -1; - } - - return s; -} - -ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen, - struct sockaddr_storage *ss, socklen_t *sslen, - uint8_t *ttl, uint32_t *id) -{ - struct cmsghdr *cmsg; - struct bfd_echo_pkt *bep; - ssize_t readlen; - struct iovec iov; - struct msghdr msg; - uint8_t msgctl[255]; - char errbuf[255]; - - /* Prepare socket read. */ - memset(ss, 0, sizeof(*ss)); - memset(&msg, 0, sizeof(msg)); - iov.iov_base = buf; - iov.iov_len = *buflen; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = msgctl; - msg.msg_controllen = sizeof(msgctl); - msg.msg_name = ss; - msg.msg_namelen = *sslen; - - /* Read the socket and treat errors. */ - readlen = recvmsg(sd, &msg, 0); - if (readlen == 0) { - log_error("%s: recvmsg: socket closed", __func__); - return -1; - } - if (readlen == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - return -1; - - log_error("%s: recvmsg: (%d) %s", __func__, errno, - strerror(errno)); - return -1; - } - /* Short packet, better not risk reading it. */ - if (readlen < (ssize_t)sizeof(*bep)) { - log_warning("%s: short packet (%ld of %d) from %s", __func__, - readlen, sizeof(*bep), - sockaddr_to_string(ss, errbuf, sizeof(errbuf))); - return -1; - } - *buflen = readlen; - - /* Read TTL information. */ - *ttl = 0; - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level != IPPROTO_IP) - continue; - if (cmsg->cmsg_type != IP_RECVTTL) - continue; - - *ttl = *(uint8_t *)CMSG_DATA(cmsg); - break; - } - if (*ttl == 0) { - log_debug("%s: failed to read TTL", __func__); - return -1; - } - - /* Read my discriminator from BFD Echo packet. */ - bep = (struct bfd_echo_pkt *)buf; - *id = bep->my_discr; - if (*id == 0) { - log_debug("%s: invalid packet discriminator from: %s", __func__, - sockaddr_to_string(ss, errbuf, sizeof(errbuf))); - return -1; - } - - /* Set the returned sockaddr new length. */ - *sslen = msg.msg_namelen; - - return 0; -} - -int ptm_bfd_vxlan_sock_init(void) -{ - /* TODO: not supported yet. */ - return -1; -} - int bp_bind_dev(int sd, const char *dev) { /* @@ -266,25 +109,4 @@ int bp_bind_dev(int sd, const char *dev) return 0; } -uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len) -{ - char *ptr; - struct udp_psuedo_header pudp_hdr; - uint16_t csum; - - pudp_hdr.saddr = ip->ip_src.s_addr; - pudp_hdr.daddr = ip->ip_dst.s_addr; - pudp_hdr.reserved = 0; - pudp_hdr.protocol = ip->ip_p; - pudp_hdr.len = htons(len); - - ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len); - memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN); - memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len); - - csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len); - XFREE(MTYPE_BFDD_TMP, ptr); - return csum; -} - #endif /* BFD_BSD */ diff --git a/bfdd/config.c b/bfdd/config.c index 0e0d8b7d70..06089780c6 100644 --- a/bfdd/config.c +++ b/bfdd/config.c @@ -218,10 +218,6 @@ static int parse_peer_config(struct json_object *jo, struct bfd_peer_cfg *bpc) } else { log_debug("\tlocal-interface: %s", sval); } - } else if (strcmp(key, "vxlan") == 0) { - bpc->bpc_vxlan = json_object_get_int64(jo_val); - bpc->bpc_has_vxlan = true; - log_debug("\tvxlan: %ld", bpc->bpc_vxlan); } else if (strcmp(key, "vrf-name") == 0) { bpc->bpc_has_vrfname = true; sval = json_object_get_string(jo_val); diff --git a/bfdd/event.c b/bfdd/event.c index ba12f5b4e8..63f64077eb 100644 --- a/bfdd/event.c +++ b/bfdd/event.c @@ -49,8 +49,7 @@ void bfd_recvtimer_update(struct bfd_session *bs) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->recvtimer_ev) - bfd_recvtimer_delete(bs); + bfd_recvtimer_delete(bs); thread_add_timer_tv(master, bfd_recvtimer_cb, bs, &tv, &bs->recvtimer_ev); @@ -70,8 +69,7 @@ void bfd_echo_recvtimer_update(struct bfd_session *bs) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->echo_recvtimer_ev) - bfd_echo_recvtimer_delete(bs); + bfd_echo_recvtimer_delete(bs); thread_add_timer_tv(master, bfd_echo_recvtimer_cb, bs, &tv, &bs->echo_recvtimer_ev); @@ -91,8 +89,7 @@ void bfd_xmttimer_update(struct bfd_session *bs, uint64_t jitter) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->xmttimer_ev) - bfd_xmttimer_delete(bs); + bfd_xmttimer_delete(bs); thread_add_timer_tv(master, bfd_xmt_cb, bs, &tv, &bs->xmttimer_ev); } @@ -111,8 +108,7 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->echo_xmttimer_ev) - bfd_echo_xmttimer_delete(bs); + bfd_echo_xmttimer_delete(bs); thread_add_timer_tv(master, bfd_echo_xmt_cb, bs, &tv, &bs->echo_xmttimer_ev); @@ -120,36 +116,20 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter) void bfd_recvtimer_delete(struct bfd_session *bs) { - if (bs->recvtimer_ev == NULL) - return; - - thread_cancel(bs->recvtimer_ev); - bs->recvtimer_ev = NULL; + THREAD_OFF(bs->recvtimer_ev); } void bfd_echo_recvtimer_delete(struct bfd_session *bs) { - if (bs->echo_recvtimer_ev == NULL) - return; - - thread_cancel(bs->echo_recvtimer_ev); - bs->echo_recvtimer_ev = NULL; + THREAD_OFF(bs->echo_recvtimer_ev); } void bfd_xmttimer_delete(struct bfd_session *bs) { - if (bs->xmttimer_ev == NULL) - return; - - thread_cancel(bs->xmttimer_ev); - bs->xmttimer_ev = NULL; + THREAD_OFF(bs->xmttimer_ev); } void bfd_echo_xmttimer_delete(struct bfd_session *bs) { - if (bs->echo_xmttimer_ev == NULL) - return; - - thread_cancel(bs->echo_xmttimer_ev); - bs->echo_xmttimer_ev = NULL; + THREAD_OFF(bs->echo_xmttimer_ev); } diff --git a/bfdd/linux.c b/bfdd/linux.c index 5f24ef4d19..e260851ddb 100644 --- a/bfdd/linux.c +++ b/bfdd/linux.c @@ -23,49 +23,8 @@ #ifdef BFD_LINUX -/* XXX: fix compilation error on Ubuntu 16.04 or older. */ -#ifndef _UAPI_IPV6_H -#define _UAPI_IPV6_H -#endif /* _UAPI_IPV6_H */ - -#include <linux/filter.h> -#include <linux/if_packet.h> - -#include <netinet/if_ether.h> - -#include <net/if.h> -#include <sys/ioctl.h> - #include "bfd.h" -/* Berkeley Packet filter code to filter out BFD Echo packets. - * tcpdump -dd "(udp dst port 3785)" - */ -static struct sock_filter bfd_echo_filter[] = { - {0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd}, - {0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011}, - {0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x00000ec9}, - {0x15, 0, 8, 0x00000800}, {0x30, 0, 0, 0x00000017}, - {0x15, 0, 6, 0x00000011}, {0x28, 0, 0, 0x00000014}, - {0x45, 4, 0, 0x00001fff}, {0xb1, 0, 0, 0x0000000e}, - {0x48, 0, 0, 0x00000010}, {0x15, 0, 1, 0x00000ec9}, - {0x6, 0, 0, 0x0000ffff}, {0x6, 0, 0, 0x00000000}, -}; - -/* Berkeley Packet filter code to filter out BFD vxlan packets. - * tcpdump -dd "(udp dst port 4789)" - */ -static struct sock_filter bfd_vxlan_filter[] = { - {0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd}, - {0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011}, - {0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x000012b5}, - {0x15, 0, 8, 0x00000800}, {0x30, 0, 0, 0x00000017}, - {0x15, 0, 6, 0x00000011}, {0x28, 0, 0, 0x00000014}, - {0x45, 4, 0, 0x00001fff}, {0xb1, 0, 0, 0x0000000e}, - {0x48, 0, 0, 0x00000010}, {0x15, 0, 1, 0x000012b5}, - {0x6, 0, 0, 0x0000ffff}, {0x6, 0, 0, 0x00000000}, -}; - /* * Definitions. @@ -128,55 +87,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen) ifr.ifr_name, ifname); } -int ptm_bfd_echo_sock_init(void) -{ - int s; - struct sock_fprog bpf = {.len = sizeof(bfd_echo_filter) - / sizeof(bfd_echo_filter[0]), - .filter = bfd_echo_filter}; - - s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); - if (s == -1) { - log_error("echo-socket: creation failure: %s", strerror(errno)); - return -1; - } - - if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)) - == -1) { - log_error("echo-socket: setsockopt(SO_ATTACH_FILTER): %s", - strerror(errno)); - close(s); - return -1; - } - - return s; -} - -int ptm_bfd_vxlan_sock_init(void) -{ - int s; - struct sock_fprog bpf = {.len = sizeof(bfd_vxlan_filter) - / sizeof(bfd_vxlan_filter[0]), - .filter = bfd_vxlan_filter}; - - s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); - if (s == -1) { - log_error("vxlan-socket: creation failure: %s", - strerror(errno)); - return -1; - } - - if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)) - == -1) { - log_error("vxlan-socket: setsockopt(SO_ATTACH_FILTER): %s", - strerror(errno)); - close(s); - return -1; - } - - return s; -} - int bp_bind_dev(int sd __attribute__((__unused__)), const char *dev __attribute__((__unused__))) { @@ -197,25 +107,4 @@ int bp_bind_dev(int sd __attribute__((__unused__)), return 0; } -uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len) -{ - char *ptr; - struct udp_psuedo_header pudp_hdr; - uint16_t csum; - - pudp_hdr.saddr = iph->saddr; - pudp_hdr.daddr = iph->daddr; - pudp_hdr.reserved = 0; - pudp_hdr.protocol = iph->protocol; - pudp_hdr.len = htons(len); - - ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len); - memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN); - memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len); - - csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len); - XFREE(MTYPE_BFDD_TMP, ptr); - return csum; -} - #endif /* BFD_LINUX */ diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 4287891621..a5fae3383c 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -289,7 +289,7 @@ static int _ptm_msg_read(struct stream *msg, int command, { uint32_t pid; uint8_t ttl __attribute__((unused)); - uint8_t ifnamelen; + size_t ifnamelen; /* * Register/Deregister/Update Message format: diff --git a/bfdd/subdir.am b/bfdd/subdir.am index 86923f5cec..334e974b04 100644 --- a/bfdd/subdir.am +++ b/bfdd/subdir.am @@ -6,6 +6,8 @@ if BFDD noinst_LIBRARIES += bfdd/libbfd.a sbin_PROGRAMS += bfdd/bfdd dist_examples_DATA += bfdd/bfdd.conf.sample +vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c +man8 += $(MANBUILD)/bfdd.8 endif bfdd_libbfd_a_SOURCES = \ diff --git a/bgpd/.gitignore b/bgpd/.gitignore index 105be22995..2e77195b90 100644 --- a/bgpd/.gitignore +++ b/bgpd/.gitignore @@ -1,18 +1,3 @@ -Makefile -Makefile.in -*.o bgpd bgp_btoa bgpd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/bgpd/Makefile b/bgpd/Makefile new file mode 100644 index 0000000000..b8664a8e23 --- /dev/null +++ b/bgpd/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C .. bgpd/bgpd +%: ALWAYS + @$(MAKE) -s -C .. bgpd/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am deleted file mode 100644 index b6b125f752..0000000000 --- a/bgpd/Makefile.am +++ /dev/null @@ -1,140 +0,0 @@ -## Process this file with automake to produce Makefile.in. -AUTOMAKE_OPTIONS = subdir-objects - -include ../common.am - -if ENABLE_BGP_VNC -#o file to keep linker happy -BGP_VNC_RFP_LIB=rfapi/rfapi_descriptor_rfp_utils.o @top_builddir@/$(LIBRFP)/librfp.a -BGP_VNC_RFP_INC=-I@top_srcdir@/$(RFPINC) -BGP_VNC_RFP_HD=\ - @top_srcdir@/$(RFPINC)/rfp.h -BGP_VNC_RFP_LD_FLAGS_FILE=@top_srcdir@/$(LIBRFP)/rfp_ld_flags -BGP_VNC_RFP_LD_FLAGS=`if [ -e "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ] ; then cat "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ; fi ` - -#BGP_VNC_RFAPI_SRCDIR=rfapi -BGP_VNC_RFAPI_SRCDIR= -BGP_VNC_RFAPI_INC=-Irfapi -BGP_VNC_RFAPI_SRC=rfapi/bgp_rfapi_cfg.c \ - rfapi/rfapi_import.c \ - rfapi/rfapi.c \ - rfapi/rfapi_ap.c \ - rfapi/rfapi_descriptor_rfp_utils.c \ - rfapi/rfapi_encap_tlv.c \ - rfapi/rfapi_nve_addr.c \ - rfapi/rfapi_monitor.c \ - rfapi/rfapi_rib.c \ - rfapi/rfapi_vty.c \ - rfapi/vnc_debug.c \ - rfapi/vnc_export_bgp.c \ - rfapi/vnc_export_table.c \ - rfapi/vnc_import_bgp.c \ - rfapi/vnc_zebra.c -BGP_VNC_RFAPI_HD=rfapi/bgp_rfapi_cfg.h \ - rfapi/rfapi_import.h \ - rfapi/rfapi.h \ - rfapi/rfapi_ap.h \ - rfapi/rfapi_backend.h \ - rfapi/rfapi_descriptor_rfp_utils.h \ - rfapi/rfapi_encap_tlv.h \ - rfapi/rfapi_nve_addr.h \ - rfapi/rfapi_monitor.h \ - rfapi/rfapi_private.h \ - rfapi/rfapi_rib.h \ - rfapi/rfapi_vty.h \ - rfapi/vnc_debug.h \ - rfapi/vnc_export_bgp.h \ - rfapi/vnc_export_table.h \ - rfapi/vnc_import_bgp.h \ - rfapi/vnc_zebra.h \ - rfapi/vnc_export_bgp_p.h \ - rfapi/vnc_import_bgp_p.h \ - bgp_vnc_types.h $(BGP_VNC_RFP_HD) - -else -BGP_VNC_RFAPI_INC= -BGP_VNC_RFAPI_SRC= -BGP_VNC_RFAPI_HD= -BGP_VNC_RFP_LIB= -BGP_VNC_RFP_INC= -BGP_VNC_RFP_HD= -BGP_VNC_RFP_LD_FLAGS= -endif - -AM_CPPFLAGS += -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC) -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -INSTALL_SDATA=@INSTALL@ -m 600 - -noinst_LIBRARIES = libbgp.a -module_LTLIBRARIES = -sbin_PROGRAMS = bgpd -bin_PROGRAMS = bgp_btoa - -BUILT_SOURCES = - -libbgp_a_SOURCES = \ - bgp_memory.c \ - bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \ - bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \ - bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \ - bgp_dump.c bgp_ecommunity.c bgp_lcommunity.c \ - bgp_mplsvpn.c bgp_nexthop.c \ - bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \ - bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \ - bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \ - bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c bgp_rd.c \ - bgp_keepalives.c bgp_io.c bgp_flowspec.c bgp_flowspec_util.c \ - bgp_flowspec_vty.c bgp_labelpool.c bgp_pbr.c bgp_errors.c - -noinst_HEADERS = \ - bgp_memory.h \ - bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \ - bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \ - bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \ - bgp_ecommunity.h bgp_lcommunity.h \ - bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \ - bgp_advertise.h bgp_vty.h bgp_mpath.h bgp_nht.h \ - bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h \ - $(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \ - bgp_vpn.h bgp_label.h bgp_rd.h bgp_evpn_private.h bgp_keepalives.h \ - bgp_io.h bgp_flowspec.h bgp_flowspec_private.h bgp_flowspec_util.h \ - bgp_labelpool.h bgp_pbr.h bgp_errors.h - -bgpd_SOURCES = bgp_main.c -bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@ -bgpd_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS) - -bgp_btoa_SOURCES = bgp_btoa.c -bgp_btoa_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@ -bgp_btoa_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS) - -if SNMP -module_LTLIBRARIES += bgpd_snmp.la -endif - -bgpd_snmp_la_SOURCES = bgp_snmp.c -bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 -bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -bgpd_snmp_la_LIBADD = ../lib/libfrrsnmp.la - -if RPKI -module_LTLIBRARIES += bgpd_rpki.la -BUILT_SOURCES += bgp_rpki_clippy.c -endif - -bgpd_rpki_la_SOURCES = bgp_rpki.c -bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS) -bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS) - -examplesdir = $(exampledir) -dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \ - bgpd.conf.vnc.sample - -bgp_vty.o: bgp_vty_clippy.c -bgp_route.o: bgp_route_clippy.c -bgp_debug.o: bgp_debug_clippy.c - -EXTRA_DIST = BGP4-MIB.txt - diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index d6ad52b3a6..1f8a910f2f 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -35,9 +35,10 @@ #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) @@ -1638,7 +1639,8 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath, 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, diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 6acd4c8cf1..c7d7c56a12 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -260,11 +260,11 @@ void bgp_attr_flush_encap(struct attr *attr) * * 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; @@ -357,8 +357,8 @@ static unsigned int encap_hash_key_make(void *p) 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) @@ -997,14 +997,13 @@ bgp_attr_flags_diagnose(struct bgp_attr_parser_args *args, 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) { @@ -1063,7 +1062,7 @@ static int bgp_attr_flag_invalid(struct bgp_attr_parser_args *args) 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; @@ -1075,18 +1074,18 @@ static int bgp_attr_flag_invalid(struct bgp_attr_parser_args *args) */ 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; } } @@ -1118,8 +1117,8 @@ static bgp_attr_parse_ret_t bgp_attr_origin(struct bgp_attr_parser_args *args) 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); } @@ -1132,8 +1131,8 @@ static bgp_attr_parse_ret_t bgp_attr_origin(struct bgp_attr_parser_args *args) 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); } @@ -1161,9 +1160,9 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args) /* 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); } @@ -1191,8 +1190,8 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer, && !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; @@ -1202,9 +1201,9 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer, 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; @@ -1236,9 +1235,9 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args, /* 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); } @@ -1260,8 +1259,8 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) /* 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); @@ -1285,7 +1284,7 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args) { 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); } @@ -1305,8 +1304,8 @@ static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args) /* 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); @@ -1329,8 +1328,8 @@ bgp_attr_local_pref(struct bgp_attr_parser_args *args) /* 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); } @@ -1359,9 +1358,9 @@ static int bgp_attr_atomic(struct bgp_attr_parser_args *args) /* 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); } @@ -1386,9 +1385,9 @@ static int bgp_attr_aggregator(struct bgp_attr_parser_args *args) 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); } @@ -1416,8 +1415,8 @@ bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args, 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); } @@ -1576,8 +1575,8 @@ bgp_attr_originator_id(struct bgp_attr_parser_args *args) /* 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); @@ -1600,8 +1599,7 @@ bgp_attr_cluster_list(struct bgp_attr_parser_args *args) /* 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); @@ -1707,8 +1705,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, 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: @@ -1718,8 +1722,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, 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 */ @@ -1743,6 +1753,11 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, 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: @@ -1760,7 +1775,8 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, { 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); } @@ -2071,7 +2087,7 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(int32_t type, 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, @@ -2106,9 +2122,9 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(int32_t type, /* 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); @@ -2130,7 +2146,7 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(int32_t type, 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( @@ -2180,7 +2196,7 @@ bgp_attr_prefix_sid(int32_t tlength, struct bgp_attr_parser_args *args, 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, @@ -2207,24 +2223,24 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *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); @@ -2336,7 +2352,8 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr) 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, @@ -2352,7 +2369,7 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, 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; @@ -2377,7 +2394,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, /* 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 @@ -2399,7 +2417,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, /* 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 @@ -2421,7 +2440,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, 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); @@ -2439,7 +2459,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, 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); @@ -2503,7 +2524,6 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, 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); @@ -2597,7 +2617,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, /* 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); @@ -2605,7 +2626,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, } 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) @@ -2615,7 +2637,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, /* 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); @@ -2627,7 +2650,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, /* 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); @@ -2637,13 +2661,10 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr, } /* 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; } /* @@ -2825,7 +2846,7 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, 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; diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 071ee6b9c6..5ffab0bf4f 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -177,7 +177,7 @@ int bgp_damp_withdraw(struct bgp_info *binfo, struct bgp_node *rn, afi_t afi, { time_t t_now; struct bgp_damp_info *bdi = NULL; - double last_penalty = 0; + unsigned int last_penalty = 0; t_now = bgp_clock(); diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index d69b1c46f2..ef746597a4 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -36,6 +36,7 @@ #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, @@ -119,7 +120,7 @@ static FILE *bgp_dump_open_file(struct bgp_dump *bgp_dump) 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; } @@ -131,7 +132,7 @@ static FILE *bgp_dump_open_file(struct bgp_dump *bgp_dump) 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; diff --git a/bgpd/bgp_errors.c b/bgpd/bgp_errors.c index 50dd001b8b..bd42901c2d 100644 --- a/bgpd/bgp_errors.c +++ b/bgpd/bgp_errors.c @@ -24,272 +24,440 @@ #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" @@ -303,4 +471,5 @@ static struct log_ref ferr_bgp_err[] = { void bgp_error_init(void) { log_ref_add(ferr_bgp_err); + log_ref_add(ferr_bgp_warn); } diff --git a/bgpd/bgp_errors.h b/bgpd/bgp_errors.h index be718d99e7..853f2da222 100644 --- a/bgpd/bgp_errors.h +++ b/bgpd/bgp_errors.h @@ -25,53 +25,80 @@ 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); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 9e814516b7..41aceae9f7 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -173,8 +173,8 @@ static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) 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; } @@ -204,8 +204,8 @@ static void vrf_import_rt_free(struct vrf_irt_node *irt) 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; } @@ -226,9 +226,8 @@ static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) 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; } @@ -543,7 +542,7 @@ static void evpn_convert_nexthop_to_ipv6(struct attr *attr) static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, struct prefix_evpn *p, struct in_addr remote_vtep_ip, int add, - uint8_t flags) + uint8_t flags, uint32_t seq) { struct stream *s; int ipa_len; @@ -579,19 +578,22 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, stream_put_in_addr(s, &remote_vtep_ip); /* TX flags - MAC sticky status and/or gateway mac */ - if (add) + /* Also TX the sequence number of the best route. */ + if (add) { stream_putc(s, flags); + stream_putl(s, seq); + } stream_putw_at(s, 0, stream_get_endp(s)); if (bgp_debug_zebra(NULL)) zlog_debug( - "Tx %s MACIP, VNI %u MAC %s IP %s (flags: 0x%x) remote VTEP %s", + "Tx %s MACIP, VNI %u MAC %s IP %s flags 0x%x seq %u remote VTEP %s", add ? "ADD" : "DEL", vpn->vni, prefix_mac2str(&p->prefix.macip_addr.mac, buf1, sizeof(buf1)), ipaddr2str(&p->prefix.macip_addr.ip, - buf3, sizeof(buf3)), flags, + buf3, sizeof(buf3)), flags, seq, inet_ntop(AF_INET, &remote_vtep_ip, buf2, sizeof(buf2))); @@ -625,7 +627,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, 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; @@ -875,13 +877,14 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr) /* Install EVPN route into zebra. */ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn, struct prefix_evpn *p, - struct in_addr remote_vtep_ip, uint8_t flags) + struct in_addr remote_vtep_ip, uint8_t flags, + uint32_t seq) { int ret; if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip, - 1, flags); + 1, flags, seq); else ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1); @@ -897,7 +900,7 @@ static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn, if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip, - 0, 0); + 0, 0, 0); else ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 0); @@ -1141,7 +1144,8 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, ret = evpn_zebra_install( bgp, vpn, (struct prefix_evpn *)&rn->p, - old_select->attr->nexthop, flags); + old_select->attr->nexthop, flags, + mac_mobility_seqnum(old_select->attr)); } UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG); bgp_zebra_clear_route_change_flags(rn); @@ -1177,7 +1181,8 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p, - new_select->attr->nexthop, flags); + new_select->attr->nexthop, flags, + mac_mobility_seqnum(new_select->attr)); /* If an old best existed and it was a "local" route, the only * reason * it would be supplanted is due to MAC mobility procedures. So, @@ -1296,7 +1301,7 @@ static int update_evpn_type4_route_entry(struct bgp *bgp, */ 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)), @@ -1383,12 +1388,11 @@ static int update_evpn_type4_route(struct bgp *bgp, &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); @@ -1557,11 +1561,12 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, */ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, afi_t afi, safi_t safi, struct bgp_node *rn, - struct attr *attr, int add, int vni_table, - struct bgp_info **ri, uint8_t flags) + struct attr *attr, int add, + struct bgp_info **ri, uint8_t flags, + uint32_t seq) { struct bgp_info *tmp_ri; - struct bgp_info *local_ri, *remote_ri; + struct bgp_info *local_ri; struct attr *attr_new; mpls_label_t label[BGP_MAX_LABELS]; uint32_t num_labels = 1; @@ -1573,28 +1578,13 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, evp = (struct prefix_evpn *)&rn->p; memset(&label, 0, sizeof(label)); - /* See if this is an update of an existing route, or a new add. Also, - * identify if already known from remote, and if so, the one with the - * highest sequence number; this is only when adding to the VNI routing - * table. - */ - local_ri = remote_ri = NULL; + /* See if this is an update of an existing route, or a new add. */ + local_ri = NULL; for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) { if (tmp_ri->peer == bgp->peer_self && tmp_ri->type == ZEBRA_ROUTE_BGP && tmp_ri->sub_type == BGP_ROUTE_STATIC) local_ri = tmp_ri; - if (vni_table) { - if (tmp_ri->type == ZEBRA_ROUTE_BGP - && tmp_ri->sub_type == BGP_ROUTE_IMPORTED - && CHECK_FLAG(tmp_ri->flags, BGP_INFO_VALID)) { - if (!remote_ri) - remote_ri = tmp_ri; - else if (mac_mobility_seqnum(tmp_ri->attr) - > mac_mobility_seqnum(remote_ri->attr)) - remote_ri = tmp_ri; - } - } } /* If route doesn't exist already, create a new one, if told to. @@ -1604,22 +1594,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, if (!local_ri && !add) return 0; - if (!local_ri) { - /* When learnt locally for the first time but already known from - * remote, we have to initiate appropriate MAC mobility steps. - * This is applicable when updating the VNI routing table. - * We need to skip mobility steps for g/w macs (local mac on g/w - * SVI) advertised in EVPN. - * This will ensure that local routes are preferred for g/w macs - */ - if (remote_ri && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { - uint32_t cur_seqnum; - - /* Add MM extended community to route. */ - cur_seqnum = mac_mobility_seqnum(remote_ri->attr); - add_mac_mobility_to_attr(cur_seqnum + 1, attr); - } + /* For non-GW MACs, update MAC mobility seq number, if needed. */ + if (seq && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) + add_mac_mobility_to_attr(seq, attr); + if (!local_ri) { /* Add (or update) attribute to hash. */ attr_new = bgp_attr_intern(attr); @@ -1685,6 +1664,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, attr_new = bgp_attr_intern(attr); bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED); + /* Extract MAC mobility sequence number, if any. */ + attr_new->mm_seqnum = + bgp_attr_mac_mobility_seqnum(attr_new, &sticky); + attr_new->sticky = sticky; + /* Restore route, if needed. */ if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED)) bgp_info_restore(rn, tmp_ri); @@ -1706,7 +1690,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, * and schedule for processing. */ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, - struct prefix_evpn *p, uint8_t flags) + struct prefix_evpn *p, uint8_t flags, + uint32_t seq) { struct bgp_node *rn; struct attr attr; @@ -1758,7 +1743,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, /* Create or update route entry. */ route_change = update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr, - 1, 1, &ri, flags); + 1, &ri, flags, seq); assert(ri); attr_new = ri->attr; @@ -1778,8 +1763,8 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, (struct prefix *)p, &vpn->prd); - update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, 0, - &global_ri, flags); + update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, + &global_ri, flags, seq); /* Schedule for processing and unlock node. */ bgp_process(bgp, rn, afi, safi); @@ -1954,58 +1939,14 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) afi_t afi; safi_t safi; struct bgp_node *rn; - struct bgp_info *ri; + struct bgp_info *ri, *tmp_ri; struct attr attr; - struct attr attr_sticky; - struct attr attr_def_gw; - struct attr attr_ip6_ll; struct attr *attr_new; + uint32_t seq; int add_l3_ecomm = 0; afi = AFI_L2VPN; safi = SAFI_EVPN; - memset(&attr, 0, sizeof(struct attr)); - memset(&attr_sticky, 0, sizeof(struct attr)); - memset(&attr_def_gw, 0, sizeof(struct attr)); - memset(&attr_ip6_ll, 0, sizeof(struct attr)); - - /* Build path-attribute - multiple type-2 routes for this VNI will share - * the same path attribute, but we need separate structures for sticky - * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC). - */ - bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); - bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP); - bgp_attr_default_set(&attr_def_gw, BGP_ORIGIN_IGP); - attr.nexthop = vpn->originator_ip; - attr.mp_nexthop_global_in = vpn->originator_ip; - attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - bgpevpn_get_rmac(vpn, &attr.rmac); - attr_sticky.nexthop = vpn->originator_ip; - attr_sticky.mp_nexthop_global_in = vpn->originator_ip; - attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr_sticky.sticky = 1; - bgpevpn_get_rmac(vpn, &attr_sticky.rmac); - attr_def_gw.nexthop = vpn->originator_ip; - attr_def_gw.mp_nexthop_global_in = vpn->originator_ip; - attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr_def_gw.default_gw = 1; - bgpevpn_get_rmac(vpn, &attr_def_gw.rmac); - bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP); - attr_ip6_ll.nexthop = vpn->originator_ip; - attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip; - attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - - /* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if - * using L3 VNI for type-2 routes also. - */ - if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS) && - bgpevpn_get_l3vni(vpn)) - add_l3_ecomm = 1; - - build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm); - build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm); - build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm); - build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0); /* Walk this VNI's route table and update local type-2 routes. For any * routes updated, update corresponding entry in the global table too. @@ -2019,35 +1960,57 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE) continue; - if (is_evpn_prefix_ipaddr_v6(evp) && - IN6_IS_ADDR_LINKLOCAL(&evp->prefix.macip_addr.ip.ipaddr_v6)) - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr_ip6_ll, 0, 1, &ri, 0); - else { - if (evpn_route_is_sticky(bgp, rn)) - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr_sticky, 0, 1, &ri, - 0); - else if (evpn_route_is_def_gw(bgp, rn)) { - if (is_evpn_prefix_ipaddr_v6(evp)) - attr_def_gw.router_flag = 1; - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr_def_gw, 0, 1, &ri, - 0); - } else - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr, 0, 1, &ri, 0); + /* Identify local route. */ + for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) { + if (tmp_ri->peer == bgp->peer_self + && tmp_ri->type == ZEBRA_ROUTE_BGP + && tmp_ri->sub_type == BGP_ROUTE_STATIC) + break; } - /* If a local route exists for this prefix, we need to update - * the global routing table too. - */ - if (!ri) + if (!tmp_ri) continue; + /* + * Build attribute per local route as the MAC mobility and + * some other values could differ for different routes. The + * attributes will be shared in the hash table. + */ + bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); + attr.nexthop = vpn->originator_ip; + attr.mp_nexthop_global_in = vpn->originator_ip; + attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; + bgpevpn_get_rmac(vpn, &attr.rmac); + + if (evpn_route_is_sticky(bgp, rn)) + attr.sticky = 1; + else if (evpn_route_is_def_gw(bgp, rn)) { + attr.default_gw = 1; + if (is_evpn_prefix_ipaddr_v6(evp)) + attr.router_flag = 1; + } + + /* Add L3 VNI RTs and RMAC for non IPv6 link-local if + * using L3 VNI for type-2 routes also. + */ + if ((is_evpn_prefix_ipaddr_v4(evp) || + !IN6_IS_ADDR_LINKLOCAL( + &evp->prefix.macip_addr.ip.ipaddr_v6)) && + CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS) && + bgpevpn_get_l3vni(vpn)) + add_l3_ecomm = 1; + + /* Set up extended community. */ + build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm); + + seq = mac_mobility_seqnum(tmp_ri->attr); + + /* Update the route entry. */ + update_evpn_route_entry(bgp, vpn, afi, safi, rn, + &attr, 0, &ri, 0, seq); + /* Perform route selection; this is just to set the flags - * correctly - * as local route in the VNI always wins. + * correctly as local route in the VNI always wins. */ evpn_route_select_install(bgp, vpn, rn); @@ -2058,18 +2021,17 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) (struct prefix *)evp, &vpn->prd); assert(rd_rn); update_evpn_route_entry(bgp, vpn, afi, safi, rd_rn, attr_new, 0, - 0, &global_ri, 0); + &global_ri, 0, + mac_mobility_seqnum(attr_new)); /* Schedule for processing and unlock node. */ bgp_process(bgp, rd_rn, afi, safi); bgp_unlock_node(rd_rn); - } - /* Unintern temporary. */ - aspath_unintern(&attr.aspath); - aspath_unintern(&attr_sticky.aspath); - aspath_unintern(&attr_def_gw.aspath); - aspath_unintern(&attr_ip6_ll.aspath); + /* Unintern temporary. */ + aspath_unintern(&attr.aspath); + + } return 0; } @@ -2206,7 +2168,7 @@ static int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) * locally learnt type-2 routes (MACIP) - for this VNI. */ build_evpn_type3_prefix(&p, vpn->originator_ip); - ret = update_evpn_route(bgp, vpn, &p, 0); + ret = update_evpn_route(bgp, vpn, &p, 0, 0); if (ret) return ret; @@ -2227,9 +2189,9 @@ static int delete_routes_for_es(struct bgp *bgp, struct evpnes *es) 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 */ @@ -2887,7 +2849,7 @@ static int install_uninstall_routes_for_es(struct bgp *bgp, if (ret) { flog_err( - BGP_ERR_EVPN_FAIL, + EC_BGP_EVPN_FAIL, "Failed to %s EVPN %s route in ESI %s", install ? "install" : "uninstall", @@ -2967,7 +2929,7 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) if (ret) { flog_err( - BGP_ERR_EVPN_FAIL, + EC_BGP_EVPN_FAIL, "Failed to %s EVPN %s route in VRF %s", install ? "install" : "uninstall", @@ -3041,7 +3003,7 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp, 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" @@ -3144,7 +3106,7 @@ static int install_uninstall_route_in_es(struct bgp *bgp, struct evpnes *es, 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))); @@ -3186,12 +3148,12 @@ static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi, 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; } } @@ -3222,14 +3184,13 @@ static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi, 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; } } @@ -3451,8 +3412,8 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, (struct prefix *)&p, &vpn->prd); - update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri, - 0); + update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, &ri, + 0, mac_mobility_seqnum(attr)); /* Schedule for processing and unlock node. */ bgp_process(bgp, global_rn, afi, safi); @@ -3485,7 +3446,8 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) (struct prefix *)evp, &vpn->prd); assert(global_rn); update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, - 0, &global_ri, 0); + &global_ri, 0, + mac_mobility_seqnum(attr)); /* Schedule for processing and unlock node. */ bgp_process(bgp, global_rn, afi, safi); @@ -3594,9 +3556,9 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, */ 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; } @@ -3632,7 +3594,7 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, 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; @@ -3644,7 +3606,7 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, 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; @@ -3705,9 +3667,9 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, * 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; } @@ -3718,9 +3680,11 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, 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); } } @@ -3748,7 +3712,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, 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; @@ -3784,9 +3748,9 @@ static int process_type4_route(struct peer *peer, afi_t afi, safi_t safi, * 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; } @@ -3807,7 +3771,7 @@ static int process_type4_route(struct peer *peer, afi_t afi, safi_t safi, 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; @@ -3849,9 +3813,9 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, * 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; } @@ -3883,7 +3847,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, 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; @@ -4110,7 +4074,7 @@ void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p, 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)); @@ -4156,9 +4120,9 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p, 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 @@ -4717,7 +4681,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, 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; @@ -4729,7 +4693,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, 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; @@ -4741,7 +4705,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, 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; @@ -4752,7 +4716,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, 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; @@ -5197,7 +5161,8 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac, /* 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; } @@ -5213,7 +5178,7 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac, * Handle add of a local MACIP. */ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, - struct ipaddr *ip, uint8_t flags) + struct ipaddr *ip, uint8_t flags, uint32_t seq) { struct bgpevpn *vpn; struct prefix_evpn p; @@ -5221,19 +5186,20 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, /* 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; } /* Create EVPN type-2 route and schedule for processing. */ build_evpn_type2_prefix(&p, mac, ip); - if (update_evpn_route(bgp, vpn, &p, flags)) { + if (update_evpn_route(bgp, vpn, &p, flags, seq)) { char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; 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) @@ -5275,7 +5241,7 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, 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; @@ -5292,16 +5258,16 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac, 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; } @@ -5363,7 +5329,7 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) 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; @@ -5372,7 +5338,7 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) 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; @@ -5433,7 +5399,8 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni) 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; @@ -5503,7 +5470,7 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, 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; @@ -5525,10 +5492,10 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, /* Create EVPN type-3 route and schedule for processing. */ build_evpn_type3_prefix(&p, vpn->originator_ip); - if (update_evpn_route(bgp, vpn, &p, 0)) { - flog_err(BGP_ERR_EVPN_ROUTE_CREATE, - "%u: Type3 route creation failure for VNI %u", - bgp->vrf_id, vni); + if (update_evpn_route(bgp, vpn, &p, 0, 0)) { + flog_err(EC_BGP_EVPN_ROUTE_CREATE, + "%u: Type3 route creation failure for VNI %u", + bgp->vrf_id, vni); return -1; } @@ -5556,17 +5523,17 @@ int bgp_evpn_local_es_del(struct bgp *bgp, 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; } @@ -5593,8 +5560,8 @@ int bgp_evpn_local_es_add(struct bgp *bgp, 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; } @@ -5604,7 +5571,7 @@ int bgp_evpn_local_es_add(struct bgp *bgp, 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; @@ -5615,9 +5582,9 @@ int bgp_evpn_local_es_add(struct bgp *bgp, 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; } diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 91d4c9fac4..b002be3d3d 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -132,7 +132,7 @@ extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac, struct ipaddr *ip); extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, struct ipaddr *ip, - uint8_t flags); + uint8_t flags, uint32_t seq); extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id, struct ethaddr *rmac, struct in_addr originator_ip, int filter); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index a6cc2d9b53..6f907c3ab5 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -1890,9 +1890,10 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) 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; } @@ -1902,7 +1903,7 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni) 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; diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index e29508bf36..ab8bfcb770 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "math.h" - #include <zebra.h> +#include <math.h> + #include "prefix.h" #include "lib_errors.h" @@ -104,15 +104,14 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, 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; } @@ -128,14 +127,16 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, /* 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; @@ -188,9 +189,9 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, 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; } } diff --git a/bgpd/bgp_flowspec.h b/bgpd/bgp_flowspec.h index 9f69dbedda..f07b696b8d 100644 --- a/bgpd/bgp_flowspec.h +++ b/bgpd/bgp_flowspec.h @@ -34,9 +34,8 @@ extern void bgp_flowspec_vty_init(void); extern int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi, struct bgp_table *table, - enum bgp_show_type type, - void *output_arg, uint8_t use_json, - int is_last, + enum bgp_show_type type, void *output_arg, + bool use_json, int is_last, unsigned long *output_cum, unsigned long *total_cum); @@ -50,12 +49,10 @@ extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p, extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi); -extern int bgp_flowspec_display_match_per_ip(afi_t afi, - struct bgp_table *rib, - struct prefix *match, - int prefix_check, - struct vty *vty, - uint8_t use_json, - json_object *json_paths); +extern int bgp_flowspec_display_match_per_ip(afi_t afi, struct bgp_table *rib, + struct prefix *match, + int prefix_check, struct vty *vty, + bool use_json, + json_object *json_paths); #endif /* _FRR_BGP_FLOWSPEC_H */ diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c index 9f92a3c3a6..cb71a64a85 100644 --- a/bgpd/bgp_flowspec_util.c +++ b/bgpd/bgp_flowspec_util.c @@ -68,9 +68,8 @@ static int bgp_flowspec_call_non_opaque_decode(uint8_t *nlri_content, int len, 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; @@ -447,9 +446,9 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len, 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; @@ -542,9 +541,10 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len, 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 */ @@ -557,16 +557,17 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len, 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; diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 31d2c540fa..faa88f9850 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -365,9 +365,8 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi, struct bgp_table *table, enum bgp_show_type type, - void *output_arg, uint8_t use_json, - int is_last, unsigned long *output_cum, - unsigned long *total_cum) + void *output_arg, bool use_json, int is_last, + unsigned long *output_cum, unsigned long *total_cum) { struct bgp_info *ri; struct bgp_node *rn; @@ -520,20 +519,18 @@ DEFUN (bgp_fs_local_install_ifname, { 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; return bgp_fs_local_install_interface(bgp, no, ifname); } -extern int bgp_flowspec_display_match_per_ip(afi_t afi, - struct bgp_table *rib, - struct prefix *match, - int prefix_check, - struct vty *vty, - uint8_t use_json, - json_object *json_paths) +extern int bgp_flowspec_display_match_per_ip(afi_t afi, struct bgp_table *rib, + struct prefix *match, + int prefix_check, struct vty *vty, + bool use_json, + json_object *json_paths) { struct bgp_node *rn; struct prefix *prefix; diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 14d692ebf0..384d2bca82 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -167,7 +167,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) */ 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, @@ -246,7 +246,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) 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" @@ -259,7 +259,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) 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, @@ -1286,15 +1286,15 @@ static int bgp_connect_check(struct thread *thread) 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, @@ -1354,10 +1354,10 @@ int bgp_start(struct peer *peer) 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; } @@ -1390,7 +1390,7 @@ int bgp_start(struct peer *peer) 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; @@ -1444,9 +1444,9 @@ int bgp_start(struct peer *peer) "%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; } /* @@ -1492,9 +1492,8 @@ static int bgp_fsm_open(struct peer *peer) 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); } @@ -1526,7 +1525,7 @@ static int bgp_establish(struct peer *peer) 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; } @@ -1686,7 +1685,7 @@ static int bgp_fsm_update(struct peer *peer) 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), @@ -1699,7 +1698,7 @@ static int bgp_ignore(struct peer *peer) 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), @@ -1974,7 +1973,7 @@ int bgp_event_update(struct peer *peer, int event) */ 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], diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index 311f98001d..c3bfbe4a90 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -402,9 +402,9 @@ static uint16_t bgp_read(struct peer *peer) 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)) { diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 633e589333..ba059d66e6 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -187,11 +187,12 @@ static int bgp_nlri_get_labels(struct peer *peer, uint8_t *pnt, uint8_t plen, /* 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); @@ -246,7 +247,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, /* 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; @@ -258,10 +259,10 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, /* 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; @@ -287,7 +288,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, * 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; @@ -300,7 +301,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, 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, @@ -313,7 +314,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, 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, @@ -337,7 +338,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, /* 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; diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index 8d15649ea5..73d3dc67e8 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -127,8 +127,8 @@ static wq_item_status lp_cbq_docallback(struct work_queue *wq, void *data) 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; } @@ -338,9 +338,9 @@ void bgp_lp_get( 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; } @@ -427,9 +427,9 @@ void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last) 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; } @@ -530,6 +530,7 @@ void bgp_lp_event_zebra_up(void) int chunks_needed; void *labelid; struct lp_lcb *lcb; + int lm_init_ok; /* * Get label chunk allocation request dispatched to zebra @@ -541,6 +542,11 @@ void bgp_lp_event_zebra_up(void) 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; diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index e0834604b2..6643795f55 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -77,6 +77,7 @@ static const struct option longopts[] = { {"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 */ @@ -371,15 +372,17 @@ int main(int argc, char **argv) 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) { @@ -410,7 +413,7 @@ int main(int argc, char **argv) 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; @@ -426,6 +429,12 @@ int main(int argc, char **argv) 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; @@ -448,7 +457,7 @@ int main(int argc, char **argv) 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); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 459775c8ec..276945cbf6 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -152,7 +152,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, 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; @@ -161,7 +161,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, /* 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; @@ -170,7 +170,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, /* 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, @@ -181,7 +181,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, /* 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, @@ -218,8 +218,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, #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 */ } @@ -242,7 +241,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, /* 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; @@ -366,10 +365,10 @@ int vpn_leak_label_callback( 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 */ } diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 22d5d35c82..d56fdd75ce 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -36,6 +36,7 @@ #include "filter.h" #include "ns.h" #include "lib_errors.h" +#include "nexthop.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_open.h" @@ -44,6 +45,7 @@ #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; @@ -84,7 +86,8 @@ static int bgp_md5_set_socket(int socket, union sockunion *su, #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; @@ -148,7 +151,7 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) 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, @@ -164,7 +167,7 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) 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, @@ -176,7 +179,7 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock) 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, @@ -221,10 +224,9 @@ static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst) 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 } @@ -279,7 +281,7 @@ static int bgp_accept(struct thread *thread) /* 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; } @@ -291,7 +293,7 @@ static int bgp_accept(struct thread *thread) /* 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; @@ -561,7 +563,8 @@ int bgp_connect(struct peer *peer) 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 @@ -617,15 +620,12 @@ int bgp_getsockname(struct peer *peer) 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; } @@ -657,14 +657,13 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, } 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; } @@ -706,7 +705,7 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address) 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; } @@ -727,7 +726,7 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address) ? 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; } @@ -746,10 +745,10 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address) 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); } diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 0c0c079950..3d2a4ee0dd 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -345,7 +345,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) 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; @@ -592,7 +592,8 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) 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)) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 5bdee5f512..62b412af0c 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -254,7 +254,8 @@ static int bgp_capability_mp(struct peer *peer, struct capability_header *hdr) /* 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; @@ -449,7 +450,8 @@ static int bgp_capability_restart(struct peer *peer, /* 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; @@ -521,9 +523,9 @@ static as_t bgp_capability_as4(struct peer *peer, struct capability_header *hdr) 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; } @@ -546,7 +548,8 @@ static int bgp_capability_addpath(struct peer *peer, /* 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; @@ -604,7 +607,8 @@ static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr) /* 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; @@ -646,7 +650,8 @@ static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr) 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); @@ -677,7 +682,8 @@ static int bgp_capability_hostname(struct peer *peer, 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; @@ -707,7 +713,8 @@ static int bgp_capability_hostname(struct peer *peer, } 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; @@ -715,7 +722,8 @@ static int bgp_capability_hostname(struct peer *peer, 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; @@ -952,10 +960,12 @@ static int bgp_capability_parse(struct peer *peer, size_t length, 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); @@ -970,7 +980,8 @@ static int bgp_capability_parse(struct peer *peer, size_t length, } 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, @@ -1186,10 +1197,10 @@ int bgp_open_option_parse(struct peer *peer, uint8_t length, int *mp_capability) && !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( diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index bb474b9e20..96f3c8324f 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1091,9 +1091,9 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) /* 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); @@ -1107,7 +1107,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) */ 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, @@ -1137,7 +1137,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) && 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); @@ -1304,7 +1304,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) /* 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; @@ -1320,7 +1320,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) 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, @@ -1337,7 +1337,7 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) 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, @@ -1399,10 +1399,10 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) /* 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; } @@ -1423,10 +1423,10 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) 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; @@ -1437,10 +1437,10 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) /* 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; @@ -1457,9 +1457,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) /* 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); @@ -1471,9 +1471,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) /* 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); @@ -1512,7 +1512,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) 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); @@ -1572,8 +1572,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) } 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, @@ -1744,9 +1744,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) /* 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; @@ -1755,7 +1755,7 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) /* 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)); @@ -2104,7 +2104,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, return BGP_Stop; } } else { - zlog_warn( + flog_warn( + EC_BGP_UNRECOGNIZED_CAPABILITY, "%s unrecognized capability code: %d - ignored", peer->host, hdr->code); } @@ -2135,9 +2136,9 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size) /* 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; @@ -2146,7 +2147,7 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size) /* 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)); @@ -2228,7 +2229,7 @@ int bgp_process_packet(struct thread *thread) 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; @@ -2239,7 +2240,7 @@ int bgp_process_packet(struct thread *thread) 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; @@ -2249,7 +2250,7 @@ int bgp_process_packet(struct thread *thread) 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; @@ -2260,7 +2261,7 @@ int bgp_process_packet(struct thread *thread) 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; @@ -2271,7 +2272,7 @@ int bgp_process_packet(struct thread *thread) 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; @@ -2281,7 +2282,7 @@ int bgp_process_packet(struct thread *thread) 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; diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index b182fde1e2..a74b584e90 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -653,9 +653,10 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p, 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]; @@ -1881,14 +1882,14 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp, } /* 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 @@ -2251,17 +2252,16 @@ void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p, 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); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 50ffea27bf..5c65d5e615 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -355,7 +355,7 @@ static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_info *ri) 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)) { @@ -4040,7 +4040,6 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi) 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) @@ -4217,7 +4216,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, /* 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; @@ -4229,7 +4228,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, /* 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; @@ -4239,7 +4238,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, * 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; @@ -4261,7 +4260,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, * 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; @@ -4274,7 +4273,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, 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, @@ -4286,7 +4285,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, 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, @@ -4316,7 +4315,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, /* 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; @@ -4728,7 +4727,6 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p, 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) @@ -5456,7 +5454,8 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate) XFREE(MTYPE_BGP_AGGREGATE, aggregate); } -static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath, +static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin, + struct aspath *aspath, struct community *comm) { static struct aspath *ae = NULL; @@ -5467,6 +5466,9 @@ static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath, if (!ri) return 0; + if (origin != ri->attr->origin) + return 0; + if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae)) return 0; @@ -5501,7 +5503,8 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi, * If the aggregate information has not changed * no need to re-install it again. */ - if (bgp_aggregate_info_same(rn->info, aspath, community)) { + if (bgp_aggregate_info_same(rn->info, origin, aspath, + community)) { bgp_unlock_node(rn); if (aspath) @@ -8286,8 +8289,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, continue; } if (type == bgp_show_type_prefix_longer) { - struct prefix *p = output_arg; - + p = output_arg; if (!prefix_match(p, &rn->p)) continue; } @@ -8911,7 +8913,7 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str, static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, struct cmd_token **argv, afi_t afi, safi_t safi, - uint8_t uj) + bool uj) { struct lcommunity *lcom; struct buffer *b; @@ -8948,7 +8950,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, const char *lcom, afi_t afi, safi_t safi, - uint8_t uj) + bool uj) { struct community_list *list; @@ -9888,12 +9890,14 @@ static int bgp_peer_count_walker(struct thread *t) 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"); } } } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index bee4fca705..0b4355805c 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3086,7 +3086,6 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name, 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]; diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 82b268c31d..2e0bb1ae62 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -49,6 +49,7 @@ #include "bgpd/bgp_route.h" #include "lib/network.h" #include "lib/thread.h" +#ifndef VTYSH_EXTRACT_PL #include "rtrlib/rtrlib.h" #include "rtrlib/rtr_mgr.h" #include "rtrlib/lib/ip.h" @@ -56,6 +57,7 @@ #if defined(FOUND_SSH) #include "rtrlib/transport/ssh/ssh_transport.h" #endif +#endif #include "hook.h" #include "libfrr.h" #include "version.h" diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 37740671ca..7f7b4a893f 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -1631,9 +1631,9 @@ void update_group_adjust_peer(struct peer_af *paf) 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; } } diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index c0761503f1..56a82c801c 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -427,7 +427,8 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, 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); @@ -532,7 +533,8 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, 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); @@ -788,7 +790,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) * 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); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 3669ea7736..e6d44c1a2c 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7367,7 +7367,7 @@ DEFUN (show_bgp_vrfs, 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; @@ -7387,7 +7387,7 @@ DEFUN (show_bgp_vrfs, 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++; @@ -10822,7 +10822,7 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, 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"); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index f42c16c1c1..3b762a362b 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -287,6 +287,7 @@ static int bgp_interface_down(int command, struct zclient *zclient, struct nbr_connected *nc; struct listnode *node, *nnode; struct bgp *bgp; + struct peer *peer; bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) @@ -307,11 +308,7 @@ static int bgp_interface_down(int command, struct zclient *zclient, 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) @@ -474,6 +471,7 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient, 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); @@ -495,12 +493,7 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient, 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; @@ -777,8 +770,9 @@ static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr) 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; @@ -786,9 +780,9 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote, 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; @@ -815,8 +809,24 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote, 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; @@ -912,7 +922,7 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote, /* 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, @@ -1078,8 +1088,8 @@ int bgp_zebra_get_table_range(uint32_t chunk_size, 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]", @@ -2380,7 +2390,8 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, int ipa_len; char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; - uint8_t flags; + uint8_t flags = 0; + uint32_t seqnum = 0; memset(&ip, 0, sizeof(ip)); s = zclient->ibuf; @@ -2389,10 +2400,10 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, 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; } @@ -2401,20 +2412,24 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6; stream_get(&ip.ip.addr, s, ipa_len); } - flags = stream_getc(s); + if (command == ZEBRA_MACIP_ADD) { + flags = stream_getc(s); + seqnum = stream_getl(s); + } bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) return 0; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u", + zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u", vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags, prefix_mac2str(&mac, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni); + ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum); if (command == ZEBRA_MACIP_ADD) - return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, flags); + return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, + flags, seqnum); else return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip); } @@ -2482,13 +2497,13 @@ static void bgp_zebra_process_label_chunk( 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; } @@ -2496,8 +2511,8 @@ static void bgp_zebra_process_label_chunk( 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)) { @@ -2513,7 +2528,7 @@ stream_failure: /* for STREAM_GETX */ 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; @@ -2552,6 +2567,7 @@ void bgp_zebra_init(struct thread_master *master) 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) diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index 546d72402a..0223c423df 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -23,7 +23,8 @@ #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); @@ -73,6 +74,9 @@ extern int bgp_zebra_advertise_all_vni(struct bgp *, int); 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; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index a9707a7fc7..fd3a6c9443 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1804,8 +1804,8 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) 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; } @@ -1918,8 +1918,8 @@ static int non_peergroup_deactivate_af(struct peer *peer, afi_t afi, 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; } @@ -1931,9 +1931,9 @@ static int non_peergroup_deactivate_af(struct peer *peer, afi_t afi, 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; } @@ -1982,9 +1982,9 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) 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)) { @@ -7332,7 +7332,6 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, } if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT)) { - struct listnode *node; char *name; for (ALL_LIST_ELEMENTS_RO( @@ -7788,7 +7787,7 @@ 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 @@ -7798,7 +7797,7 @@ void bgp_init(void) 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); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 8a99741390..ebcb9b5ea2 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1470,8 +1470,6 @@ extern void bgp_terminate(void); 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 *); @@ -1520,7 +1518,7 @@ extern int bgp_config_write(struct vty *); 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); diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index f1dd08fda0..15e3974248 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -4015,21 +4015,21 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) 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 ", @@ -4040,28 +4040,28 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) 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", @@ -4074,7 +4074,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) .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"); } diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index a0e9ffbbd0..16dcbd4ee7 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" @@ -462,8 +459,6 @@ void del_vnc_route(struct rfapi_descriptor *rfd, 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", @@ -2928,6 +2923,8 @@ static void test_nexthops_callback( rfapiPrintNhl(stream, next_hops); + fp(out, "\n"); + rfapi_free_next_hop_list(next_hops); } @@ -3049,7 +3046,7 @@ DEFUN (debug_rfapi_close_rfd, DEFUN (debug_rfapi_register_vn_un, debug_rfapi_register_vn_un_cmd, - "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS", + "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS [cost (0-255)]", DEBUG_STR DEBUG_RFAPI_STR "rfapi_register\n" @@ -3063,7 +3060,9 @@ DEFUN (debug_rfapi_register_vn_un, "IPv4 prefix\n" "IPv6 prefix\n" "indicate lifetime follows\n" - "lifetime\n") + "lifetime\n" + "Cost (localpref = 255-cost)\n" + "0-255\n") { struct rfapi_ip_addr vn; struct rfapi_ip_addr un; @@ -3072,6 +3071,7 @@ DEFUN (debug_rfapi_register_vn_un, uint32_t lifetime; struct rfapi_ip_prefix hpfx; int rc; + uint8_t cost = 100; /* * Get VN addr @@ -3112,8 +3112,12 @@ DEFUN (debug_rfapi_register_vn_un, lifetime = strtoul(argv[10]->arg, NULL, 10); } + if (argc >= 13) + cost = (uint8_t) strtoul(argv[12]->arg, NULL, 10); + hpfx.cost = cost; - rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, 0); + rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, + RFAPI_REGISTER_ADD); if (rc) { vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, strerror(rc)); @@ -3213,7 +3217,8 @@ DEFUN (debug_rfapi_register_vn_un_l2o, /* L2 option parsing END */ /* TBD fixme */ - rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, 0); + rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, + RFAPI_REGISTER_ADD); if (rc) { vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, strerror(rc)); @@ -3225,7 +3230,7 @@ DEFUN (debug_rfapi_register_vn_un_l2o, DEFUN (debug_rfapi_unregister_vn_un, debug_rfapi_unregister_vn_un_cmd, - "debug rfapi-dev unregister vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>", + "debug rfapi-dev unregister vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> [kill]", DEBUG_STR DEBUG_RFAPI_STR "rfapi_register\n" @@ -3233,7 +3238,8 @@ DEFUN (debug_rfapi_unregister_vn_un, "virtual network interface address\n" "indicate xt addr follows\n" "underlay network interface address\n" - "indicate prefix follows\n" "prefix") + "prefix to remove\n" + "Remove without holddown") { struct rfapi_ip_addr vn; struct rfapi_ip_addr un; @@ -3275,7 +3281,9 @@ DEFUN (debug_rfapi_unregister_vn_un, } rfapiQprefix2Rprefix(&pfx, &hpfx); - rfapi_register(handle, &hpfx, 0, NULL, NULL, 1); + rfapi_register(handle, &hpfx, 0, NULL, NULL, + (argc == 10 ? + RFAPI_REGISTER_KILL : RFAPI_REGISTER_WITHDRAW)); return CMD_SUCCESS; } @@ -3934,8 +3942,8 @@ void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val, 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; @@ -4049,8 +4057,8 @@ void *rfapi_rfp_get_group_config_ptr_name( 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; diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c index 691e1e4ec8..c5fda15d33 100644 --- a/bgpd/rfapi/rfapi_ap.c +++ b/bgpd/rfapi/rfapi_ap.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c index 3217d34e77..ce5acf002c 100644 --- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c +++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/table.h" diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 4c506da686..398de6b3a1 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -23,8 +23,6 @@ * Purpose: Handle import of routes from BGP to RFAPI */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" @@ -3035,7 +3033,7 @@ static void rfapiBgpInfoFilteredImportEncap( 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; } @@ -3494,7 +3492,7 @@ void rfapiBgpInfoFilteredImportVPN( 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; } @@ -3680,12 +3678,12 @@ void rfapiBgpInfoFilteredImportVPN( 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; } @@ -3899,8 +3897,7 @@ rfapiBgpInfoFilteredImportFunction(safi_t safi) 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; } } diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c index 59387240fa..f18c6bfe12 100644 --- a/bgpd/rfapi/rfapi_monitor.c +++ b/bgpd/rfapi/rfapi_monitor.c @@ -24,8 +24,6 @@ /* TBD remove unneeded includes */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 3ac217ff89..008da30118 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -23,8 +23,6 @@ * Purpose: maintain per-nve ribs and generate change lists */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index b2767da8b2..1dc2d02f15 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" @@ -669,7 +666,6 @@ void rfapiPrintBi(void *stream, struct bgp_info *bi) 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, @@ -2008,7 +2004,8 @@ register_add(struct vty *vty, struct cmd_token *carg_prefix, "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")) { @@ -2022,7 +2019,8 @@ register_add(struct vty *vty, struct cmd_token *carg_prefix, "Missing parameter for local-cost\n"); return CMD_WARNING_CONFIG_FAILED; } - ++argv, --argc; + ++argv; + --argc; arg_lnh_cost = argv[0]->arg; } } @@ -3182,8 +3180,6 @@ static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg *cda, 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) diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index 6289175645..f830c3ed52 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -188,8 +188,8 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn, 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; } @@ -335,7 +335,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn, 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; } @@ -700,8 +700,8 @@ void vnc_direct_bgp_add_prefix(struct bgp *bgp, 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; } @@ -810,8 +810,8 @@ void vnc_direct_bgp_del_prefix(struct bgp *bgp, 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; } @@ -926,8 +926,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) 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; } @@ -979,8 +979,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) 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; } @@ -1073,8 +1073,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) 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; } @@ -1121,8 +1121,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) 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; } @@ -1298,7 +1298,7 @@ static void vnc_direct_bgp_add_group_afi(struct bgp *bgp, 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; } @@ -1642,8 +1642,8 @@ void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi, 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; } @@ -1762,8 +1762,8 @@ void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi, 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; } diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 6022e4cc24..71a4485d39 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -603,8 +603,8 @@ static void vnc_import_bgp_add_route_mode_resolve_nve( */ 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; } @@ -720,8 +720,8 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, } 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; } @@ -908,8 +908,8 @@ vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix, 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; } @@ -1010,13 +1010,13 @@ vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix, 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( @@ -2398,11 +2398,11 @@ void vnc_import_bgp_exterior_add_route_interior( } 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); } @@ -2634,8 +2634,8 @@ void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix, 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; } diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index a93fb60735..1db1755368 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -571,8 +571,8 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp, 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; } @@ -644,8 +644,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd, 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; } @@ -743,13 +743,13 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp, 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; } diff --git a/bgpd/rfp-example/librfp/Makefile b/bgpd/rfp-example/librfp/Makefile new file mode 100644 index 0000000000..8deb93d745 --- /dev/null +++ b/bgpd/rfp-example/librfp/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/librfp/librfp.a +%: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/librfp/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/bgpd/rfp-example/librfp/Makefile.am b/bgpd/rfp-example/librfp/Makefile.am deleted file mode 100644 index fc66a40f00..0000000000 --- a/bgpd/rfp-example/librfp/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -# -# This file has been modified by LabN Consulting, L.L.C. -# -# -## Process this file with automake to produce Makefile.in. - -if ENABLE_BGP_VNC -BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi -BGP_VNC_RFP_LIBDIR=. -BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR) -BGP_VNC_RFP_LIB=librfp.a -BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR) - -librfp_a_SOURCES = \ - rfp_example.c - -librfp_a_INCLUDES = \ - rfp.h \ - rfp_internal.h - -else -BGP_VNC_RFAPI_INC= -BGP_VNC_RFAPI_SRC= -BGP_VNC_RFP_LIB= -BGP_VNC_RFP_INC= -endif - -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \ - -I$(top_builddir) -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC) -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -INSTALL_SDATA=@INSTALL@ -m 600 - -AM_CFLAGS = $(PICFLAGS) -AM_LDFLAGS = $(PILDFLAGS) - -noinst_LIBRARIES = $(BGP_VNC_RFP_LIB) - -noinst_HEADERS = \ - $(librfp_a_INCLUDES) diff --git a/bgpd/rfp-example/librfp/rfp_example.c b/bgpd/rfp-example/librfp/rfp_example.c index 2751e7a44b..af3092232c 100644 --- a/bgpd/rfp-example/librfp/rfp_example.c +++ b/bgpd/rfp-example/librfp/rfp_example.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + /* stub rfp */ #include "rfp_internal.h" #include "bgpd/rfapi/rfapi.h" @@ -55,6 +59,54 @@ DEFUN (rfp_example_config_value, return CMD_SUCCESS; } +DEFUN (rfp_holddown_factor, + rfp_holddown_factor_cmd, + "rfp holddown-factor (0-4294967295)", + RFP_SHOW_STR + "Set Hold-Down Factor as a percentage of registration lifetime.\n" + "Percentage of registration lifetime\n") +{ + struct rfp_instance_t *rfi; + uint32_t value = 0; + + value = strtoul((argv[--argc]->arg), NULL, 10); + rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */ + if (!rfi) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING; + } + rfi->rfapi_config.holddown_factor = value; + rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config); + return CMD_SUCCESS; +} + + +DEFUN (rfp_full_table_download, + rfp_full_table_download_cmd, + "rfp full-table-download <on|off>", + RFP_SHOW_STR + "RFP full table download support (default=on)\n" + "Enable RFP full table download\n" + "Disable RFP full table download\n") +{ + struct rfp_instance_t *rfi; + rfapi_rfp_download_type old; + + rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */ + if (!rfi) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING; + } + old = rfi->rfapi_config.download_type; + if (argv[--argc]->arg[1] == 'n' || argv[argc]->arg[1] == 'N') + rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_FULL; + else + rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL; + if (old != rfi->rfapi_config.download_type) + rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config); + return CMD_SUCCESS; +} + static void rfp_vty_install() { static int installed = 0; @@ -63,6 +115,8 @@ static void rfp_vty_install() installed = 1; /* example of new cli command */ install_element(BGP_NODE, &rfp_example_config_value_cmd); + install_element(BGP_NODE, &rfp_holddown_factor_cmd); + install_element(BGP_NODE, &rfp_full_table_download_cmd); } /*********************************************************************** @@ -196,7 +250,15 @@ static int rfp_cfg_write_cb(struct vty *vty, void *rfp_start_val) vty_out(vty, "\n"); write++; } - + if (rfi->rfapi_config.holddown_factor != 0) { + vty_out(vty, " rfp holddown-factor %u\n", + rfi->rfapi_config.holddown_factor); + write++; + } + if (rfi->rfapi_config.download_type != RFAPI_RFP_DOWNLOAD_FULL) { + vty_out(vty, " rfp full-table-download off\n"); + write++; + } return write; } diff --git a/bgpd/rfp-example/librfp/subdir.am b/bgpd/rfp-example/librfp/subdir.am new file mode 100644 index 0000000000..254ab716d5 --- /dev/null +++ b/bgpd/rfp-example/librfp/subdir.am @@ -0,0 +1,17 @@ +# +# librfp +# + +if ENABLE_BGP_VNC +noinst_LIBRARIES += bgpd/rfp-example/librfp/librfp.a +RFPLDADD = bgpd/rfp-example/librfp/librfp.a +endif + +bgpd_rfp_example_librfp_librfp_a_SOURCES = \ + bgpd/rfp-example/librfp/rfp_example.c \ + # end + +noinst_HEADERS += \ + bgpd/rfp-example/librfp/rfp.h \ + bgpd/rfp-example/librfp/rfp_internal.h \ + # end diff --git a/bgpd/rfp-example/rfptest/Makefile b/bgpd/rfp-example/rfptest/Makefile new file mode 100644 index 0000000000..659a9ceb17 --- /dev/null +++ b/bgpd/rfp-example/rfptest/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/rfptest/rfptest +%: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/rfptest/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/bgpd/rfp-example/rfptest/Makefile.am b/bgpd/rfp-example/rfptest/Makefile.am deleted file mode 100644 index f5db852dbb..0000000000 --- a/bgpd/rfp-example/rfptest/Makefile.am +++ /dev/null @@ -1,52 +0,0 @@ -# -# This file has been modified by LabN Consulting, L.L.C. -# -# -## Process this file with automake to produce Makefile.in. - -if ENABLE_BGP_VNC -BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi -BGP_VNC_RFP_LIBDIR=../librfp -BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR) -BGP_VNC_RFP_LIB=$(BGP_VNC_RFP_LIBDIR)/librfp.a -BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR) - -rfptest_SOURCES = \ - rfptest.c - -rfptest_INCLUDES = \ - rfptest.h - - -RFPTEST_BIN = rfptest - -else -BGP_VNC_RFAPI_INC= -BGP_VNC_RFAPI_SRC= -BGP_VNC_RFP_LIB= -BGP_VNC_RFP_INC= -RFPTEST_BIN= -endif - -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \ - -I$(top_builddir) -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC) - -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -INSTALL_SDATA=@INSTALL@ -m 600 - - -AM_CFLAGS = $(PICFLAGS) -AM_LDFLAGS = $(PILDFLAGS) - - -noinst_HEADERS = \ - $(rfptest_INCLUDES) - -noinst_LIBRARIES = -sbin_PROGRAMS = $(RFPTEST_BIN) - -examplesdir = $(exampledir) - -rfptest_LDADD = $(top_builddir)/lib/libfrr.la $(BGP_VNC_RFP_LIB) -dist_examples_DATA = diff --git a/bgpd/rfp-example/rfptest/rfptest.c b/bgpd/rfp-example/rfptest/rfptest.c index 53e1c33cfb..48df6c0cc7 100644 --- a/bgpd/rfp-example/rfptest/rfptest.c +++ b/bgpd/rfp-example/rfptest/rfptest.c @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* dummy test program */ #include <stdio.h> diff --git a/bgpd/rfp-example/rfptest/subdir.am b/bgpd/rfp-example/rfptest/subdir.am new file mode 100644 index 0000000000..fa7c660116 --- /dev/null +++ b/bgpd/rfp-example/rfptest/subdir.am @@ -0,0 +1,20 @@ +# +# libtest +# + +if ENABLE_BGP_VNC +sbin_PROGRAMS += bgpd/rfp-example/rfptest/rfptest +endif + +bgpd_rfp_example_rfptest_rfptest_CFLAGS = -I$(top_srcdir)/bgpd/rfapi +bgpd_rfp_example_rfptest_rfptest_SOURCES = \ + bgpd/rfp-example/rfptest/rfptest.c \ + # end +noinst_HEADERS += \ + bgpd/rfp-example/rfptest/rfptest.h \ + # end + +bgpd_rfp_example_rfptest_rfptest_LDADD = \ + lib/libfrr.la \ + $(RFPLDADD) \ + # end diff --git a/bgpd/subdir.am b/bgpd/subdir.am new file mode 100644 index 0000000000..4291388567 --- /dev/null +++ b/bgpd/subdir.am @@ -0,0 +1,221 @@ +# +# bgpd +# + +if BGPD +noinst_LIBRARIES += bgpd/libbgp.a +sbin_PROGRAMS += bgpd/bgpd +noinst_PROGRAMS += bgpd/bgp_btoa +dist_examples_DATA += \ + bgpd/bgpd.conf.sample \ + bgpd/bgpd.conf.sample2 \ + bgpd/bgpd.conf.vnc.sample \ + # end +vtysh_scan += \ + $(top_srcdir)/bgpd/bgp_bfd.c \ + $(top_srcdir)/bgpd/bgp_debug.c \ + $(top_srcdir)/bgpd/bgp_dump.c \ + $(top_srcdir)/bgpd/bgp_evpn_vty.c \ + $(top_srcdir)/bgpd/bgp_filter.c \ + $(top_srcdir)/bgpd/bgp_mplsvpn.c \ + $(top_srcdir)/bgpd/bgp_nexthop.c \ + $(top_srcdir)/bgpd/bgp_route.c \ + $(top_srcdir)/bgpd/bgp_routemap.c \ + $(top_srcdir)/bgpd/bgp_vty.c \ + $(top_srcdir)/bgpd/bgp_flowspec_vty.c \ + # end + +# can be loaded as DSO - always include for vtysh +vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c + +if ENABLE_BGP_VNC +vtysh_scan += \ + $(top_srcdir)/bgpd/rfapi/bgp_rfapi_cfg.c \ + $(top_srcdir)/bgpd/rfapi/rfapi.c \ + $(top_srcdir)/bgpd/rfapi/rfapi_vty.c \ + $(top_srcdir)/bgpd/rfapi/vnc_debug.c \ + # end +endif +if SNMP +module_LTLIBRARIES += bgpd/bgpd_snmp.la +endif +if RPKI +module_LTLIBRARIES += bgpd/bgpd_rpki.la +endif +man8 += $(MANBUILD)/bgpd.8 +endif + +bgpd_libbgp_a_SOURCES = \ + bgpd/bgp_advertise.c \ + bgpd/bgp_aspath.c \ + bgpd/bgp_attr.c \ + bgpd/bgp_attr_evpn.c \ + bgpd/bgp_bfd.c \ + bgpd/bgp_clist.c \ + bgpd/bgp_community.c \ + bgpd/bgp_damp.c \ + bgpd/bgp_debug.c \ + bgpd/bgp_dump.c \ + bgpd/bgp_ecommunity.c \ + bgpd/bgp_encap_tlv.c \ + bgpd/bgp_errors.c \ + bgpd/bgp_evpn.c \ + bgpd/bgp_evpn_vty.c \ + bgpd/bgp_filter.c \ + bgpd/bgp_flowspec.c \ + bgpd/bgp_flowspec_util.c \ + bgpd/bgp_flowspec_vty.c \ + bgpd/bgp_fsm.c \ + bgpd/bgp_io.c \ + bgpd/bgp_keepalives.c \ + bgpd/bgp_label.c \ + bgpd/bgp_labelpool.c \ + bgpd/bgp_lcommunity.c \ + bgpd/bgp_memory.c \ + bgpd/bgp_mpath.c \ + bgpd/bgp_mplsvpn.c \ + bgpd/bgp_network.c \ + bgpd/bgp_nexthop.c \ + bgpd/bgp_nht.c \ + bgpd/bgp_open.c \ + bgpd/bgp_packet.c \ + bgpd/bgp_pbr.c \ + bgpd/bgp_rd.c \ + bgpd/bgp_regex.c \ + bgpd/bgp_route.c \ + bgpd/bgp_routemap.c \ + bgpd/bgp_table.c \ + bgpd/bgp_updgrp.c \ + bgpd/bgp_updgrp_adv.c \ + bgpd/bgp_updgrp_packet.c \ + bgpd/bgp_vpn.c \ + bgpd/bgp_vty.c \ + bgpd/bgp_zebra.c \ + bgpd/bgpd.c \ + # end + +if ENABLE_BGP_VNC +bgpd_libbgp_a_SOURCES += \ + bgpd/rfapi/bgp_rfapi_cfg.c \ + bgpd/rfapi/rfapi_import.c \ + bgpd/rfapi/rfapi.c \ + bgpd/rfapi/rfapi_ap.c \ + bgpd/rfapi/rfapi_descriptor_rfp_utils.c \ + bgpd/rfapi/rfapi_encap_tlv.c \ + bgpd/rfapi/rfapi_nve_addr.c \ + bgpd/rfapi/rfapi_monitor.c \ + bgpd/rfapi/rfapi_rib.c \ + bgpd/rfapi/rfapi_vty.c \ + bgpd/rfapi/vnc_debug.c \ + bgpd/rfapi/vnc_export_bgp.c \ + bgpd/rfapi/vnc_export_table.c \ + bgpd/rfapi/vnc_import_bgp.c \ + bgpd/rfapi/vnc_zebra.c \ + # end +endif + +noinst_HEADERS += \ + bgpd/bgp_advertise.h \ + bgpd/bgp_aspath.h \ + bgpd/bgp_attr.h \ + bgpd/bgp_attr_evpn.h \ + bgpd/bgp_bfd.h \ + bgpd/bgp_clist.h \ + bgpd/bgp_community.h \ + bgpd/bgp_damp.h \ + bgpd/bgp_debug.h \ + bgpd/bgp_dump.h \ + bgpd/bgp_ecommunity.h \ + bgpd/bgp_encap_tlv.h \ + bgpd/bgp_encap_types.h \ + bgpd/bgp_errors.h \ + bgpd/bgp_evpn.h \ + bgpd/bgp_evpn_private.h \ + bgpd/bgp_evpn_vty.h \ + bgpd/bgp_filter.h \ + bgpd/bgp_flowspec.h \ + bgpd/bgp_flowspec_private.h \ + bgpd/bgp_flowspec_util.h \ + bgpd/bgp_fsm.h \ + bgpd/bgp_io.h \ + bgpd/bgp_keepalives.h \ + bgpd/bgp_label.h \ + bgpd/bgp_labelpool.h \ + bgpd/bgp_lcommunity.h \ + bgpd/bgp_memory.h \ + bgpd/bgp_mpath.h \ + bgpd/bgp_mplsvpn.h \ + bgpd/bgp_network.h \ + bgpd/bgp_nexthop.h \ + bgpd/bgp_nht.h \ + bgpd/bgp_open.h \ + bgpd/bgp_packet.h \ + bgpd/bgp_pbr.h \ + bgpd/bgp_rd.h \ + bgpd/bgp_regex.h \ + bgpd/bgp_route.h \ + bgpd/bgp_table.h \ + bgpd/bgp_updgrp.h \ + bgpd/bgp_vpn.h \ + bgpd/bgp_vty.h \ + bgpd/bgp_zebra.h \ + bgpd/bgpd.h \ + \ + bgpd/rfapi/bgp_rfapi_cfg.h \ + bgpd/rfapi/rfapi_import.h \ + bgpd/rfapi/rfapi.h \ + bgpd/rfapi/rfapi_ap.h \ + bgpd/rfapi/rfapi_backend.h \ + bgpd/rfapi/rfapi_descriptor_rfp_utils.h \ + bgpd/rfapi/rfapi_encap_tlv.h \ + bgpd/rfapi/rfapi_nve_addr.h \ + bgpd/rfapi/rfapi_monitor.h \ + bgpd/rfapi/rfapi_private.h \ + bgpd/rfapi/rfapi_rib.h \ + bgpd/rfapi/rfapi_vty.h \ + bgpd/rfapi/vnc_debug.h \ + bgpd/rfapi/vnc_export_bgp.h \ + bgpd/rfapi/vnc_export_table.h \ + bgpd/rfapi/vnc_import_bgp.h \ + bgpd/rfapi/vnc_zebra.h \ + bgpd/rfapi/vnc_export_bgp_p.h \ + bgpd/rfapi/vnc_import_bgp_p.h \ + bgpd/bgp_vnc_types.h \ + # end + +bgpd_bgpd_SOURCES = bgpd/bgp_main.c +bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c + +if ENABLE_BGP_VNC +bgpd_bgpd_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c +bgpd_bgpd_CFLAGS = -Irfapi -I@top_srcdir@/$(RFPINC) + +bgpd_bgp_btoa_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c +bgpd_bgp_btoa_CFLAGS = -Irfapi -I@top_srcdir@/$(RFPINC) +endif + +# RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am +bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la @LIBCAP@ @LIBM@ +bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la @LIBCAP@ @LIBM@ + +bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c +bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +bgpd_bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic +bgpd_bgpd_snmp_la_LIBADD = lib/libfrrsnmp.la + +bgpd_bgpd_rpki_la_SOURCES = bgpd/bgp_rpki.c +bgpd_bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS) +bgpd_bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic +bgpd_bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS) + +bgpd/bgp_vty_clippy.c: $(CLIPPY_DEPS) +bgpd/bgp_vty.$(OBJEXT): bgpd/bgp_vty_clippy.c +bgpd/bgp_route_clippy.c: $(CLIPPY_DEPS) +bgpd/bgp_route.$(OBJEXT): bgpd/bgp_route_clippy.c +bgpd/bgp_debug_clippy.c: $(CLIPPY_DEPS) +bgpd/bgp_debug.$(OBJEXT): bgpd/bgp_debug_clippy.c +bgpd/bgp_rpki_clippy.c: $(CLIPPY_DEPS) +$(AUTOMAKE_DUMMY)bgpd/bgpd_bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c +$(AUTOMAKE_DUMMY)bgpd/bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c + +EXTRA_DIST += bgpd/BGP4-MIB.txt diff --git a/common.am b/common.am deleted file mode 100644 index 9c0c547811..0000000000 --- a/common.am +++ /dev/null @@ -1,61 +0,0 @@ -# -# Automake fragment intended to be shared by Makefile.am files in the -# tree. When used, should be included at the very top of the file. -# -AM_CPPFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ -AM_CFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ $(WERROR) - -AM_V_CLIPPY = $(am__v_CLIPPY_$(V)) -am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY)) -am__v_CLIPPY_0 = @echo " CLIPPY " $@; -am__v_CLIPPY_1 = - -CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py - -SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h -.c_clippy.c: - @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } - $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $< - -## automake's "ylwrap" is a great piece of GNU software... not. -.l.c: - $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $< -.y.c: - $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $< - - -if HAVE_PROTOBUF - -# Uncomment to use an non-system version of libprotobuf-c. -# -# Q_PROTOBUF_C_CLIENT_INCLUDES = -I$(top_srcdir)/third-party/protobuf-c/src -# Q_PROTOBUF_C_CLIENT_LDOPTS = $(top_builddir)/third-party/protobuf-c/src/libprotobuf-c.la - -Q_PROTOBUF_C_CLIENT_INCLUDES= -Q_PROTOBUF_C_CLIENT_LDOPTS=-lprotobuf-c - -Q_PROTOC=protoc -Q_PROTOC_C=protoc-c - -# Rules -.proto.pb.h: - $(Q_PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^ - -AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V)) -am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY)) -am__v_PROTOC_C_0 = @echo " PROTOC_C" $@; -am__v_PROTOC_C_1 = - -.proto.pb-c.c: - $(AM_V_PROTOC_C)$(Q_PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^ -.pb-c.c.pb-c.h: - @/bin/true - -# -# Information about how to link to various libraries. -# -Q_FRR_PB_CLIENT_LDOPTS = $(top_srcdir)/qpb/libfrr_pb.la $(Q_PROTOBUF_C_CLIENT_LDOPTS) - -Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfrrfpm_pb.la $(Q_FRR_PB_CLIENT_LDOPTS) - -endif # HAVE_PROTOBUF diff --git a/configure.ac b/configure.ac index 09a6f364fb..32d5756a61 100755 --- a/configure.ac +++ b/configure.ac @@ -57,7 +57,7 @@ AM_CONDITIONAL([BUILD_CLIPPY], [$build_clippy]) # Disable portability warnings -- our automake code (in particular # common.am) uses some constructs specific to gmake. -AM_INIT_AUTOMAKE([1.12 -Wno-portability]) +AM_INIT_AUTOMAKE([1.12 -Wno-portability foreign]) m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])]) AM_SILENT_RULES([yes]) AC_CONFIG_HEADERS(config.h) @@ -189,46 +189,6 @@ CC="${CC% -std=c99}" AC_C_FLAG([-std=gnu11], [CC="$ac_cc"], [CC="$CC -std=gnu11"]) -dnl AddressSanitizer support -AC_ARG_ENABLE([address-sanitizer], AS_HELP_STRING([--enable-address-sanitizer], \ - [enabled AddressSanitizer support for detecting a wide variety of \ - memory allocation and deallocation errors]), \ - [AC_DEFINE(HAVE_ADDRESS_SANITIZER, 1, [enable AddressSanitizer]) - ASAN_FLAGS="-fsanitize=address" - SAN_CLIPPY_FLAGS="-fno-sanitize=all" - AC_SUBST([ASAN_FLAGS]) - AC_SUBST([SAN_CLIPPY_FLAGS]) - LIBS="-ldl $LIBS" - AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Address Sanitizer Enabled])], - [AC_MSG_ERROR([Address Sanitizer not available])]) - ]) - -dnl ThreadSanitizer support -AC_ARG_ENABLE([thread-sanitizer], AS_HELP_STRING([--enable-thread-sanitizer], \ - [enabled ThreadSanitizer support for detecting data races]), \ - [AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable ThreadSanitizer]) - TSAN_FLAGS="-fsanitize=thread" - SAN_CLIPPY_FLAGS="-fno-sanitize=all" - AC_SUBST([TSAN_FLAGS]) - AC_SUBST([SAN_CLIPPY_FLAGS]) - LIBS="-ldl $LIBS" - AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Thread Sanitizer Enabled])], - [AC_MSG_ERROR([Thread Sanitizer not available])]) - ]) - -dnl MemorySanitizer support -AC_ARG_ENABLE([memory-sanitizer], AS_HELP_STRING([--enable-memory-sanitizer], \ - [enabled MemorySanitizer support for detecting uninitialized memory reads]), \ - [AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable MemorySanitizer]) - MSAN_FLAGS="-fsanitize=memory -fPIE -pie" - SAN_CLIPPY_FLAGS="-fno-sanitize=all" - AC_SUBST([MSAN_FLAGS]) - AC_SUBST([SAN_CLIPPY_FLAGS]) - LIBS="-ldl $LIBS" - AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Memory Sanitizer Enabled])], - [AC_MSG_ERROR([Memory Sanitizer not available])]) - ]) - dnl if the user has specified any CFLAGS, override our settings if test "x${enable_gcov}" = "xyes"; then if test "z$orig_cflags" = "z"; then @@ -271,6 +231,7 @@ if test x"${enable_gcc_ultra_verbose}" = x"yes" ; 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 @@ -287,19 +248,29 @@ if test x"${enable_werror}" = x"yes" ; then fi AC_SUBST(WERROR) -dnl need link on this one, not compile -AC_LANG_PUSH(C) -ac_ld_flag_save="$LDFLAGS" -LDFLAGS="$LDFLAGS -rdynamic" -AC_MSG_CHECKING([[whether linker supports -rdynamic]]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[]])], - [AC_MSG_RESULT([yes])], - [ - LDFLAGS="$ac_ld_flag_save" - AC_MSG_RESULT([no]) - ]) -AC_LANG_POP(C) +SAN_FLAGS="" +if test "$enable_address_sanitizer" = "yes"; then + AC_C_FLAG([-fsanitize=address], [ + AC_MSG_ERROR([$CC does not support Address Sanitizer.]) + ], [ + SAN_FLAGS="$SAN_FLAGS -fsanitize=address" + ]) +fi +if test "$enable_thread_sanitizer" = "yes"; then + AC_C_FLAG([-fsanitize=thread], [ + AC_MSG_ERROR([$CC does not support Thread Sanitizer.]) + ], [ + SAN_FLAGS="$SAN_FLAGS -fsanitize=thread" + ]) +fi +if test "$enable_memory_sanitizer" = "yes"; then + AC_C_FLAG([-fsanitize=thread -fPIE -pie], [ + AC_MSG_ERROR([$CC does not support Thread Sanitizer.]) + ], [ + SAN_FLAGS="-fsanitize=memory -fPIE -pie" + ]) +fi +AC_SUBST([SAN_FLAGS]) dnl ---------- dnl Essentials @@ -313,6 +284,13 @@ AX_PTHREAD([ AC_MSG_FAILURE([This FRR version needs pthreads]) ]) +AC_SEARCH_LIBS([pthread_condattr_setclock], [], + [frr_cv_pthread_condattr_setclock=yes], + [frr_cv_pthread_condattr_setclock=no]) +if test "$frr_cv_pthread_condattr_setclock" = yes; then + AC_DEFINE(HAVE_PTHREAD_CONDATTR_SETCLOCK, 1, [Have pthread.h pthread_condattr_setclock]) +fi + dnl -------------- dnl Check programs dnl -------------- @@ -321,11 +299,6 @@ AC_PROG_LN_S AC_PROG_MAKE_SET AC_CHECK_TOOL(AR, ar) -dnl ----------------- -dnl System extensions -dnl ----------------- -AC_GNU_SOURCE - dnl ------- dnl libtool dnl ------- @@ -381,12 +354,12 @@ AC_ARG_ENABLE(sharpd, AS_HELP_STRING([--enable-sharpd], [build sharpd])) AC_ARG_ENABLE(staticd, AS_HELP_STRING([--disable-staticd], [do not build staticd])) +AC_ARG_ENABLE(fabricd, + AS_HELP_STRING([--disable-fabricd], [do not build fabricd])) AC_ARG_ENABLE(bgp-announce, AS_HELP_STRING([--disable-bgp-announce,], [turn off BGP route announcement])) AC_ARG_ENABLE(bgp-vnc, AS_HELP_STRING([--disable-bgp-vnc],[turn off BGP VNC support])) -AC_ARG_WITH(rfp-path, - AS_HELP_STRING([--with-rfp-path[=DIR]],[path to replaced stub RFP used with BGP VNC])) AC_ARG_ENABLE(snmp, AS_HELP_STRING([--enable-snmp], [enable SNMP support for agentx])) AC_ARG_ENABLE(zeromq, @@ -460,6 +433,12 @@ AC_ARG_ENABLE([gcov], AS_HELP_STRING([--enable-gcov], [Add code coverage information])) AC_ARG_ENABLE(bfdd, AS_HELP_STRING([--disable-bfdd], [do not build bfdd])) +AC_ARG_ENABLE([address-sanitizer], + AS_HELP_STRING([--enable-address-sanitizer], [enable AddressSanitizer support for detecting a wide variety of memory allocation and deallocation errors])) +AC_ARG_ENABLE([thread-sanitizer], + AS_HELP_STRING([--enable-thread-sanitizer], [enable ThreadSanitizer support for detecting data races])) +AC_ARG_ENABLE([memory-sanitizer], + AS_HELP_STRING([--enable-memory-sanitizer], [enable MemorySanitizer support for detecting uninitialized memory reads])) AS_IF([test "${enable_clippy_only}" != "yes"], [ AC_CHECK_HEADERS(json-c/json.h) @@ -623,27 +602,26 @@ AC_SUBST(PYTHON_LIBS) # Logic for protobuf support. # if test "$enable_protobuf" = "yes"; then - have_protobuf=yes - - # Check for protoc-c - AC_CHECK_PROG([PROTOC_C], [protoc-c], [protoc-c], [/bin/false]) - if test "x$PROTOC_C" = "x/bin/false"; then - have_protobuf=no - else - found_protobuf_c=no - PKG_CHECK_MODULES([PROTOBUF_C], libprotobuf-c >= 0.14, - [found_protobuf_c=yes], - [AC_MSG_RESULT([pkg-config did not find libprotobuf-c])]) - - if test "x$found_protobuf_c" = "xyes"; then - LDFLAGS="$LDFLAGS $PROTOBUF_C_LIBS" - CFLAGS="$CFLAGS $PROTOBUF_C_CFLAGS" - else - AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [], - [have_protobuf=no; AC_MSG_RESULT([Couldn't find google/protobuf-c.h])]) - fi - fi + # Check for protoc & protoc-c + + # protoc is not required, it's only for a "be nice" helper target + AC_CHECK_PROGS([PROTOC], [protoc], [/bin/false]) + + AC_CHECK_PROGS([PROTOC_C], [protoc-c], [/bin/false]) + if test "$PROTOC_C" = "/bin/false"; then + AC_MSG_FAILURE([protobuf requested but protoc-c not found. Install protobuf-c.]) + fi + + PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c >= 0.14],, [ + AC_MSG_FAILURE([protobuf requested but libprotobuf-c not found. Install protobuf-c.]) + ]) + AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [], [ + AC_MSG_FAILURE([protobuf requested but protobuf-c.h not found. Install protobuf-c.]) + ]) + + AC_DEFINE(HAVE_PROTOBUF,, protobuf) fi +AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$enable_protobuf" = "xyes"]) # # Logic for old vpn commans support. @@ -652,18 +630,6 @@ if test "$enable_oldvpn_commands" = "yes"; then AC_DEFINE(KEEP_OLD_VPN_COMMANDS,, [Define for compiling with old vpn commands]) fi -# Fail if the user explicity enabled protobuf support and we couldn't -# find the compiler or libraries. -if test "x$have_protobuf" = "xno" && test "x$enable_protobuf" = "xyes"; then - AC_MSG_ERROR([Protobuf enabled explicitly but can't find libraries/tools]) -fi - -if test "x$have_protobuf" = "xyes"; then - AC_DEFINE(HAVE_PROTOBUF,, protobuf) -fi - -AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$have_protobuf" = "xyes"]) - # # End of logic for protobuf support. # @@ -850,10 +816,15 @@ int main(int argc, char **argv) { ]) ]) +AC_CHECK_HEADERS([pthread_np.h],,, [ +#include <pthread.h> +]) +AC_CHECK_FUNCS([pthread_setname_np pthread_set_name_np]) + dnl Utility macro to avoid retyping includes all the time m4_define([FRR_INCLUDES], [#ifdef SUNOS_5 -#define _XPG4_2 +#define _POSIX_C_SOURCE 200809L #define __EXTENSIONS__ #endif #include <stdio.h> @@ -946,6 +917,7 @@ case "$host_os" in AC_DEFINE(SUNOS_5, 1, [SunOS 5]) AC_DEFINE(SOLARIS_IPV6, 1, Solaris IPv6) + AC_DEFINE(_POSIX_C_SOURCE, 200809L, [enable POSIX.1-2008 and XPG7/SUSv4]) AC_CHECK_LIB(socket, main) AC_CHECK_LIB(nsl, main) @@ -1049,6 +1021,10 @@ dnl [TODO] on Linux, and in [TODO] on Solaris. if test $ac_cv_lib_readline_rl_completion_matches = no; then AC_DEFINE(rl_completion_matches,completion_matches,Old readline) fi + AC_SEARCH_LIBS([append_history], [readline], [frr_cv_append_history=yes], [frr_cv_append_history=no]) + if test "$frr_cv_append_history" = yes; then + AC_DEFINE(HAVE_APPEND_HISTORY, 1, [Have history.h append_history]) + fi ;; esac AC_SUBST(LIBREADLINE) @@ -1197,11 +1173,12 @@ case "$host_os" in if test $ac_cv_header_net_bpf_h = no; then if test $ac_cv_header_sys_dlpi_h = no; then AC_MSG_RESULT(none) - if test "${enable_isisd}" = yes; then + if test "${enable_isisd}" = yes -o "${enable_fabricd}" = yes; then AC_MSG_FAILURE([IS-IS support requested but no packet backend found]) fi AC_MSG_WARN([*** IS-IS support will not be built ***]) enable_isisd="no" + enable_fabricd="no" else AC_MSG_RESULT(DLPI) fi @@ -1339,8 +1316,13 @@ FRR_INCLUDES ])dnl dnl disable doc check -AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [no]) -AM_CONDITIONAL(DOC, test "${enable_doc}" != "no") +AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [/bin/false]) +if test "$SPHINXBUILD" = "/bin/false"; then + if test "${enable_doc}" = "yes"; then + AC_MSG_ERROR([Documentation was explicitly requested with --enable-doc but sphinx-build is not available. Please disable docs or install sphinx.]) + fi +fi +AM_CONDITIONAL(DOC, test "${enable_doc}" != "no" -a "$SPHINXBUILD" != "/bin/false") AM_CONDITIONAL(DOC_HTML, test "${enable_doc_html}" = "yes") dnl -------------------- @@ -1429,6 +1411,7 @@ AM_CONDITIONAL(PIMD, test "${enable_pimd}" != "no") AM_CONDITIONAL(PBRD, test "${enable_pbrd}" != "no") AM_CONDITIONAL(SHARPD, test "${enable_sharpd}" = "yes") AM_CONDITIONAL(STATICD, test "${enable_staticd}" != "no") +AM_CONDITIONAL(FABRICD, test "${enable_fabricd}" != "no") if test "${enable_bgp_announce}" = "no";then AC_DEFINE(DISABLE_BGP_ANNOUNCE,1,Disable BGP installation to zebra) @@ -1436,33 +1419,12 @@ else AC_DEFINE(DISABLE_BGP_ANNOUNCE,0,Disable BGP installation to zebra) fi -if test "${with_rfp_path}" = "yes" || test x"${with_rfp_path}" = x""; then - with_rfp_path="bgpd/rfp-example" -fi -if test "${with_rfp_path}" != "no"; then - VNC_RFP_PATH="${with_rfp_path}" - AC_SUBST(VNC_RFP_PATH) -fi - if test "${enable_bgp_vnc}" != "no";then AC_DEFINE(ENABLE_BGP_VNC,1,Enable BGP VNC support) - RFPTEST="${with_rfp_path}/rfptest" - LIBRFP="${with_rfp_path}/librfp" - RFPINC="${with_rfp_path}/librfp" -else - RFPTEST= - LIBRFP= - RFPINC="bgpd/rfp-example/librfp" fi -# set AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno]) -AC_SUBST(RFPTEST) -AC_SUBST(LIBRFP) -AC_SUBST(RFPINC) -AC_SUBST(BGPD) AC_SUBST(SOLARIS) -AC_SUBST(VTYSH) AC_SUBST(CURSES) AC_CHECK_LIB(crypt, crypt, [], [AC_CHECK_LIB(crypto, DES_crypt)]) @@ -1833,13 +1795,16 @@ dnl order to check no alternative allocator dnl has been specified, which might not provide dnl mallinfo, e.g. such as Umem on Solaris. dnl ----------------------------------------- -AC_CHECK_HEADERS([malloc.h malloc/malloc.h],,, [FRR_INCLUDES]) +AC_CHECK_HEADERS([malloc.h malloc_np.h malloc/malloc.h],,, [FRR_INCLUDES]) AC_CACHE_CHECK([whether mallinfo is available], [frr_cv_mallinfo], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [ #ifdef HAVE_MALLOC_H #include <malloc.h> #endif +#ifdef HAVE_MALLOC_NP_H +#include <malloc_np.h> +#endif #ifdef HAVE_MALLOC_MALLOC_H #include <malloc/malloc.h> #endif @@ -1983,8 +1948,7 @@ dnl Enable RPKI and add librtr to libs dnl ------------------------------------ if test "${enable_rpki}" = "yes"; then PKG_CHECK_MODULES(RTRLIB,[rtrlib >= 0.5.0], - [AC_DEFINE(HAVE_RPKI,1,Enable RPKI prefix validation for BGP) - RPKI=true], + [RPKI=true], [RPKI=false AC_MSG_ERROR([rtrlib was not found on your system or is too old.])] ) @@ -2016,11 +1980,6 @@ AC_MSG_RESULT($ac_cv_htonl_works) AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile]) AC_CONFIG_FILES([ - bgpd/Makefile - vtysh/Makefile - tests/Makefile - bgpd/rfp-example/rfptest/Makefile - bgpd/rfp-example/librfp/Makefile redhat/frr.spec solaris/Makefile debianpkg/changelog @@ -2032,12 +1991,6 @@ AC_CONFIG_FILES([ pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh pkgsrc/eigrpd.sh]) -if test "${enable_bgp_vnc}" != "no"; then - if test "${with_rfp_path}" != "bgpd/rfp-example" ; then - AC_CONFIG_FILES([${with_rfp_path}/rfptest/Makefile ${with_rfp_path}/librfp/Makefile]) - fi -fi - AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl]) AC_CONFIG_COMMANDS([lib/route_types.h], [ @@ -2079,9 +2032,9 @@ FRR version : ${PACKAGE_VERSION} host operating system : ${host_os} source code location : ${srcdir} compiler : ${CC} -compiler flags : ${CFLAGS} +compiler flags : ${CFLAGS} ${SAN_FLAGS} make : ${MAKE-make} -linker flags : ${LDFLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM} +linker flags : ${LDFLAGS} ${SAN_FLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM} state file directory : ${frr_statedir} config file directory : `eval echo \`echo ${sysconfdir}\`` example directory : `eval echo \`echo ${exampledir}\`` @@ -2091,12 +2044,12 @@ group to run as : ${enable_group} group for vty sockets : ${enable_vty_group} config file mask : ${enable_configfile_mask} log file mask : ${enable_logfile_mask} -zebra protobuf enabled : ${have_protobuf:-no} +zebra protobuf enabled : ${enable_protobuf:-no} The above user and group must have read/write access to the state file directory and to the config files in the config file directory." if test "${enable_doc}" != "no";then - AS_IF([test "x$SPHINXBUILD" = xno], + AS_IF([test "$SPHINXBUILD" = /bin/false], AC_MSG_WARN(sphinx-build is missing but required to build documentation)) fi diff --git a/debianpkg/frr-doc.docs b/debianpkg/frr-doc.docs index d2218d00f9..605353289c 100644 --- a/debianpkg/frr-doc.docs +++ b/debianpkg/frr-doc.docs @@ -1,5 +1,3 @@ -AUTHORS -NEWS -README +README.md doc/user/*.rst doc/figures/*.png diff --git a/doc/.gitignore b/doc/.gitignore index d99a6a5b2d..fa2b508321 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,4 +1,3 @@ -!Makefile mdate-sh draft-zebra-00.txt *.pdf @@ -6,7 +5,6 @@ draft-zebra-00.txt frr.ps frr.dvi stamp-vti -.nfs* *.aux *.cp *.cps @@ -20,8 +18,4 @@ stamp-vti *.toc *.tp *.vr -.arch-inventory -.arch-ids -*~ -*.loT refix diff --git a/doc/developer/building-frr-for-centos6.rst b/doc/developer/building-frr-for-centos6.rst index d4c2c3bfd0..5f10f3715d 100644 --- a/doc/developer/building-frr-for-centos6.rst +++ b/doc/developer/building-frr-for-centos6.rst @@ -128,8 +128,8 @@ Add frr groups and user .. code-block:: shell sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + sudo groupadd -r -g 85 frrvty + sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr Download Source, configure and compile it @@ -158,7 +158,7 @@ an example.) --enable-ospfapi=yes \ --enable-user=frr \ --enable-group=frr \ - --enable-vty-group=frrvt \ + --enable-vty-group=frrvty \ --enable-rtadv \ --disable-exampledir \ --enable-watchfrr \ @@ -168,10 +168,11 @@ an example.) --enable-eigrpd \ --enable-babeld \ --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make SPHINXBUILD=sphinx-build2.7 - make check PYTHON=/usr/bin/python2.7 SPHINXBUILD=sphinx-build2.7 - sudo make SPHINXBUILD=sphinx-build2.7 install + --with-pkg-extra-version=-MyOwnFRRVersion \ + SPHINXBUILD=sphinx-build2.7 + make + make check PYTHON=/usr/bin/python2.7 + sudo make install Create empty FRR configuration files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst index 31cd4dcc49..b157f540ab 100644 --- a/doc/developer/building-frr-for-centos7.rst +++ b/doc/developer/building-frr-for-centos7.rst @@ -36,8 +36,8 @@ Add frr groups and user :: sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + sudo groupadd -r -g 85 frrvty + sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr Download Source, configure and compile it @@ -66,7 +66,7 @@ an example.) --enable-ospfapi=yes \ --enable-user=frr \ --enable-group=frr \ - --enable-vty-group=frrvt \ + --enable-vty-group=frrvty \ --enable-rtadv \ --enable-systemd=yes \ --disable-exampledir \ @@ -102,7 +102,7 @@ Create empty FRR configuration files sudo touch /etc/frr/babeld.conf sudo chown -R frr:frr /etc/frr/ sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf + sudo chown frr:frrvty /etc/frr/vtysh.conf sudo chmod 640 /etc/frr/*.conf Install daemon config file diff --git a/doc/developer/building-frr-for-fedora24.rst b/doc/developer/building-frr-for-fedora24.rst index 208c580b63..669cc4ae2f 100644 --- a/doc/developer/building-frr-for-fedora24.rst +++ b/doc/developer/building-frr-for-fedora24.rst @@ -29,8 +29,8 @@ Add frr groups and user :: sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + sudo groupadd -r -g 85 frrvty + sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr Download Source, configure and compile it @@ -59,7 +59,7 @@ an example.) --enable-ospfapi=yes \ --enable-user=frr \ --enable-group=frr \ - --enable-vty-group=frrvt \ + --enable-vty-group=frrvty \ --enable-rtadv \ --disable-exampledir \ --enable-watchfrr \ @@ -95,7 +95,7 @@ Create empty FRR configuration files sudo touch /etc/frr/babeld.conf sudo chown -R frr:frr /etc/frr/ sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf + sudo chown frr:frrvty /etc/frr/vtysh.conf sudo chmod 640 /etc/frr/*.conf Install daemon config file diff --git a/doc/developer/building.rst b/doc/developer/building.rst index d145849f7f..4c18445f9d 100644 --- a/doc/developer/building.rst +++ b/doc/developer/building.rst @@ -7,21 +7,21 @@ Building FRR .. toctree:: :maxdepth: 2 - building-frr-on-alpine - building-frr-on-centos6 - building-frr-on-centos7 - building-frr-on-debian8 - building-frr-on-debian9 - building-frr-on-fedora24 - building-frr-on-freebsd10 - building-frr-on-freebsd11 - building-frr-on-freebsd9 - building-frr-on-netbsd6 - building-frr-on-netbsd7 - building-frr-on-omnios - building-frr-on-openbsd6 + building-frr-for-alpine + building-frr-for-centos6 + building-frr-for-centos7 + building-frr-for-debian8 + building-frr-for-debian9 + building-frr-for-fedora24 + building-frr-for-freebsd10 + building-frr-for-freebsd11 + building-frr-for-freebsd9 + building-frr-for-netbsd6 + building-frr-for-netbsd7 + building-frr-for-omnios + building-frr-for-openbsd6 building-frr-for-openwrt - building-frr-on-ubuntu1204 - building-frr-on-ubuntu1404 - building-frr-on-ubuntu1604 - building-frr-on-ubuntu1804 + building-frr-for-ubuntu1204 + building-frr-for-ubuntu1404 + building-frr-for-ubuntu1604 + building-frr-for-ubuntu1804 diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst index 20391c47bc..c0716a5c93 100644 --- a/doc/developer/cli.rst +++ b/doc/developer/cli.rst @@ -450,8 +450,6 @@ is no ordering requirement) .. code-block:: make - include ../common.am - # ... # if linked into a LTLIBRARY (.la/.so): diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index d316de0f38..ee7592fd6a 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -778,6 +778,8 @@ That said, compatibility measures can (and should) be removed when either: - 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 diff --git a/doc/manpages/bgpd.rst b/doc/manpages/bgpd.rst index 94213db4d7..f1736ffd0b 100644 --- a/doc/manpages/bgpd.rst +++ b/doc/manpages/bgpd.rst @@ -21,6 +21,13 @@ OPTIONS available for the |DAEMON| command: .. 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 ===== diff --git a/doc/manpages/common-options.rst b/doc/manpages/common-options.rst index 5fff6fca66..74d3eb7bbd 100644 --- a/doc/manpages/common-options.rst +++ b/doc/manpages/common-options.rst @@ -125,6 +125,7 @@ These following options control the daemon's VTY (interactive command line) inte pbrd 2615 staticd 2616 bfdd 2617 + fabricd 2618 Port 2607 is used for ospfd's Opaque LSA API. diff --git a/doc/manpages/conf.py b/doc/manpages/conf.py index e540d236ea..f57bc1d278 100644 --- a/doc/manpages/conf.py +++ b/doc/manpages/conf.py @@ -333,6 +333,7 @@ man_pages = [ ('vtysh', 'vtysh', 'an integrated shell for FRRouting.', [], 1), ('frr', 'frr', 'a systemd interaction script', [], 1), ('bfdd', 'bfdd', fwfrr.format("a bfd"), [], 8), + ('fabricd', 'fabricd', fwfrr.format("an OpenFabric "), [], 8), ] # -- Options for Texinfo output ------------------------------------------- diff --git a/doc/manpages/fabricd.rst b/doc/manpages/fabricd.rst new file mode 100644 index 0000000000..c14c07661e --- /dev/null +++ b/doc/manpages/fabricd.rst @@ -0,0 +1,38 @@ +******* +FABRICD +******* + +.. include:: defines.rst +.. |DAEMON| replace:: fabricd + +SYNOPSIS +======== +|DAEMON| |synopsis-options-hv| + +|DAEMON| |synopsis-options| + +DESCRIPTION +=========== +|DAEMON| is a routing component that works with the FRRouting routing engine. + +OPTIONS +======= +OPTIONS available for the |DAEMON| command: + +.. include:: common-options.rst + +FILES +===== + +|INSTALL_PREFIX_SBIN|/|DAEMON| + The default location of the |DAEMON| binary. + +|INSTALL_PREFIX_ETC|/|DAEMON|.conf + The default location of the |DAEMON| config file. + +$(PWD)/|DAEMON|.log + If the |DAEMON| process is configured to output logs to a file, then you + will find this file in the directory where you started |DAEMON|. + +.. include:: epilogue.rst + diff --git a/doc/manpages/index.rst b/doc/manpages/index.rst index c62835c770..053555c4e4 100644 --- a/doc/manpages/index.rst +++ b/doc/manpages/index.rst @@ -10,6 +10,7 @@ bgpd eigrpd isisd + fabricd ldpd nhrpd ospf6d diff --git a/doc/manpages/subdir.am b/doc/manpages/subdir.am index 24f47fc7a5..4a9aa4de4d 100644 --- a/doc/manpages/subdir.am +++ b/doc/manpages/subdir.am @@ -9,6 +9,7 @@ man_RSTFILES = \ doc/manpages/defines.rst \ doc/manpages/eigrpd.rst \ doc/manpages/epilogue.rst \ + doc/manpages/fabricd.rst \ doc/manpages/frr.rst \ doc/manpages/index.rst \ doc/manpages/isisd.rst \ @@ -46,83 +47,16 @@ rstman8dir = $(mandir)/man8 rstman1_DATA = rstman8_DATA = -rstman1_DATA += $(MANBUILD)/frr.1 +if DOC +rstman1_DATA += $(man1) +rstman8_DATA += $(man8) +endif # DOC -if PIMD -rstman8_DATA += $(MANBUILD)/pimd.8 -rstman8_DATA += $(MANBUILD)/mtracebis.8 -endif - -if PBRD -rstman8_DATA += $(MANBUILD)/pbrd.8 -endif - -if BGPD -rstman8_DATA += $(MANBUILD)/bgpd.8 -endif - -if ISISD -rstman8_DATA += $(MANBUILD)/isisd.8 -endif - -if OSPF6D -rstman8_DATA += $(MANBUILD)/ospf6d.8 -endif - -if OSPFCLIENT -rstman8_DATA += $(MANBUILD)/ospfclient.8 -endif - -if OSPFD -rstman8_DATA += $(MANBUILD)/ospfd.8 -endif - -if LDPD -rstman8_DATA += $(MANBUILD)/ldpd.8 -endif - -if RIPD -rstman8_DATA += $(MANBUILD)/ripd.8 -endif - -if RIPNGD -rstman8_DATA += $(MANBUILD)/ripngd.8 -endif - -if NHRPD -rstman8_DATA += $(MANBUILD)/nhrpd.8 -endif - -if VTYSH -rstman1_DATA += $(MANBUILD)/vtysh.1 -endif - -if WATCHFRR -rstman8_DATA += $(MANBUILD)/watchfrr.8 -endif - -if ZEBRA -rstman8_DATA += $(MANBUILD)/zebra.8 -endif - -if EIGRPD -rstman8_DATA += $(MANBUILD)/eigrpd.8 -endif - -if SHARPD -rstman8_DATA += $(MANBUILD)/sharpd.8 -endif - -if STATICD -rstman8_DATA += $(MANBUILD)/staticd.8 -endif - -if BFDD -rstman8_DATA += $(MANBUILD)/bfdd.8 -endif +man1 = $(MANBUILD)/frr.1 +man8 = # dependency -$(rstman8_DATA) $(rstman1_DATA): $(MANBUILD)/man.stamp +$(man8) $(man1): $(MANBUILD)/man.stamp # # hook-ins for clean / doc diff --git a/doc/mpls/.gitignore b/doc/mpls/.gitignore deleted file mode 100644 index b0a4a4619f..0000000000 --- a/doc/mpls/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.arch-ids -.arch-inventory -*~ -*.loT - diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 2cea24a8bd..14f2c8dc9a 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -845,6 +845,14 @@ Configuring Peers 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 diff --git a/doc/user/fabricd.rst b/doc/user/fabricd.rst new file mode 100644 index 0000000000..cf0f937c13 --- /dev/null +++ b/doc/user/fabricd.rst @@ -0,0 +1,404 @@ +.. _fabricd: + +********** +OpenFabric +********** + +OpenFabric, specified in :t:`draft-white-openfabric-06.txt`, is a routing +protocol derived from IS-IS, providing link-state routing with efficient +flooding for topologies like spine-leaf networks. + +FRR implements OpenFabric in a daemon called *fabricd* + +.. _configuring-fabricd: + +Configuring fabricd +=================== + +There are no *fabricd* specific options. Common options can be specified +(:ref:`common-invocation-options`) to *fabricd*. *fabricd* needs to acquire +interface information from *zebra* in order to function. Therefore *zebra* must +be running before invoking *fabricd*. Also, if *zebra* is restarted then *fabricd* +must be too. + +Like other daemons, *fabricd* configuration is done in an OpenFabric specific +configuration file :file:`fabricd.conf`. + +.. _openfabric-router: + +OpenFabric router +================= + +To enable the OpenFabric routing protocol, an OpenFabric router needs to be created +in the configuration: + +.. index:: router openfabric WORD +.. clicmd:: router openfabric WORD + +.. index:: no router openfabric WORD +.. clicmd:: no router openfabric WORD + + Enable or disable the OpenFabric process by specifying the OpenFabric domain with + 'WORD'. + +.. index:: net XX.XXXX. ... .XXX.XX +.. clicmd:: net XX.XXXX. ... .XXX.XX + +.. index:: no net XX.XXXX. ... .XXX.XX +.. clicmd:: no net XX.XXXX. ... .XXX.XX + + Set/Unset network entity title (NET) provided in ISO format. + +.. index:: domain-password [clear | md5] <password> +.. clicmd:: domain-password [clear | md5] <password> + +.. index:: no domain-password +.. clicmd:: no domain-password + + Configure the authentication password for a domain, as clear text or md5 one. + +.. index:: log-adjacency-changes +.. clicmd:: log-adjacency-changes + +.. index:: no log-adjacency-changes +.. clicmd:: no log-adjacency-changes + + Log changes in adjacency state. + +.. index:: set-overload-bit +.. clicmd:: set-overload-bit + +.. index:: no set-overload-bit +.. clicmd:: no set-overload-bit + + Set overload bit to avoid any transit traffic. + +.. index:: purge-originator +.. clicmd:: purge-originator + +.. index:: no purge-originator +.. clicmd:: no purge-originator + + Enable or disable :rfc:`6232` purge originator identification. + +.. index:: fabric-tier (0-14) +.. clicmd:: fabric-tier (0-14) + +.. index:: no fabric-tier +.. clicmd:: no fabric-tier + + Configure a static tier number to advertise as location in the fabric + +.. _openfabric-timer: + +OpenFabric Timer +================ + +.. index:: lsp-gen-interval (1-120) +.. clicmd:: lsp-gen-interval (1-120) + +.. index:: no lsp-gen-interval +.. clicmd:: no lsp-gen-interval + + Set minimum interval in seconds between regenerating same LSP. + +.. index:: lsp-refresh-interval (1-65235) +.. clicmd:: lsp-refresh-interval (1-65235) + +.. index:: no lsp-refresh-interval +.. clicmd:: no lsp-refresh-interval + + Set LSP refresh interval in seconds. + +.. index:: max-lsp-lifetime (360-65535) +.. clicmd:: max-lsp-lifetime (360-65535) + +.. index:: no max-lsp-lifetime +.. clicmd:: no max-lsp-lifetime + + Set LSP maximum LSP lifetime in seconds. + +.. index:: spf-interval (1-120) +.. clicmd:: spf-interval (1-120) + +.. index:: no spf-interval +.. clicmd:: no spf-interval + + Set minimum interval between consecutive SPF calculations in seconds. + +.. _openfabric-interface: + +OpenFabric interface +==================== + +.. index:: ip router openfabric WORD +.. clicmd:: ip router openfabric WORD + +.. index:: no ip router openfabric WORD +.. clicmd:: no ip router openfabric WORD + +.. _ip-router-openfabric-word: + + Activate OpenFabric on this interface. Note that the name + of OpenFabric instance must be the same as the one used to configure the + routing process (see command :clicmd:`router openfabric WORD`). + +.. index:: openfabric csnp-interval (1-600) +.. clicmd:: openfabric csnp-interval (1-600) + +.. index:: no openfabric csnp-interval +.. clicmd:: no openfabric csnp-interval + + Set CSNP interval in seconds. + +.. index:: openfabric hello-interval (1-600) +.. clicmd:: openfabric hello-interval (1-600) + +.. index:: no openfabric hello-interval +.. clicmd:: no openfabric hello-interval + + Set Hello interval in seconds. + +.. index:: openfabric hello-multiplier (2-100) +.. clicmd:: openfabric hello-multiplier (2-100) + +.. index:: no openfabric hello-multiplier +.. clicmd:: no openfabric hello-multiplier + + Set multiplier for Hello holding time. + +.. index:: openfabric metric (0-16777215) +.. clicmd:: openfabric metric (0-16777215) + +.. index:: no openfabric metric +.. clicmd:: no openfabric metric + + Set interface metric value. + +.. index:: openfabric passive +.. clicmd:: openfabric passive + +.. index:: no openfabric passive +.. clicmd:: no openfabric passive + + Configure the passive mode for this interface. + +.. index:: openfabric password [clear | md5] <password> +.. clicmd:: openfabric password [clear | md5] <password> + +.. index:: no openfabric password +.. clicmd:: no openfabric password + + Configure the authentication password (clear or encoded text) for the + interface. + +.. index:: openfabric psnp-interval (1-120) +.. clicmd:: openfabric psnp-interval (1-120) + +.. index:: no openfabric psnp-interval +.. clicmd:: no openfabric psnp-interval + + Set PSNP interval in seconds. + +.. _showing-openfabric-information: + +Showing OpenFabric information +============================== + +.. index:: show openfabric summary +.. clicmd:: show openfabric summary + + Show summary information about OpenFabric. + +.. index:: show openfabric hostname +.. clicmd:: show openfabric hostname + + Show which hostnames are associated with which OpenFabric system ids. + +.. index:: show openfabric interface +.. clicmd:: show openfabric interface + +.. index:: show openfabric interface detail +.. clicmd:: show openfabric interface detail + +.. index:: show openfabric interface <interface name> +.. clicmd:: show openfabric interface <interface name> + + Show state and configuration of specified OpenFabric interface, or all interfaces + if no interface is given with or without details. + +.. index:: show openfabric neighbor +.. clicmd:: show openfabric neighbor + +.. index:: show openfabric neighbor <System Id> +.. clicmd:: show openfabric neighbor <System Id> + +.. index:: show openfabric neighbor detail +.. clicmd:: show openfabric neighbor detail + + Show state and information of specified OpenFabric neighbor, or all neighbors if + no system id is given with or without details. + +.. index:: show openfabric database +.. clicmd:: show openfabric database + +.. index:: show openfabric database [detail] +.. clicmd:: show openfabric database [detail] + +.. index:: show openfabric database <LSP id> [detail] +.. clicmd:: show openfabric database <LSP id> [detail] + +.. index:: show openfabric database detail <LSP id> +.. clicmd:: show openfabric database detail <LSP id> + + Show the OpenFabric database globally, for a specific LSP id without or with + details. + +.. index:: show openfabric topology +.. clicmd:: show openfabric topology + + Show calculated OpenFabric paths and associated topology information. + +.. _debugging-openfabric: + +Debugging OpenFabric +==================== + +.. index:: debug openfabric adj-packets +.. clicmd:: debug openfabric adj-packets + +.. index:: no debug openfabric adj-packets +.. clicmd:: no debug openfabric adj-packets + +OpenFabric Adjacency related packets. + +.. index:: debug openfabric checksum-errors +.. clicmd:: debug openfabric checksum-errors + +.. index:: no debug openfabric checksum-errors +.. clicmd:: no debug openfabric checksum-errors + +OpenFabric LSP checksum errors. + +.. index:: debug openfabric events +.. clicmd:: debug openfabric events + +.. index:: no debug openfabric events +.. clicmd:: no debug openfabric events + +OpenFabric Events. + +.. index:: debug openfabric local-updates +.. clicmd:: debug openfabric local-updates + +.. index:: no debug openfabric local-updates +.. clicmd:: no debug openfabric local-updates + +OpenFabric local update packets. + +.. index:: debug openfabric lsp-gen +.. clicmd:: debug openfabric lsp-gen + +.. index:: no debug openfabric lsp-gen +.. clicmd:: no debug openfabric lsp-gen + +Generation of own LSPs. + +.. index:: debug openfabric lsp-sched +.. clicmd:: debug openfabric lsp-sched + +.. index:: no debug openfabric lsp-sched +.. clicmd:: no debug openfabric lsp-sched + +Debug scheduling of generation of own LSPs. + +.. index:: debug openfabric packet-dump +.. clicmd:: debug openfabric packet-dump + +.. index:: no debug openfabric packet-dump +.. clicmd:: no debug openfabric packet-dump + +OpenFabric packet dump. + +.. index:: debug openfabric protocol-errors +.. clicmd:: debug openfabric protocol-errors + +.. index:: no debug openfabric protocol-errors +.. clicmd:: no debug openfabric protocol-errors + +OpenFabric LSP protocol errors. + +.. index:: debug openfabric route-events +.. clicmd:: debug openfabric route-events + +.. index:: no debug openfabric route-events +.. clicmd:: no debug openfabric route-events + +OpenFabric Route related events. + +.. index:: debug openfabric snp-packets +.. clicmd:: debug openfabric snp-packets + +.. index:: no debug openfabric snp-packets +.. clicmd:: no debug openfabric snp-packets + +OpenFabric CSNP/PSNP packets. + +.. index:: debug openfabric spf-events +.. clicmd:: debug openfabric spf-events + +.. index:: debug openfabric spf-statistics +.. clicmd:: debug openfabric spf-statistics + +.. index:: debug openfabric spf-triggers +.. clicmd:: debug openfabric spf-triggers + +.. index:: no debug openfabric spf-events +.. clicmd:: no debug openfabric spf-events + +.. index:: no debug openfabric spf-statistics +.. clicmd:: no debug openfabric spf-statistics + +.. index:: no debug openfabric spf-triggers +.. clicmd:: no debug openfabric spf-triggers + +OpenFabric Shortest Path First Events, Timing and Statistic Data and triggering +events. + +.. index:: debug openfabric update-packets +.. clicmd:: debug openfabric update-packets + +.. index:: no debug openfabric update-packets +.. clicmd:: no debug openfabric update-packets + +Update related packets. + +.. index:: show debugging openfabric +.. clicmd:: show debugging openfabric + + Print which OpenFabric debug levels are active. + +OpenFabric configuration example +================================ + +A simple example: + +.. code-block:: frr + + ! + interface lo + ip address 192.0.2.1/32 + ip router openfabric 1 + ipv6 address 2001:db8::1/128 + ipv6 router openfabric 1 + ! + interface eth0 + ip router openfabric 1 + ipv6 router openfabric 1 + ! + interface eth1 + ip router openfabric 1 + ipv6 router openfabric 1 + ! + router openfabric 1 + net 49.0000.0000.0001.00 diff --git a/doc/user/index.rst b/doc/user/index.rst index 5818551343..8190415bf4 100644 --- a/doc/user/index.rst +++ b/doc/user/index.rst @@ -42,6 +42,7 @@ Protocols bfd bgp babeld + fabricd ldpd eigrpd isisd diff --git a/doc/user/installation.rst b/doc/user/installation.rst index 3da5a6cd30..da431916ae 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -139,6 +139,10 @@ options from the list below. Do not build isisd. +.. option:: --disable-fabricd + + Do not build fabricd. + .. option:: --enable-isis-topology Enable IS-IS topology generator. diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 54f82f6832..ee681858d1 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -106,6 +106,14 @@ writing, *isisd* does not support multiple ISIS processes. Set overload bit to avoid any transit traffic. +.. index:: purge-originator +.. clicmd:: purge-originator + +.. index:: no purge-originator +.. clicmd:: no purge-originator + + Enable or disable :rfc:`6232` purge originator identification. + .. _isis-timer: ISIS Timer diff --git a/doc/user/setup.rst b/doc/user/setup.rst index 68ce14982b..8a76a61e78 100644 --- a/doc/user/setup.rst +++ b/doc/user/setup.rst @@ -32,6 +32,7 @@ systemd. The file initially looks like this: staticd=no pbrd=no bfdd=no + fabricd=no To enable a particular daemon, simply change the corresponding 'no' to 'yes'. Subsequent service restarts should start the daemon. @@ -68,6 +69,7 @@ This file has several parts. Here is an example: staticd_options=" --daemon -A 127.0.0.1" pbrd_options=" --daemon -A 127.0.0.1" bfdd_options=" --daemon -A 127.0.0.1" + fabricd_options=" --daemon -A 127.0.0.1" # The list of daemons to watch is automatically generated by the init script. watchfrr_enable=yes @@ -139,6 +141,7 @@ add the following entries to :file:`/etc/services`. ldpd 2612/tcp # LDPd vty eigprd 2613/tcp # EIGRPd vty bfdd 2617/tcp # bfdd vty + fabricd 2618/tcp # fabricd vty If you use a FreeBSD newer than 2.2.8, the above entries are already added to diff --git a/doc/user/sharp.rst b/doc/user/sharp.rst index e27da63b53..8831c0159b 100644 --- a/doc/user/sharp.rst +++ b/doc/user/sharp.rst @@ -33,13 +33,14 @@ All sharp commands are under the enable node and preceeded by the ``sharp`` keyword. At present, no sharp commands will be preserved in the config. .. index:: sharp install -.. clicmd:: sharp install routes A.B.C.D nexthop E.F.G.H (1-1000000) +.. clicmd:: sharp install routes A.B.C.D nexthop <E.F.G.H|X:X::X:X> (1-1000000) Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D`` - with specified nexthop ``E.F.G.H``. The nexthop is a ``NEXTHOP_TYPE_IPV4`` - and must be reachable to be installed into the kernel. The routes are - installed into zebra as ``ZEBRA_ROUTE_SHARP`` and can be used as part of a - normal route redistribution. Route installation time is noted in the debug + with specified nexthop ``E.F.G.H`` or ``X:X::X:X``. The nexthop is + a ``NEXTHOP_TYPE_IPV4`` or ``NEXTHOP_TYPE_IPV6`` and must be reachable + to be installed into the kernel. The routes are installed into zebra as + ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route + redistribution. Route installation time is noted in the debug log. When zebra successfully installs a route into the kernel and SHARP receives success notifications for all routes this is logged as well. diff --git a/doc/user/subdir.am b/doc/user/subdir.am index 6e51eed9d1..53d36052ac 100644 --- a/doc/user/subdir.am +++ b/doc/user/subdir.am @@ -10,6 +10,7 @@ user_RSTFILES = \ doc/user/bugs.rst \ doc/user/conf.py \ doc/user/eigrpd.rst \ + doc/user/fabricd.rst \ doc/user/filter.rst \ doc/user/glossary.rst \ doc/user/index.rst \ diff --git a/eigrpd/.gitignore b/eigrpd/.gitignore index 5b72399e72..0303c6f0d4 100644 --- a/eigrpd/.gitignore +++ b/eigrpd/.gitignore @@ -1,18 +1,2 @@ -!Makefile -Makefile.in -*.o -*.a eigrpd eigrpd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/eigrpd/eigrp_errors.c b/eigrpd/eigrp_errors.c index 3db0ec8545..75cf953557 100644 --- a/eigrpd/eigrp_errors.c +++ b/eigrpd/eigrp_errors.c @@ -26,13 +26,13 @@ /* 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" diff --git a/eigrpd/eigrp_errors.h b/eigrpd/eigrp_errors.h index e1ace8ab49..3270e65138 100644 --- a/eigrpd/eigrp_errors.h +++ b/eigrpd/eigrp_errors.h @@ -24,8 +24,8 @@ #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); diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index eeefc51968..d291cab4c0 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -67,8 +67,8 @@ * 7- state not changed, usually by receiving not last reply */ -#include <thread.h> #include <zebra.h> +#include <thread.h> #include "prefix.h" #include "table.h" diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index d438db28d6..413a35f2fa 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -421,9 +421,9 @@ void eigrp_sw_version_initialize(void) 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); } /** diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index b10673d9e4..66dd5f3419 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -336,8 +336,8 @@ int eigrp_nbr_count_get(void) 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; } diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index 6338e5cf74..f3b583abdd 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -348,14 +348,14 @@ int eigrp_write(struct thread *thread) /* 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; @@ -1214,9 +1214,8 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s, 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); diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index b6e6352def..ccf0496736 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -170,10 +170,11 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, 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; } diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 61eee99f6a..80814d6d36 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -412,8 +412,8 @@ eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg) } 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: diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 190c18777e..311fbce4ab 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -1085,7 +1085,7 @@ DEFUN (eigrp_redistribute_source_metric, DEFUN (no_eigrp_redistribute_source_metric, no_eigrp_redistribute_source_metric_cmd, "no redistribute " FRR_REDIST_STR_EIGRPD - " metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)", + " [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]", "Disable\n" REDIST_STR FRR_REDIST_HELP_STR_EIGRPD diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 91c0046bb9..b30f14f748 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -163,7 +163,7 @@ static struct eigrp *eigrp_new(const char *AS) 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); } diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 2635d555d9..bc48173bba 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -6,6 +6,12 @@ if EIGRPD noinst_LIBRARIES += eigrpd/libeigrp.a sbin_PROGRAMS += eigrpd/eigrpd dist_examples_DATA += eigrpd/eigrpd.conf.sample +vtysh_scan += \ + $(top_srcdir)/eigrpd/eigrp_dump.c \ + $(top_srcdir)/eigrpd/eigrp_vty.c \ + # end +# $(top_srcdir)/eigrpd/eigrp_routemap.c +man8 += $(MANBUILD)/eigrpd.8 endif eigrpd_libeigrp_a_SOURCES = \ diff --git a/fpm/.gitignore b/fpm/.gitignore deleted file mode 100644 index 17e90443e9..0000000000 --- a/fpm/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -!Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/fpm/subdir.am b/fpm/subdir.am index 795535596b..05cec5a528 100644 --- a/fpm/subdir.am +++ b/fpm/subdir.am @@ -3,8 +3,7 @@ lib_LTLIBRARIES += fpm/libfrrfpm_pb.la endif fpm_libfrrfpm_pb_la_LDFLAGS = -version-info 0:0:0 -fpm_libfrrfpm_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \ - $(Q_PROTOBUF_C_CLIENT_INCLUDES) +fpm_libfrrfpm_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS) fpm_libfrrfpm_pb_la_SOURCES = \ fpm/fpm.h \ fpm/fpm_pb.h \ @@ -12,11 +11,14 @@ fpm_libfrrfpm_pb_la_SOURCES = \ # end if HAVE_PROTOBUF -nodist_fpm_libfrrfpm_pb_la_SOURCES = fpm/fpm.pb-c.c +nodist_fpm_libfrrfpm_pb_la_SOURCES = \ + fpm/fpm.pb-c.c \ + # end +endif + CLEANFILES += \ fpm/fpm.pb-c.c \ fpm/fpm.pb-c.h \ # end -endif EXTRA_DIST += fpm/fpm.proto diff --git a/init/.gitignore b/init/.gitignore deleted file mode 100644 index 30b4bc99ec..0000000000 --- a/init/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile -Makefile.in -.nfs* -*~ -*.loT - diff --git a/isisd/.gitignore b/isisd/.gitignore index a882bbf675..b6184ca0f5 100644 --- a/isisd/.gitignore +++ b/isisd/.gitignore @@ -1,15 +1,3 @@ -!Makefile -Makefile.in -*.o isisd -.deps +fabricd isisd.conf -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/isisd/fabricd.c b/isisd/fabricd.c new file mode 100644 index 0000000000..7951efe5a1 --- /dev/null +++ b/isisd/fabricd.c @@ -0,0 +1,717 @@ +/* + * IS-IS Rout(e)ing protocol - OpenFabric extensions + * + * Copyright (C) 2018 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> +#include "isisd/fabricd.h" +#include "isisd/isisd.h" +#include "isisd/isis_memory.h" +#include "isisd/isis_circuit.h" +#include "isisd/isis_misc.h" +#include "isisd/isis_adjacency.h" +#include "isisd/isis_spf.h" +#include "isisd/isis_tlvs.h" +#include "isisd/isis_lsp.h" +#include "isisd/isis_spf_private.h" +#include "isisd/isis_tx_queue.h" + +DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric") +DEFINE_MTYPE_STATIC(ISISD, FABRICD_NEIGHBOR, "ISIS OpenFabric Neighbor Entry") + +/* Tracks initial synchronization as per section 2.4 + * + * We declare the sync complete once we have seen at least one + * CSNP and there are no more LSPs with SSN or SRM set. + */ +enum fabricd_sync_state { + FABRICD_SYNC_PENDING, + FABRICD_SYNC_STARTED, + FABRICD_SYNC_COMPLETE +}; + +struct fabricd { + struct isis_area *area; + + enum fabricd_sync_state initial_sync_state; + time_t initial_sync_start; + struct isis_circuit *initial_sync_circuit; + struct thread *initial_sync_timeout; + + struct isis_spftree *spftree; + struct skiplist *neighbors; + struct hash *neighbors_neighbors; + + uint8_t tier; + uint8_t tier_config; + uint8_t tier_pending; + struct thread *tier_calculation_timer; + struct thread *tier_set_timer; +}; + +/* Code related to maintaining the neighbor lists */ + +struct neighbor_entry { + struct isis_vertex *vertex; + bool present; +}; + +static struct neighbor_entry *neighbor_entry_new(struct isis_vertex *vertex) +{ + struct neighbor_entry *rv = XMALLOC(MTYPE_FABRICD_NEIGHBOR, sizeof(*rv)); + + rv->vertex = vertex; + return rv; +} + +static void neighbor_entry_del(struct neighbor_entry *neighbor) +{ + XFREE(MTYPE_FABRICD_NEIGHBOR, neighbor); +} + +static void neighbor_entry_del_void(void *arg) +{ + neighbor_entry_del((struct neighbor_entry *)arg); +} + +static void neighbor_lists_clear(struct fabricd *f) +{ + while (!skiplist_empty(f->neighbors)) + skiplist_delete_first(f->neighbors); + + hash_clean(f->neighbors_neighbors, neighbor_entry_del_void); +} + +static unsigned neighbor_entry_hash_key(void *np) +{ + struct neighbor_entry *n = np; + + return jhash(n->vertex->N.id, ISIS_SYS_ID_LEN, 0x55aa5a5a); +} + +static int neighbor_entry_hash_cmp(const void *a, const void *b) +{ + const struct neighbor_entry *na = a, *nb = b; + + return memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN) == 0; +} + +static int neighbor_entry_list_cmp(void *a, void *b) +{ + struct neighbor_entry *na = a, *nb = b; + + return -memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN); +} + +static struct neighbor_entry *neighbor_entry_lookup_list(struct skiplist *list, + const uint8_t *id) +{ + struct isis_vertex querier; + isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS); + + struct neighbor_entry n = { + .vertex = &querier + }; + + struct neighbor_entry *rv; + + if (skiplist_search(list, &n, (void**)&rv)) + return NULL; + + if (!rv->present) + return NULL; + + return rv; +} + +static struct neighbor_entry *neighbor_entry_lookup_hash(struct hash *hash, + const uint8_t *id) +{ + struct isis_vertex querier; + isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS); + + struct neighbor_entry n = { + .vertex = &querier + }; + + struct neighbor_entry *rv = hash_lookup(hash, &n); + + if (!rv || !rv->present) + return NULL; + + return rv; +} + +static void neighbor_lists_update(struct fabricd *f) +{ + neighbor_lists_clear(f); + + struct listnode *node; + struct isis_vertex *v; + + for (ALL_QUEUE_ELEMENTS_RO(&f->spftree->paths, node, v)) { + if (!v->d_N || !VTYPE_IS(v->type)) + continue; + + if (v->d_N > 2) + break; + + struct neighbor_entry *n = neighbor_entry_new(v); + if (v->d_N == 1) { + skiplist_insert(f->neighbors, n, n); + } else { + struct neighbor_entry *inserted; + inserted = hash_get(f->neighbors_neighbors, n, hash_alloc_intern); + assert(inserted == n); + } + } +} + +struct fabricd *fabricd_new(struct isis_area *area) +{ + struct fabricd *rv = XCALLOC(MTYPE_FABRICD_STATE, sizeof(*rv)); + + rv->area = area; + rv->initial_sync_state = FABRICD_SYNC_PENDING; + + rv->spftree = isis_spftree_new(area); + rv->neighbors = skiplist_new(0, neighbor_entry_list_cmp, + neighbor_entry_del_void); + rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key, + neighbor_entry_hash_cmp, + "Fabricd Neighbors"); + + rv->tier = rv->tier_config = ISIS_TIER_UNDEFINED; + return rv; +}; + +void fabricd_finish(struct fabricd *f) +{ + if (f->initial_sync_timeout) + thread_cancel(f->initial_sync_timeout); + + if (f->tier_calculation_timer) + thread_cancel(f->tier_calculation_timer); + + if (f->tier_set_timer) + thread_cancel(f->tier_set_timer); + + isis_spftree_del(f->spftree); + neighbor_lists_clear(f); + skiplist_free(f->neighbors); + hash_free(f->neighbors_neighbors); +} + +static int fabricd_initial_sync_timeout(struct thread *thread) +{ + struct fabricd *f = THREAD_ARG(thread); + + zlog_info("OpenFabric: Initial synchronization on %s timed out!", + f->initial_sync_circuit->interface->name); + f->initial_sync_state = FABRICD_SYNC_PENDING; + f->initial_sync_circuit = NULL; + f->initial_sync_timeout = NULL; + return 0; +} + +void fabricd_initial_sync_hello(struct isis_circuit *circuit) +{ + struct fabricd *f = circuit->area->fabricd; + + if (!f) + return; + + if (f->initial_sync_state > FABRICD_SYNC_PENDING) + return; + + f->initial_sync_state = FABRICD_SYNC_STARTED; + + long timeout = 2 * circuit->hello_interval[1] * circuit->hello_multiplier[1]; + + f->initial_sync_circuit = circuit; + if (f->initial_sync_timeout) + return; + + thread_add_timer(master, fabricd_initial_sync_timeout, f, + timeout, &f->initial_sync_timeout); + f->initial_sync_start = monotime(NULL); + + zlog_info("OpenFabric: Started initial synchronization with %s on %s", + sysid_print(circuit->u.p2p.neighbor->sysid), + circuit->interface->name); +} + +bool fabricd_initial_sync_is_in_progress(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return false; + + if (f->initial_sync_state > FABRICD_SYNC_PENDING + && f->initial_sync_state < FABRICD_SYNC_COMPLETE) + return true; + + return false; +} + +bool fabricd_initial_sync_is_complete(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return false; + + return f->initial_sync_state == FABRICD_SYNC_COMPLETE; +} + +struct isis_circuit *fabricd_initial_sync_circuit(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + if (!f) + return NULL; + + return f->initial_sync_circuit; +} + +void fabricd_initial_sync_finish(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return; + + if (monotime(NULL) - f->initial_sync_start < 5) + return; + + zlog_info("OpenFabric: Initial synchronization on %s complete.", + f->initial_sync_circuit->interface->name); + f->initial_sync_state = FABRICD_SYNC_COMPLETE; + f->initial_sync_circuit = NULL; + thread_cancel(f->initial_sync_timeout); + f->initial_sync_timeout = NULL; +} + +static void fabricd_bump_tier_calculation_timer(struct fabricd *f); +static void fabricd_set_tier(struct fabricd *f, uint8_t tier); + +static uint8_t fabricd_calculate_fabric_tier(struct isis_area *area) +{ + struct isis_spftree *local_tree = fabricd_spftree(area); + struct listnode *node; + + struct isis_vertex *furthest_t0 = NULL, + *second_furthest_t0 = NULL; + + struct isis_vertex *v; + + for (ALL_QUEUE_ELEMENTS_RO(&local_tree->paths, node, v)) { + struct isis_lsp *lsp = lsp_for_vertex(local_tree, v); + + if (!lsp || !lsp->tlvs + || !lsp->tlvs->spine_leaf + || !lsp->tlvs->spine_leaf->has_tier + || lsp->tlvs->spine_leaf->tier != 0) + continue; + + second_furthest_t0 = furthest_t0; + furthest_t0 = v; + } + + if (!second_furthest_t0) { + zlog_info("OpenFabric: Could not find two T0 routers"); + return ISIS_TIER_UNDEFINED; + } + + zlog_info("OpenFabric: Found %s as furthest t0 from local system, dist == %" + PRIu32, rawlspid_print(furthest_t0->N.id), furthest_t0->d_N); + + struct isis_spftree *remote_tree = + isis_run_hopcount_spf(area, furthest_t0->N.id, NULL); + + struct isis_vertex *furthest_from_remote = + isis_vertex_queue_last(&remote_tree->paths); + + if (!furthest_from_remote) { + zlog_info("OpenFabric: Found no furthest node in remote spf"); + isis_spftree_del(remote_tree); + return ISIS_TIER_UNDEFINED; + } else { + zlog_info("OpenFabric: Found %s as furthest from remote dist == %" + PRIu32, rawlspid_print(furthest_from_remote->N.id), + furthest_from_remote->d_N); + } + + int64_t tier = furthest_from_remote->d_N - furthest_t0->d_N; + isis_spftree_del(remote_tree); + + if (tier < 0 || tier >= ISIS_TIER_UNDEFINED) { + zlog_info("OpenFabric: Calculated tier %" PRId64 " seems implausible", + tier); + return ISIS_TIER_UNDEFINED; + } + + zlog_info("OpenFabric: Calculated %" PRId64 " as tier", tier); + return tier; +} + +static int fabricd_tier_set_timer(struct thread *thread) +{ + struct fabricd *f = THREAD_ARG(thread); + f->tier_set_timer = NULL; + + fabricd_set_tier(f, f->tier_pending); + return 0; +} + +static int fabricd_tier_calculation_cb(struct thread *thread) +{ + struct fabricd *f = THREAD_ARG(thread); + uint8_t tier = ISIS_TIER_UNDEFINED; + f->tier_calculation_timer = NULL; + + tier = fabricd_calculate_fabric_tier(f->area); + if (tier == ISIS_TIER_UNDEFINED) + return 0; + + zlog_info("OpenFabric: Got tier %" PRIu8 " from algorithm. Arming timer.", + tier); + f->tier_pending = tier; + thread_add_timer(master, fabricd_tier_set_timer, f, + f->area->lsp_gen_interval[ISIS_LEVEL2 - 1], + &f->tier_set_timer); + + return 0; +} + +static void fabricd_bump_tier_calculation_timer(struct fabricd *f) +{ + /* Cancel timer if we already know our tier */ + if (f->tier != ISIS_TIER_UNDEFINED + || f->tier_set_timer) { + if (f->tier_calculation_timer) { + thread_cancel(f->tier_calculation_timer); + f->tier_calculation_timer = NULL; + } + return; + } + + /* If we need to calculate the tier, wait some + * time for the topology to settle before running + * the calculation */ + if (f->tier_calculation_timer) { + thread_cancel(f->tier_calculation_timer); + f->tier_calculation_timer = NULL; + } + + thread_add_timer(master, fabricd_tier_calculation_cb, f, + 2 * f->area->lsp_gen_interval[ISIS_LEVEL2 - 1], + &f->tier_calculation_timer); +} + +static void fabricd_set_tier(struct fabricd *f, uint8_t tier) +{ + if (f->tier == tier) + return; + + zlog_info("OpenFabric: Set own tier to %" PRIu8, tier); + f->tier = tier; + + fabricd_bump_tier_calculation_timer(f); + lsp_regenerate_schedule(f->area, ISIS_LEVEL2, 0); +} + +void fabricd_run_spf(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return; + + isis_run_hopcount_spf(area, isis->sysid, f->spftree); + neighbor_lists_update(f); + fabricd_bump_tier_calculation_timer(f); +} + +struct isis_spftree *fabricd_spftree(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return NULL; + + return f->spftree; +} + +void fabricd_configure_tier(struct isis_area *area, uint8_t tier) +{ + struct fabricd *f = area->fabricd; + + if (!f || f->tier_config == tier) + return; + + f->tier_config = tier; + fabricd_set_tier(f, tier); +} + +uint8_t fabricd_tier(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return ISIS_TIER_UNDEFINED; + + return f->tier; +} + +int fabricd_write_settings(struct isis_area *area, struct vty *vty) +{ + struct fabricd *f = area->fabricd; + int written = 0; + + if (!f) + return written; + + if (f->tier_config != ISIS_TIER_UNDEFINED) { + vty_out(vty, " fabric-tier %" PRIu8 "\n", f->tier_config); + written++; + } + + return written; +} + +static void move_to_dnr(struct isis_lsp *lsp, struct neighbor_entry *n) +{ + struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N); + + n->present = false; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("OpenFabric: Adding %s to DNR", + vid2string(n->vertex, buff, sizeof(buff))); + } + + if (adj) { + isis_tx_queue_add(adj->circuit->tx_queue, lsp, + TX_LSP_CIRCUIT_SCOPED); + } +} + +static void move_to_rf(struct isis_lsp *lsp, struct neighbor_entry *n) +{ + struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N); + + n->present = false; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("OpenFabric: Adding %s to RF", + vid2string(n->vertex, buff, sizeof(buff))); + } + + if (adj) { + isis_tx_queue_add(adj->circuit->tx_queue, lsp, + TX_LSP_NORMAL); + } +} + +static void mark_neighbor_as_present(struct hash_backet *backet, void *arg) +{ + struct neighbor_entry *n = backet->data; + + n->present = true; +} + +static void handle_firsthops(struct hash_backet *backet, void *arg) +{ + struct isis_lsp *lsp = arg; + struct fabricd *f = lsp->area->fabricd; + struct isis_vertex *vertex = backet->data; + + struct neighbor_entry *n; + + n = neighbor_entry_lookup_list(f->neighbors, vertex->N.id); + if (n) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Removing %s from NL as its in the reverse path", + vid2string(vertex, buff, sizeof(buff))); + } + n->present = false; + } + + n = neighbor_entry_lookup_hash(f->neighbors_neighbors, vertex->N.id); + if (n) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Removing %s from NN as its in the reverse path", + vid2string(vertex, buff, sizeof(buff))); + } + n->present = false; + } +} + +void fabricd_lsp_flood(struct isis_lsp *lsp) +{ + struct fabricd *f = lsp->area->fabricd; + assert(f); + + void *cursor = NULL; + struct neighbor_entry *n; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + zlog_debug("OpenFabric: Flooding LSP %s", + rawlspid_print(lsp->hdr.lsp_id)); + } + + /* Mark all elements in NL as present and move T0s into DNR */ + while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) { + n->present = true; + + struct isis_lsp *lsp = lsp_for_vertex(f->spftree, n->vertex); + if (!lsp || !lsp->tlvs || !lsp->tlvs->spine_leaf) + continue; + + if (!lsp->tlvs->spine_leaf->has_tier + || lsp->tlvs->spine_leaf->tier != 0) + continue; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + zlog_debug("Moving %s to DNR because it's T0", + rawlspid_print(lsp->hdr.lsp_id)); + } + + move_to_dnr(lsp, n); + } + + /* Mark all elements in NN as present */ + hash_iterate(f->neighbors_neighbors, mark_neighbor_as_present, NULL); + + struct isis_vertex *originator = isis_find_vertex(&f->spftree->paths, + lsp->hdr.lsp_id, + VTYPE_NONPSEUDO_TE_IS); + + /* Remove all IS from NL and NN in the shortest path + * to the IS that originated the LSP */ + if (originator) + hash_iterate(originator->firsthops, handle_firsthops, lsp); + + /* Iterate over all remaining IS in NL */ + cursor = NULL; + while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) { + if (!n->present) + continue; + + struct isis_lsp *nlsp = lsp_for_vertex(f->spftree, n->vertex); + if (!nlsp || !nlsp->tlvs) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Moving %s to DNR as it has no LSP", + vid2string(n->vertex, buff, sizeof(buff))); + } + + move_to_dnr(lsp, n); + continue; + } + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Considering %s from NL...", + vid2string(n->vertex, buff, sizeof(buff))); + } + + /* For all neighbors of the NL IS check whether they are present + * in NN. If yes, remove from NN and set need_reflood. */ + bool need_reflood = false; + struct isis_extended_reach *er; + for (er = (struct isis_extended_reach *)nlsp->tlvs->extended_reach.head; + er; er = er->next) { + struct neighbor_entry *nn; + + nn = neighbor_entry_lookup_hash(f->neighbors_neighbors, + er->id); + + if (nn) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Found neighbor %s in NN, removing it from NN and setting reflood.", + vid2string(nn->vertex, buff, sizeof(buff))); + } + + nn->present = false; + need_reflood = true; + } + } + + if (need_reflood) + move_to_rf(lsp, n); + else + move_to_dnr(lsp, n); + } + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + zlog_debug("OpenFabric: Flooding algorithm complete."); + } +} + +void fabricd_trigger_csnp(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return; + + struct listnode *node; + struct isis_circuit *circuit; + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if (!circuit->t_send_csnp[1]) + continue; + + thread_cancel(circuit->t_send_csnp[ISIS_LEVEL2 - 1]); + thread_add_timer_msec(master, send_l2_csnp, circuit, + isis_jitter(500, CSNP_JITTER), + &circuit->t_send_csnp[ISIS_LEVEL2 - 1]); + } +} + +struct list *fabricd_ip_addrs(struct isis_circuit *circuit) +{ + if (circuit->ip_addrs && listcount(circuit->ip_addrs)) + return circuit->ip_addrs; + + if (!fabricd || !circuit->area || !circuit->area->circuit_list) + return NULL; + + struct listnode *node; + struct isis_circuit *c; + + for (ALL_LIST_ELEMENTS_RO(circuit->area->circuit_list, node, c)) { + if (c->circ_type != CIRCUIT_T_LOOPBACK) + continue; + + if (!c->ip_addrs || !listcount(c->ip_addrs)) + return NULL; + + return c->ip_addrs; + } + + return NULL; +} diff --git a/isisd/fabricd.conf.sample b/isisd/fabricd.conf.sample new file mode 100644 index 0000000000..be9e33ba62 --- /dev/null +++ b/isisd/fabricd.conf.sample @@ -0,0 +1,27 @@ +! -*- openfabric -*- +! +! fabricd sample configuration file +! +hostname fabricd +password foo +enable password foo +log stdout +!log file /tmp/fabricd.log +! +! +router openfabric DEAD + net 47.0023.0000.0003.0300.0100.0102.0304.0506.00 +! lsp-lifetime 65535 + +! hostname isisd-router +! domain-password foobar + +interface eth0 + ip router openfabric DEAD +! openfabric hello-interval 5 +! openfabric lsp-interval 1000 + +! -- optional +! openfabric retransmit-interval 10 +! openfabric retransmit-throttle-interval +! diff --git a/isisd/fabricd.h b/isisd/fabricd.h new file mode 100644 index 0000000000..76c182f2d2 --- /dev/null +++ b/isisd/fabricd.h @@ -0,0 +1,49 @@ +/* + * IS-IS Rout(e)ing protocol - OpenFabric extensions + * + * Copyright (C) 2018 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef FABRICD_H +#define FABRICD_H + +struct fabricd; + +struct isis_circuit; +struct isis_area; +struct isis_spftree; +struct isis_lsp; +struct vty; + +struct fabricd *fabricd_new(struct isis_area *area); +void fabricd_finish(struct fabricd *f); +void fabricd_initial_sync_hello(struct isis_circuit *circuit); +bool fabricd_initial_sync_is_complete(struct isis_area *area); +bool fabricd_initial_sync_is_in_progress(struct isis_area *area); +struct isis_circuit *fabricd_initial_sync_circuit(struct isis_area *area); +void fabricd_initial_sync_finish(struct isis_area *area); +void fabricd_run_spf(struct isis_area *area); +struct isis_spftree *fabricd_spftree(struct isis_area *area); +void fabricd_configure_tier(struct isis_area *area, uint8_t tier); +uint8_t fabricd_tier(struct isis_area *area); +int fabricd_write_settings(struct isis_area *area, struct vty *vty); +void fabricd_lsp_flood(struct isis_lsp *lsp); +void fabricd_trigger_csnp(struct isis_area *area); +struct list *fabricd_ip_addrs(struct isis_circuit *circuit); + +#endif diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 4b3d78421e..a41d6ff815 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -48,6 +48,7 @@ #include "isisd/isis_events.h" #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" +#include "isisd/fabricd.h" extern struct isis *isis; @@ -193,6 +194,9 @@ void isis_adj_process_threeway(struct isis_adjacency *adj, } } + if (next_tw_state != ISIS_THREEWAY_DOWN) + fabricd_initial_sync_hello(adj->circuit); + if (next_tw_state == ISIS_THREEWAY_DOWN) { isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Neighbor restarted"); return; @@ -264,7 +268,7 @@ void isis_adj_state_change(struct isis_adjacency *adj, circuit->upadjcount[level - 1]--; if (circuit->upadjcount[level - 1] == 0) - isis_circuit_lsp_queue_clean(circuit); + isis_tx_queue_clean(circuit->tx_queue); isis_event_adjacency_state_change(adj, new_state); @@ -306,16 +310,21 @@ void isis_adj_state_change(struct isis_adjacency *adj, adj->last_flap = time(NULL); adj->flaps++; - /* 7.3.17 - going up on P2P -> send CSNP */ - /* FIXME: yup, I know its wrong... but i will do - * it! (for now) */ - send_csnp(circuit, level); + if (level == IS_LEVEL_1) { + thread_add_timer(master, send_l1_csnp, + circuit, 0, + &circuit->t_send_csnp[0]); + } else { + thread_add_timer(master, send_l2_csnp, + circuit, 0, + &circuit->t_send_csnp[1]); + } } else if (new_state == ISIS_ADJ_DOWN) { if (adj->circuit->u.p2p.neighbor == adj) adj->circuit->u.p2p.neighbor = NULL; circuit->upadjcount[level - 1]--; if (circuit->upadjcount[level - 1] == 0) - isis_circuit_lsp_queue_clean(circuit); + isis_tx_queue_clean(circuit->tx_queue); isis_event_adjacency_state_change(adj, new_state); diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c index 7e8a4a4eda..28750278b0 100644 --- a/isisd/isis_bpf.c +++ b/isisd/isis_bpf.c @@ -213,7 +213,7 @@ int isis_sock_init(struct isis_circuit *circuit) int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa) { - int bytesread = 0, bytestoread, offset, one = 1, err = ISIS_OK; + int bytesread = 0, bytestoread, offset, one = 1; uint8_t *buff_ptr; struct bpf_hdr *bpf_hdr; @@ -249,7 +249,7 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa) memcpy(ssnpa, buff_ptr + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN, ETHER_ADDR_LEN); - err = isis_handle_pdu(circuit, ssnpa); + isis_handle_pdu(circuit, ssnpa); stream_reset(circuit->rcv_stream); buff_ptr += BPF_WORDALIGN(bpf_hdr->bh_hdrlen + bpf_hdr->bh_datalen); diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index cd4b76139f..b43a3915ae 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -45,7 +45,6 @@ #include "isisd/isis_flags.h" #include "isisd/isis_circuit.h" #include "isisd/isis_lsp.h" -#include "isisd/isis_lsp_hash.h" #include "isisd/isis_pdu.h" #include "isisd/isis_network.h" #include "isisd/isis_misc.h" @@ -58,6 +57,7 @@ #include "isisd/isis_te.h" #include "isisd/isis_mt.h" #include "isisd/isis_errors.h" +#include "isisd/isis_tx_queue.h" DEFINE_QOBJ_TYPE(isis_circuit) @@ -412,7 +412,7 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp) isis_circuit_if_bind(circuit, ifp); if (if_is_broadcast(ifp)) { - if (circuit->circ_type_config == CIRCUIT_T_P2P) + if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P) circuit->circ_type = CIRCUIT_T_P2P; else circuit->circ_type = CIRCUIT_T_BROADCAST; @@ -495,29 +495,29 @@ static void isis_circuit_update_all_srmflags(struct isis_circuit *circuit, { struct isis_area *area; struct isis_lsp *lsp; - dnode_t *dnode, *dnode_next; + dnode_t *dnode; int level; assert(circuit); area = circuit->area; assert(area); for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) { - if (level & circuit->is_type) { - if (area->lspdb[level - 1] - && dict_count(area->lspdb[level - 1]) > 0) { - for (dnode = dict_first(area->lspdb[level - 1]); - dnode != NULL; dnode = dnode_next) { - dnode_next = dict_next( - area->lspdb[level - 1], dnode); - lsp = dnode_get(dnode); - if (is_set) { - ISIS_SET_FLAG(lsp->SRMflags, - circuit); - } else { - ISIS_CLEAR_FLAG(lsp->SRMflags, - circuit); - } - } + if (!(level & circuit->is_type)) + continue; + + if (!area->lspdb[level - 1] + || !dict_count(area->lspdb[level - 1])) + continue; + + for (dnode = dict_first(area->lspdb[level - 1]); + dnode != NULL; + dnode = dict_next(area->lspdb[level - 1], dnode)) { + lsp = dnode_get(dnode); + if (is_set) { + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); + } else { + isis_tx_queue_del(circuit->tx_queue, lsp); } } } @@ -568,7 +568,7 @@ int isis_circuit_up(struct isis_circuit *circuit) 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); @@ -580,7 +580,7 @@ int isis_circuit_up(struct isis_circuit *circuit) 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; } @@ -672,10 +672,7 @@ int isis_circuit_up(struct isis_circuit *circuit) isis_circuit_prepare(circuit); - circuit->lsp_queue = list_new(); - circuit->lsp_hash = isis_lsp_hash_new(); - circuit->lsp_queue_last_push[0] = circuit->lsp_queue_last_push[1] = - monotime(NULL); + circuit->tx_queue = isis_tx_queue_new(circuit, send_lsp); return ISIS_OK; } @@ -743,13 +740,9 @@ void isis_circuit_down(struct isis_circuit *circuit) THREAD_OFF(circuit->t_send_lsp); THREAD_OFF(circuit->t_read); - if (circuit->lsp_queue) { - list_delete_and_null(&circuit->lsp_queue); - } - - if (circuit->lsp_hash) { - isis_lsp_hash_free(circuit->lsp_hash); - circuit->lsp_hash = NULL; + if (circuit->tx_queue) { + isis_tx_queue_free(circuit->tx_queue); + circuit->tx_queue = NULL; } /* send one gratuitous hello to spead up convergence */ @@ -904,16 +897,16 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, 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 @@ -921,8 +914,8 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, 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); } } @@ -957,33 +950,35 @@ int isis_interface_config_write(struct vty *vty) if (circuit == NULL) continue; if (circuit->ip_router) { - vty_out(vty, " ip router isis %s\n", + vty_out(vty, " ip router " PROTO_NAME " %s\n", area->area_tag); write++; } if (circuit->is_passive) { - vty_out(vty, " isis passive\n"); + vty_out(vty, " " PROTO_NAME " passive\n"); write++; } if (circuit->circ_type_config == CIRCUIT_T_P2P) { - vty_out(vty, " isis network point-to-point\n"); + vty_out(vty, " " PROTO_NAME " network point-to-point\n"); write++; } if (circuit->ipv6_router) { - vty_out(vty, " ipv6 router isis %s\n", + vty_out(vty, " ipv6 router " PROTO_NAME " %s\n", area->area_tag); write++; } /* ISIS - circuit type */ - if (circuit->is_type == IS_LEVEL_1) { - vty_out(vty, " isis circuit-type level-1\n"); - write++; - } else { - if (circuit->is_type == IS_LEVEL_2) { - vty_out(vty, - " isis circuit-type level-2-only\n"); + if (!fabricd) { + if (circuit->is_type == IS_LEVEL_1) { + vty_out(vty, " " PROTO_NAME " circuit-type level-1\n"); write++; + } else { + if (circuit->is_type == IS_LEVEL_2) { + vty_out(vty, + " " PROTO_NAME " circuit-type level-2-only\n"); + write++; + } } } @@ -992,7 +987,7 @@ int isis_interface_config_write(struct vty *vty) == circuit->csnp_interval[1]) { if (circuit->csnp_interval[0] != DEFAULT_CSNP_INTERVAL) { - vty_out(vty, " isis csnp-interval %d\n", + vty_out(vty, " " PROTO_NAME " csnp-interval %d\n", circuit->csnp_interval[0]); write++; } @@ -1001,7 +996,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->csnp_interval[i] != DEFAULT_CSNP_INTERVAL) { vty_out(vty, - " isis csnp-interval %d level-%d\n", + " " PROTO_NAME " csnp-interval %d level-%d\n", circuit->csnp_interval [i], i + 1); @@ -1015,7 +1010,7 @@ int isis_interface_config_write(struct vty *vty) == circuit->psnp_interval[1]) { if (circuit->psnp_interval[0] != DEFAULT_PSNP_INTERVAL) { - vty_out(vty, " isis psnp-interval %d\n", + vty_out(vty, " " PROTO_NAME " psnp-interval %d\n", circuit->psnp_interval[0]); write++; } @@ -1024,7 +1019,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->psnp_interval[i] != DEFAULT_PSNP_INTERVAL) { vty_out(vty, - " isis psnp-interval %d level-%d\n", + " " PROTO_NAME " psnp-interval %d level-%d\n", circuit->psnp_interval [i], i + 1); @@ -1036,7 +1031,7 @@ int isis_interface_config_write(struct vty *vty) /* ISIS - Hello padding - Defaults to true so only * display if false */ if (circuit->pad_hellos == 0) { - vty_out(vty, " no isis hello padding\n"); + vty_out(vty, " no " PROTO_NAME " hello padding\n"); write++; } @@ -1051,7 +1046,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_interval[0] != DEFAULT_HELLO_INTERVAL) { vty_out(vty, - " isis hello-interval %d\n", + " " PROTO_NAME " hello-interval %d\n", circuit->hello_interval[0]); write++; } @@ -1060,7 +1055,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_interval[i] != DEFAULT_HELLO_INTERVAL) { vty_out(vty, - " isis hello-interval %d level-%d\n", + " " PROTO_NAME " hello-interval %d level-%d\n", circuit->hello_interval [i], i + 1); @@ -1075,7 +1070,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_multiplier[0] != DEFAULT_HELLO_MULTIPLIER) { vty_out(vty, - " isis hello-multiplier %d\n", + " " PROTO_NAME " hello-multiplier %d\n", circuit->hello_multiplier[0]); write++; } @@ -1084,7 +1079,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_multiplier[i] != DEFAULT_HELLO_MULTIPLIER) { vty_out(vty, - " isis hello-multiplier %d level-%d\n", + " " PROTO_NAME " hello-multiplier %d level-%d\n", circuit->hello_multiplier [i], i + 1); @@ -1096,7 +1091,7 @@ int isis_interface_config_write(struct vty *vty) /* ISIS - Priority */ if (circuit->priority[0] == circuit->priority[1]) { if (circuit->priority[0] != DEFAULT_PRIORITY) { - vty_out(vty, " isis priority %d\n", + vty_out(vty, " " PROTO_NAME " priority %d\n", circuit->priority[0]); write++; } @@ -1105,7 +1100,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->priority[i] != DEFAULT_PRIORITY) { vty_out(vty, - " isis priority %d level-%d\n", + " " PROTO_NAME " priority %d level-%d\n", circuit->priority[i], i + 1); write++; @@ -1117,7 +1112,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->te_metric[0] == circuit->te_metric[1]) { if (circuit->te_metric[0] != DEFAULT_CIRCUIT_METRIC) { - vty_out(vty, " isis metric %d\n", + vty_out(vty, " " PROTO_NAME " metric %d\n", circuit->te_metric[0]); write++; } @@ -1126,7 +1121,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->te_metric[i] != DEFAULT_CIRCUIT_METRIC) { vty_out(vty, - " isis metric %d level-%d\n", + " " PROTO_NAME " metric %d level-%d\n", circuit->te_metric[i], i + 1); write++; @@ -1134,12 +1129,12 @@ int isis_interface_config_write(struct vty *vty) } } if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) { - vty_out(vty, " isis password md5 %s\n", + vty_out(vty, " " PROTO_NAME " password md5 %s\n", circuit->passwd.passwd); write++; } else if (circuit->passwd.type == ISIS_PASSWD_TYPE_CLEARTXT) { - vty_out(vty, " isis password clear %s\n", + vty_out(vty, " " PROTO_NAME " password clear %s\n", circuit->passwd.passwd); write++; } @@ -1343,60 +1338,4 @@ void isis_circuit_init() /* Install interface node */ install_node(&interface_node, isis_interface_config_write); if_cmd_init(); - - isis_vty_init(); -} - -void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit) -{ - if (circuit->t_send_lsp) - return; - circuit->t_send_lsp = - thread_add_event(master, send_lsp, circuit, 0, NULL); -} - -void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp) -{ - if (isis_lsp_hash_lookup(circuit->lsp_hash, lsp)) - return; - - listnode_add(circuit->lsp_queue, lsp); - isis_lsp_hash_add(circuit->lsp_hash, lsp); - isis_circuit_schedule_lsp_send(circuit); -} - -void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit) -{ - if (!circuit->lsp_queue) - return; - - list_delete_all_node(circuit->lsp_queue); - isis_lsp_hash_clean(circuit->lsp_hash); -} - -void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit, - struct isis_lsp *lsp) -{ - if (!circuit->lsp_queue) - return; - - listnode_delete(circuit->lsp_queue, lsp); - isis_lsp_hash_release(circuit->lsp_hash, lsp); -} - -struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit) -{ - if (!circuit->lsp_queue) - return NULL; - - struct listnode *node = listhead(circuit->lsp_queue); - if (!node) - return NULL; - - struct isis_lsp *rv = listgetdata(node); - - list_delete_node(circuit->lsp_queue, node); - isis_lsp_hash_release(circuit->lsp_hash, rv); - - return rv; } diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index 8dbd7ac492..ea68767fe0 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -80,14 +80,8 @@ struct isis_circuit { struct thread *t_send_csnp[2]; struct thread *t_send_psnp[2]; struct thread *t_send_lsp; - struct list *lsp_queue; /* LSPs to be txed (both levels) */ - struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */ - time_t lsp_queue_last_push[2]; /* timestamp used to enforce transmit - * interval; - * for scalability, use one timestamp per - * circuit, instead of one per lsp per - * circuit - */ + struct isis_tx_queue *tx_queue; + /* there is no real point in two streams, just for programming kicker */ int (*rx)(struct isis_circuit *circuit, uint8_t *ssnpa); struct stream *rcv_stream; /* Stream for receiving */ @@ -114,10 +108,10 @@ struct isis_circuit { struct isis_passwd passwd; /* Circuit rx/tx password */ int is_type; /* circuit is type == level of circuit * differentiated from circuit type (media) */ - uint32_t hello_interval[2]; /* l1HelloInterval in msecs */ - uint16_t hello_multiplier[2]; /* l1HelloMultiplier */ - uint16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */ - uint16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */ + uint32_t hello_interval[2]; /* hello-interval in seconds */ + uint16_t hello_multiplier[2]; /* hello-multiplier */ + uint16_t csnp_interval[2]; /* csnp-interval in seconds */ + uint16_t psnp_interval[2]; /* psnp-interval in seconds */ uint8_t metric[2]; uint32_t te_metric[2]; struct mpls_te_circuit @@ -196,10 +190,4 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit, int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, bool enabled); -void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit); -void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp); -void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit); -void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit, - struct isis_lsp *lsp); -struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit); #endif /* _ZEBRA_ISIS_CIRCUIT_H */ diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c index aae90b0080..e50f57ae1d 100644 --- a/isisd/isis_csm.c +++ b/isisd/isis_csm.c @@ -139,11 +139,11 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) 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) { diff --git a/isisd/isis_errors.c b/isisd/isis_errors.c index ecff65da1f..755e70dbf6 100644 --- a/isisd/isis_errors.c +++ b/isisd/isis_errors.c @@ -26,13 +26,13 @@ /* 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" diff --git a/isisd/isis_errors.h b/isisd/isis_errors.h index f738254a30..0732737607 100644 --- a/isisd/isis_errors.h +++ b/isisd/isis_errors.h @@ -24,8 +24,8 @@ #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); diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 52a0b9fac6..342787af30 100644 --- a/isisd/isis_events.c +++ b/isisd/isis_events.c @@ -158,7 +158,7 @@ void isis_circuit_is_type_set(struct isis_circuit *circuit, int newtype) 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)); diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 66c97ae897..b2c6f092ee 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -56,6 +56,8 @@ #include "isisd/isis_te.h" #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" +#include "isisd/fabricd.h" +#include "isisd/isis_tx_queue.h" static int lsp_l1_refresh(struct thread *thread); static int lsp_l2_refresh(struct thread *thread); @@ -117,10 +119,9 @@ static void lsp_destroy(struct isis_lsp *lsp) return; for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, circuit)) - isis_circuit_cancel_queued_lsp(circuit, lsp); + isis_tx_queue_del(circuit->tx_queue, lsp); ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags); - ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); lsp_clear_data(lsp); @@ -352,7 +353,21 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno) isis_spf_schedule(lsp->area, lsp->level); } -static void lsp_purge(struct isis_lsp *lsp, int level) +static void lsp_purge_add_poi(struct isis_lsp *lsp, + const uint8_t *sender) +{ + if (!lsp->area->purge_originator) + return; + + /* add purge originator identification */ + if (!lsp->tlvs) + lsp->tlvs = isis_alloc_tlvs(); + isis_tlvs_set_purge_originator(lsp->tlvs, isis->sysid, sender); + isis_tlvs_set_dynamic_hostname(lsp->tlvs, cmd_hostname_get()); +} + +static void lsp_purge(struct isis_lsp *lsp, int level, + const uint8_t *sender) { /* reset stream */ lsp_clear_data(lsp); @@ -364,8 +379,10 @@ static void lsp_purge(struct isis_lsp *lsp, int level) lsp->level = level; lsp->age_out = lsp->area->max_lsp_lifetime[level - 1]; + lsp_purge_add_poi(lsp, sender); + lsp_pack_pdu(lsp); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); } /* @@ -385,7 +402,7 @@ static void lsp_seqno_update(struct isis_lsp *lsp0) if (lsp->tlvs) lsp_inc_seqno(lsp, 0); else - lsp_purge(lsp, lsp0->level); + lsp_purge(lsp, lsp0->level, NULL); } return; @@ -425,7 +442,8 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, lsp->tlvs = tlvs; - if (area->dynhostname && lsp->tlvs->hostname) { + if (area->dynhostname && lsp->tlvs->hostname + && lsp->hdr.rem_lifetime) { isis_dynhn_insert(lsp->hdr.lsp_id, lsp->tlvs->hostname, (lsp->hdr.lsp_bits & LSPBIT_IST) == IS_LEVEL_1_AND_2 @@ -455,17 +473,17 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, { 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) { @@ -928,6 +946,14 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) lsp_debug("ISIS (%s): Adding circuit specific information.", area->area_tag); + if (fabricd) { + lsp_debug( + "ISIS (%s): Adding tier %" PRIu8 " spine-leaf-extension tlv.", + area->area_tag, fabricd_tier(area)); + isis_tlvs_add_spine_leaf(lsp->tlvs, fabricd_tier(area), true, + false, false, false); + } + struct isis_circuit *circuit; for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { if (!circuit->interface) @@ -1091,9 +1117,16 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) */ subtlv_len = 0; + uint32_t neighbor_metric; + if (fabricd_tier(area) == 0) { + neighbor_metric = 0xffe; + } else { + neighbor_metric = metric; + } + tlvs_add_mt_p2p(lsp->tlvs, circuit, - ne_id, metric, subtlvs, - subtlv_len); + ne_id, neighbor_metric, + subtlvs, subtlv_len); } } else { lsp_debug( @@ -1192,7 +1225,7 @@ int lsp_generate(struct isis_area *area, int level) /* time to calculate our checksum */ lsp_seqno_update(newlsp); newlsp->last_generated = time(NULL); - lsp_set_all_srmflags(newlsp); + lsp_flood(newlsp, NULL); refresh_time = lsp_refresh_time(newlsp, rem_lifetime); @@ -1223,7 +1256,7 @@ int lsp_generate(struct isis_area *area, int level) } /* - * Search own LSPs, update holding time and set SRM + * Search own LSPs, update holding time and flood */ static int lsp_regenerate(struct isis_area *area, int level) { @@ -1244,9 +1277,9 @@ 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; } @@ -1255,7 +1288,7 @@ static int lsp_regenerate(struct isis_area *area, int level) rem_lifetime = lsp_rem_lifetime(area, level); lsp->hdr.rem_lifetime = rem_lifetime; lsp->last_generated = time(NULL); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { frag->hdr.lsp_bits = lsp_bits_generate( level, area->overload_bit, area->attached_bit); @@ -1265,7 +1298,7 @@ static int lsp_regenerate(struct isis_area *area, int level) */ frag->hdr.rem_lifetime = rem_lifetime; frag->age_out = ZERO_AGE_LIFETIME; - lsp_set_all_srmflags(frag); + lsp_flood(frag, NULL); } lsp_seqno_update(lsp); @@ -1565,7 +1598,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level) lsp_pack_pdu(lsp); lsp->own_lsp = 1; lsp_insert(lsp, lspdb); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); refresh_time = lsp_refresh_time(lsp, rem_lifetime); THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); @@ -1613,9 +1646,9 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level) 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; } @@ -1624,7 +1657,7 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level) lsp_build_pseudo(lsp, circuit, level); lsp_inc_seqno(lsp, 0); lsp->last_generated = time(NULL); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); refresh_time = lsp_refresh_time(lsp, rem_lifetime); if (level == IS_LEVEL_1) @@ -1800,30 +1833,25 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level) /* * Walk through LSPs for an area * - set remaining lifetime - * - set LSPs with SRMflag set for sending */ int lsp_tick(struct thread *thread) { struct isis_area *area; - struct isis_circuit *circuit; struct isis_lsp *lsp; - struct list *lsp_list; - struct listnode *lspnode, *cnode; dnode_t *dnode, *dnode_next; int level; uint16_t rem_lifetime; - time_t now = monotime(NULL); - - lsp_list = list_new(); + bool fabricd_sync_incomplete = false; area = THREAD_ARG(thread); assert(area); area->t_tick = NULL; thread_add_timer(master, lsp_tick, area, 1, &area->t_tick); + struct isis_circuit *fabricd_init_c = fabricd_initial_sync_circuit(area); + /* - * Build a list of LSPs with (any) SRMflag set - * and removed the ones that have aged out + * Remove LSPs which have aged out */ for (level = 0; level < ISIS_LEVELS; level++) { if (area->lspdb[level] && dict_count(area->lspdb[level]) > 0) { @@ -1854,17 +1882,14 @@ int lsp_tick(struct thread *thread) */ if (rem_lifetime == 1 && lsp->hdr.seqno != 0) { /* 7.3.16.4 a) set SRM flags on all */ - lsp_set_all_srmflags(lsp); - /* 7.3.16.4 b) retain only the header - * FIXME */ + /* 7.3.16.4 b) retain only the header */ + if (lsp->area->purge_originator) + lsp_purge(lsp, lsp->level, NULL); + else + lsp_flood(lsp, NULL); /* 7.3.16.4 c) record the time to purge * FIXME */ - /* run/schedule spf */ - /* isis_spf_schedule is called inside - * lsp_destroy() below; - * so it is not needed here. */ - /* isis_spf_schedule (lsp->area, - * lsp->level); */ + isis_spf_schedule(lsp->area, lsp->level); } if (lsp->age_out == 0) { @@ -1878,44 +1903,22 @@ int lsp_tick(struct thread *thread) lsp = NULL; dict_delete_free(area->lspdb[level], dnode); - } else if (flags_any_set(lsp->SRMflags)) - listnode_add(lsp_list, lsp); - } - - /* - * Send LSPs on circuits indicated by the SRMflags - */ - if (listcount(lsp_list) > 0) { - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, - cnode, circuit)) { - if (!circuit->lsp_queue) - continue; - - if (now - circuit->lsp_queue_last_push[level] - < MIN_LSP_RETRANS_INTERVAL) { - continue; - } + } - circuit->lsp_queue_last_push[level] = now; - - for (ALL_LIST_ELEMENTS_RO( - lsp_list, lspnode, lsp)) { - if (circuit->upadjcount - [lsp->level - 1] - && ISIS_CHECK_FLAG( - lsp->SRMflags, - circuit)) { - isis_circuit_queue_lsp( - circuit, lsp); - } - } + if (fabricd_init_c && 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; } @@ -1928,7 +1931,7 @@ void lsp_purge_pseudo(uint8_t *id, struct isis_circuit *circuit, int level) if (!lsp) return; - lsp_purge(lsp, level); + lsp_purge(lsp, level, NULL); } /* @@ -1952,27 +1955,44 @@ void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr, memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr)); lsp->hdr.rem_lifetime = 0; + lsp_purge_add_poi(lsp, NULL); + lsp_pack_pdu(lsp); lsp_insert(lsp, area->lspdb[lsp->level - 1]); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); return; } -void lsp_set_all_srmflags(struct isis_lsp *lsp) +void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set) { struct listnode *node; struct isis_circuit *circuit; assert(lsp); - ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); + if (!lsp->area) + return; - if (lsp->area) { - struct list *circuit_list = lsp->area->circuit_list; - for (ALL_LIST_ELEMENTS_RO(circuit_list, node, circuit)) { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + struct list *circuit_list = lsp->area->circuit_list; + for (ALL_LIST_ELEMENTS_RO(circuit_list, node, circuit)) { + if (set) { + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); + } else { + isis_tx_queue_del(circuit->tx_queue, lsp); } } } + +void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit) +{ + if (!fabricd) { + lsp_set_all_srmflags(lsp, true); + if (circuit) + isis_tx_queue_del(circuit->tx_queue, lsp); + } else { + fabricd_lsp_flood(lsp); + } +} diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index d531cb1576..4e6379447c 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -37,7 +37,6 @@ struct isis_lsp { struct list *frags; struct isis_lsp *zero_lsp; } lspu; - uint32_t SRMflags[ISIS_MAX_CIRCUITS]; uint32_t SSNflags[ISIS_MAX_CIRCUITS]; int level; /* L1 or L2? */ int scheduled; /* scheduled for sending */ @@ -100,6 +99,7 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost); void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost); int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost); /* sets SRMflags for all active circuits of an lsp */ -void lsp_set_all_srmflags(struct isis_lsp *lsp); +void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set); +void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit); #endif /* ISIS_LSP */ diff --git a/isisd/isis_lsp_hash.c b/isisd/isis_lsp_hash.c deleted file mode 100644 index c521f42b3c..0000000000 --- a/isisd/isis_lsp_hash.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * IS-IS Rout(e)ing protocol - LSP Hash - * - * Copyright (C) 2017 Christian Franke - * - * This file is part of FreeRangeRouting (FRR) - * - * FRR is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * FRR is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include <zebra.h> - -#include "hash.h" -#include "jhash.h" - -#include "isisd/isis_memory.h" -#include "isisd/isis_flags.h" -#include "dict.h" -#include "isisd/isis_circuit.h" -#include "isisd/isis_lsp.h" -#include "isisd/isis_lsp_hash.h" - -DEFINE_MTYPE_STATIC(ISISD, LSP_HASH, "ISIS LSP Hash") - -struct isis_lsp_hash { - struct hash *h; -}; - -static unsigned lsp_hash_key(void *lp) -{ - struct isis_lsp *lsp = lp; - - return jhash(lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 2, 0x55aa5a5a); -} - -static int lsp_hash_cmp(const void *a, const void *b) -{ - const struct isis_lsp *la = a, *lb = b; - - return 0 == memcmp(la->hdr.lsp_id, lb->hdr.lsp_id, ISIS_SYS_ID_LEN + 2); -} - -struct isis_lsp_hash *isis_lsp_hash_new(void) -{ - struct isis_lsp_hash *rv = XCALLOC(MTYPE_LSP_HASH, sizeof(*rv)); - - rv->h = hash_create(lsp_hash_key, lsp_hash_cmp, NULL); - return rv; -} - -void isis_lsp_hash_clean(struct isis_lsp_hash *ih) -{ - hash_clean(ih->h, NULL); -} - -void isis_lsp_hash_free(struct isis_lsp_hash *ih) -{ - isis_lsp_hash_clean(ih); - hash_free(ih->h); -} - -struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih, - struct isis_lsp *lsp) -{ - return hash_lookup(ih->h, lsp); -} - -void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp) -{ - struct isis_lsp *inserted; - inserted = hash_get(ih->h, lsp, hash_alloc_intern); - assert(inserted == lsp); -} - -void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp) -{ - hash_release(ih->h, lsp); -} diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 3b4168adb9..4d6a6da5d6 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -54,11 +54,13 @@ #include "isisd/isis_zebra.h" #include "isisd/isis_te.h" #include "isisd/isis_errors.h" +#include "isisd/isis_vty_common.h" /* Default configuration file name */ #define ISISD_DEFAULT_CONFIG "isisd.conf" /* Default vty port */ #define ISISD_VTY_PORT 2608 +#define FABRICD_VTY_PORT 2618 /* isisd privileges */ zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND}; @@ -145,9 +147,15 @@ struct quagga_signal_t isisd_signals[] = { }, }; +#ifdef FABRICD +FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT, + + .proghelp = "Implementation of the OpenFabric routing protocol.", +#else FRR_DAEMON_INFO(isisd, ISIS, .vty_port = ISISD_VTY_PORT, .proghelp = "Implementation of the IS-IS routing protocol.", +#endif .copyright = "Copyright (c) 2001-2002 Sampo Saaristo," " Ofer Wald and Hannes Gredler", @@ -164,7 +172,11 @@ int main(int argc, char **argv, char **envp) { int opt; +#ifdef FABRICD + frr_preinit(&fabricd_di, argc, argv); +#else frr_preinit(&isisd_di, argc, argv); +#endif frr_opt_add("", longopts, ""); /* Command line argument treatment. */ @@ -196,6 +208,7 @@ int main(int argc, char **argv, char **envp) prefix_list_init(); isis_init(); isis_circuit_init(); + isis_vty_init(); isis_spf_cmds_init(); isis_redist_init(); isis_route_map_init(); diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index 2155bf584e..2dfccf9830 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -311,7 +311,7 @@ int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty) for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, setting)) { const char *name = isis_mtid2str(setting->mtid); if (name && !setting->enabled) { - vty_out(vty, " no isis topology %s\n", name); + vty_out(vty, " no " PROTO_NAME " topology %s\n", name); written++; } } diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 5c4e3a35bc..7843fb9b9d 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -56,6 +56,8 @@ #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" #include "isisd/isis_errors.h" +#include "isisd/fabricd.h" +#include "isisd/isis_tx_queue.h" static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit, int level) @@ -88,10 +90,10 @@ static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit, 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; } @@ -207,6 +209,12 @@ static int process_p2p_hello(struct iih_info *iih) thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, &adj->t_expire); + /* While fabricds initial sync is in progress, ignore hellos from other + * interfaces than the one we are performing the initial sync on. */ + if (fabricd_initial_sync_is_in_progress(iih->circuit->area) + && fabricd_initial_sync_circuit(iih->circuit->area) != iih->circuit) + return ISIS_OK; + /* 8.2.5.2 a) a match was detected */ if (isis_tlvs_area_addresses_match(iih->tlvs, iih->circuit->area->area_addrs)) { @@ -617,9 +625,9 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, } 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; } @@ -671,7 +679,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, goto out; } - iih.v4_usable = (circuit->ip_addrs && listcount(circuit->ip_addrs) + iih.v4_usable = (fabricd_ip_addrs(circuit) && iih.tlvs->ipv4_address.count); iih.v6_usable = (circuit->ipv6_link && listcount(circuit->ipv6_link) @@ -700,14 +708,37 @@ out: * Section 7.3.15.1 - Action on receipt of a link state PDU */ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit, - const uint8_t *ssnpa) + const uint8_t *ssnpa, uint8_t max_area_addrs) { - int level = (pdu_type == L1_LINK_STATE) ? ISIS_LEVEL1 : ISIS_LEVEL2; + int level; + bool circuit_scoped; + + if (pdu_type == FS_LINK_STATE) { + if (!fabricd) + return ISIS_ERROR; + if (max_area_addrs != L2_CIRCUIT_FLOODING_SCOPE) + return ISIS_ERROR; + level = ISIS_LEVEL2; + circuit_scoped = true; + + /* The stream is used verbatim for sending out new LSPDUs. + * So make sure we store it as an L2 LSPDU internally. + * (compare for the reverse in `send_lsp`) */ + stream_putc_at(circuit->rcv_stream, 4, L2_LINK_STATE); + stream_putc_at(circuit->rcv_stream, 7, 0); + } else { + if (pdu_type == L1_LINK_STATE) + level = ISIS_LEVEL1; + else + level = ISIS_LEVEL2; + circuit_scoped = false; + } if (isis->debugs & DEBUG_UPDATE_PACKETS) { zlog_debug( - "ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u", - circuit->area->area_tag, level, + "ISIS-Upd (%s): Rcvd %sL%d LSP on %s, cirType %s, cirID %u", + circuit->area->area_tag, + circuit_scoped ? "Circuit scoped " : "", level, circuit->interface->name, circuit_t2string(circuit->is_type), circuit->circuit_id); @@ -869,7 +900,8 @@ dontcheckadj: * but * wrong checksum, initiate a purge. */ if (lsp && (lsp->hdr.seqno == hdr.seqno) - && (lsp->hdr.checksum != hdr.checksum)) { + && (lsp->hdr.checksum != hdr.checksum) + && hdr.rem_lifetime) { zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08" PRIx32 " with confused checksum received.", circuit->area->area_tag, rawlspid_print(hdr.lsp_id), @@ -899,7 +931,8 @@ dontcheckadj: lsp_confusion); tlvs = NULL; /* ii */ - lsp_set_all_srmflags(lsp); + if (!circuit_scoped) + lsp_flood(lsp, NULL); /* v */ ISIS_FLAGS_CLEAR_ALL( lsp->SSNflags); /* FIXME: @@ -913,9 +946,10 @@ dontcheckadj: * Otherwise, don't reflood * through incoming circuit as usual */ if (!lsp_confusion) { - /* iii */ - ISIS_CLEAR_FLAG(lsp->SRMflags, - circuit); + isis_tx_queue_del( + circuit->tx_queue, + lsp); + /* iv */ if (circuit->circ_type != CIRCUIT_T_BROADCAST) @@ -926,7 +960,8 @@ dontcheckadj: } /* 7.3.16.4 b) 2) */ else if (comp == LSP_EQUAL) { /* i */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, + lsp); /* ii */ if (circuit->circ_type != CIRCUIT_T_BROADCAST) @@ -934,16 +969,19 @@ dontcheckadj: circuit); } /* 7.3.16.4 b) 3) */ else { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, + lsp, TX_LSP_NORMAL); ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); } } else if (lsp->hdr.rem_lifetime != 0) { /* our own LSP -> 7.3.16.4 c) */ if (comp == LSP_NEWER) { lsp_inc_seqno(lsp, hdr.seqno); - lsp_set_all_srmflags(lsp); + if (!circuit_scoped) + lsp_flood(lsp, NULL); } else { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, + lsp, TX_LSP_NORMAL); ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); } if (isis->debugs & DEBUG_UPDATE_PACKETS) @@ -985,7 +1023,7 @@ dontcheckadj: } /* If the received LSP is older or equal, * resend the LSP which will act as ACK */ - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); } else { /* 7.3.15.1 e) - This lsp originated on another system */ @@ -1006,7 +1044,7 @@ dontcheckadj: if (!lsp0) { zlog_debug( "Got lsp frag, while zero lsp not in database"); - return ISIS_OK; + goto out; } } /* i */ @@ -1023,10 +1061,8 @@ dontcheckadj: circuit->area, level, false); tlvs = NULL; } - /* ii */ - lsp_set_all_srmflags(lsp); - /* iii */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + if (!circuit_scoped) + lsp_flood(lsp, circuit); /* iv */ if (circuit->circ_type != CIRCUIT_T_BROADCAST) @@ -1035,7 +1071,7 @@ dontcheckadj: } /* 7.3.15.1 e) 2) LSP equal to the one in db */ else if (comp == LSP_EQUAL) { - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream, circuit->area, level, false); tlvs = NULL; @@ -1044,7 +1080,8 @@ dontcheckadj: } /* 7.3.15.1 e) 3) LSP older than the one in db */ else { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); } } @@ -1052,6 +1089,10 @@ dontcheckadj: retval = ISIS_OK; out: + if (circuit_scoped) { + fabricd_trigger_csnp(circuit->area); + } + isis_free_tlvs(tlvs); return retval; } @@ -1157,7 +1198,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, circuit->u.bc.adjdb[level - 1])) return ISIS_OK; /* Silently discard */ } else { - if (!circuit->u.p2p.neighbor) { + if (!fabricd && !circuit->u.p2p.neighbor) { zlog_warn("no p2p neighbor on circuit %s", circuit->interface->name); return ISIS_OK; /* Silently discard */ @@ -1206,6 +1247,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, } } + bool resync_needed = false; + /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */ for (struct isis_lsp_entry *entry = entry_head; entry; entry = entry->next) { @@ -1221,25 +1264,28 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, if (cmp == LSP_EQUAL) { /* if (circuit->circ_type != * CIRCUIT_T_BROADCAST) */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); } /* 7.3.15.2 b) 3) if it is older, clear SSN and set SRM */ else if (cmp == LSP_OLDER) { ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); } /* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM on p2p */ else { if (own_lsp) { lsp_inc_seqno(lsp, entry->seqno); - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); } else { ISIS_SET_FLAG(lsp->SSNflags, circuit); /* if (circuit->circ_type != * CIRCUIT_T_BROADCAST) */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); + resync_needed = true; } } } else { @@ -1265,14 +1311,15 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, 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; } } } @@ -1303,12 +1350,18 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, } /* on remaining LSPs we set SRM (neighbor knew not of) */ - for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) - ISIS_SET_FLAG(lsp->SRMflags, circuit); + for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) { + isis_tx_queue_add(circuit->tx_queue, lsp, TX_LSP_NORMAL); + resync_needed = true; + } + /* lets free it */ list_delete_and_null(&lsp_list); } + if (fabricd_initial_sync_is_complete(circuit->area) && resync_needed) + zlog_warn("OpenFabric: Needed to resync LSPDB using CSNP!\n"); + retval = ISIS_OK; out: isis_free_tlvs(tlvs); @@ -1327,6 +1380,7 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size) break; case L1_LINK_STATE: case L2_LINK_STATE: + case FS_LINK_STATE: *size = ISIS_LSP_HDR_LEN; break; case L1_COMPLETE_SEQ_NUM: @@ -1354,7 +1408,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) /* 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; } @@ -1369,14 +1423,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) 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; } @@ -1387,7 +1441,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) 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); @@ -1401,16 +1455,16 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) } 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; } @@ -1427,9 +1481,11 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) } /* either 3 or 0 */ - if (max_area_addrs != 0 && max_area_addrs != isis->max_area_addrs) { + if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr field */ + && max_area_addrs != 0 + && max_area_addrs != isis->max_area_addrs) { flog_err( - ISIS_ERR_PACKET, + 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); @@ -1440,11 +1496,18 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) case L1_LAN_HELLO: case L2_LAN_HELLO: case P2P_HELLO: + if (fabricd && pdu_type != P2P_HELLO) + return ISIS_ERROR; retval = process_hello(pdu_type, circuit, ssnpa); break; case L1_LINK_STATE: case L2_LINK_STATE: - retval = process_lsp(pdu_type, circuit, ssnpa); + case FS_LINK_STATE: + if (fabricd + && pdu_type != L2_LINK_STATE + && pdu_type != FS_LINK_STATE) + return ISIS_ERROR; + retval = process_lsp(pdu_type, circuit, ssnpa, max_area_addrs); break; case L1_COMPLETE_SEQ_NUM: case L2_COMPLETE_SEQ_NUM: @@ -1582,8 +1645,15 @@ int send_hello(struct isis_circuit *circuit, int level) && !circuit->disable_threeway_adj) { uint32_t ext_circuit_id = circuit->idx; if (circuit->u.p2p.neighbor) { + uint8_t threeway_state; + + if (fabricd_initial_sync_is_in_progress(circuit->area) + && fabricd_initial_sync_circuit(circuit->area) != circuit) + threeway_state = ISIS_THREEWAY_DOWN; + else + threeway_state = circuit->u.p2p.neighbor->threeway_state; isis_tlvs_add_threeway_adj(tlvs, - circuit->u.p2p.neighbor->threeway_state, + threeway_state, ext_circuit_id, circuit->u.p2p.neighbor->sysid, circuit->u.p2p.neighbor->ext_circuit_id); @@ -1618,8 +1688,12 @@ int send_hello(struct isis_circuit *circuit, int level) false, false); } - if (circuit->ip_router && circuit->ip_addrs) - isis_tlvs_add_ipv4_addresses(tlvs, circuit->ip_addrs); + if (circuit->ip_router) { + struct list *circuit_ip_addrs = fabricd_ip_addrs(circuit); + + if (circuit_ip_addrs) + isis_tlvs_add_ipv4_addresses(tlvs, circuit_ip_addrs); + } if (circuit->ipv6_router && circuit->ipv6_link) isis_tlvs_add_ipv6_addresses(tlvs, circuit->ipv6_link); @@ -1653,10 +1727,10 @@ int send_hello(struct isis_circuit *circuit, int level) 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; } @@ -1851,10 +1925,10 @@ int send_csnp(struct isis_circuit *circuit, int level) 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; } @@ -1889,8 +1963,9 @@ int send_l1_csnp(struct thread *thread) circuit->t_send_csnp[0] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST - && circuit->u.bc.is_dr[0]) { + if ((circuit->circ_type == CIRCUIT_T_BROADCAST + && circuit->u.bc.is_dr[0]) + || circuit->circ_type == CIRCUIT_T_P2P) { send_csnp(circuit, 1); } /* set next timer thread */ @@ -1911,8 +1986,9 @@ int send_l2_csnp(struct thread *thread) circuit->t_send_csnp[1] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST - && circuit->u.bc.is_dr[1]) { + if ((circuit->circ_type == CIRCUIT_T_BROADCAST + && circuit->u.bc.is_dr[1]) + || circuit->circ_type == CIRCUIT_T_P2P) { send_csnp(circuit, 2); } /* set next timer thread */ @@ -2016,10 +2092,10 @@ static int send_psnp(int level, struct isis_circuit *circuit) 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; } @@ -2086,25 +2162,12 @@ int send_l2_psnp(struct thread *thread) /* * ISO 10589 - 7.3.14.3 */ -int send_lsp(struct thread *thread) +void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type) { - struct isis_circuit *circuit; - struct isis_lsp *lsp; + struct isis_circuit *circuit = arg; int clear_srm = 1; int retval = ISIS_OK; - circuit = THREAD_ARG(thread); - assert(circuit); - circuit->t_send_lsp = NULL; - - lsp = isis_circuit_lsp_queue_pop(circuit); - if (!lsp) - return ISIS_OK; - - if (!list_isempty(circuit->lsp_queue)) { - isis_circuit_schedule_lsp_send(circuit); - } - if (circuit->state != C_STATE_UP || circuit->is_passive == 1) goto out; @@ -2125,7 +2188,7 @@ int send_lsp(struct thread *thread) * 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.", @@ -2144,6 +2207,11 @@ int send_lsp(struct thread *thread) /* copy our lsp to the send buffer */ stream_copy(circuit->snd_stream, lsp->pdu); + if (tx_type == TX_LSP_CIRCUIT_SCOPED) { + stream_putc_at(circuit->snd_stream, 4, FS_LINK_STATE); + stream_putc_at(circuit->snd_stream, 7, L2_CIRCUIT_FLOODING_SCOPE); + } + if (isis->debugs & DEBUG_UPDATE_PACKETS) { zlog_debug("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 @@ -2160,12 +2228,12 @@ int send_lsp(struct thread *thread) 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: @@ -2181,8 +2249,6 @@ out: * to clear * the fag. */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); } - - return retval; } diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h index c69bfedeae..3d2420eb03 100644 --- a/isisd/isis_pdu.h +++ b/isisd/isis_pdu.h @@ -24,6 +24,8 @@ #ifndef _ZEBRA_ISIS_PDU_H #define _ZEBRA_ISIS_PDU_H +#include "isisd/isis_tx_queue.h" + #ifdef __SUNPRO_C #pragma pack(1) #endif @@ -125,6 +127,8 @@ struct isis_p2p_hello_hdr { #define L1_LINK_STATE 18 #define L2_LINK_STATE 20 +#define FS_LINK_STATE 10 +#define L2_CIRCUIT_FLOODING_SCOPE 2 struct isis_lsp_hdr { uint16_t pdu_len; uint16_t rem_lifetime; @@ -212,7 +216,7 @@ int send_l1_csnp(struct thread *thread); int send_l2_csnp(struct thread *thread); int send_l1_psnp(struct thread *thread); int send_l2_psnp(struct thread *thread); -int send_lsp(struct thread *thread); +void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type); void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream); int send_hello(struct isis_circuit *circuit, int level); int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa); diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index cd3ca44379..6564149a43 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -171,8 +171,7 @@ static void isis_redist_update_ext_reach(struct isis_area *area, int level, 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; } @@ -377,7 +376,7 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis) * routes to Zebra and has nothing to do with * redistribution, * so skip it. */ - if (type == ZEBRA_ROUTE_ISIS) + if (type == PROTO_TYPE) continue; afi_t afi = afi_for_redist_protocol(protocol); @@ -441,7 +440,8 @@ static void isis_redist_set(struct isis_area *area, int level, int family, } isis_redist_update_ext_reach(area, level, redist, p, - (struct prefix_ipv6 *)src_p, info); + (const struct prefix_ipv6 *)src_p, + info); } } @@ -515,13 +515,19 @@ void isis_redist_area_finish(struct isis_area *area) DEFUN (isis_redistribute, isis_redistribute_cmd, - "redistribute <ipv4|ipv6> " FRR_REDIST_STR_ISISD " <level-1|level-2> [<metric (0-16777215)|route-map WORD>]", + "redistribute <ipv4|ipv6> " PROTO_REDIST_STR +#ifndef FABRICD + " <level-1|level-2>" +#endif + " [<metric (0-16777215)|route-map WORD>]", REDIST_STR "Redistribute IPv4 routes\n" "Redistribute IPv6 routes\n" - FRR_REDIST_HELP_STR_ISISD + PROTO_REDIST_HELP +#ifndef FABRICD "Redistribute into level-1\n" "Redistribute into level-2\n" +#endif "Metric for redistributed routes\n" "ISIS default metric\n" "Route map reference\n" @@ -530,7 +536,7 @@ DEFUN (isis_redistribute, int idx_afi = 1; int idx_protocol = 2; int idx_level = 3; - int idx_metric_rmap = 4; + int idx_metric_rmap = fabricd ? 3 : 4; VTY_DECLVAR_CONTEXT(isis_area, area); int family; int afi; @@ -551,7 +557,9 @@ DEFUN (isis_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - if (!strcmp("level-1", argv[idx_level]->arg)) + if (fabricd) + level = 2; + else if (!strcmp("level-1", argv[idx_level]->arg)) level = 1; else if (!strcmp("level-2", argv[idx_level]->arg)) level = 2; @@ -585,14 +593,20 @@ DEFUN (isis_redistribute, DEFUN (no_isis_redistribute, no_isis_redistribute_cmd, - "no redistribute <ipv4|ipv6> " FRR_REDIST_STR_ISISD " <level-1|level-2>", - NO_STR + "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR +#ifndef FABRICD + " <level-1|level-2>" +#endif + , NO_STR REDIST_STR "Redistribute IPv4 routes\n" "Redistribute IPv6 routes\n" - FRR_REDIST_HELP_STR_ISISD + PROTO_REDIST_HELP +#ifndef FABRICD "Redistribute into level-1\n" - "Redistribute into level-2\n") + "Redistribute into level-2\n" +#endif + ) { int idx_afi = 2; int idx_protocol = 3; @@ -615,7 +629,10 @@ DEFUN (no_isis_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + if (fabricd) + level = 2; + else + level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; isis_redist_unset(area, level, family, type); return 0; @@ -623,13 +640,19 @@ DEFUN (no_isis_redistribute, DEFUN (isis_default_originate, isis_default_originate_cmd, - "default-information originate <ipv4|ipv6> <level-1|level-2> [always] [<metric (0-16777215)|route-map WORD>]", + "default-information originate <ipv4|ipv6>" +#ifndef FABRICD + " <level-1|level-2>" +#endif + " [always] [<metric (0-16777215)|route-map WORD>]", "Control distribution of default information\n" "Distribute a default route\n" "Distribute default route for IPv4\n" "Distribute default route for IPv6\n" +#ifndef FABRICD "Distribute default route into level-1\n" "Distribute default route into level-2\n" +#endif "Always advertise default route\n" "Metric for default route\n" "ISIS default metric\n" @@ -638,8 +661,8 @@ DEFUN (isis_default_originate, { int idx_afi = 2; int idx_level = 3; - int idx_always = 4; - int idx_metric_rmap = 4; + int idx_always = fabricd ? 3 : 4; + int idx_metric_rmap = fabricd ? 3 : 4; VTY_DECLVAR_CONTEXT(isis_area, area); int family; int originate_type = DEFAULT_ORIGINATE; @@ -651,7 +674,10 @@ DEFUN (isis_default_originate, if (family < 0) return CMD_WARNING_CONFIG_FAILED; - level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + if (fabricd) + level = 2; + else + level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; if ((area->is_type & level) != level) { vty_out(vty, "Node is not a level-%d IS\n", level); @@ -685,14 +711,20 @@ DEFUN (isis_default_originate, DEFUN (no_isis_default_originate, no_isis_default_originate_cmd, - "no default-information originate <ipv4|ipv6> <level-1|level-2>", - NO_STR + "no default-information originate <ipv4|ipv6>" +#ifndef FABRICD + " <level-1|level-2>" +#endif + , NO_STR "Control distribution of default information\n" "Distribute a default route\n" "Distribute default route for IPv4\n" "Distribute default route for IPv6\n" +#ifndef FABRICD "Distribute default route into level-1\n" - "Distribute default route into level-2\n") + "Distribute default route into level-2\n" +#endif + ) { int idx_afi = 3; int idx_level = 4; @@ -704,7 +736,9 @@ DEFUN (no_isis_default_originate, if (family < 0) return CMD_WARNING_CONFIG_FAILED; - if (strmatch("level-1", argv[idx_level]->text)) + if (fabricd) + level = 2; + else if (strmatch("level-1", argv[idx_level]->text)) level = 1; else if (strmatch("level-2", argv[idx_level]->text)) level = 2; @@ -732,15 +766,17 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, return 0; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if (type == ZEBRA_ROUTE_ISIS) + if (type == PROTO_TYPE) continue; for (level = 1; level <= ISIS_LEVELS; level++) { redist = get_redist_settings(area, family, type, level); if (!redist->redist) continue; - vty_out(vty, " redistribute %s %s level-%d", family_str, - zebra_route_string(type), level); + vty_out(vty, " redistribute %s %s", family_str, + zebra_route_string(type)); + if (!fabricd) + vty_out(vty, " level-%d", level); if (redist->metric) vty_out(vty, " metric %u", redist->metric); if (redist->map_name) @@ -755,8 +791,10 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, get_redist_settings(area, family, DEFAULT_ROUTE, level); if (!redist->redist) continue; - vty_out(vty, " default-information originate %s level-%d", - family_str, level); + vty_out(vty, " default-information originate %s", + family_str); + if (!fabricd) + vty_out(vty, " level-%d", level); if (redist->redist == DEFAULT_ORIGINATE_ALWAYS) vty_out(vty, " always"); if (redist->metric) @@ -772,8 +810,8 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, void isis_redist_init(void) { - install_element(ISIS_NODE, &isis_redistribute_cmd); - install_element(ISIS_NODE, &no_isis_redistribute_cmd); - install_element(ISIS_NODE, &isis_default_originate_cmd); - install_element(ISIS_NODE, &no_isis_default_originate_cmd); + install_element(ROUTER_NODE, &isis_redistribute_cmd); + install_element(ROUTER_NODE, &no_isis_redistribute_cmd); + install_element(ROUTER_NODE, &isis_default_originate_cmd); + install_element(ROUTER_NODE, &no_isis_default_originate_cmd); } diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 341921146b..6a7528623c 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -31,14 +31,10 @@ #include "command.h" #include "memory.h" #include "prefix.h" -#include "hash.h" #include "if.h" #include "table.h" #include "spf_backoff.h" -#include "jhash.h" -#include "skiplist.h" #include "srcdest_table.h" -#include "lib_errors.h" #include "isis_constants.h" #include "isis_common.h" @@ -56,256 +52,11 @@ #include "isis_csm.h" #include "isis_mt.h" #include "isis_tlvs.h" +#include "fabricd.h" +#include "isis_spf_private.h" DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info"); -enum vertextype { - VTYPE_PSEUDO_IS = 1, - VTYPE_PSEUDO_TE_IS, - VTYPE_NONPSEUDO_IS, - VTYPE_NONPSEUDO_TE_IS, - VTYPE_ES, - VTYPE_IPREACH_INTERNAL, - VTYPE_IPREACH_EXTERNAL, - VTYPE_IPREACH_TE, - VTYPE_IP6REACH_INTERNAL, - VTYPE_IP6REACH_EXTERNAL -}; - -#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS) -#define VTYPE_ES(t) ((t) == VTYPE_ES) -#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL) - -struct prefix_pair { - struct prefix dest; - struct prefix_ipv6 src; -}; - -/* - * Triple <N, d(N), {Adj(N)}> - */ -union isis_N { - uint8_t id[ISIS_SYS_ID_LEN + 1]; - struct prefix_pair ip; -}; -struct isis_vertex { - enum vertextype type; - union isis_N N; - uint32_t d_N; /* d(N) Distance from this IS */ - uint16_t depth; /* The depth in the imaginary tree */ - struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */ - struct list *parents; /* list of parents for ECMP */ - uint64_t insert_counter; -}; - -/* Vertex Queue and associated functions */ - -struct isis_vertex_queue { - union { - struct skiplist *slist; - struct list *list; - } l; - struct hash *hash; - uint64_t insert_counter; -}; - -static unsigned isis_vertex_queue_hash_key(void *vp) -{ - struct isis_vertex *vertex = vp; - - if (VTYPE_IP(vertex->type)) { - uint32_t key; - - key = prefix_hash_key(&vertex->N.ip.dest); - key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key); - return key; - } - - return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a); -} - -static int isis_vertex_queue_hash_cmp(const void *a, const void *b) -{ - const struct isis_vertex *va = a, *vb = b; - - if (va->type != vb->type) - return 0; - - if (VTYPE_IP(va->type)) { - if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest)) - return 0; - - return prefix_cmp((struct prefix *)&va->N.ip.src, - (struct prefix *)&vb->N.ip.src) == 0; - } - - return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0; -} - -/* - * Compares vertizes for sorting in the TENT list. Returns true - * if candidate should be considered before current, false otherwise. - */ -static int isis_vertex_queue_tent_cmp(void *a, void *b) -{ - struct isis_vertex *va = a; - struct isis_vertex *vb = b; - - if (va->d_N < vb->d_N) - return -1; - - if (va->d_N > vb->d_N) - return 1; - - if (va->type < vb->type) - return -1; - - if (va->type > vb->type) - return 1; - - if (va->insert_counter < vb->insert_counter) - return -1; - - if (va->insert_counter > vb->insert_counter) - return 1; - - return 0; -} - -static struct skiplist *isis_vertex_queue_skiplist(void) -{ - return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL); -} - -static void isis_vertex_queue_init(struct isis_vertex_queue *queue, - const char *name, bool ordered) -{ - if (ordered) { - queue->insert_counter = 1; - queue->l.slist = isis_vertex_queue_skiplist(); - } else { - queue->insert_counter = 0; - queue->l.list = list_new(); - } - queue->hash = hash_create(isis_vertex_queue_hash_key, - isis_vertex_queue_hash_cmp, name); -} - -static void isis_vertex_del(struct isis_vertex *vertex); - -static void isis_vertex_queue_clear(struct isis_vertex_queue *queue) -{ - hash_clean(queue->hash, NULL); - - if (queue->insert_counter) { - struct isis_vertex *vertex; - while (0 == skiplist_first(queue->l.slist, NULL, - (void **)&vertex)) { - isis_vertex_del(vertex); - skiplist_delete_first(queue->l.slist); - } - queue->insert_counter = 1; - } else { - queue->l.list->del = (void (*)(void *))isis_vertex_del; - list_delete_all_node(queue->l.list); - queue->l.list->del = NULL; - } -} - -static void isis_vertex_queue_free(struct isis_vertex_queue *queue) -{ - isis_vertex_queue_clear(queue); - - hash_free(queue->hash); - queue->hash = NULL; - - if (queue->insert_counter) { - skiplist_free(queue->l.slist); - queue->l.slist = NULL; - } else - list_delete_and_null(&queue->l.list); -} - -static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue) -{ - return hashcount(queue->hash); -} - -static void isis_vertex_queue_append(struct isis_vertex_queue *queue, - struct isis_vertex *vertex) -{ - assert(!queue->insert_counter); - - listnode_add(queue->l.list, vertex); - - struct isis_vertex *inserted; - - inserted = hash_get(queue->hash, vertex, hash_alloc_intern); - assert(inserted == vertex); -} - -static void isis_vertex_queue_insert(struct isis_vertex_queue *queue, - struct isis_vertex *vertex) -{ - assert(queue->insert_counter); - vertex->insert_counter = queue->insert_counter++; - assert(queue->insert_counter != (uint64_t)-1); - - skiplist_insert(queue->l.slist, vertex, vertex); - - struct isis_vertex *inserted; - inserted = hash_get(queue->hash, vertex, hash_alloc_intern); - assert(inserted == vertex); -} - -static struct isis_vertex * -isis_vertex_queue_pop(struct isis_vertex_queue *queue) -{ - assert(queue->insert_counter); - - struct isis_vertex *rv; - - if (skiplist_first(queue->l.slist, NULL, (void **)&rv)) - return NULL; - - skiplist_delete_first(queue->l.slist); - hash_release(queue->hash, rv); - - return rv; -} - -static void isis_vertex_queue_delete(struct isis_vertex_queue *queue, - struct isis_vertex *vertex) -{ - assert(queue->insert_counter); - - skiplist_delete(queue->l.slist, vertex, vertex); - hash_release(queue->hash, vertex); -} - -#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \ - ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data) - - -/* End of vertex queue definitions */ - -struct isis_spftree { - struct isis_vertex_queue paths; /* the SPT */ - struct isis_vertex_queue tents; /* TENT */ - struct route_table *route_table; - struct isis_area *area; /* back pointer to area */ - unsigned int runcount; /* number of runs since uptime */ - time_t last_run_timestamp; /* last run timestamp as wall time for display */ - time_t last_run_monotime; /* last run as monotime for scheduling */ - time_t last_run_duration; /* last run duration in msec */ - - uint16_t mtid; - int family; - int level; - enum spf_tree_id tree_id; -}; - - /* * supports the given af ? */ @@ -411,8 +162,7 @@ static const char *vtype2string(enum vertextype vtype) return NULL; /* Not reached */ } -#define VID2STR_BUFFER SRCDEST2STR_BUFFER -static const char *vid2string(struct isis_vertex *vertex, char *buff, int size) +const char *vid2string(struct isis_vertex *vertex, char *buff, int size) { if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) { return print_sys_hostname(vertex->N.id); @@ -428,44 +178,26 @@ static const char *vid2string(struct isis_vertex *vertex, char *buff, int size) return "UNKNOWN"; } -static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n, - enum vertextype vtype) -{ - vertex->type = vtype; - - if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) { - memcpy(vertex->N.id, n->id, ISIS_SYS_ID_LEN + 1); - } else if (VTYPE_IP(vtype)) { - memcpy(&vertex->N.ip, &n->ip, sizeof(n->ip)); - } else { - flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type"); - } -} - -static struct isis_vertex *isis_vertex_new(union isis_N *n, +static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree, + void *id, enum vertextype vtype) { struct isis_vertex *vertex; vertex = XCALLOC(MTYPE_ISIS_VERTEX, sizeof(struct isis_vertex)); - isis_vertex_id_init(vertex, n, vtype); + isis_vertex_id_init(vertex, id, vtype); vertex->Adj_N = list_new(); vertex->parents = list_new(); - return vertex; -} - -static void isis_vertex_del(struct isis_vertex *vertex) -{ - list_delete_and_null(&vertex->Adj_N); - list_delete_and_null(&vertex->parents); - - memset(vertex, 0, sizeof(struct isis_vertex)); - XFREE(MTYPE_ISIS_VERTEX, vertex); + if (spftree->hopcount_metric) { + vertex->firsthops = hash_create(isis_vertex_queue_hash_key, + isis_vertex_queue_hash_cmp, + NULL); + } - return; + return vertex; } static void isis_vertex_adj_del(struct isis_vertex *vertex, @@ -563,6 +295,9 @@ void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj) adj); } } + + if (fabricd_spftree(area) != NULL) + isis_spftree_adj_del(fabricd_spftree(area), adj); } /* @@ -595,17 +330,13 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree, #ifdef EXTREME_DEBUG char buff[VID2STR_BUFFER]; #endif /* EXTREME_DEBUG */ - union isis_N n; - - memcpy(n.id, sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID(n.id) = 0; lsp = isis_root_system_lsp(spftree->area, spftree->level, sysid); if (lsp == NULL) zlog_warn("ISIS-Spf: could not find own l%d LSP!", spftree->level); - vertex = isis_vertex_new(&n, + vertex = isis_vertex_new(spftree, sysid, spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS : VTYPE_NONPSEUDO_TE_IS); @@ -621,14 +352,24 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree, return vertex; } -static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue, - union isis_N *n, - enum vertextype vtype) +static void vertex_add_parent_firsthop(struct hash_backet *backet, void *arg) { - struct isis_vertex querier; + struct isis_vertex *vertex = arg; + struct isis_vertex *hop = backet->data; - isis_vertex_id_init(&querier, n, vtype); - return hash_lookup(queue->hash, &querier); + hash_get(vertex->firsthops, hop, hash_alloc_intern); +} + +static void vertex_update_firsthops(struct isis_vertex *vertex, + struct isis_vertex *parent) +{ + if (vertex->d_N <= 2) + hash_get(vertex->firsthops, vertex, hash_alloc_intern); + + if (vertex->d_N < 2 || !parent) + return; + + hash_iterate(parent->firsthops, vertex_add_parent_firsthop, vertex); } /* @@ -649,7 +390,7 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, assert(isis_find_vertex(&spftree->paths, id, vtype) == NULL); assert(isis_find_vertex(&spftree->tents, id, vtype) == NULL); - vertex = isis_vertex_new(id, vtype); + vertex = isis_vertex_new(spftree, id, vtype); vertex->d_N = cost; vertex->depth = depth; @@ -657,6 +398,9 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, listnode_add(vertex->parents, parent); } + if (spftree->hopcount_metric) + vertex_update_firsthops(vertex, parent); + if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) { for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_adj)) listnode_add(vertex->Adj_N, parent_adj); @@ -722,6 +466,10 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, assert(spftree && parent); + if (spftree->hopcount_metric + && !VTYPE_IS(vtype)) + return; + struct prefix_pair p; if (vtype >= VTYPE_IPREACH_INTERNAL) { memcpy(&p, id, sizeof(p)); @@ -774,6 +522,8 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, if (listnode_lookup(vertex->Adj_N, parent_adj) == NULL) listnode_add(vertex->Adj_N, parent_adj); + if (spftree->hopcount_metric) + vertex_update_firsthops(vertex, parent); /* 2) */ if (listcount(vertex->Adj_N) > ISIS_MAX_PATH_SPLITS) remove_excess_adjs(vertex->Adj_N); @@ -853,6 +603,9 @@ lspfragloop: for (r = (struct isis_oldstyle_reach *) lsp->tlvs->oldstyle_reach.head; r; r = r->next) { + if (fabricd) + continue; + /* C.2.6 a) */ /* Two way connectivity */ if (!memcmp(r->id, root_sysid, ISIS_SYS_ID_LEN)) @@ -889,7 +642,7 @@ lspfragloop: if (!pseudo_lsp && !memcmp(er->id, null_sysid, ISIS_SYS_ID_LEN)) continue; - dist = cost + er->metric; + dist = cost + (spftree->hopcount_metric ? 1 : er->metric); process_N(spftree, LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS : VTYPE_NONPSEUDO_TE_IS, @@ -897,7 +650,7 @@ lspfragloop: } } - if (!pseudo_lsp && spftree->family == AF_INET + if (!fabricd && !pseudo_lsp && spftree->family == AF_INET && spftree->mtid == ISIS_MT_IPV4_UNICAST) { struct isis_item_list *reachs[] = { &lsp->tlvs->oldstyle_ip_reach, @@ -1037,7 +790,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, /* * Add IP(v6) addresses of this circuit */ - if (spftree->family == AF_INET) { + if (spftree->family == AF_INET && !spftree->hopcount_metric) { memset(&ip_info, 0, sizeof(ip_info)); ip_info.dest.family = AF_INET; for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, ipnode, @@ -1050,7 +803,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, &ip_info, NULL, 0, parent); } } - if (spftree->family == AF_INET6) { + if (spftree->family == AF_INET6 && !spftree->hopcount_metric) { memset(&ip_info, 0, sizeof(ip_info)); ip_info.dest.family = AF_INET6; for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, @@ -1094,6 +847,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, LSP_PSEUDO_ID(lsp_id) = 0; isis_spf_add_local( spftree, VTYPE_ES, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric [spftree->level - 1], parent); @@ -1111,6 +865,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, ? VTYPE_NONPSEUDO_IS : VTYPE_NONPSEUDO_TE_IS, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric [spftree->level - 1], parent); @@ -1180,10 +935,10 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, circuit->circuit_id); continue; } - isis_spf_process_lsp( - spftree, lsp, - circuit->te_metric[spftree->level - 1], 0, - root_sysid, parent); + isis_spf_process_lsp(spftree, lsp, + spftree->hopcount_metric ? + 1 : circuit->te_metric[spftree->level - 1], + 0, root_sysid, parent); } else if (circuit->circ_type == CIRCUIT_T_P2P) { adj = circuit->u.p2p.neighbor; if (!adj || adj->adj_state != ISIS_ADJ_UP) @@ -1196,6 +951,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, LSP_PSEUDO_ID(lsp_id) = 0; isis_spf_add_local( spftree, VTYPE_ES, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric[spftree->level - 1], parent); break; @@ -1215,6 +971,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, ? VTYPE_NONPSEUDO_IS : VTYPE_NONPSEUDO_TE_IS, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric [spftree->level - 1], parent); @@ -1275,7 +1032,8 @@ static void add_to_paths(struct isis_spftree *spftree, } static void init_spt(struct isis_spftree *spftree, int mtid, int level, - int family, enum spf_tree_id tree_id) + int family, enum spf_tree_id tree_id, + bool hopcount_metric) { isis_vertex_queue_clear(&spftree->tents); isis_vertex_queue_clear(&spftree->paths); @@ -1284,7 +1042,63 @@ static void init_spt(struct isis_spftree *spftree, int mtid, int level, spftree->level = level; spftree->family = family; spftree->tree_id = tree_id; - return; + spftree->hopcount_metric = hopcount_metric; +} + +static void isis_spf_loop(struct isis_spftree *spftree, + uint8_t *root_sysid) +{ + struct isis_vertex *vertex; + struct isis_lsp *lsp; + + while (isis_vertex_queue_count(&spftree->tents)) { + vertex = isis_vertex_queue_pop(&spftree->tents); + +#ifdef EXTREME_DEBUG + zlog_debug( + "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS", + print_sys_hostname(vertex->N.id), + vtype2string(vertex->type), vertex->depth, vertex->d_N); +#endif /* EXTREME_DEBUG */ + + add_to_paths(spftree, vertex); + if (!VTYPE_IS(vertex->type)) + continue; + + lsp = lsp_for_vertex(spftree, vertex); + if (!lsp) { + zlog_warn("ISIS-Spf: No LSP found for %s", + rawlspid_print(vertex->N.id)); /* FIXME */ + continue; + } + + isis_spf_process_lsp(spftree, lsp, vertex->d_N, vertex->depth, + root_sysid, vertex); + } +} + +struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area, + uint8_t *sysid, + struct isis_spftree *spftree) +{ + if (!spftree) + spftree = isis_spftree_new(area); + + init_spt(spftree, ISIS_MT_IPV4_UNICAST, ISIS_LEVEL2, + AF_INET, SPFTREE_IPV4, true); + if (!memcmp(sysid, isis->sysid, ISIS_SYS_ID_LEN)) { + /* If we are running locally, initialize with information from adjacencies */ + struct isis_vertex *root = isis_spf_add_root(spftree, sysid); + isis_spf_preload_tent(spftree, sysid, root); + } else { + isis_vertex_queue_insert(&spftree->tents, isis_vertex_new( + spftree, sysid, + VTYPE_NONPSEUDO_TE_IS)); + } + + isis_spf_loop(spftree, sysid); + + return spftree; } static int isis_run_spf(struct isis_area *area, int level, @@ -1292,11 +1106,8 @@ static int isis_run_spf(struct isis_area *area, int level, uint8_t *sysid, struct timeval *nowtv) { int retval = ISIS_OK; - struct isis_vertex *vertex; struct isis_vertex *root_vertex; struct isis_spftree *spftree = area->spftree[tree_id][level - 1]; - uint8_t lsp_id[ISIS_SYS_ID_LEN + 2]; - struct isis_lsp *lsp; struct timeval time_now; unsigned long long start_time, end_time; uint16_t mtid = 0; @@ -1330,7 +1141,7 @@ static int isis_run_spf(struct isis_area *area, int level, /* * C.2.5 Step 0 */ - init_spt(spftree, mtid, level, family, tree_id); + init_spt(spftree, mtid, level, family, tree_id, false); /* a) */ root_vertex = isis_spf_add_root(spftree, sysid); /* b) */ @@ -1350,32 +1161,7 @@ static int isis_run_spf(struct isis_area *area, int level, print_sys_hostname(sysid)); } - while (isis_vertex_queue_count(&spftree->tents)) { - vertex = isis_vertex_queue_pop(&spftree->tents); - -#ifdef EXTREME_DEBUG - zlog_debug( - "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS", - print_sys_hostname(vertex->N.id), - vtype2string(vertex->type), vertex->depth, vertex->d_N); -#endif /* EXTREME_DEBUG */ - - add_to_paths(spftree, vertex); - if (VTYPE_IS(vertex->type)) { - memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1); - LSP_FRAGMENT(lsp_id) = 0; - lsp = lsp_search(lsp_id, area->lspdb[level - 1]); - if (lsp && lsp->hdr.rem_lifetime != 0) { - isis_spf_process_lsp(spftree, lsp, vertex->d_N, - vertex->depth, sysid, - vertex); - } else { - zlog_warn("ISIS-Spf: No LSP found for %s", - rawlspid_print(lsp_id)); - } - } - } - + isis_spf_loop(spftree, sysid); out: spftree->runcount++; spftree->last_run_timestamp = time(NULL); @@ -1446,6 +1232,8 @@ static int isis_run_spf_cb(struct thread *thread) for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); + fabricd_run_spf(area); + return retval; } @@ -1617,12 +1405,18 @@ static void isis_print_spftree(struct vty *vty, int level, DEFUN (show_isis_topology, show_isis_topology_cmd, - "show isis topology [<level-1|level-2>]", - SHOW_STR - "IS-IS information\n" + "show " PROTO_NAME " topology" +#ifndef FABRICD + " [<level-1|level-2>]" +#endif + , SHOW_STR + PROTO_HELP "IS-IS paths to Intermediate Systems\n" +#ifndef FABRICD "Paths to all level-1 routers in the area\n" - "Paths to all level-2 routers in the domain\n") + "Paths to all level-2 routers in the domain\n" +#endif + ) { int levels; struct listnode *node; @@ -1660,6 +1454,13 @@ DEFUN (show_isis_topology, } } + if (fabricd_spftree(area)) { + vty_out(vty, + "IS-IS paths to level-2 routers with hop-by-hop metric\n"); + isis_print_paths(vty, &fabricd_spftree(area)->paths, isis->sysid); + vty_out(vty, "\n"); + } + vty_out(vty, "\n"); } diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h index 9a73ca8783..f4db98cfed 100644 --- a/isisd/isis_spf.h +++ b/isisd/isis_spf.h @@ -37,4 +37,7 @@ void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj); int isis_spf_schedule(struct isis_area *area, int level); void isis_spf_cmds_init(void); void isis_spf_print(struct isis_spftree *spftree, struct vty *vty); +struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area, + uint8_t *sysid, + struct isis_spftree *spftree); #endif /* _ZEBRA_ISIS_SPF_H */ diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h new file mode 100644 index 0000000000..453abfedd8 --- /dev/null +++ b/isisd/isis_spf_private.h @@ -0,0 +1,362 @@ +/* + * IS-IS Rout(e)ing protocol - isis_spf_private.h + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2017 Christian Franke <chris@opensourcerouting.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef ISIS_SPF_PRIVATE_H +#define ISIS_SPF_PRIVATE_H + +#include "hash.h" +#include "jhash.h" +#include "skiplist.h" +#include "lib_errors.h" + +enum vertextype { + VTYPE_PSEUDO_IS = 1, + VTYPE_PSEUDO_TE_IS, + VTYPE_NONPSEUDO_IS, + VTYPE_NONPSEUDO_TE_IS, + VTYPE_ES, + VTYPE_IPREACH_INTERNAL, + VTYPE_IPREACH_EXTERNAL, + VTYPE_IPREACH_TE, + VTYPE_IP6REACH_INTERNAL, + VTYPE_IP6REACH_EXTERNAL +}; + +#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS) +#define VTYPE_ES(t) ((t) == VTYPE_ES) +#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL) + +struct prefix_pair { + struct prefix dest; + struct prefix_ipv6 src; +}; + +/* + * Triple <N, d(N), {Adj(N)}> + */ +struct isis_vertex { + enum vertextype type; + union { + uint8_t id[ISIS_SYS_ID_LEN + 1]; + struct prefix_pair ip; + } N; + uint32_t d_N; /* d(N) Distance from this IS */ + uint16_t depth; /* The depth in the imaginary tree */ + struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */ + struct list *parents; /* list of parents for ECMP */ + struct hash *firsthops; /* first two hops to neighbor */ + uint64_t insert_counter; +}; + +/* Vertex Queue and associated functions */ + +struct isis_vertex_queue { + union { + struct skiplist *slist; + struct list *list; + } l; + struct hash *hash; + uint64_t insert_counter; +}; + +__attribute__((__unused__)) +static unsigned isis_vertex_queue_hash_key(void *vp) +{ + struct isis_vertex *vertex = vp; + + if (VTYPE_IP(vertex->type)) { + uint32_t key; + + key = prefix_hash_key(&vertex->N.ip.dest); + key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key); + return key; + } + + return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a); +} + +__attribute__((__unused__)) +static int isis_vertex_queue_hash_cmp(const void *a, const void *b) +{ + const struct isis_vertex *va = a, *vb = b; + + if (va->type != vb->type) + return 0; + + if (VTYPE_IP(va->type)) { + if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest)) + return 0; + + return prefix_cmp((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 diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 44ba64ce26..08b905c650 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -67,17 +67,6 @@ const char *mode2text[] = {"Disable", "Area", "AS", "Emulate"}; * Followings are control functions for MPLS-TE parameters management. *------------------------------------------------------------------------*/ -/* Search MPLS TE Circuit context from Interface */ -static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp) -{ - struct isis_circuit *circuit; - - if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) - return NULL; - - return circuit->mtc; -} - /* Create new MPLS TE Circuit context */ struct mpls_te_circuit *mpls_te_circuit_new() { @@ -1085,6 +1074,18 @@ void isis_mpls_te_config_write_router(struct vty *vty) /*------------------------------------------------------------------------* * Followings are vty command functions. *------------------------------------------------------------------------*/ +#ifndef FABRICD + +/* Search MPLS TE Circuit context from Interface */ +static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp) +{ + struct isis_circuit *circuit; + + if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) + return NULL; + + return circuit->mtc; +} DEFUN (isis_mpls_te_on, isis_mpls_te_on_cmd, @@ -1223,9 +1224,9 @@ DEFUN (no_isis_mpls_te_inter_as, DEFUN (show_isis_mpls_te_router, show_isis_mpls_te_router_cmd, - "show isis mpls-te router", + "show " PROTO_NAME " mpls-te router", SHOW_STR - ISIS_STR + PROTO_HELP MPLS_TE_STR "Router information\n") { @@ -1314,9 +1315,9 @@ static void show_mpls_te_sub(struct vty *vty, struct interface *ifp) DEFUN (show_isis_mpls_te_interface, show_isis_mpls_te_interface_cmd, - "show isis mpls-te interface [INTERFACE]", + "show " PROTO_NAME " mpls-te interface [INTERFACE]", SHOW_STR - ISIS_STR + PROTO_HELP MPLS_TE_STR "Interface information\n" "Interface name\n") @@ -1342,6 +1343,7 @@ DEFUN (show_isis_mpls_te_interface, return CMD_SUCCESS; } +#endif /* Initialize MPLS_TE */ void isis_mpls_te_init(void) @@ -1357,15 +1359,17 @@ void isis_mpls_te_init(void) isisMplsTE.cir_list = list_new(); isisMplsTE.router_id.s_addr = 0; +#ifndef FABRICD /* Register new VTY commands */ install_element(VIEW_NODE, &show_isis_mpls_te_router_cmd); install_element(VIEW_NODE, &show_isis_mpls_te_interface_cmd); - install_element(ISIS_NODE, &isis_mpls_te_on_cmd); - install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd); - install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd); - install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd); - install_element(ISIS_NODE, &no_isis_mpls_te_inter_as_cmd); + install_element(ROUTER_NODE, &isis_mpls_te_on_cmd); + install_element(ROUTER_NODE, &no_isis_mpls_te_on_cmd); + install_element(ROUTER_NODE, &isis_mpls_te_router_addr_cmd); + install_element(ROUTER_NODE, &isis_mpls_te_inter_as_cmd); + install_element(ROUTER_NODE, &no_isis_mpls_te_inter_as_cmd); +#endif return; } diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index a433fcdb41..782462766a 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -107,6 +107,111 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX]; /* Prototypes */ static void append_item(struct isis_item_list *dest, struct isis_item *item); +/* Functions for Sub-TLV 3 SR Prefix-SID */ + +static struct isis_item *copy_item_prefix_sid(struct isis_item *i) +{ + struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i; + struct isis_prefix_sid *rv = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*rv)); + + rv->flags = sid->flags; + rv->algorithm = sid->algorithm; + rv->value = sid->value; + return (struct isis_item *)rv; +} + +static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i, + struct sbuf *buf, int indent) +{ + struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i; + + sbuf_push(buf, indent, "SR Prefix-SID:\n"); + sbuf_push(buf, indent, " Flags:%s%s%s%s%s%s\n", + sid->flags & ISIS_PREFIX_SID_READVERTISED ? " READVERTISED" : "", + sid->flags & ISIS_PREFIX_SID_NODE ? " NODE" : "", + sid->flags & ISIS_PREFIX_SID_NO_PHP ? " NO_PHP" : "", + sid->flags & ISIS_PREFIX_SID_EXPLICIT_NULL ? " EXPLICIT-NULL" : "", + sid->flags & ISIS_PREFIX_SID_VALUE ? " VALUE" : "", + sid->flags & ISIS_PREFIX_SID_LOCAL ? " LOCAL" : ""); + sbuf_push(buf, indent, " Algorithm: %" PRIu8 "\n", sid->algorithm); + if (sid->flags & ISIS_PREFIX_SID_VALUE) { + sbuf_push(buf, indent, "Label: %" PRIu32 "\n", sid->value); + } else { + sbuf_push(buf, indent, "Index: %" PRIu32 "\n", sid->value); + } +} + +static void free_item_prefix_sid(struct isis_item *i) +{ + XFREE(MTYPE_ISIS_SUBTLV, i); +} + +static int pack_item_prefix_sid(struct isis_item *i, struct stream *s) +{ + struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i; + + uint8_t size = (sid->flags & ISIS_PREFIX_SID_VALUE) ? 5 : 6; + + if (STREAM_WRITEABLE(s) < size) + return 1; + + stream_putc(s, sid->flags); + stream_putc(s, sid->algorithm); + + if (sid->flags & ISIS_PREFIX_SID_VALUE) { + stream_put3(s, sid->value); + } else { + stream_putl(s, sid->value); + } + + return 0; +} + +static int unpack_item_prefix_sid(uint16_t mtid, uint8_t len, struct stream *s, + struct sbuf *log, void *dest, int indent) +{ + struct isis_subtlvs *subtlvs = dest; + struct isis_prefix_sid sid = { + }; + + sbuf_push(log, indent, "Unpacking SR Prefix-SID...\n"); + + if (len < 5) { + sbuf_push(log, indent, + "Not enough data left. (expected 5 or more bytes, got %" PRIu8 ")\n", + len); + return 1; + } + + sid.flags = stream_getc(s); + if ((sid.flags & ISIS_PREFIX_SID_VALUE) + != (sid.flags & ISIS_PREFIX_SID_LOCAL)) { + sbuf_push(log, indent, "Flags inplausible: Local Flag needs to match Value Flag\n"); + return 0; + } + + sid.algorithm = stream_getc(s); + + uint8_t expected_size = (sid.flags & ISIS_PREFIX_SID_VALUE) ? 5 : 6; + if (len != expected_size) { + sbuf_push(log, indent, + "TLV size differs from expected size. " + "(expected %u but got %" PRIu8 ")\n", + expected_size, len); + return 1; + } + + if (sid.flags & ISIS_PREFIX_SID_VALUE) { + sid.value = stream_get3(s); + } else { + sid.value = stream_getl(s); + } + + format_item_prefix_sid(mtid, (struct isis_item *)&sid, log, indent + 2); + append_item(&subtlvs->prefix_sids, copy_item_prefix_sid((struct isis_item *)&sid)); + return 0; +} + /* Functions for Sub-TVL ??? IPv6 Source Prefix */ static struct prefix_ipv6 *copy_subtlv_ipv6_source_prefix(struct prefix_ipv6 *p) @@ -198,14 +303,36 @@ static int unpack_subtlv_ipv6_source_prefix(enum isis_tlv_context context, memcpy(subtlvs->source_prefix, &p, sizeof(p)); return 0; } +static void init_item_list(struct isis_item_list *items); +static struct isis_item *copy_item(enum isis_tlv_context context, + enum isis_tlv_type type, + struct isis_item *item); +static void copy_items(enum isis_tlv_context context, enum isis_tlv_type type, + struct isis_item_list *src, struct isis_item_list *dest); +static void format_items_(uint16_t mtid, enum isis_tlv_context context, + enum isis_tlv_type type, struct isis_item_list *items, + struct sbuf *buf, int indent); +#define format_items(...) format_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__) +static void free_items(enum isis_tlv_context context, enum isis_tlv_type type, + struct isis_item_list *items); +static int pack_items_(uint16_t mtid, enum isis_tlv_context context, + enum isis_tlv_type type, struct isis_item_list *items, + struct stream *s, struct isis_tlvs **fragment_tlvs, + struct pack_order_entry *pe, + struct isis_tlvs *(*new_fragment)(struct list *l), + struct list *new_fragment_arg); +#define pack_items(...) pack_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__) /* Functions related to subtlvs */ -static struct isis_subtlvs *isis_alloc_subtlvs(void) +static struct isis_subtlvs *isis_alloc_subtlvs(enum isis_tlv_context context) { struct isis_subtlvs *result; result = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*result)); + result->context = context; + + init_item_list(&result->prefix_sids); return result; } @@ -217,6 +344,11 @@ static struct isis_subtlvs *copy_subtlvs(struct isis_subtlvs *subtlvs) struct isis_subtlvs *rv = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*rv)); + rv->context = subtlvs->context; + + copy_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids, &rv->prefix_sids); + rv->source_prefix = copy_subtlv_ipv6_source_prefix(subtlvs->source_prefix); return rv; @@ -225,6 +357,9 @@ static struct isis_subtlvs *copy_subtlvs(struct isis_subtlvs *subtlvs) static void format_subtlvs(struct isis_subtlvs *subtlvs, struct sbuf *buf, int indent) { + format_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids, buf, indent); + format_subtlv_ipv6_source_prefix(subtlvs->source_prefix, buf, indent); } @@ -233,6 +368,9 @@ static void isis_free_subtlvs(struct isis_subtlvs *subtlvs) if (!subtlvs) return; + free_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids); + XFREE(MTYPE_ISIS_SUBTLV, subtlvs->source_prefix); XFREE(MTYPE_ISIS_SUBTLV, subtlvs); @@ -248,6 +386,11 @@ static int pack_subtlvs(struct isis_subtlvs *subtlvs, struct stream *s) stream_putc(s, 0); /* Put 0 as subtlvs length, filled in later */ + rv = pack_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids, s, NULL, NULL, NULL, NULL); + if (rv) + return rv; + rv = pack_subtlv_ipv6_source_prefix(subtlvs->source_prefix, s); if (rv) return rv; @@ -1135,6 +1278,7 @@ static void free_item_extended_ip_reach(struct isis_item *i) { struct isis_extended_ip_reach *item = (struct isis_extended_ip_reach *)i; + isis_free_subtlvs(item->subtlvs); XFREE(MTYPE_ISIS_TLV, item); } @@ -1149,11 +1293,16 @@ static int pack_item_extended_ip_reach(struct isis_item *i, struct stream *s) control = r->down ? ISIS_EXTENDED_IP_REACH_DOWN : 0; control |= r->prefix.prefixlen; + control |= r->subtlvs ? ISIS_EXTENDED_IP_REACH_SUBTLV : 0; + stream_putc(s, control); if (STREAM_WRITEABLE(s) < (unsigned)PSIZE(r->prefix.prefixlen)) return 1; stream_put(s, &r->prefix.prefix.s_addr, PSIZE(r->prefix.prefixlen)); + + if (r->subtlvs) + return pack_subtlvs(r->subtlvs, s); return 0; } @@ -1235,9 +1384,12 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len, len - 6 - PSIZE(rv->prefix.prefixlen)); goto out; } - sbuf_push(log, indent, "Skipping %" PRIu8 " bytes of subvls", - subtlv_len); - stream_forward_getp(s, subtlv_len); + + rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH); + if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IP_REACH, subtlv_len, s, + log, rv->subtlvs, indent + 4)) { + goto out; + } } append_item(items, (struct isis_item *)rv); @@ -1329,6 +1481,126 @@ static int unpack_tlv_dynamic_hostname(enum isis_tlv_context context, return 0; } +/* Functions related to TLV 150 Spine-Leaf-Extension */ + +static struct isis_spine_leaf *copy_tlv_spine_leaf( + const struct isis_spine_leaf *spine_leaf) +{ + if (!spine_leaf) + return NULL; + + struct isis_spine_leaf *rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + memcpy(rv, spine_leaf, sizeof(*rv)); + + return rv; +} + +static void format_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf, + struct sbuf *buf, int indent) +{ + if (!spine_leaf) + return; + + sbuf_push(buf, indent, "Spine-Leaf-Extension:\n"); + if (spine_leaf->has_tier) { + if (spine_leaf->tier == ISIS_TIER_UNDEFINED) { + sbuf_push(buf, indent, " Tier: undefined\n"); + } else { + sbuf_push(buf, indent, " Tier: %" PRIu8 "\n", + spine_leaf->tier); + } + } + + sbuf_push(buf, indent, " Flags:%s%s%s\n", + spine_leaf->is_leaf ? " LEAF" : "", + spine_leaf->is_spine ? " SPINE" : "", + spine_leaf->is_backup ? " BACKUP" : ""); + +} + +static void free_tlv_spine_leaf(struct isis_spine_leaf *spine_leaf) +{ + XFREE(MTYPE_ISIS_TLV, spine_leaf); +} + +#define ISIS_SPINE_LEAF_FLAG_TIER 0x08 +#define ISIS_SPINE_LEAF_FLAG_BACKUP 0x04 +#define ISIS_SPINE_LEAF_FLAG_SPINE 0x02 +#define ISIS_SPINE_LEAF_FLAG_LEAF 0x01 + +static int pack_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf, + struct stream *s) +{ + if (!spine_leaf) + return 0; + + uint8_t tlv_len = 2; + + if (STREAM_WRITEABLE(s) < (unsigned)(2 + tlv_len)) + return 1; + + stream_putc(s, ISIS_TLV_SPINE_LEAF_EXT); + stream_putc(s, tlv_len); + + uint16_t spine_leaf_flags = 0; + + if (spine_leaf->has_tier) { + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_TIER; + spine_leaf_flags |= spine_leaf->tier << 12; + } + + if (spine_leaf->is_leaf) + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_LEAF; + + if (spine_leaf->is_spine) + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_SPINE; + + if (spine_leaf->is_backup) + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_BACKUP; + + stream_putw(s, spine_leaf_flags); + + return 0; +} + +static int unpack_tlv_spine_leaf(enum isis_tlv_context context, + uint8_t tlv_type, uint8_t tlv_len, + struct stream *s, struct sbuf *log, + void *dest, int indent) +{ + struct isis_tlvs *tlvs = dest; + + sbuf_push(log, indent, "Unpacking Spine Leaf Extension TLV...\n"); + if (tlv_len < 2) { + sbuf_push(log, indent, "WARNING: Unexepected TLV size\n"); + stream_forward_getp(s, tlv_len); + return 0; + } + + if (tlvs->spine_leaf) { + sbuf_push(log, indent, + "WARNING: Spine Leaf Extension TLV present multiple times.\n"); + stream_forward_getp(s, tlv_len); + return 0; + } + + tlvs->spine_leaf = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->spine_leaf)); + + uint16_t spine_leaf_flags = stream_getw(s); + + if (spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_TIER) { + tlvs->spine_leaf->has_tier = true; + tlvs->spine_leaf->tier = spine_leaf_flags >> 12; + } + + tlvs->spine_leaf->is_leaf = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_LEAF; + tlvs->spine_leaf->is_spine = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_SPINE; + tlvs->spine_leaf->is_backup = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_BACKUP; + + stream_forward_getp(s, tlv_len - 2); + return 0; +} + /* Functions related to TLV 240 P2P Three-Way Adjacency */ const char *isis_threeway_state_name(enum isis_threeway_state state) @@ -1592,7 +1864,7 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s, goto out; } - rv->subtlvs = isis_alloc_subtlvs(); + rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH); if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH, subtlv_len, s, log, rv->subtlvs, indent + 4)) { goto out; @@ -1632,9 +1904,9 @@ static void format_item_auth(uint16_t mtid, struct isis_item *i, 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; @@ -1713,6 +1985,114 @@ static int unpack_item_auth(uint16_t mtid, uint8_t len, struct stream *s, return 0; } +/* Functions related to TLV 13 Purge Originator */ + +static struct isis_purge_originator *copy_tlv_purge_originator( + struct isis_purge_originator *poi) +{ + if (!poi) + return NULL; + + struct isis_purge_originator *rv; + + rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + rv->sender_set = poi->sender_set; + memcpy(rv->generator, poi->generator, sizeof(rv->generator)); + if (poi->sender_set) + memcpy(rv->sender, poi->sender, sizeof(rv->sender)); + return rv; +} + +static void format_tlv_purge_originator(struct isis_purge_originator *poi, + struct sbuf *buf, int indent) +{ + if (!poi) + return; + + sbuf_push(buf, indent, "Purge Originator Identification:\n"); + sbuf_push(buf, indent, " Generator: %s\n", + isis_format_id(poi->generator, sizeof(poi->generator))); + if (poi->sender_set) { + sbuf_push(buf, indent, " Received-From: %s\n", + isis_format_id(poi->sender, sizeof(poi->sender))); + } +} + +static void free_tlv_purge_originator(struct isis_purge_originator *poi) +{ + XFREE(MTYPE_ISIS_TLV, poi); +} + +static int pack_tlv_purge_originator(struct isis_purge_originator *poi, + struct stream *s) +{ + if (!poi) + return 0; + + uint8_t data_len = 1 + sizeof(poi->generator); + + if (poi->sender_set) + data_len += sizeof(poi->sender); + + if (STREAM_WRITEABLE(s) < (unsigned)(2 + data_len)) + return 1; + + stream_putc(s, ISIS_TLV_PURGE_ORIGINATOR); + stream_putc(s, data_len); + stream_putc(s, poi->sender_set ? 2 : 1); + stream_put(s, poi->generator, sizeof(poi->generator)); + if (poi->sender_set) + stream_put(s, poi->sender, sizeof(poi->sender)); + return 0; +} + +static int unpack_tlv_purge_originator(enum isis_tlv_context context, + uint8_t tlv_type, uint8_t tlv_len, + struct stream *s, struct sbuf *log, + void *dest, int indent) +{ + struct isis_tlvs *tlvs = dest; + struct isis_purge_originator poi = {}; + + sbuf_push(log, indent, "Unpacking Purge Originator Identification TLV...\n"); + if (tlv_len < 7) { + sbuf_push(log, indent, "Not enough data left. (Expected at least 7 bytes, got %" + PRIu8 ")\n", tlv_len); + return 1; + } + + uint8_t number_of_ids = stream_getc(s); + + if (number_of_ids == 1) { + poi.sender_set = false; + } else if (number_of_ids == 2) { + poi.sender_set = true; + } else { + sbuf_push(log, indent, "Got invalid value for number of system IDs: %" + PRIu8 ")\n", number_of_ids); + return 1; + } + + if (tlv_len != 1 + 6 * number_of_ids) { + sbuf_push(log, indent, "Incorrect tlv len for number of IDs.\n"); + return 1; + } + + stream_get(poi.generator, s, sizeof(poi.generator)); + if (poi.sender_set) + stream_get(poi.sender, s, sizeof(poi.sender)); + + if (tlvs->purge_originator) { + sbuf_push(log, indent, + "WARNING: Purge originator present multiple times, ignoring.\n"); + return 0; + } + + tlvs->purge_originator = copy_tlv_purge_originator(&poi); + return 0; +} + + /* Functions relating to item TLVs */ static void init_item_list(struct isis_item_list *items) @@ -1770,7 +2150,6 @@ static void format_items_(uint16_t mtid, enum isis_tlv_context context, for (i = items->head; i; i = i->next) format_item(mtid, context, type, i, buf, indent); } -#define format_items(...) format_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__) static void free_item(enum isis_tlv_context tlv_context, enum isis_tlv_type tlv_type, struct isis_item *item) @@ -1876,6 +2255,14 @@ top: break; } + /* Multiple prefix-sids don't go into one TLV, so always break */ + if (type == ISIS_SUBTLV_PREFIX_SID + && (context == ISIS_CONTEXT_SUBTLV_IP_REACH + || context == ISIS_CONTEXT_SUBTLV_IPV6_REACH)) { + item = item->next; + break; + } + if (len > 255) { if (!last_len) /* strange, not a single item fit */ return 1; @@ -2131,6 +2518,9 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs) copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth, &rv->isis_auth); + rv->purge_originator = + copy_tlv_purge_originator(tlvs->purge_originator); + copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES, &tlvs->area_addresses, &rv->area_addresses); @@ -2187,6 +2577,8 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs) rv->threeway_adj = copy_tlv_threeway_adj(tlvs->threeway_adj); + rv->spine_leaf = copy_tlv_spine_leaf(tlvs->spine_leaf); + return rv; } @@ -2197,6 +2589,8 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent) format_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth, buf, indent); + format_tlv_purge_originator(tlvs->purge_originator, buf, indent); + format_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES, &tlvs->area_addresses, buf, indent); @@ -2250,6 +2644,8 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent) &tlvs->mt_ipv6_reach, buf, indent); format_tlv_threeway_adj(tlvs->threeway_adj, buf, indent); + + format_tlv_spine_leaf(tlvs->spine_leaf, buf, indent); } const char *isis_format_tlvs(struct isis_tlvs *tlvs) @@ -2270,6 +2666,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs) return; free_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth); + free_tlv_purge_originator(tlvs->purge_originator); free_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES, &tlvs->area_addresses); free_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_ROUTER_INFO, @@ -2301,6 +2698,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs) free_mt_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_IPV6_REACH, &tlvs->mt_ipv6_reach); free_tlv_threeway_adj(tlvs->threeway_adj); + free_tlv_spine_leaf(tlvs->spine_leaf); XFREE(MTYPE_ISIS_TLV, tlvs); } @@ -2417,6 +2815,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream, return rv; } + rv = pack_tlv_purge_originator(tlvs->purge_originator, stream); + if (rv) + return rv; + if (fragment_tlvs) { + fragment_tlvs->purge_originator = + copy_tlv_purge_originator(tlvs->purge_originator); + } + rv = pack_tlv_protocols_supported(&tlvs->protocols_supported, stream); if (rv) return rv; @@ -2480,6 +2886,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream, copy_tlv_threeway_adj(tlvs->threeway_adj); } + rv = pack_tlv_spine_leaf(tlvs->spine_leaf, stream); + if (rv) + return rv; + if (fragment_tlvs) { + fragment_tlvs->spine_leaf = + copy_tlv_spine_leaf(tlvs->spine_leaf); + } + for (size_t pack_idx = 0; pack_idx < array_size(pack_order); pack_idx++) { rv = handle_pack_entry(&pack_order[pack_idx], tlvs, stream, @@ -2667,11 +3081,15 @@ int isis_unpack_tlvs(size_t avail_len, struct stream *stream, .name = _desc_, .unpack = unpack_subtlv_##_name_, \ } +#define ITEM_SUBTLV_OPS(_name_, _desc_) \ + ITEM_TLV_OPS(_name_, _desc_) + ITEM_TLV_OPS(area_address, "TLV 1 Area Addresses"); ITEM_TLV_OPS(oldstyle_reach, "TLV 2 IS Reachability"); ITEM_TLV_OPS(lan_neighbor, "TLV 6 LAN Neighbors"); ITEM_TLV_OPS(lsp_entry, "TLV 9 LSP Entries"); ITEM_TLV_OPS(auth, "TLV 10 IS-IS Auth"); +TLV_OPS(purge_originator, "TLV 13 Purge Originator Identification"); ITEM_TLV_OPS(extended_reach, "TLV 22 Extended Reachability"); ITEM_TLV_OPS(oldstyle_ip_reach, "TLV 128/130 IP Reachability"); TLV_OPS(protocols_supported, "TLV 129 Protocols Supported"); @@ -2679,11 +3097,13 @@ ITEM_TLV_OPS(ipv4_address, "TLV 132 IPv4 Interface Address"); TLV_OPS(te_router_id, "TLV 134 TE Router ID"); ITEM_TLV_OPS(extended_ip_reach, "TLV 135 Extended IP Reachability"); TLV_OPS(dynamic_hostname, "TLV 137 Dynamic Hostname"); +TLV_OPS(spine_leaf, "TLV 150 Spine Leaf Extensions"); ITEM_TLV_OPS(mt_router_info, "TLV 229 MT Router Information"); TLV_OPS(threeway_adj, "TLV 240 P2P Three-Way Adjacency"); ITEM_TLV_OPS(ipv6_address, "TLV 232 IPv6 Interface Address"); ITEM_TLV_OPS(ipv6_reach, "TLV 236 IPv6 Reachability"); +ITEM_SUBTLV_OPS(prefix_sid, "Sub-TLV 3 SR Prefix-SID"); SUBTLV_OPS(ipv6_source_prefix, "Sub-TLV 22 IPv6 Source Prefix"); static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { @@ -2693,6 +3113,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { [ISIS_TLV_LAN_NEIGHBORS] = &tlv_lan_neighbor_ops, [ISIS_TLV_LSP_ENTRY] = &tlv_lsp_entry_ops, [ISIS_TLV_AUTH] = &tlv_auth_ops, + [ISIS_TLV_PURGE_ORIGINATOR] = &tlv_purge_originator_ops, [ISIS_TLV_EXTENDED_REACH] = &tlv_extended_reach_ops, [ISIS_TLV_MT_REACH] = &tlv_extended_reach_ops, [ISIS_TLV_OLDSTYLE_IP_REACH] = &tlv_oldstyle_ip_reach_ops, @@ -2703,6 +3124,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { [ISIS_TLV_EXTENDED_IP_REACH] = &tlv_extended_ip_reach_ops, [ISIS_TLV_MT_IP_REACH] = &tlv_extended_ip_reach_ops, [ISIS_TLV_DYNAMIC_HOSTNAME] = &tlv_dynamic_hostname_ops, + [ISIS_TLV_SPINE_LEAF_EXT] = &tlv_spine_leaf_ops, [ISIS_TLV_MT_ROUTER_INFO] = &tlv_mt_router_info_ops, [ISIS_TLV_THREE_WAY_ADJ] = &tlv_threeway_adj_ops, [ISIS_TLV_IPV6_ADDRESS] = &tlv_ipv6_address_ops, @@ -2710,8 +3132,11 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { [ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops, }, [ISIS_CONTEXT_SUBTLV_NE_REACH] = {}, - [ISIS_CONTEXT_SUBTLV_IP_REACH] = {}, + [ISIS_CONTEXT_SUBTLV_IP_REACH] = { + [ISIS_SUBTLV_PREFIX_SID] = &tlv_prefix_sid_ops, + }, [ISIS_CONTEXT_SUBTLV_IPV6_REACH] = { + [ISIS_SUBTLV_PREFIX_SID] = &tlv_prefix_sid_ops, [ISIS_SUBTLV_IPV6_SOURCE_PREFIX] = &subtlv_ipv6_source_prefix_ops, } }; @@ -3183,7 +3608,7 @@ void isis_tlvs_add_ipv6_dstsrc_reach(struct isis_tlvs *tlvs, uint16_t mtid, mtid); struct isis_ipv6_reach *r = (struct isis_ipv6_reach*)last_item(l); - r->subtlvs = isis_alloc_subtlvs(); + r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH); r->subtlvs->source_prefix = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*src)); memcpy(r->subtlvs->source_prefix, src, sizeof(*src)); } @@ -3239,6 +3664,24 @@ void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs, } } +void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier, + bool has_tier, bool is_leaf, bool is_spine, + bool is_backup) +{ + assert(!tlvs->spine_leaf); + + tlvs->spine_leaf = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->spine_leaf)); + + if (has_tier) { + tlvs->spine_leaf->tier = tier; + } + + tlvs->spine_leaf->has_tier = has_tier; + tlvs->spine_leaf->is_leaf = is_leaf; + tlvs->spine_leaf->is_spine = is_spine; + tlvs->spine_leaf->is_backup = is_backup; +} + struct isis_mt_router_info * isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid) { @@ -3254,3 +3697,20 @@ isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid) return NULL; } + +void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs, + const uint8_t *generator, + const uint8_t *sender) +{ + assert(!tlvs->purge_originator); + + tlvs->purge_originator = XCALLOC(MTYPE_ISIS_TLV, + sizeof(*tlvs->purge_originator)); + memcpy(tlvs->purge_originator->generator, generator, + sizeof(tlvs->purge_originator->generator)); + if (sender) { + tlvs->purge_originator->sender_set = true; + memcpy(tlvs->purge_originator->sender, sender, + sizeof(tlvs->purge_originator->sender)); + } +} diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index bd1fa3e676..4144809fa3 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -83,6 +83,8 @@ struct isis_extended_ip_reach { uint32_t metric; bool down; struct prefix_ipv4 prefix; + + struct isis_subtlvs *subtlvs; }; struct isis_ipv6_reach; @@ -103,6 +105,17 @@ struct isis_protocols_supported { uint8_t *protocols; }; +#define ISIS_TIER_UNDEFINED 15 + +struct isis_spine_leaf { + uint8_t tier; + + bool has_tier; + bool is_leaf; + bool is_spine; + bool is_backup; +}; + enum isis_threeway_state { ISIS_THREEWAY_DOWN = 2, ISIS_THREEWAY_INITIALIZING = 1, @@ -176,6 +189,13 @@ struct isis_item_list { unsigned int count; }; +struct isis_purge_originator { + bool sender_set; + + uint8_t generator[6]; + uint8_t sender[6]; +}; + RB_HEAD(isis_mt_item_list, isis_item_list); struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m, @@ -185,6 +205,7 @@ struct isis_item_list *isis_lookup_mt_items(struct isis_mt_item_list *m, struct isis_tlvs { struct isis_item_list isis_auth; + struct isis_purge_originator *purge_originator; struct isis_item_list area_addresses; struct isis_item_list oldstyle_reach; struct isis_item_list lan_neighbor; @@ -205,11 +226,24 @@ struct isis_tlvs { struct isis_item_list ipv6_reach; struct isis_mt_item_list mt_ipv6_reach; struct isis_threeway_adj *threeway_adj; + struct isis_spine_leaf *spine_leaf; }; -struct isis_subtlvs { - /* draft-baker-ipv6-isis-dst-src-routing-06 */ - struct prefix_ipv6 *source_prefix; +#define ISIS_PREFIX_SID_READVERTISED 0x80 +#define ISIS_PREFIX_SID_NODE 0x40 +#define ISIS_PREFIX_SID_NO_PHP 0x20 +#define ISIS_PREFIX_SID_EXPLICIT_NULL 0x10 +#define ISIS_PREFIX_SID_VALUE 0x08 +#define ISIS_PREFIX_SID_LOCAL 0x04 + +struct isis_prefix_sid; +struct isis_prefix_sid { + struct isis_prefix_sid *next; + + uint8_t flags; + uint8_t algorithm; + + uint32_t value; }; enum isis_tlv_context { @@ -220,6 +254,15 @@ enum isis_tlv_context { ISIS_CONTEXT_MAX }; +struct isis_subtlvs { + enum isis_tlv_context context; + + /* draft-baker-ipv6-isis-dst-src-routing-06 */ + struct prefix_ipv6 *source_prefix; + /* draft-ietf-isis-segment-routing-extensions-16 */ + struct isis_item_list prefix_sids; +}; + enum isis_tlv_type { ISIS_TLV_AREA_ADDRESSES = 1, ISIS_TLV_OLDSTYLE_REACH = 2, @@ -227,6 +270,7 @@ enum isis_tlv_type { ISIS_TLV_PADDING = 8, ISIS_TLV_LSP_ENTRY = 9, ISIS_TLV_AUTH = 10, + ISIS_TLV_PURGE_ORIGINATOR = 13, ISIS_TLV_EXTENDED_REACH = 22, ISIS_TLV_OLDSTYLE_IP_REACH = 128, @@ -236,6 +280,7 @@ enum isis_tlv_type { ISIS_TLV_TE_ROUTER_ID = 134, ISIS_TLV_EXTENDED_IP_REACH = 135, ISIS_TLV_DYNAMIC_HOSTNAME = 137, + ISIS_TLV_SPINE_LEAF_EXT = 150, ISIS_TLV_MT_REACH = 222, ISIS_TLV_MT_ROUTER_INFO = 229, ISIS_TLV_IPV6_ADDRESS = 232, @@ -245,6 +290,7 @@ enum isis_tlv_type { ISIS_TLV_THREE_WAY_ADJ = 240, ISIS_TLV_MAX = 256, + ISIS_SUBTLV_PREFIX_SID = 3, ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22 }; @@ -331,6 +377,14 @@ void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs, const uint8_t *neighbor_id, uint32_t neighbor_circuit_id); +void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier, + bool has_tier, bool is_leaf, bool is_spine, + bool is_backup); + struct isis_mt_router_info * isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid); + +void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs, + const uint8_t *generator, + const uint8_t *sender); #endif diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c new file mode 100644 index 0000000000..32427628ad --- /dev/null +++ b/isisd/isis_tx_queue.c @@ -0,0 +1,182 @@ +/* + * IS-IS Rout(e)ing protocol - LSP TX Queuing logic + * + * Copyright (C) 2018 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> + +#include "hash.h" +#include "jhash.h" + +#include "isisd/isisd.h" +#include "isisd/isis_memory.h" +#include "isisd/isis_flags.h" +#include "dict.h" +#include "isisd/isis_circuit.h" +#include "isisd/isis_lsp.h" +#include "isisd/isis_tx_queue.h" + +DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE, "ISIS TX Queue") +DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE_ENTRY, "ISIS TX Queue Entry") + +struct isis_tx_queue { + void *arg; + void (*send_event)(void *arg, struct isis_lsp *, enum isis_tx_type); + struct hash *hash; +}; + +struct isis_tx_queue_entry { + struct isis_lsp *lsp; + enum isis_tx_type type; + struct thread *retry; + struct isis_tx_queue *queue; +}; + +static unsigned tx_queue_hash_key(void *p) +{ + struct isis_tx_queue_entry *e = p; + + uint32_t id_key = jhash(e->lsp->hdr.lsp_id, + ISIS_SYS_ID_LEN + 2, 0x55aa5a5a); + + return jhash_1word(e->lsp->level, id_key); +} + +static int tx_queue_hash_cmp(const void *a, const void *b) +{ + const struct isis_tx_queue_entry *ea = a, *eb = b; + + if (ea->lsp->level != eb->lsp->level) + return 0; + + if (memcmp(ea->lsp->hdr.lsp_id, eb->lsp->hdr.lsp_id, + ISIS_SYS_ID_LEN + 2)) + return 0; + + return 1; +} + +struct isis_tx_queue *isis_tx_queue_new(void *arg, + void(*send_event)(void *arg, + struct isis_lsp *, + enum isis_tx_type)) +{ + struct isis_tx_queue *rv = XCALLOC(MTYPE_TX_QUEUE, sizeof(*rv)); + + rv->arg = arg; + rv->send_event = send_event; + + rv->hash = hash_create(tx_queue_hash_key, tx_queue_hash_cmp, NULL); + return rv; +} + +static void tx_queue_element_free(void *element) +{ + struct isis_tx_queue_entry *e = element; + + if (e->retry) + thread_cancel(e->retry); + + XFREE(MTYPE_TX_QUEUE_ENTRY, e); +} + +void isis_tx_queue_free(struct isis_tx_queue *queue) +{ + hash_clean(queue->hash, tx_queue_element_free); + hash_free(queue->hash); + XFREE(MTYPE_TX_QUEUE, queue); +} + +static struct isis_tx_queue_entry *tx_queue_find(struct isis_tx_queue *queue, + struct isis_lsp *lsp) +{ + struct isis_tx_queue_entry e = { + .lsp = lsp + }; + + return hash_lookup(queue->hash, &e); +} + +static int tx_queue_send_event(struct thread *thread) +{ + struct isis_tx_queue_entry *e = THREAD_ARG(thread); + struct isis_tx_queue *queue = e->queue; + + e->retry = NULL; + thread_add_timer(master, tx_queue_send_event, e, 5, &e->retry); + + queue->send_event(queue->arg, e->lsp, e->type); + /* Don't access e here anymore, send_event might have destroyed it */ + + return 0; +} + +void isis_tx_queue_add(struct isis_tx_queue *queue, + struct isis_lsp *lsp, + enum isis_tx_type type) +{ + if (!queue) + return; + + struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp); + if (!e) { + e = XCALLOC(MTYPE_TX_QUEUE_ENTRY, sizeof(*e)); + e->lsp = lsp; + e->queue = queue; + + struct isis_tx_queue_entry *inserted; + inserted = hash_get(queue->hash, e, hash_alloc_intern); + assert(inserted == e); + } + + e->type = type; + + if (e->retry) + thread_cancel(e->retry); + thread_add_event(master, tx_queue_send_event, e, 0, &e->retry); +} + +void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp) +{ + if (!queue) + return; + + struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp); + if (!e) + return; + + if (e->retry) + thread_cancel(e->retry); + + hash_release(queue->hash, e); + XFREE(MTYPE_TX_QUEUE_ENTRY, e); +} + +unsigned long isis_tx_queue_len(struct isis_tx_queue *queue) +{ + if (!queue) + return 0; + + return hashcount(queue->hash); +} + +void isis_tx_queue_clean(struct isis_tx_queue *queue) +{ + hash_clean(queue->hash, tx_queue_element_free); +} diff --git a/isisd/isis_lsp_hash.h b/isisd/isis_tx_queue.h index b50aa09dc1..ddecdf1e4f 100644 --- a/isisd/isis_lsp_hash.h +++ b/isisd/isis_tx_queue.h @@ -1,7 +1,7 @@ /* - * IS-IS Rout(e)ing protocol - LSP Hash + * IS-IS Rout(e)ing protocol - LSP TX Queuing logic * - * Copyright (C) 2017 Christian Franke + * Copyright (C) 2018 Christian Franke * * This file is part of FreeRangeRouting (FRR) * @@ -19,16 +19,31 @@ * with this program; see the file COPYING; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef ISIS_LSP_HASH_H -#define ISIS_LSP_HASH_H - -struct isis_lsp_hash; - -struct isis_lsp_hash *isis_lsp_hash_new(void); -void isis_lsp_hash_clean(struct isis_lsp_hash *ih); -void isis_lsp_hash_free(struct isis_lsp_hash *ih); -struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih, - struct isis_lsp *lsp); -void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp); -void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp); +#ifndef ISIS_TX_QUEUE_H +#define ISIS_TX_QUEUE_H + +enum isis_tx_type { + TX_LSP_NORMAL = 0, + TX_LSP_CIRCUIT_SCOPED +}; + +struct isis_tx_queue; + +struct isis_tx_queue *isis_tx_queue_new(void *arg, + void(*send_event)(void *arg, + struct isis_lsp *, + enum isis_tx_type)); + +void isis_tx_queue_free(struct isis_tx_queue *queue); + +void isis_tx_queue_add(struct isis_tx_queue *queue, + struct isis_lsp *lsp, + enum isis_tx_type type); + +void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp); + +unsigned long isis_tx_queue_len(struct isis_tx_queue *queue); + +void isis_tx_queue_clean(struct isis_tx_queue *queue); + #endif diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c deleted file mode 100644 index ce2952c135..0000000000 --- a/isisd/isis_vty.c +++ /dev/null @@ -1,2165 +0,0 @@ -/* - * IS-IS Rout(e)ing protocol - isis_circuit.h - * - * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology - * Institute of Communications Engineering - * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include "command.h" -#include "spf_backoff.h" - -#include "isis_circuit.h" -#include "isis_csm.h" -#include "isis_misc.h" -#include "isis_mt.h" -#include "isisd.h" - -static struct isis_circuit *isis_circuit_lookup(struct vty *vty) -{ - struct interface *ifp = VTY_GET_CONTEXT(interface); - struct isis_circuit *circuit; - - if (!ifp) { - vty_out(vty, "Invalid interface \n"); - return NULL; - } - - circuit = circuit_scan_by_ifp(ifp); - if (!circuit) { - vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); - return NULL; - } - - return circuit; -} - -DEFUN (ip_router_isis, - ip_router_isis_cmd, - "ip router isis WORD", - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - "IS-IS Routing for IP\n" - "Routing process tag\n") -{ - int idx_afi = 0; - int idx_word = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct isis_circuit *circuit; - struct isis_area *area; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - /* Prevent more than one area per circuit */ - circuit = circuit_scan_by_ifp(ifp); - if (circuit && circuit->area) { - if (strcmp(circuit->area->area_tag, area_tag)) { - vty_out(vty, "ISIS circuit is already defined on %s\n", - circuit->area->area_tag); - return CMD_ERR_NOTHING_TODO; - } - } - - area = isis_area_lookup(area_tag); - if (!area) - area = isis_area_create(area_tag); - - if (!circuit || !circuit->area) { - circuit = isis_circuit_create(area, ifp); - - if (circuit->state != C_STATE_CONF - && circuit->state != C_STATE_UP) { - vty_out(vty, - "Couldn't bring up interface, please check log.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = true; - else - ip = true; - - isis_circuit_af_set(circuit, ip, ipv6); - return CMD_SUCCESS; -} - -DEFUN (ip6_router_isis, - ip6_router_isis_cmd, - "ipv6 router isis WORD", - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - "IS-IS Routing for IP\n" - "Routing process tag\n") -{ - return ip_router_isis(self, vty, argc, argv); -} - -DEFUN (no_ip_router_isis, - no_ip_router_isis_cmd, - "no <ip|ipv6> router isis WORD", - NO_STR - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - "IP router interface commands\n" - "IS-IS Routing for IP\n" - "Routing process tag\n") -{ - int idx_afi = 1; - int idx_word = 4; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct isis_area *area; - struct isis_circuit *circuit; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - area = isis_area_lookup(area_tag); - if (!area) { - vty_out(vty, "Can't find ISIS instance %s\n", - argv[idx_afi]->arg); - return CMD_ERR_NO_MATCH; - } - - circuit = circuit_lookup_by_ifp(ifp, area->circuit_list); - if (!circuit) { - vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); - return CMD_ERR_NO_MATCH; - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = false; - else - ip = false; - - isis_circuit_af_set(circuit, ip, ipv6); - return CMD_SUCCESS; -} - -DEFUN (isis_passive, - isis_passive_cmd, - "isis passive", - "IS-IS commands\n" - "Configure the passive mode for interface\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1), - "Cannot set passive: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_passive, - no_isis_passive_cmd, - "no isis passive", - NO_STR - "IS-IS commands\n" - "Configure the passive mode for interface\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0), - "Cannot set no passive: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (isis_circuit_type, - isis_circuit_type_cmd, - "isis circuit-type <level-1|level-1-2|level-2-only>", - "IS-IS commands\n" - "Configure circuit type for interface\n" - "Level-1 only adjacencies are formed\n" - "Level-1-2 adjacencies are formed\n" - "Level-2 only adjacencies are formed\n") -{ - int idx_level = 2; - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - is_type = string2circuit_t(argv[idx_level]->arg); - if (!is_type) { - vty_out(vty, "Unknown circuit-type \n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (circuit->state == C_STATE_UP - && circuit->area->is_type != IS_LEVEL_1_AND_2 - && circuit->area->is_type != is_type) { - vty_out(vty, "Invalid circuit level for area %s.\n", - circuit->area->area_tag); - return CMD_WARNING_CONFIG_FAILED; - } - isis_circuit_is_type_set(circuit, is_type); - - return CMD_SUCCESS; -} - -DEFUN (no_isis_circuit_type, - no_isis_circuit_type_cmd, - "no isis circuit-type <level-1|level-1-2|level-2-only>", - NO_STR - "IS-IS commands\n" - "Configure circuit type for interface\n" - "Level-1 only adjacencies are formed\n" - "Level-1-2 adjacencies are formed\n" - "Level-2 only adjacencies are formed\n") -{ - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - /* - * Set the circuits level to its default value - */ - if (circuit->state == C_STATE_UP) - is_type = circuit->area->is_type; - else - is_type = IS_LEVEL_1_AND_2; - isis_circuit_is_type_set(circuit, is_type); - - return CMD_SUCCESS; -} - -DEFUN (isis_network, - isis_network_cmd, - "isis network point-to-point", - "IS-IS commands\n" - "Set network type\n" - "point-to-point network type\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) { - vty_out(vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (no_isis_network, - no_isis_network_cmd, - "no isis network point-to-point", - NO_STR - "IS-IS commands\n" - "Set network type for circuit\n" - "point-to-point network type\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) { - vty_out(vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (isis_passwd, - isis_passwd_cmd, - "isis password <md5|clear> WORD", - "IS-IS commands\n" - "Configure the authentication password for a circuit\n" - "HMAC-MD5 authentication\n" - "Cleartext password\n" - "Circuit password\n") -{ - int idx_encryption = 2; - int idx_word = 3; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - ferr_r rv; - - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (argv[idx_encryption]->arg[0] == 'm') - rv = isis_circuit_passwd_hmac_md5_set(circuit, - argv[idx_word]->arg); - else - rv = isis_circuit_passwd_cleartext_set(circuit, - argv[idx_word]->arg); - - CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_passwd, - no_isis_passwd_cmd, - "no isis password [<md5|clear> WORD]", - NO_STR - "IS-IS commands\n" - "Configure the authentication password for a circuit\n" - "HMAC-MD5 authentication\n" - "Cleartext password\n" - "Circuit password\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit), - "Failed to unset circuit password: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (isis_priority, - isis_priority_cmd, - "isis priority (0-127)", - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n") -{ - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - prio = atoi(argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { - vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->priority[0] = prio; - circuit->priority[1] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority, - no_isis_priority_cmd, - "no isis priority [(0-127)]", - NO_STR - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[0] = DEFAULT_PRIORITY; - circuit->priority[1] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - - -DEFUN (isis_priority_l1, - isis_priority_l1_cmd, - "isis priority (0-127) level-1", - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-1 routing\n") -{ - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - prio = atoi(argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { - vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->priority[0] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority_l1, - no_isis_priority_l1_cmd, - "no isis priority [(0-127)] level-1", - NO_STR - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-1 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[0] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - - -DEFUN (isis_priority_l2, - isis_priority_l2_cmd, - "isis priority (0-127) level-2", - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-2 routing\n") -{ - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - prio = atoi(argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { - vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->priority[1] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority_l2, - no_isis_priority_l2_cmd, - "no isis priority [(0-127)] level-2", - NO_STR - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-2 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[1] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - - -/* Metric command */ -DEFUN (isis_metric, - isis_metric_cmd, - "isis metric (0-16777215)", - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n") -{ - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - met = atoi(argv[idx_number]->arg); - - /* RFC3787 section 5.1 */ - if (circuit->area && circuit->area->oldmetric == 1 - && met > MAX_NARROW_LINK_METRIC) { - vty_out(vty, - "Invalid metric %d - should be <0-63> " - "when narrow metric type enabled\n", - met); - return CMD_WARNING_CONFIG_FAILED; - } - - /* RFC4444 */ - if (circuit->area && circuit->area->newmetric == 1 - && met > MAX_WIDE_LINK_METRIC) { - vty_out(vty, - "Invalid metric %d - should be <0-16777215> " - "when wide metric type enabled\n", - met); - return CMD_WARNING_CONFIG_FAILED; - } - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met), - "Failed to set L1 metric: $ERR"); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (no_isis_metric, - no_isis_metric_cmd, - "no isis metric [(0-16777215)]", - NO_STR - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L1 metric: $ERR"); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (isis_metric_l1, - isis_metric_l1_cmd, - "isis metric (0-16777215) level-1", - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-1 routing\n") -{ - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - met = atoi(argv[idx_number]->arg); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met), - "Failed to set L1 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (no_isis_metric_l1, - no_isis_metric_l1_cmd, - "no isis metric [(0-16777215)] level-1", - NO_STR - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-1 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L1 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (isis_metric_l2, - isis_metric_l2_cmd, - "isis metric (0-16777215) level-2", - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-2 routing\n") -{ - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - met = atoi(argv[idx_number]->arg); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (no_isis_metric_l2, - no_isis_metric_l2_cmd, - "no isis metric [(0-16777215)] level-2", - NO_STR - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-2 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - -/* end of metrics */ - -DEFUN (isis_hello_interval, - isis_hello_interval_cmd, - "isis hello-interval (1-600)", - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 seconds, interval depends on multiplier\n") -{ - int idx_number = 2; - int interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atoi(argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { - vty_out(vty, "Invalid hello-interval %d - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_interval[0] = (uint16_t)interval; - circuit->hello_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_interval, - no_isis_hello_interval_cmd, - "no isis hello-interval [(1-600)]", - NO_STR - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; - circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_interval_l1, - isis_hello_interval_l1_cmd, - "isis hello-interval (1-600) level-1", - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-1 IIHs\n") -{ - int idx_number = 2; - long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atoi(argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { - vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_interval[0] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_interval_l1, - no_isis_hello_interval_l1_cmd, - "no isis hello-interval [(1-600)] level-1", - NO_STR - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-1 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_interval_l2, - isis_hello_interval_l2_cmd, - "isis hello-interval (1-600) level-2", - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-2 IIHs\n") -{ - int idx_number = 2; - long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atoi(argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { - vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_interval_l2, - no_isis_hello_interval_l2_cmd, - "no isis hello-interval [(1-600)] level-2", - NO_STR - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-2 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_multiplier, - isis_hello_multiplier_cmd, - "isis hello-multiplier (2-100)", - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n") -{ - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - mult = atoi(argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { - vty_out(vty, - "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_multiplier[0] = (uint16_t)mult; - circuit->hello_multiplier[1] = (uint16_t)mult; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_multiplier, - no_isis_hello_multiplier_cmd, - "no isis hello-multiplier [(2-100)]", - NO_STR - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; - circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_multiplier_l1, - isis_hello_multiplier_l1_cmd, - "isis hello-multiplier (2-100) level-1", - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-1 IIHs\n") -{ - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - mult = atoi(argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { - vty_out(vty, - "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_multiplier[0] = (uint16_t)mult; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_multiplier_l1, - no_isis_hello_multiplier_l1_cmd, - "no isis hello-multiplier [(2-100)] level-1", - NO_STR - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-1 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_multiplier_l2, - isis_hello_multiplier_l2_cmd, - "isis hello-multiplier (2-100) level-2", - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-2 IIHs\n") -{ - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - mult = atoi(argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { - vty_out(vty, - "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_multiplier[1] = (uint16_t)mult; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_multiplier_l2, - no_isis_hello_multiplier_l2_cmd, - "no isis hello-multiplier [(2-100)] level-2", - NO_STR - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-2 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_padding, - isis_hello_padding_cmd, - "isis hello padding", - "IS-IS commands\n" - "Add padding to IS-IS hello packets\n" - "Pad hello packets\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->pad_hellos = 1; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_hello_padding, - no_isis_hello_padding_cmd, - "no isis hello padding", - NO_STR - "IS-IS commands\n" - "Add padding to IS-IS hello packets\n" - "Pad hello packets\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->pad_hellos = 0; - - return CMD_SUCCESS; -} - -DEFUN (isis_threeway_adj, - isis_threeway_adj_cmd, - "[no] isis three-way-handshake", - NO_STR - "IS-IS commands\n" - "Enable/Disable three-way handshake\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->disable_threeway_adj = !strcmp(argv[0]->text, "no"); - return CMD_SUCCESS; -} - -DEFUN (csnp_interval, - csnp_interval_cmd, - "isis csnp-interval (1-600)", - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { - vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->csnp_interval[0] = (uint16_t)interval; - circuit->csnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_csnp_interval, - no_csnp_interval_cmd, - "no isis csnp-interval [(1-600)]", - NO_STR - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; - circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (csnp_interval_l1, - csnp_interval_l1_cmd, - "isis csnp-interval (1-600) level-1", - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-1 CSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { - vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->csnp_interval[0] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_csnp_interval_l1, - no_csnp_interval_l1_cmd, - "no isis csnp-interval [(1-600)] level-1", - NO_STR - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-1 CSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (csnp_interval_l2, - csnp_interval_l2_cmd, - "isis csnp-interval (1-600) level-2", - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-2 CSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { - vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->csnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_csnp_interval_l2, - no_csnp_interval_l2_cmd, - "no isis csnp-interval [(1-600)] level-2", - NO_STR - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-2 CSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (psnp_interval, - psnp_interval_cmd, - "isis psnp-interval (1-120)", - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { - vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->psnp_interval[0] = (uint16_t)interval; - circuit->psnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_psnp_interval, - no_psnp_interval_cmd, - "no isis psnp-interval [(1-120)]", - NO_STR - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; - circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (psnp_interval_l1, - psnp_interval_l1_cmd, - "isis psnp-interval (1-120) level-1", - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-1 PSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { - vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->psnp_interval[0] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_psnp_interval_l1, - no_psnp_interval_l1_cmd, - "no isis psnp-interval [(1-120)] level-1", - NO_STR - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-1 PSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (psnp_interval_l2, - psnp_interval_l2_cmd, - "isis psnp-interval (1-120) level-2", - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-2 PSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { - vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->psnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_psnp_interval_l2, - no_psnp_interval_l2_cmd, - "no isis psnp-interval [(1-120)] level-2", - NO_STR - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-2 PSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (circuit_topology, - circuit_topology_cmd, - "isis topology " ISIS_MT_NAMES, - "IS-IS commands\n" - "Configure interface IS-IS topologies\n" - ISIS_MT_DESCRIPTIONS) -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[2]->arg; - uint16_t mtid = isis_str2mtid(arg); - - if (circuit->area && circuit->area->oldmetric) { - vty_out(vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (mtid == (uint16_t)-1) { - vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return isis_circuit_mt_enabled_set(circuit, mtid, true); -} - -DEFUN (no_circuit_topology, - no_circuit_topology_cmd, - "no isis topology " ISIS_MT_NAMES, - NO_STR - "IS-IS commands\n" - "Configure interface IS-IS topologies\n" - ISIS_MT_DESCRIPTIONS) -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[3]->arg; - uint16_t mtid = isis_str2mtid(arg); - - if (circuit->area && circuit->area->oldmetric) { - vty_out(vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (mtid == (uint16_t)-1) { - vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return isis_circuit_mt_enabled_set(circuit, mtid, false); -} - -static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) -{ - struct isis_circuit *circuit; - struct listnode *node; - - if (!vty) - return CMD_WARNING_CONFIG_FAILED; - - if (!area) { - vty_out(vty, "ISIS area is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { - if ((area->is_type & IS_LEVEL_1) - && (circuit->is_type & IS_LEVEL_1) - && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) { - vty_out(vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_WARNING_CONFIG_FAILED; - } - if ((area->is_type & IS_LEVEL_2) - && (circuit->is_type & IS_LEVEL_2) - && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) { - vty_out(vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_WARNING_CONFIG_FAILED; - } - } - - return CMD_SUCCESS; -} - -DEFUN (metric_style, - metric_style_cmd, - "metric-style <narrow|transition|wide>", - "Use old-style (ISO 10589) or new-style packet formats\n" - "Use old style of TLVs with narrow metric\n" - "Send and accept both styles of TLVs during transition\n" - "Use new style of TLVs to carry wider metric\n") -{ - int idx_metric_style = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - int ret; - - if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) { - isis_area_metricstyle_set(area, false, true); - return CMD_SUCCESS; - } - - if (area_is_mt(area)) { - vty_out(vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = validate_metric_style_narrow(vty, area); - if (ret != CMD_SUCCESS) - return ret; - - if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0) - isis_area_metricstyle_set(area, true, true); - else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0) - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; - - return CMD_SUCCESS; -} - -DEFUN (no_metric_style, - no_metric_style_cmd, - "no metric-style", - NO_STR - "Use old-style (ISO 10589) or new-style packet formats\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int ret; - - if (area_is_mt(area)) { - vty_out(vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = validate_metric_style_narrow(vty, area); - if (ret != CMD_SUCCESS) - return ret; - - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; -} - -DEFUN (set_overload_bit, - set_overload_bit_cmd, - "set-overload-bit", - "Set overload bit to avoid any transit traffic\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_overload_bit_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_set_overload_bit, - no_set_overload_bit_cmd, - "no set-overload-bit", - "Reset overload bit to accept transit traffic\n" - "Reset overload bit\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_overload_bit_set(area, false); - return CMD_SUCCESS; -} - -DEFUN (set_attached_bit, - set_attached_bit_cmd, - "set-attached-bit", - "Set attached bit to identify as L1/L2 router for inter-area traffic\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_attached_bit_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_set_attached_bit, - no_set_attached_bit_cmd, - "no set-attached-bit", - NO_STR - "Reset attached bit\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_attached_bit_set(area, false); - return CMD_SUCCESS; -} - -DEFUN (dynamic_hostname, - dynamic_hostname_cmd, - "hostname dynamic", - "Dynamic hostname for IS-IS\n" - "Dynamic hostname\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_dynhostname_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_dynamic_hostname, - no_dynamic_hostname_cmd, - "no hostname dynamic", - NO_STR - "Dynamic hostname for IS-IS\n" - "Dynamic hostname\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_dynhostname_set(area, false); - return CMD_SUCCESS; -} - -static int area_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - struct listnode *node; - struct isis_circuit *circuit; - - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { - if (circuit->state != C_STATE_INIT - && circuit->state != C_STATE_UP) - continue; - if (lsp_mtu > isis_circuit_pdu_size(circuit)) { - vty_out(vty, - "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", - circuit->interface->name, - isis_circuit_pdu_size(circuit)); - return CMD_WARNING_CONFIG_FAILED; - } - } - - isis_area_lsp_mtu_set(area, lsp_mtu); - return CMD_SUCCESS; -} - -DEFUN (area_lsp_mtu, - area_lsp_mtu_cmd, - "lsp-mtu (128-4352)", - "Configure the maximum size of generated LSPs\n" - "Maximum size of generated LSPs\n") -{ - int idx_number = 1; - unsigned int lsp_mtu; - - lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10); - - return area_lsp_mtu_set(vty, lsp_mtu); -} - - -DEFUN (no_area_lsp_mtu, - no_area_lsp_mtu_cmd, - "no lsp-mtu [(128-4352)]", - NO_STR - "Configure the maximum size of generated LSPs\n" - "Maximum size of generated LSPs\n") -{ - return area_lsp_mtu_set(vty, DEFAULT_LSP_MTU); -} - - -DEFUN (is_type, - is_type_cmd, - "is-type <level-1|level-1-2|level-2-only>", - "IS Level for this routing process (OSI only)\n" - "Act as a station router only\n" - "Act as both a station router and an area router\n" - "Act as an area router only\n") -{ - int idx_level = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - int type; - - type = string2circuit_t(argv[idx_level]->arg); - if (!type) { - vty_out(vty, "Unknown IS level \n"); - return CMD_SUCCESS; - } - - isis_area_is_type_set(area, type); - - return CMD_SUCCESS; -} - -DEFUN (no_is_type, - no_is_type_cmd, - "no is-type <level-1|level-1-2|level-2-only>", - NO_STR - "IS Level for this routing process (OSI only)\n" - "Act as a station router only\n" - "Act as both a station router and an area router\n" - "Act as an area router only\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int type; - - /* - * Put the is-type back to defaults: - * - level-1-2 on first area - * - level-1 for the rest - */ - if (listgetdata(listhead(isis->area_list)) == area) - type = IS_LEVEL_1_AND_2; - else - type = IS_LEVEL_1; - - isis_area_is_type_set(area, type); - - return CMD_SUCCESS; -} - -static int set_lsp_gen_interval(struct vty *vty, struct isis_area *area, - uint16_t interval, int level) -{ - int lvl; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - - if (interval >= area->lsp_refresh[lvl - 1]) { - vty_out(vty, - "LSP gen interval %us must be less than " - "the LSP refresh interval %us\n", - interval, area->lsp_refresh[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - area->lsp_gen_interval[lvl - 1] = interval; - } - - return CMD_SUCCESS; -} - -DEFUN (lsp_gen_interval, - lsp_gen_interval_cmd, - "lsp-gen-interval [<level-1|level-2>] (1-120)", - "Minimum interval between regenerating same LSP\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval in seconds\n") -{ - int idx = 0; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - int level; - - level = 0; - level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; - level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; - if (!level) - level = IS_LEVEL_1 | IS_LEVEL_2; - - argv_find(argv, argc, "(1-120)", &idx); - - interval = atoi(argv[idx]->arg); - return set_lsp_gen_interval(vty, area, interval, level); -} - -DEFUN (no_lsp_gen_interval, - no_lsp_gen_interval_cmd, - "no lsp-gen-interval [<level-1|level-2>] [(1-120)]", - NO_STR - "Minimum interval between regenerating same LSP\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval in seconds\n") -{ - int idx = 0; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - int level; - - level = 0; - level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; - level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; - if (!level) - level = IS_LEVEL_1 | IS_LEVEL_2; - - interval = DEFAULT_MIN_LSP_GEN_INTERVAL; - return set_lsp_gen_interval(vty, area, interval, level); -} - -DEFUN (spf_interval, - spf_interval_cmd, - "spf-interval (1-120)", - "Minimum interval between SPF calculations\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - int idx_number = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - - interval = atoi(argv[idx_number]->arg); - area->min_spf_interval[0] = interval; - area->min_spf_interval[1] = interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_spf_interval, - no_spf_interval_cmd, - "no spf-interval [[<level-1|level-2>] (1-120)]", - NO_STR - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (spf_interval_l1, - spf_interval_l1_cmd, - "spf-interval level-1 (1-120)", - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - int idx_number = 2; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - - interval = atoi(argv[idx_number]->arg); - area->min_spf_interval[0] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_interval_l1, - no_spf_interval_l1_cmd, - "no spf-interval level-1", - NO_STR - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (spf_interval_l2, - spf_interval_l2_cmd, - "spf-interval level-2 (1-120)", - "Minimum interval between SPF calculations\n" - "Set interval for level 2 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - int idx_number = 2; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - - interval = atoi(argv[idx_number]->arg); - area->min_spf_interval[1] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_interval_l2, - no_spf_interval_l2_cmd, - "no spf-interval level-2", - NO_STR - "Minimum interval between SPF calculations\n" - "Set interval for level 2 only\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_delay_ietf, - no_spf_delay_ietf_cmd, - "no spf-delay-ietf", - NO_STR - "IETF SPF delay algorithm\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - spf_backoff_free(area->spf_delay_ietf[0]); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[0] = NULL; - area->spf_delay_ietf[1] = NULL; - - return CMD_SUCCESS; -} - -DEFUN (spf_delay_ietf, - spf_delay_ietf_cmd, - "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", - "IETF SPF delay algorithm\n" - "Delay used while in QUIET state\n" - "Delay used while in QUIET state in milliseconds\n" - "Delay used while in SHORT_WAIT state\n" - "Delay used while in SHORT_WAIT state in milliseconds\n" - "Delay used while in LONG_WAIT\n" - "Delay used while in LONG_WAIT state in milliseconds\n" - "Time with no received IGP events before considering IGP stable\n" - "Time with no received IGP events before considering IGP stable (in milliseconds)\n" - "Maximum duration needed to learn all the events related to a single failure\n" - "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - long init_delay = atol(argv[2]->arg); - long short_delay = atol(argv[4]->arg); - long long_delay = atol(argv[6]->arg); - long holddown = atol(argv[8]->arg); - long timetolearn = atol(argv[10]->arg); - - size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); - char *buf = XCALLOC(MTYPE_TMP, bufsiz); - - snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[0]); - area->spf_delay_ietf[0] = - spf_backoff_new(master, buf, init_delay, short_delay, - long_delay, holddown, timetolearn); - - snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[1] = - spf_backoff_new(master, buf, init_delay, short_delay, - long_delay, holddown, timetolearn); - - XFREE(MTYPE_TMP, buf); - return CMD_SUCCESS; -} - -static int area_max_lsp_lifetime_set(struct vty *vty, int level, - uint16_t interval) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int lvl; - uint16_t refresh_interval = interval - 300; - int set_refresh_interval[ISIS_LEVELS] = {0, 0}; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { - if (!(lvl & level)) - continue; - - if (refresh_interval < area->lsp_refresh[lvl - 1]) { - vty_out(vty, - "Level %d Max LSP lifetime %us must be 300s greater than " - "the configured LSP refresh interval %us\n", - lvl, interval, area->lsp_refresh[lvl - 1]); - vty_out(vty, - "Automatically reducing level %d LSP refresh interval " - "to %us\n", - lvl, refresh_interval); - set_refresh_interval[lvl - 1] = 1; - - if (refresh_interval - <= area->lsp_gen_interval[lvl - 1]) { - vty_out(vty, - "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - refresh_interval, - area->lsp_gen_interval[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { - if (!(lvl & level)) - continue; - isis_area_max_lsp_lifetime_set(area, lvl, interval); - if (set_refresh_interval[lvl - 1]) - isis_area_lsp_refresh_set(area, lvl, refresh_interval); - } - - return CMD_SUCCESS; -} - -DEFUN (max_lsp_lifetime, - max_lsp_lifetime_cmd, - "max-lsp-lifetime [<level-1|level-2>] (350-65535)", - "Maximum LSP lifetime\n" - "Maximum LSP lifetime for Level 1 only\n" - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - argv_find(argv, argc, "(350-65535)", &idx); - int lifetime = atoi(argv[idx]->arg); - - return area_max_lsp_lifetime_set(vty, level, lifetime); -} - - -DEFUN (no_max_lsp_lifetime, - no_max_lsp_lifetime_cmd, - "no max-lsp-lifetime [<level-1|level-2>] [(350-65535)]", - NO_STR - "Maximum LSP lifetime\n" - "Maximum LSP lifetime for Level 1 only\n" - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - return area_max_lsp_lifetime_set(vty, level, DEFAULT_LSP_LIFETIME); -} - -static int area_lsp_refresh_interval_set(struct vty *vty, int level, - uint16_t interval) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int lvl; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - if (interval <= area->lsp_gen_interval[lvl - 1]) { - vty_out(vty, - "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - interval, area->lsp_gen_interval[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) { - vty_out(vty, - "LSP refresh interval %us must be less than " - "the configured LSP lifetime %us less 300\n", - interval, area->max_lsp_lifetime[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - isis_area_lsp_refresh_set(area, lvl, interval); - } - - return CMD_SUCCESS; -} - -DEFUN (lsp_refresh_interval, - lsp_refresh_interval_cmd, - "lsp-refresh-interval [<level-1|level-2>] (1-65235)", - "LSP refresh interval\n" - "LSP refresh interval for Level 1 only\n" - "LSP refresh interval for Level 2 only\n" - "LSP refresh interval in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - unsigned int interval = 0; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - interval = atoi(argv[argc - 1]->arg); - return area_lsp_refresh_interval_set(vty, level, interval); -} - -DEFUN (no_lsp_refresh_interval, - no_lsp_refresh_interval_cmd, - "no lsp-refresh-interval [<level-1|level-2>] [(1-65235)]", - NO_STR - "LSP refresh interval\n" - "LSP refresh interval for Level 1 only\n" - "LSP refresh interval for Level 2 only\n" - "LSP refresh interval in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - return area_lsp_refresh_interval_set(vty, level, - DEFAULT_MAX_LSP_GEN_INTERVAL); -} - -static int area_passwd_set(struct vty *vty, int level, - int (*type_set)(struct isis_area *area, int level, - const char *passwd, - uint8_t snp_auth), - const char *passwd, uint8_t snp_auth) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - if (passwd && strlen(passwd) > 254) { - vty_out(vty, "Too long area password (>254)\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - type_set(area, level, passwd, snp_auth); - return CMD_SUCCESS; -} - - -DEFUN (area_passwd_md5, - area_passwd_md5_cmd, - "area-password md5 WORD [authenticate snp <send-only|validate>]", - "Configure the authentication password for an area\n" - "Authentication type\n" - "Level-wide password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - int idx_password = 0; - int idx_word = 2; - int idx_type = 5; - uint8_t snp_auth = 0; - int level = strmatch(argv[idx_password]->text, "domain-password") - ? IS_LEVEL_2 - : IS_LEVEL_1; - - if (argc > 3) { - snp_auth = SNP_AUTH_SEND; - if (strmatch(argv[idx_type]->text, "validate")) - snp_auth |= SNP_AUTH_RECV; - } - - return area_passwd_set(vty, level, isis_area_passwd_hmac_md5_set, - argv[idx_word]->arg, snp_auth); -} - -DEFUN (domain_passwd_md5, - domain_passwd_md5_cmd, - "domain-password md5 WORD [authenticate snp <send-only|validate>]", - "Set the authentication password for a routing domain\n" - "Authentication type\n" - "Level-wide password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - return area_passwd_md5(self, vty, argc, argv); -} - -DEFUN (area_passwd_clear, - area_passwd_clear_cmd, - "area-password clear WORD [authenticate snp <send-only|validate>]", - "Configure the authentication password for an area\n" - "Authentication type\n" - "Area password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - int idx_password = 0; - int idx_word = 2; - int idx_type = 5; - uint8_t snp_auth = 0; - int level = strmatch(argv[idx_password]->text, "domain-password") - ? IS_LEVEL_2 - : IS_LEVEL_1; - - if (argc > 3) { - snp_auth = SNP_AUTH_SEND; - if (strmatch(argv[idx_type]->text, "validate")) - snp_auth |= SNP_AUTH_RECV; - } - - return area_passwd_set(vty, level, isis_area_passwd_cleartext_set, - argv[idx_word]->arg, snp_auth); -} - -DEFUN (domain_passwd_clear, - domain_passwd_clear_cmd, - "domain-password clear WORD [authenticate snp <send-only|validate>]", - "Set the authentication password for a routing domain\n" - "Authentication type\n" - "Area password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - return area_passwd_clear(self, vty, argc, argv); -} - -DEFUN (no_area_passwd, - no_area_passwd_cmd, - "no <area-password|domain-password>", - NO_STR - "Configure the authentication password for an area\n" - "Set the authentication password for a routing domain\n") -{ - int idx_password = 1; - int level = strmatch(argv[idx_password]->text, "domain-password") - ? IS_LEVEL_2 - : IS_LEVEL_1; - VTY_DECLVAR_CONTEXT(isis_area, area); - - return isis_area_passwd_unset(area, level); -} - -void isis_vty_init(void) -{ - install_element(INTERFACE_NODE, &ip_router_isis_cmd); - install_element(INTERFACE_NODE, &ip6_router_isis_cmd); - install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); - - install_element(INTERFACE_NODE, &isis_passive_cmd); - install_element(INTERFACE_NODE, &no_isis_passive_cmd); - - install_element(INTERFACE_NODE, &isis_circuit_type_cmd); - install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); - - install_element(INTERFACE_NODE, &isis_network_cmd); - install_element(INTERFACE_NODE, &no_isis_network_cmd); - - install_element(INTERFACE_NODE, &isis_passwd_cmd); - install_element(INTERFACE_NODE, &no_isis_passwd_cmd); - - install_element(INTERFACE_NODE, &isis_priority_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_cmd); - install_element(INTERFACE_NODE, &isis_priority_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_l1_cmd); - install_element(INTERFACE_NODE, &isis_priority_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_l2_cmd); - - install_element(INTERFACE_NODE, &isis_metric_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_cmd); - install_element(INTERFACE_NODE, &isis_metric_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_l1_cmd); - install_element(INTERFACE_NODE, &isis_metric_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_l2_cmd); - - install_element(INTERFACE_NODE, &isis_hello_interval_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); - install_element(INTERFACE_NODE, &isis_hello_interval_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_l1_cmd); - install_element(INTERFACE_NODE, &isis_hello_interval_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_l2_cmd); - - install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); - install_element(INTERFACE_NODE, &isis_hello_multiplier_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd); - install_element(INTERFACE_NODE, &isis_hello_multiplier_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd); - - install_element(INTERFACE_NODE, &isis_hello_padding_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd); - - install_element(INTERFACE_NODE, &isis_threeway_adj_cmd); - - install_element(INTERFACE_NODE, &csnp_interval_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_cmd); - install_element(INTERFACE_NODE, &csnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &csnp_interval_l2_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_l2_cmd); - - install_element(INTERFACE_NODE, &psnp_interval_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_cmd); - install_element(INTERFACE_NODE, &psnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &psnp_interval_l2_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_l2_cmd); - - install_element(INTERFACE_NODE, &circuit_topology_cmd); - install_element(INTERFACE_NODE, &no_circuit_topology_cmd); - - install_element(ISIS_NODE, &metric_style_cmd); - install_element(ISIS_NODE, &no_metric_style_cmd); - - install_element(ISIS_NODE, &set_overload_bit_cmd); - install_element(ISIS_NODE, &no_set_overload_bit_cmd); - - install_element(ISIS_NODE, &set_attached_bit_cmd); - install_element(ISIS_NODE, &no_set_attached_bit_cmd); - - install_element(ISIS_NODE, &dynamic_hostname_cmd); - install_element(ISIS_NODE, &no_dynamic_hostname_cmd); - - install_element(ISIS_NODE, &area_lsp_mtu_cmd); - install_element(ISIS_NODE, &no_area_lsp_mtu_cmd); - - install_element(ISIS_NODE, &is_type_cmd); - install_element(ISIS_NODE, &no_is_type_cmd); - - install_element(ISIS_NODE, &lsp_gen_interval_cmd); - install_element(ISIS_NODE, &no_lsp_gen_interval_cmd); - - install_element(ISIS_NODE, &spf_interval_cmd); - install_element(ISIS_NODE, &no_spf_interval_cmd); - install_element(ISIS_NODE, &spf_interval_l1_cmd); - install_element(ISIS_NODE, &no_spf_interval_l1_cmd); - install_element(ISIS_NODE, &spf_interval_l2_cmd); - install_element(ISIS_NODE, &no_spf_interval_l2_cmd); - - install_element(ISIS_NODE, &max_lsp_lifetime_cmd); - install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd); - - install_element(ISIS_NODE, &lsp_refresh_interval_cmd); - install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd); - - install_element(ISIS_NODE, &area_passwd_md5_cmd); - install_element(ISIS_NODE, &area_passwd_clear_cmd); - install_element(ISIS_NODE, &domain_passwd_md5_cmd); - install_element(ISIS_NODE, &domain_passwd_clear_cmd); - install_element(ISIS_NODE, &no_area_passwd_cmd); - - install_element(ISIS_NODE, &spf_delay_ietf_cmd); - install_element(ISIS_NODE, &no_spf_delay_ietf_cmd); -} diff --git a/isisd/isis_vty_common.c b/isisd/isis_vty_common.c new file mode 100644 index 0000000000..2b98a88b34 --- /dev/null +++ b/isisd/isis_vty_common.c @@ -0,0 +1,960 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_common.c + * + * This file contains the CLI that is shared between OpenFabric and IS-IS + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. + * Copyright (C) 2018 Christian Franke, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "command.h" +#include "spf_backoff.h" + +#include "isis_circuit.h" +#include "isis_csm.h" +#include "isis_misc.h" +#include "isis_mt.h" +#include "isisd.h" +#include "isis_vty_common.h" + +struct isis_circuit *isis_circuit_lookup(struct vty *vty) +{ + struct interface *ifp = VTY_GET_CONTEXT(interface); + struct isis_circuit *circuit; + + if (!ifp) { + vty_out(vty, "Invalid interface \n"); + return NULL; + } + + circuit = circuit_scan_by_ifp(ifp); + if (!circuit) { + vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); + return NULL; + } + + return circuit; +} + +DEFUN (ip_router_isis, + ip_router_isis_cmd, + "ip router " PROTO_NAME " WORD", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + PROTO_HELP + "Routing process tag\n") +{ + int idx_afi = 0; + int idx_word = 3; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct isis_circuit *circuit; + struct isis_area *area; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; + + /* Prevent more than one area per circuit */ + circuit = circuit_scan_by_ifp(ifp); + if (circuit && circuit->area) { + if (strcmp(circuit->area->area_tag, area_tag)) { + vty_out(vty, "ISIS circuit is already defined on %s\n", + circuit->area->area_tag); + return CMD_ERR_NOTHING_TODO; + } + } + + area = isis_area_lookup(area_tag); + if (!area) + area = isis_area_create(area_tag); + + if (!circuit || !circuit->area) { + circuit = isis_circuit_create(area, ifp); + + if (circuit->state != C_STATE_CONF + && circuit->state != C_STATE_UP) { + vty_out(vty, + "Couldn't bring up interface, please check log.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; + if (af[2] != '\0') + ipv6 = true; + else + ip = true; + + isis_circuit_af_set(circuit, ip, ipv6); + return CMD_SUCCESS; +} + +DEFUN (ip6_router_isis, + ip6_router_isis_cmd, + "ipv6 router " PROTO_NAME " WORD", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + PROTO_HELP + "Routing process tag\n") +{ + return ip_router_isis(self, vty, argc, argv); +} + +DEFUN (no_ip_router_isis, + no_ip_router_isis_cmd, + "no <ip|ipv6> router " PROTO_NAME " WORD", + NO_STR + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + "IP router interface commands\n" + PROTO_HELP + "Routing process tag\n") +{ + int idx_afi = 1; + int idx_word = 4; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct isis_area *area; + struct isis_circuit *circuit; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; + + area = isis_area_lookup(area_tag); + if (!area) { + vty_out(vty, "Can't find ISIS instance %s\n", + area_tag); + return CMD_ERR_NO_MATCH; + } + + circuit = circuit_lookup_by_ifp(ifp, area->circuit_list); + if (!circuit) { + vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); + return CMD_ERR_NO_MATCH; + } + + bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; + if (af[2] != '\0') + ipv6 = false; + else + ip = false; + + isis_circuit_af_set(circuit, ip, ipv6); + return CMD_SUCCESS; +} + +DEFUN (isis_passive, + isis_passive_cmd, + PROTO_NAME " passive", + PROTO_HELP + "Configure the passive mode for interface\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1), + "Cannot set passive: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_passive, + no_isis_passive_cmd, + "no " PROTO_NAME " passive", + NO_STR + PROTO_HELP + "Configure the passive mode for interface\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0), + "Cannot set no passive: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_passwd, + isis_passwd_cmd, + PROTO_NAME " password <md5|clear> WORD", + PROTO_HELP + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + int idx_encryption = 2; + int idx_word = 3; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + ferr_r rv; + + if (!circuit) + return CMD_ERR_NO_MATCH; + + if (argv[idx_encryption]->arg[0] == 'm') + rv = isis_circuit_passwd_hmac_md5_set(circuit, + argv[idx_word]->arg); + else + rv = isis_circuit_passwd_cleartext_set(circuit, + argv[idx_word]->arg); + + CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_passwd, + no_isis_passwd_cmd, + "no " PROTO_NAME " password [<md5|clear> WORD]", + NO_STR + PROTO_HELP + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit), + "Failed to unset circuit password: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_metric, + isis_metric_cmd, + PROTO_NAME " metric (0-16777215)", + PROTO_HELP + "Set default metric for circuit\n" + "Default metric value\n") +{ + int idx_number = 2; + int met; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + met = atoi(argv[idx_number]->arg); + + /* RFC3787 section 5.1 */ + if (circuit->area && circuit->area->oldmetric == 1 + && met > MAX_NARROW_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-63> " + "when narrow metric type enabled\n", + met); + return CMD_WARNING_CONFIG_FAILED; + } + + /* RFC4444 */ + if (circuit->area && circuit->area->newmetric == 1 + && met > MAX_WIDE_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-16777215> " + "when wide metric type enabled\n", + met); + return CMD_WARNING_CONFIG_FAILED; + } + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met), + "Failed to set L1 metric: $ERR"); + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met), + "Failed to set L2 metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_metric, + no_isis_metric_cmd, + "no " PROTO_NAME " metric [(0-16777215)]", + NO_STR + PROTO_HELP + "Set default metric for circuit\n" + "Default metric value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, + DEFAULT_CIRCUIT_METRIC), + "Failed to set L1 metric: $ERR"); + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, + DEFAULT_CIRCUIT_METRIC), + "Failed to set L2 metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_hello_interval, + isis_hello_interval_cmd, + PROTO_NAME " hello-interval (1-600)", + PROTO_HELP + "Set Hello interval\n" + "Holdtime 1 seconds, interval depends on multiplier\n") +{ + uint32_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[0] = interval; + circuit->hello_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_interval, + no_isis_hello_interval_cmd, + "no " PROTO_NAME " hello-interval [(1-600)]", + NO_STR + PROTO_HELP + "Set Hello interval\n" + "Holdtime 1 second, interval depends on multiplier\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; + circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (isis_hello_multiplier, + isis_hello_multiplier_cmd, + PROTO_NAME " hello-multiplier (2-100)", + PROTO_HELP + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n") +{ + uint16_t mult = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[0] = mult; + circuit->hello_multiplier[1] = mult; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_multiplier, + no_isis_hello_multiplier_cmd, + "no " PROTO_NAME " hello-multiplier [(2-100)]", + NO_STR + PROTO_HELP + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; + circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; + + return CMD_SUCCESS; +} + +DEFUN (csnp_interval, + csnp_interval_cmd, + PROTO_NAME " csnp-interval (1-600)", + PROTO_HELP + "Set CSNP interval in seconds\n" + "CSNP interval value\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[0] = interval; + circuit->csnp_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_csnp_interval, + no_csnp_interval_cmd, + "no " PROTO_NAME " csnp-interval [(1-600)]", + NO_STR + PROTO_HELP + "Set CSNP interval in seconds\n" + "CSNP interval value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; + circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (psnp_interval, + psnp_interval_cmd, + PROTO_NAME " psnp-interval (1-120)", + PROTO_HELP + "Set PSNP interval in seconds\n" + "PSNP interval value\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[0] = interval; + circuit->psnp_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_psnp_interval, + no_psnp_interval_cmd, + "no " PROTO_NAME " psnp-interval [(1-120)]", + NO_STR + PROTO_HELP + "Set PSNP interval in seconds\n" + "PSNP interval value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; + circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (circuit_topology, + circuit_topology_cmd, + PROTO_NAME " topology " ISIS_MT_NAMES, + PROTO_HELP + "Configure interface IS-IS topologies\n" + ISIS_MT_DESCRIPTIONS) +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + const char *arg = argv[2]->arg; + uint16_t mtid = isis_str2mtid(arg); + + if (circuit->area && circuit->area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_WARNING_CONFIG_FAILED; + } + + return isis_circuit_mt_enabled_set(circuit, mtid, true); +} + +DEFUN (no_circuit_topology, + no_circuit_topology_cmd, + "no " PROTO_NAME " topology " ISIS_MT_NAMES, + NO_STR + PROTO_HELP + "Configure interface IS-IS topologies\n" + ISIS_MT_DESCRIPTIONS) +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + const char *arg = argv[3]->arg; + uint16_t mtid = isis_str2mtid(arg); + + if (circuit->area && circuit->area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_WARNING_CONFIG_FAILED; + } + + return isis_circuit_mt_enabled_set(circuit, mtid, false); +} + +DEFUN (set_overload_bit, + set_overload_bit_cmd, + "set-overload-bit", + "Set overload bit to avoid any transit traffic\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_overload_bit_set(area, true); + return CMD_SUCCESS; +} + +DEFUN (no_set_overload_bit, + no_set_overload_bit_cmd, + "no set-overload-bit", + "Reset overload bit to accept transit traffic\n" + "Reset overload bit\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_overload_bit_set(area, false); + return CMD_SUCCESS; +} + +static int isis_vty_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + struct listnode *node; + struct isis_circuit *circuit; + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if (circuit->state != C_STATE_INIT + && circuit->state != C_STATE_UP) + continue; + if (lsp_mtu > isis_circuit_pdu_size(circuit)) { + vty_out(vty, + "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", + circuit->interface->name, + isis_circuit_pdu_size(circuit)); + return CMD_WARNING_CONFIG_FAILED; + } + } + + isis_area_lsp_mtu_set(area, lsp_mtu); + return CMD_SUCCESS; +} + +DEFUN (area_lsp_mtu, + area_lsp_mtu_cmd, + "lsp-mtu (128-4352)", + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + int idx_number = 1; + unsigned int lsp_mtu; + + lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10); + + return isis_vty_lsp_mtu_set(vty, lsp_mtu); +} + +DEFUN (no_area_lsp_mtu, + no_area_lsp_mtu_cmd, + "no lsp-mtu [(128-4352)]", + NO_STR + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU); +} + +DEFUN (area_purge_originator, + area_purge_originator_cmd, + "[no] purge-originator", + NO_STR + "Use the RFC 6232 purge-originator\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + area->purge_originator = !!strcmp(argv[0]->text, "no"); + return CMD_SUCCESS; +} + +int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + + if (interval >= area->lsp_refresh[lvl - 1]) { + vty_out(vty, + "LSP gen interval %us must be less than " + "the LSP refresh interval %us\n", + interval, area->lsp_refresh[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + area->lsp_gen_interval[lvl - 1] = interval; + } + + return CMD_SUCCESS; +} + +DEFUN (lsp_gen_interval, + lsp_gen_interval_cmd, + "lsp-gen-interval (1-120)", + "Minimum interval between regenerating same LSP\n" + "Minimum interval in seconds\n") +{ + uint16_t interval = atoi(argv[1]->arg); + + return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval); +} + +DEFUN (no_lsp_gen_interval, + no_lsp_gen_interval_cmd, + "no lsp-gen-interval [(1-120)]", + NO_STR + "Minimum interval between regenerating same LSP\n" + "Minimum interval in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, + DEFAULT_MIN_LSP_GEN_INTERVAL); +} + +DEFUN (spf_interval, + spf_interval_cmd, + "spf-interval (1-120)", + "Minimum interval between SPF calculations\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + uint16_t interval = atoi(argv[1]->arg); + + area->min_spf_interval[0] = interval; + area->min_spf_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_spf_interval, + no_spf_interval_cmd, + "no spf-interval [(1-120)]", + NO_STR + "Minimum interval between SPF calculations\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; + area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (no_spf_delay_ietf, + no_spf_delay_ietf_cmd, + "no spf-delay-ietf", + NO_STR + "IETF SPF delay algorithm\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + spf_backoff_free(area->spf_delay_ietf[0]); + spf_backoff_free(area->spf_delay_ietf[1]); + area->spf_delay_ietf[0] = NULL; + area->spf_delay_ietf[1] = NULL; + + return CMD_SUCCESS; +} + +DEFUN (spf_delay_ietf, + spf_delay_ietf_cmd, + "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", + "IETF SPF delay algorithm\n" + "Delay used while in QUIET state\n" + "Delay used while in QUIET state in milliseconds\n" + "Delay used while in SHORT_WAIT state\n" + "Delay used while in SHORT_WAIT state in milliseconds\n" + "Delay used while in LONG_WAIT\n" + "Delay used while in LONG_WAIT state in milliseconds\n" + "Time with no received IGP events before considering IGP stable\n" + "Time with no received IGP events before considering IGP stable (in milliseconds)\n" + "Maximum duration needed to learn all the events related to a single failure\n" + "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + long init_delay = atol(argv[2]->arg); + long short_delay = atol(argv[4]->arg); + long long_delay = atol(argv[6]->arg); + long holddown = atol(argv[8]->arg); + long timetolearn = atol(argv[10]->arg); + + size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); + char *buf = XCALLOC(MTYPE_TMP, bufsiz); + + snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag); + spf_backoff_free(area->spf_delay_ietf[0]); + area->spf_delay_ietf[0] = + spf_backoff_new(master, buf, init_delay, short_delay, + long_delay, holddown, timetolearn); + + snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag); + spf_backoff_free(area->spf_delay_ietf[1]); + area->spf_delay_ietf[1] = + spf_backoff_new(master, buf, init_delay, short_delay, + long_delay, holddown, timetolearn); + + XFREE(MTYPE_TMP, buf); + return CMD_SUCCESS; +} + +int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + uint16_t refresh_interval = interval - 300; + int set_refresh_interval[ISIS_LEVELS] = {0, 0}; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + if (!(lvl & level)) + continue; + + if (refresh_interval < area->lsp_refresh[lvl - 1]) { + vty_out(vty, + "Level %d Max LSP lifetime %us must be 300s greater than " + "the configured LSP refresh interval %us\n", + lvl, interval, area->lsp_refresh[lvl - 1]); + vty_out(vty, + "Automatically reducing level %d LSP refresh interval " + "to %us\n", + lvl, refresh_interval); + set_refresh_interval[lvl - 1] = 1; + + if (refresh_interval + <= area->lsp_gen_interval[lvl - 1]) { + vty_out(vty, + "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us\n", + refresh_interval, + area->lsp_gen_interval[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + if (!(lvl & level)) + continue; + isis_area_max_lsp_lifetime_set(area, lvl, interval); + if (set_refresh_interval[lvl - 1]) + isis_area_lsp_refresh_set(area, lvl, refresh_interval); + } + + return CMD_SUCCESS; +} + +DEFUN (max_lsp_lifetime, + max_lsp_lifetime_cmd, + "max-lsp-lifetime (350-65535)", + "Maximum LSP lifetime\n" + "LSP lifetime in seconds\n") +{ + int lifetime = atoi(argv[1]->arg); + + return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime); +} + + +DEFUN (no_max_lsp_lifetime, + no_max_lsp_lifetime_cmd, + "no max-lsp-lifetime [(350-65535)]", + NO_STR + "Maximum LSP lifetime\n" + "LSP lifetime in seconds\n") +{ + return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, + DEFAULT_LSP_LIFETIME); +} + +int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + if (interval <= area->lsp_gen_interval[lvl - 1]) { + vty_out(vty, + "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us\n", + interval, area->lsp_gen_interval[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) { + vty_out(vty, + "LSP refresh interval %us must be less than " + "the configured LSP lifetime %us less 300\n", + interval, area->max_lsp_lifetime[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + isis_area_lsp_refresh_set(area, lvl, interval); + } + + return CMD_SUCCESS; +} + +DEFUN (lsp_refresh_interval, + lsp_refresh_interval_cmd, + "lsp-refresh-interval (1-65235)", + "LSP refresh interval\n" + "LSP refresh interval in seconds\n") +{ + unsigned int interval = atoi(argv[1]->arg); + return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval); +} + +DEFUN (no_lsp_refresh_interval, + no_lsp_refresh_interval_cmd, + "no lsp-refresh-interval [(1-65235)]", + NO_STR + "LSP refresh interval\n" + "LSP refresh interval in seconds\n") +{ + return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, + DEFAULT_MAX_LSP_GEN_INTERVAL); +} + +int isis_vty_password_set(struct vty *vty, int argc, + struct cmd_token *argv[], int level) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + int idx_algo = 1; + int idx_password = 2; + int idx_snp_auth = 5; + uint8_t snp_auth = 0; + + const char *passwd = argv[idx_password]->arg; + if (strlen(passwd) > 254) { + vty_out(vty, "Too long area password (>254)\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc > idx_snp_auth) { + snp_auth = SNP_AUTH_SEND; + if (strmatch(argv[idx_snp_auth]->text, "validate")) + snp_auth |= SNP_AUTH_RECV; + } + + if (strmatch(argv[idx_algo]->text, "clear")) { + return isis_area_passwd_cleartext_set(area, level, + passwd, snp_auth); + } else if (strmatch(argv[idx_algo]->text, "md5")) { + return isis_area_passwd_hmac_md5_set(area, level, + passwd, snp_auth); + } + + return CMD_WARNING_CONFIG_FAILED; +} + +DEFUN (domain_passwd, + domain_passwd_cmd, + "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]", + "Set the authentication password for a routing domain\n" + "Authentication type\n" + "Authentication type\n" + "Level-wide password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2); +} + +DEFUN (no_domain_passwd, + no_domain_passwd_cmd, + "no domain-password", + NO_STR + "Set the authentication password for a routing domain\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_area_passwd_unset(area, IS_LEVEL_2); +} + +void isis_vty_init(void) +{ + install_element(INTERFACE_NODE, &ip_router_isis_cmd); + install_element(INTERFACE_NODE, &ip6_router_isis_cmd); + install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); + + install_element(INTERFACE_NODE, &isis_passive_cmd); + install_element(INTERFACE_NODE, &no_isis_passive_cmd); + + install_element(INTERFACE_NODE, &isis_passwd_cmd); + install_element(INTERFACE_NODE, &no_isis_passwd_cmd); + + install_element(INTERFACE_NODE, &isis_metric_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_cmd); + + install_element(INTERFACE_NODE, &isis_hello_interval_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); + + install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); + + install_element(INTERFACE_NODE, &csnp_interval_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_cmd); + + install_element(INTERFACE_NODE, &psnp_interval_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_cmd); + + install_element(INTERFACE_NODE, &circuit_topology_cmd); + install_element(INTERFACE_NODE, &no_circuit_topology_cmd); + + install_element(ROUTER_NODE, &set_overload_bit_cmd); + install_element(ROUTER_NODE, &no_set_overload_bit_cmd); + + install_element(ROUTER_NODE, &area_lsp_mtu_cmd); + install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd); + + install_element(ROUTER_NODE, &area_purge_originator_cmd); + + install_element(ROUTER_NODE, &lsp_gen_interval_cmd); + install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd); + + install_element(ROUTER_NODE, &spf_interval_cmd); + install_element(ROUTER_NODE, &no_spf_interval_cmd); + + install_element(ROUTER_NODE, &max_lsp_lifetime_cmd); + install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd); + + install_element(ROUTER_NODE, &lsp_refresh_interval_cmd); + install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd); + + install_element(ROUTER_NODE, &domain_passwd_cmd); + install_element(ROUTER_NODE, &no_domain_passwd_cmd); + + install_element(ROUTER_NODE, &spf_delay_ietf_cmd); + install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd); + + isis_vty_daemon_init(); +} diff --git a/isisd/isis_vty_common.h b/isisd/isis_vty_common.h new file mode 100644 index 0000000000..b726b4ee83 --- /dev/null +++ b/isisd/isis_vty_common.h @@ -0,0 +1,38 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_common.h + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISIS_VTY_COMMON_H +#define ISIS_VTY_COMMON_H + +struct isis_circuit *isis_circuit_lookup(struct vty *vty); + +int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval); +int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval); +int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval); +int isis_vty_password_set(struct vty *vty, int argc, + struct cmd_token *argv[], int level); + +void isis_vty_daemon_init(void); +void isis_vty_init(void); + +#endif diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c new file mode 100644 index 0000000000..95ebe0de81 --- /dev/null +++ b/isisd/isis_vty_fabricd.c @@ -0,0 +1,94 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_fabricd.c + * + * This file contains the CLI that is specific to OpenFabric + * + * Copyright (C) 2018 Christian Franke, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> + +#include "command.h" + +#include "isisd.h" +#include "isis_vty_common.h" +#include "fabricd.h" +#include "isis_tlvs.h" + +DEFUN (fabric_tier, + fabric_tier_cmd, + "fabric-tier (0-14)", + "Statically configure the tier to advertise\n" + "Tier to advertise\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + uint8_t tier = atoi(argv[1]->arg); + + fabricd_configure_tier(area, tier); + return CMD_SUCCESS; +} + +DEFUN (no_fabric_tier, + no_fabric_tier_cmd, + "no fabric-tier [(0-14)]", + NO_STR + "Statically configure the tier to advertise\n" + "Tier to advertise\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + fabricd_configure_tier(area, ISIS_TIER_UNDEFINED); + return CMD_SUCCESS; +} + +DEFUN (debug_fabric_flooding, + debug_fabric_flooding_cmd, + "debug openfabric flooding", + DEBUG_STR + PROTO_HELP + "Flooding optimization algorithm\n") +{ + isis->debugs |= DEBUG_FABRICD_FLOODING; + print_debug(vty, DEBUG_FABRICD_FLOODING, 1); + + return CMD_SUCCESS; +} + +DEFUN (no_debug_fabric_flooding, + no_debug_fabric_flooding_cmd, + "no debug openfabric flooding", + NO_STR + UNDEBUG_STR + PROTO_HELP + "Flooding optimization algorithm\n") +{ + isis->debugs &= ~DEBUG_FABRICD_FLOODING; + print_debug(vty, DEBUG_FABRICD_FLOODING, 0); + + return CMD_SUCCESS; +} + + +void isis_vty_daemon_init(void) +{ + install_element(ROUTER_NODE, &fabric_tier_cmd); + install_element(ROUTER_NODE, &no_fabric_tier_cmd); + install_element(ENABLE_NODE, &debug_fabric_flooding_cmd); + install_element(ENABLE_NODE, &no_debug_fabric_flooding_cmd); + install_element(CONFIG_NODE, &debug_fabric_flooding_cmd); + install_element(CONFIG_NODE, &no_debug_fabric_flooding_cmd); +} diff --git a/isisd/isis_vty_isisd.c b/isisd/isis_vty_isisd.c new file mode 100644 index 0000000000..95aaeae816 --- /dev/null +++ b/isisd/isis_vty_isisd.c @@ -0,0 +1,858 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_isisd.c + * + * This file contains the CLI that is specific to IS-IS + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. + * Copyright (C) 2018 Christian Franke, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "command.h" + +#include "isis_circuit.h" +#include "isis_csm.h" +#include "isis_misc.h" +#include "isis_mt.h" +#include "isisd.h" +#include "isis_vty_common.h" + +static int level_for_arg(const char *arg) +{ + if (!strcmp(arg, "level-1")) + return IS_LEVEL_1; + else + return IS_LEVEL_2; +} + +DEFUN (isis_circuit_type, + isis_circuit_type_cmd, + "isis circuit-type <level-1|level-1-2|level-2-only>", + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + int idx_level = 2; + int is_type; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + is_type = string2circuit_t(argv[idx_level]->arg); + if (!is_type) { + vty_out(vty, "Unknown circuit-type \n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (circuit->state == C_STATE_UP + && circuit->area->is_type != IS_LEVEL_1_AND_2 + && circuit->area->is_type != is_type) { + vty_out(vty, "Invalid circuit level for area %s.\n", + circuit->area->area_tag); + return CMD_WARNING_CONFIG_FAILED; + } + isis_circuit_is_type_set(circuit, is_type); + + return CMD_SUCCESS; +} + +DEFUN (no_isis_circuit_type, + no_isis_circuit_type_cmd, + "no isis circuit-type <level-1|level-1-2|level-2-only>", + NO_STR + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + int is_type; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + /* + * Set the circuits level to its default value + */ + if (circuit->state == C_STATE_UP) + is_type = circuit->area->is_type; + else + is_type = IS_LEVEL_1_AND_2; + isis_circuit_is_type_set(circuit, is_type); + + return CMD_SUCCESS; +} + +DEFUN (isis_network, + isis_network_cmd, + "isis network point-to-point", + "IS-IS routing protocol\n" + "Set network type\n" + "point-to-point network type\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) { + vty_out(vty, + "isis network point-to-point is valid only on broadcast interfaces\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + return CMD_SUCCESS; +} + +DEFUN (no_isis_network, + no_isis_network_cmd, + "no isis network point-to-point", + NO_STR + "IS-IS routing protocol\n" + "Set network type for circuit\n" + "point-to-point network type\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) { + vty_out(vty, + "isis network point-to-point is valid only on broadcast interfaces\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + return CMD_SUCCESS; +} + +DEFUN (isis_priority, + isis_priority_cmd, + "isis priority (0-127)", + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n") +{ + uint8_t prio = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[0] = prio; + circuit->priority[1] = prio; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_priority, + no_isis_priority_cmd, + "no isis priority [(0-127)]", + NO_STR + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[0] = DEFAULT_PRIORITY; + circuit->priority[1] = DEFAULT_PRIORITY; + + return CMD_SUCCESS; +} + +DEFUN (isis_priority_level, + isis_priority_level_cmd, + "isis priority (0-127) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + uint8_t prio = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[level_for_arg(argv[3]->text)] = prio; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_priority_level, + no_isis_priority_level_cmd, + "no isis priority [(0-127)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[level] = DEFAULT_PRIORITY; + + return CMD_SUCCESS; +} + +DEFUN (isis_metric_level, + isis_metric_level_cmd, + "isis metric (0-16777215) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Default metric value\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n") +{ + uint32_t met = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, + level_for_arg(argv[3]->text), + met), + "Failed to set metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_metric_level, + no_isis_metric_level_cmd, + "no isis metric [(0-16777215)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Default metric value\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, level, + DEFAULT_CIRCUIT_METRIC), + "Failed to set L1 metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_hello_interval_level, + isis_hello_interval_level_cmd, + "isis hello-interval (1-600) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Holdtime 1 second, interval depends on multiplier\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n") +{ + uint32_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[level_for_arg(argv[3]->text)] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_interval_level, + no_isis_hello_interval_level_cmd, + "no isis hello-interval [(1-600)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Holdtime 1 second, interval depends on multiplier\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[level] = DEFAULT_HELLO_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (isis_hello_multiplier_level, + isis_hello_multiplier_level_cmd, + "isis hello-multiplier (2-100) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n") +{ + uint16_t mult = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[level_for_arg(argv[3]->text)] = mult; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_multiplier_level, + no_isis_hello_multiplier_level_cmd, + "no isis hello-multiplier [(2-100)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[level] = DEFAULT_HELLO_MULTIPLIER; + + return CMD_SUCCESS; +} + +DEFUN (isis_threeway_adj, + isis_threeway_adj_cmd, + "[no] isis three-way-handshake", + NO_STR + "IS-IS commands\n" + "Enable/Disable three-way handshake\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->disable_threeway_adj = !strcmp(argv[0]->text, "no"); + return CMD_SUCCESS; +} + +DEFUN (isis_hello_padding, + isis_hello_padding_cmd, + "isis hello padding", + "IS-IS routing protocol\n" + "Add padding to IS-IS hello packets\n" + "Pad hello packets\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->pad_hellos = 1; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_padding, + no_isis_hello_padding_cmd, + "no isis hello padding", + NO_STR + "IS-IS routing protocol\n" + "Add padding to IS-IS hello packets\n" + "Pad hello packets\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->pad_hellos = 0; + + return CMD_SUCCESS; +} + +DEFUN (csnp_interval_level, + csnp_interval_level_cmd, + "isis csnp-interval (1-600) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[level_for_arg(argv[3]->text)] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_csnp_interval_level, + no_csnp_interval_level_cmd, + "no isis csnp-interval [(1-600)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[level] = DEFAULT_CSNP_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (psnp_interval_level, + psnp_interval_level_cmd, + "isis psnp-interval (1-120) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[level_for_arg(argv[3]->text)] = (uint16_t)interval; + + return CMD_SUCCESS; +} + +DEFUN (no_psnp_interval_level, + no_psnp_interval_level_cmd, + "no isis psnp-interval [(1-120)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[level] = DEFAULT_PSNP_INTERVAL; + + return CMD_SUCCESS; +} + +static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) +{ + struct isis_circuit *circuit; + struct listnode *node; + + if (!vty) + return CMD_WARNING_CONFIG_FAILED; + + if (!area) { + vty_out(vty, "ISIS area is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if ((area->is_type & IS_LEVEL_1) + && (circuit->is_type & IS_LEVEL_1) + && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) { + vty_out(vty, "ISIS circuit %s metric is invalid\n", + circuit->interface->name); + return CMD_WARNING_CONFIG_FAILED; + } + if ((area->is_type & IS_LEVEL_2) + && (circuit->is_type & IS_LEVEL_2) + && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) { + vty_out(vty, "ISIS circuit %s metric is invalid\n", + circuit->interface->name); + return CMD_WARNING_CONFIG_FAILED; + } + } + + return CMD_SUCCESS; +} + +DEFUN (metric_style, + metric_style_cmd, + "metric-style <narrow|transition|wide>", + "Use old-style (ISO 10589) or new-style packet formats\n" + "Use old style of TLVs with narrow metric\n" + "Send and accept both styles of TLVs during transition\n" + "Use new style of TLVs to carry wider metric\n") +{ + int idx_metric_style = 1; + VTY_DECLVAR_CONTEXT(isis_area, area); + int ret; + + if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) { + isis_area_metricstyle_set(area, false, true); + return CMD_SUCCESS; + } + + if (area_is_mt(area)) { + vty_out(vty, + "Narrow metrics cannot be used while multi topology IS-IS is active\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = validate_metric_style_narrow(vty, area); + if (ret != CMD_SUCCESS) + return ret; + + if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0) + isis_area_metricstyle_set(area, true, true); + else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0) + isis_area_metricstyle_set(area, true, false); + return CMD_SUCCESS; + + return CMD_SUCCESS; +} + +DEFUN (no_metric_style, + no_metric_style_cmd, + "no metric-style", + NO_STR + "Use old-style (ISO 10589) or new-style packet formats\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int ret; + + if (area_is_mt(area)) { + vty_out(vty, + "Narrow metrics cannot be used while multi topology IS-IS is active\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = validate_metric_style_narrow(vty, area); + if (ret != CMD_SUCCESS) + return ret; + + isis_area_metricstyle_set(area, true, false); + return CMD_SUCCESS; +} + +DEFUN (set_attached_bit, + set_attached_bit_cmd, + "set-attached-bit", + "Set attached bit to identify as L1/L2 router for inter-area traffic\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_attached_bit_set(area, true); + return CMD_SUCCESS; +} + +DEFUN (no_set_attached_bit, + no_set_attached_bit_cmd, + "no set-attached-bit", + NO_STR + "Reset attached bit\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_attached_bit_set(area, false); + return CMD_SUCCESS; +} + +DEFUN (dynamic_hostname, + dynamic_hostname_cmd, + "hostname dynamic", + "Dynamic hostname for IS-IS\n" + "Dynamic hostname\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_dynhostname_set(area, true); + return CMD_SUCCESS; +} + +DEFUN (no_dynamic_hostname, + no_dynamic_hostname_cmd, + "no hostname dynamic", + NO_STR + "Dynamic hostname for IS-IS\n" + "Dynamic hostname\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_dynhostname_set(area, false); + return CMD_SUCCESS; +} + +DEFUN (is_type, + is_type_cmd, + "is-type <level-1|level-1-2|level-2-only>", + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + int idx_level = 1; + VTY_DECLVAR_CONTEXT(isis_area, area); + int type; + + type = string2circuit_t(argv[idx_level]->arg); + if (!type) { + vty_out(vty, "Unknown IS level \n"); + return CMD_SUCCESS; + } + + isis_area_is_type_set(area, type); + + return CMD_SUCCESS; +} + +DEFUN (no_is_type, + no_is_type_cmd, + "no is-type <level-1|level-1-2|level-2-only>", + NO_STR + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int type; + + /* + * Put the is-type back to defaults: + * - level-1-2 on first area + * - level-1 for the rest + */ + if (listgetdata(listhead(isis->area_list)) == area) + type = IS_LEVEL_1_AND_2; + else + type = IS_LEVEL_1; + + isis_area_is_type_set(area, type); + + return CMD_SUCCESS; +} + +DEFUN (lsp_gen_interval_level, + lsp_gen_interval_level_cmd, + "lsp-gen-interval <level-1|level-2> (1-120)", + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + uint16_t interval = atoi(argv[2]->arg); + + return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[1]->text), + interval); +} + +DEFUN (no_lsp_gen_interval_level, + no_lsp_gen_interval_level_cmd, + "no lsp-gen-interval <level-1|level-2> [(1-120)]", + NO_STR + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[2]->text), + DEFAULT_MIN_LSP_GEN_INTERVAL); +} + +DEFUN (max_lsp_lifetime_level, + max_lsp_lifetime_level_cmd, + "max-lsp-lifetime <level-1|level-2> (350-65535)", + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + uint16_t lifetime = atoi(argv[2]->arg); + + return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text), + lifetime); +} + +DEFUN (no_max_lsp_lifetime_level, + no_max_lsp_lifetime_level_cmd, + "no max-lsp-lifetime <level-1|level-2> [(350-65535)]", + NO_STR + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text), + DEFAULT_LSP_LIFETIME); +} + +DEFUN (spf_interval_level, + spf_interval_level_cmd, + "spf-interval <level-1|level-2> (1-120)", + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + uint16_t interval = atoi(argv[2]->arg); + + area->min_spf_interval[level_for_arg(argv[1]->text)] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_spf_interval_level, + no_spf_interval_level_cmd, + "no spf-interval <level-1|level-2> [(1-120)]", + NO_STR + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int level = level_for_arg(argv[1]->text); + + area->min_spf_interval[level] = MINIMUM_SPF_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (lsp_refresh_interval_level, + lsp_refresh_interval_level_cmd, + "lsp-refresh-interval <level-1|level-2> (1-65235)", + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + uint16_t interval = atoi(argv[2]->arg); + return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[1]->text), + interval); +} + +DEFUN (no_lsp_refresh_interval_level, + no_lsp_refresh_interval_level_cmd, + "no lsp-refresh-interval <level-1|level-2> [(1-65235)]", + NO_STR + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[2]->text), + DEFAULT_MAX_LSP_GEN_INTERVAL); +} + +DEFUN (area_passwd, + area_passwd_cmd, + "area-password <clear|md5> WORD [authenticate snp <send-only|validate>]", + "Configure the authentication password for an area\n" + "Authentication type\n" + "Authentication type\n" + "Area password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + return isis_vty_password_set(vty, argc, argv, IS_LEVEL_1); +} + +DEFUN (no_area_passwd, + no_area_passwd_cmd, + "no area-password", + NO_STR + "Configure the authentication password for an area\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_area_passwd_unset(area, IS_LEVEL_1); +} + +void isis_vty_daemon_init(void) +{ + install_element(INTERFACE_NODE, &isis_circuit_type_cmd); + install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); + + install_element(INTERFACE_NODE, &isis_network_cmd); + install_element(INTERFACE_NODE, &no_isis_network_cmd); + + install_element(INTERFACE_NODE, &isis_priority_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_cmd); + install_element(INTERFACE_NODE, &isis_priority_level_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_level_cmd); + + install_element(INTERFACE_NODE, &isis_metric_level_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_level_cmd); + + install_element(INTERFACE_NODE, &isis_hello_interval_level_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_level_cmd); + + install_element(INTERFACE_NODE, &isis_hello_multiplier_level_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_level_cmd); + + install_element(INTERFACE_NODE, &isis_threeway_adj_cmd); + + install_element(INTERFACE_NODE, &isis_hello_padding_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd); + + install_element(INTERFACE_NODE, &csnp_interval_level_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_level_cmd); + + install_element(INTERFACE_NODE, &psnp_interval_level_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_level_cmd); + + install_element(ROUTER_NODE, &metric_style_cmd); + install_element(ROUTER_NODE, &no_metric_style_cmd); + + install_element(ROUTER_NODE, &set_attached_bit_cmd); + install_element(ROUTER_NODE, &no_set_attached_bit_cmd); + + install_element(ROUTER_NODE, &dynamic_hostname_cmd); + install_element(ROUTER_NODE, &no_dynamic_hostname_cmd); + + install_element(ROUTER_NODE, &is_type_cmd); + install_element(ROUTER_NODE, &no_is_type_cmd); + + install_element(ROUTER_NODE, &lsp_gen_interval_level_cmd); + install_element(ROUTER_NODE, &no_lsp_gen_interval_level_cmd); + + install_element(ROUTER_NODE, &max_lsp_lifetime_level_cmd); + install_element(ROUTER_NODE, &no_max_lsp_lifetime_level_cmd); + + install_element(ROUTER_NODE, &spf_interval_level_cmd); + install_element(ROUTER_NODE, &no_spf_interval_level_cmd); + + install_element(ROUTER_NODE, &lsp_refresh_interval_level_cmd); + install_element(ROUTER_NODE, &no_lsp_refresh_interval_level_cmd); + + install_element(ROUTER_NODE, &area_passwd_cmd); + install_element(ROUTER_NODE, &no_area_passwd_cmd); +} diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 9bc0f2ef35..33d8a0f771 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -261,8 +261,10 @@ static void isis_zebra_route_add_route(struct prefix *prefix, return; memset(&api, 0, sizeof(api)); + if (fabricd) + api.flags |= ZEBRA_FLAG_ONLINK; api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; + api.type = PROTO_TYPE; api.safi = SAFI_UNICAST; api.prefix = *prefix; if (src_p && src_p->prefixlen) { @@ -337,7 +339,7 @@ static void isis_zebra_route_del_route(struct prefix *prefix, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; + api.type = PROTO_TYPE; api.safi = SAFI_UNICAST; api.prefix = *prefix; if (src_p && src_p->prefixlen) { @@ -378,7 +380,7 @@ static int isis_zebra_read(int command, struct zclient *zclient, */ if (api.prefix.prefixlen == 0 && api.src_prefix.prefixlen == 0 - && api.type == ZEBRA_ROUTE_ISIS) { + && api.type == PROTO_TYPE) { command = ZEBRA_REDISTRIBUTE_ROUTE_DEL; } @@ -424,7 +426,7 @@ static void isis_zebra_connected(struct zclient *zclient) void isis_zebra_init(struct thread_master *master) { zclient = zclient_new_notify(master, &zclient_options_default); - zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0, &isisd_privs); + zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs); zclient->zebra_connected = isis_zebra_connected; zclient->router_id_update = isis_router_id_update_zebra; zclient->interface_add = isis_zebra_if_add; diff --git a/isisd/isisd.c b/isisd/isisd.c index a19f287453..e3ff3b8d93 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -56,6 +56,7 @@ #include "isisd/isis_events.h" #include "isisd/isis_te.h" #include "isisd/isis_mt.h" +#include "isisd/fabricd.h" struct isis *isis = NULL; @@ -95,6 +96,7 @@ void isis_new(unsigned long process_id) */ /* isis->debugs = 0xFFFF; */ isisMplsTE.status = disable; /* Only support TE metric */ + QOBJ_REG(isis, isis); } @@ -105,10 +107,13 @@ struct isis_area *isis_area_create(const char *area_tag) area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area)); /* - * The first instance is level-1-2 rest are level-1, unless otherwise - * configured + * Fabricd runs only as level-2. + * For IS-IS, the first instance is level-1-2 rest are level-1, + * unless otherwise configured */ - if (listcount(isis->area_list) > 0) + if (fabricd) { + area->is_type = IS_LEVEL_2; + } else if (listcount(isis->area_list) > 0) area->is_type = IS_LEVEL_1; else area->is_type = IS_LEVEL_1_AND_2; @@ -153,6 +158,8 @@ struct isis_area *isis_area_create(const char *area_tag) listnode_add(isis->area_list, area); area->isis = isis; + if (fabricd) + area->fabricd = fabricd_new(area); QOBJ_REG(area, isis_area); return area; @@ -179,7 +186,7 @@ int isis_area_get(struct vty *vty, const char *area_tag) area = isis_area_lookup(area_tag); if (area) { - VTY_PUSH_CONTEXT(ISIS_NODE, area); + VTY_PUSH_CONTEXT(ROUTER_NODE, area); return CMD_SUCCESS; } @@ -188,7 +195,7 @@ int isis_area_get(struct vty *vty, const char *area_tag) if (isis->debugs & DEBUG_EVENTS) zlog_debug("New IS-IS area instance %s", area->area_tag); - VTY_PUSH_CONTEXT(ISIS_NODE, area); + VTY_PUSH_CONTEXT(ROUTER_NODE, area); return CMD_SUCCESS; } @@ -209,6 +216,9 @@ int isis_area_destroy(struct vty *vty, const char *area_tag) QOBJ_UNREG(area); + if (fabricd) + fabricd_finish(area->fabricd); + if (area->circuit_list) { for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode, circuit)) { @@ -463,9 +473,9 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail) DEFUN (show_isis_interface, show_isis_interface_cmd, - "show isis interface", + "show " PROTO_NAME " interface", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS interface\n") { return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF); @@ -473,9 +483,9 @@ DEFUN (show_isis_interface, DEFUN (show_isis_interface_detail, show_isis_interface_detail_cmd, - "show isis interface detail", + "show " PROTO_NAME " interface detail", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS interface\n" "show detailed information\n") { @@ -484,9 +494,9 @@ DEFUN (show_isis_interface_detail, DEFUN (show_isis_interface_arg, show_isis_interface_arg_cmd, - "show isis interface WORD", + "show " PROTO_NAME " interface WORD", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS interface\n" "ISIS interface name\n") { @@ -634,9 +644,9 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id) DEFUN (show_isis_neighbor, show_isis_neighbor_cmd, - "show isis neighbor", + "show " PROTO_NAME " neighbor", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n") { return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF); @@ -644,9 +654,9 @@ DEFUN (show_isis_neighbor, DEFUN (show_isis_neighbor_detail, show_isis_neighbor_detail_cmd, - "show isis neighbor detail", + "show " PROTO_NAME " neighbor detail", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n" "show detailed information\n") { @@ -655,9 +665,9 @@ DEFUN (show_isis_neighbor_detail, DEFUN (show_isis_neighbor_arg, show_isis_neighbor_arg_cmd, - "show isis neighbor WORD", + "show " PROTO_NAME " neighbor WORD", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n" "System id\n") { @@ -668,19 +678,19 @@ DEFUN (show_isis_neighbor_arg, DEFUN (clear_isis_neighbor, clear_isis_neighbor_cmd, - "clear isis neighbor", + "clear " PROTO_NAME " neighbor", CLEAR_STR - "Reset ISIS network information\n" - "Reset ISIS neighbor adjacencies\n") + PROTO_HELP + "ISIS neighbor adjacencies\n") { return clear_isis_neighbor_common(vty, NULL); } DEFUN (clear_isis_neighbor_arg, clear_isis_neighbor_arg_cmd, - "clear isis neighbor WORD", + "clear " PROTO_NAME " neighbor WORD", CLEAR_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n" "System id\n") { @@ -734,16 +744,18 @@ void print_debug(struct vty *vty, int flags, int onoff) vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs); if (flags & DEBUG_LSP_SCHED) vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs); + if (flags & DEBUG_FABRICD_FLOODING) + vty_out(vty, "OpenFabric Flooding debugging is %s\n", onoffs); } DEFUN_NOSH (show_debugging, show_debugging_isis_cmd, - "show debugging [isis]", + "show debugging [" PROTO_NAME "]", SHOW_STR "State of each debugging option\n" - ISIS_STR) + PROTO_HELP) { - vty_out(vty, "IS-IS debugging status:\n"); + vty_out(vty, PROTO_NAME " debugging status:\n"); if (isis->debugs) print_debug(vty, isis->debugs, 1); @@ -760,59 +772,63 @@ static int config_write_debug(struct vty *vty) int flags = isis->debugs; if (flags & DEBUG_ADJ_PACKETS) { - vty_out(vty, "debug isis adj-packets\n"); + vty_out(vty, "debug " PROTO_NAME " adj-packets\n"); write++; } if (flags & DEBUG_CHECKSUM_ERRORS) { - vty_out(vty, "debug isis checksum-errors\n"); + vty_out(vty, "debug " PROTO_NAME " checksum-errors\n"); write++; } if (flags & DEBUG_LOCAL_UPDATES) { - vty_out(vty, "debug isis local-updates\n"); + vty_out(vty, "debug " PROTO_NAME " local-updates\n"); write++; } if (flags & DEBUG_PROTOCOL_ERRORS) { - vty_out(vty, "debug isis protocol-errors\n"); + vty_out(vty, "debug " PROTO_NAME " protocol-errors\n"); write++; } if (flags & DEBUG_SNP_PACKETS) { - vty_out(vty, "debug isis snp-packets\n"); + vty_out(vty, "debug " PROTO_NAME " snp-packets\n"); write++; } if (flags & DEBUG_SPF_EVENTS) { - vty_out(vty, "debug isis spf-events\n"); + vty_out(vty, "debug " PROTO_NAME " spf-events\n"); write++; } if (flags & DEBUG_SPF_STATS) { - vty_out(vty, "debug isis spf-statistics\n"); + vty_out(vty, "debug " PROTO_NAME " spf-statistics\n"); write++; } if (flags & DEBUG_SPF_TRIGGERS) { - vty_out(vty, "debug isis spf-triggers\n"); + vty_out(vty, "debug " PROTO_NAME " spf-triggers\n"); write++; } if (flags & DEBUG_UPDATE_PACKETS) { - vty_out(vty, "debug isis update-packets\n"); + vty_out(vty, "debug " PROTO_NAME " update-packets\n"); write++; } if (flags & DEBUG_RTE_EVENTS) { - vty_out(vty, "debug isis route-events\n"); + vty_out(vty, "debug " PROTO_NAME " route-events\n"); write++; } if (flags & DEBUG_EVENTS) { - vty_out(vty, "debug isis events\n"); + vty_out(vty, "debug " PROTO_NAME " events\n"); write++; } if (flags & DEBUG_PACKET_DUMP) { - vty_out(vty, "debug isis packet-dump\n"); + vty_out(vty, "debug " PROTO_NAME " packet-dump\n"); write++; } if (flags & DEBUG_LSP_GEN) { - vty_out(vty, "debug isis lsp-gen\n"); + vty_out(vty, "debug " PROTO_NAME " lsp-gen\n"); write++; } if (flags & DEBUG_LSP_SCHED) { - vty_out(vty, "debug isis lsp-sched\n"); + vty_out(vty, "debug " PROTO_NAME " lsp-sched\n"); + write++; + } + if (flags & DEBUG_FABRICD_FLOODING) { + vty_out(vty, "debug " PROTO_NAME " flooding\n"); write++; } write += spf_backoff_write_config(vty); @@ -822,9 +838,9 @@ static int config_write_debug(struct vty *vty) DEFUN (debug_isis_adj, debug_isis_adj_cmd, - "debug isis adj-packets", + "debug " PROTO_NAME " adj-packets", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Adjacency related packets\n") { isis->debugs |= DEBUG_ADJ_PACKETS; @@ -835,10 +851,10 @@ DEFUN (debug_isis_adj, DEFUN (no_debug_isis_adj, no_debug_isis_adj_cmd, - "no debug isis adj-packets", + "no debug " PROTO_NAME " adj-packets", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Adjacency related packets\n") { isis->debugs &= ~DEBUG_ADJ_PACKETS; @@ -849,9 +865,9 @@ DEFUN (no_debug_isis_adj, DEFUN (debug_isis_csum, debug_isis_csum_cmd, - "debug isis checksum-errors", + "debug " PROTO_NAME " checksum-errors", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP checksum errors\n") { isis->debugs |= DEBUG_CHECKSUM_ERRORS; @@ -862,10 +878,10 @@ DEFUN (debug_isis_csum, DEFUN (no_debug_isis_csum, no_debug_isis_csum_cmd, - "no debug isis checksum-errors", + "no debug " PROTO_NAME " checksum-errors", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP checksum errors\n") { isis->debugs &= ~DEBUG_CHECKSUM_ERRORS; @@ -876,9 +892,9 @@ DEFUN (no_debug_isis_csum, DEFUN (debug_isis_lupd, debug_isis_lupd_cmd, - "debug isis local-updates", + "debug " PROTO_NAME " local-updates", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS local update packets\n") { isis->debugs |= DEBUG_LOCAL_UPDATES; @@ -889,10 +905,10 @@ DEFUN (debug_isis_lupd, DEFUN (no_debug_isis_lupd, no_debug_isis_lupd_cmd, - "no debug isis local-updates", + "no debug " PROTO_NAME " local-updates", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS local update packets\n") { isis->debugs &= ~DEBUG_LOCAL_UPDATES; @@ -903,9 +919,9 @@ DEFUN (no_debug_isis_lupd, DEFUN (debug_isis_err, debug_isis_err_cmd, - "debug isis protocol-errors", + "debug " PROTO_NAME " protocol-errors", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP protocol errors\n") { isis->debugs |= DEBUG_PROTOCOL_ERRORS; @@ -916,10 +932,10 @@ DEFUN (debug_isis_err, DEFUN (no_debug_isis_err, no_debug_isis_err_cmd, - "no debug isis protocol-errors", + "no debug " PROTO_NAME " protocol-errors", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP protocol errors\n") { isis->debugs &= ~DEBUG_PROTOCOL_ERRORS; @@ -930,9 +946,9 @@ DEFUN (no_debug_isis_err, DEFUN (debug_isis_snp, debug_isis_snp_cmd, - "debug isis snp-packets", + "debug " PROTO_NAME " snp-packets", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS CSNP/PSNP packets\n") { isis->debugs |= DEBUG_SNP_PACKETS; @@ -943,10 +959,10 @@ DEFUN (debug_isis_snp, DEFUN (no_debug_isis_snp, no_debug_isis_snp_cmd, - "no debug isis snp-packets", + "no debug " PROTO_NAME " snp-packets", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS CSNP/PSNP packets\n") { isis->debugs &= ~DEBUG_SNP_PACKETS; @@ -957,9 +973,9 @@ DEFUN (no_debug_isis_snp, DEFUN (debug_isis_upd, debug_isis_upd_cmd, - "debug isis update-packets", + "debug " PROTO_NAME " update-packets", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Update related packets\n") { isis->debugs |= DEBUG_UPDATE_PACKETS; @@ -970,10 +986,10 @@ DEFUN (debug_isis_upd, DEFUN (no_debug_isis_upd, no_debug_isis_upd_cmd, - "no debug isis update-packets", + "no debug " PROTO_NAME " update-packets", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Update related packets\n") { isis->debugs &= ~DEBUG_UPDATE_PACKETS; @@ -984,9 +1000,9 @@ DEFUN (no_debug_isis_upd, DEFUN (debug_isis_spfevents, debug_isis_spfevents_cmd, - "debug isis spf-events", + "debug " PROTO_NAME " spf-events", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Shortest Path First Events\n") { isis->debugs |= DEBUG_SPF_EVENTS; @@ -997,10 +1013,10 @@ DEFUN (debug_isis_spfevents, DEFUN (no_debug_isis_spfevents, no_debug_isis_spfevents_cmd, - "no debug isis spf-events", + "no debug " PROTO_NAME " spf-events", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Shortest Path First Events\n") { isis->debugs &= ~DEBUG_SPF_EVENTS; @@ -1011,9 +1027,9 @@ DEFUN (no_debug_isis_spfevents, DEFUN (debug_isis_spfstats, debug_isis_spfstats_cmd, - "debug isis spf-statistics ", + "debug " PROTO_NAME " spf-statistics ", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF Timing and Statistic Data\n") { isis->debugs |= DEBUG_SPF_STATS; @@ -1024,10 +1040,10 @@ DEFUN (debug_isis_spfstats, DEFUN (no_debug_isis_spfstats, no_debug_isis_spfstats_cmd, - "no debug isis spf-statistics", + "no debug " PROTO_NAME " spf-statistics", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF Timing and Statistic Data\n") { isis->debugs &= ~DEBUG_SPF_STATS; @@ -1038,9 +1054,9 @@ DEFUN (no_debug_isis_spfstats, DEFUN (debug_isis_spftrigg, debug_isis_spftrigg_cmd, - "debug isis spf-triggers", + "debug " PROTO_NAME " spf-triggers", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF triggering events\n") { isis->debugs |= DEBUG_SPF_TRIGGERS; @@ -1051,10 +1067,10 @@ DEFUN (debug_isis_spftrigg, DEFUN (no_debug_isis_spftrigg, no_debug_isis_spftrigg_cmd, - "no debug isis spf-triggers", + "no debug " PROTO_NAME " spf-triggers", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF triggering events\n") { isis->debugs &= ~DEBUG_SPF_TRIGGERS; @@ -1065,9 +1081,9 @@ DEFUN (no_debug_isis_spftrigg, DEFUN (debug_isis_rtevents, debug_isis_rtevents_cmd, - "debug isis route-events", + "debug " PROTO_NAME " route-events", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Route related events\n") { isis->debugs |= DEBUG_RTE_EVENTS; @@ -1078,10 +1094,10 @@ DEFUN (debug_isis_rtevents, DEFUN (no_debug_isis_rtevents, no_debug_isis_rtevents_cmd, - "no debug isis route-events", + "no debug " PROTO_NAME " route-events", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Route related events\n") { isis->debugs &= ~DEBUG_RTE_EVENTS; @@ -1092,9 +1108,9 @@ DEFUN (no_debug_isis_rtevents, DEFUN (debug_isis_events, debug_isis_events_cmd, - "debug isis events", + "debug " PROTO_NAME " events", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Events\n") { isis->debugs |= DEBUG_EVENTS; @@ -1105,10 +1121,10 @@ DEFUN (debug_isis_events, DEFUN (no_debug_isis_events, no_debug_isis_events_cmd, - "no debug isis events", + "no debug " PROTO_NAME " events", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Events\n") { isis->debugs &= ~DEBUG_EVENTS; @@ -1119,9 +1135,9 @@ DEFUN (no_debug_isis_events, DEFUN (debug_isis_packet_dump, debug_isis_packet_dump_cmd, - "debug isis packet-dump", + "debug " PROTO_NAME " packet-dump", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS packet dump\n") { isis->debugs |= DEBUG_PACKET_DUMP; @@ -1132,10 +1148,10 @@ DEFUN (debug_isis_packet_dump, DEFUN (no_debug_isis_packet_dump, no_debug_isis_packet_dump_cmd, - "no debug isis packet-dump", + "no debug " PROTO_NAME " packet-dump", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS packet dump\n") { isis->debugs &= ~DEBUG_PACKET_DUMP; @@ -1146,9 +1162,9 @@ DEFUN (no_debug_isis_packet_dump, DEFUN (debug_isis_lsp_gen, debug_isis_lsp_gen_cmd, - "debug isis lsp-gen", + "debug " PROTO_NAME " lsp-gen", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS generation of own LSPs\n") { isis->debugs |= DEBUG_LSP_GEN; @@ -1159,10 +1175,10 @@ DEFUN (debug_isis_lsp_gen, DEFUN (no_debug_isis_lsp_gen, no_debug_isis_lsp_gen_cmd, - "no debug isis lsp-gen", + "no debug " PROTO_NAME " lsp-gen", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS generation of own LSPs\n") { isis->debugs &= ~DEBUG_LSP_GEN; @@ -1173,9 +1189,9 @@ DEFUN (no_debug_isis_lsp_gen, DEFUN (debug_isis_lsp_sched, debug_isis_lsp_sched_cmd, - "debug isis lsp-sched", + "debug " PROTO_NAME " lsp-sched", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS scheduling of LSP generation\n") { isis->debugs |= DEBUG_LSP_SCHED; @@ -1186,10 +1202,10 @@ DEFUN (debug_isis_lsp_sched, DEFUN (no_debug_isis_lsp_sched, no_debug_isis_lsp_sched_cmd, - "no debug isis lsp-sched", + "no debug " PROTO_NAME " lsp-sched", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS scheduling of LSP generation\n") { isis->debugs &= ~DEBUG_LSP_SCHED; @@ -1200,9 +1216,9 @@ DEFUN (no_debug_isis_lsp_sched, DEFUN (show_hostname, show_hostname_cmd, - "show isis hostname", + "show " PROTO_NAME " hostname", SHOW_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Dynamic hostname mapping\n") { dynhn_print_all(vty); @@ -1212,10 +1228,10 @@ DEFUN (show_hostname, DEFUN (show_isis_spf_ietf, show_isis_spf_ietf_cmd, - "show isis spf-delay-ietf", + "show " PROTO_NAME " spf-delay-ietf", SHOW_STR - "IS-IS information\n" - "IS-IS SPF delay IETF information\n") + PROTO_HELP + "SPF delay IETF information\n") { if (!isis) { vty_out(vty, "ISIS is not running\n"); @@ -1261,15 +1277,15 @@ DEFUN (show_isis_spf_ietf, DEFUN (show_isis_summary, show_isis_summary_cmd, - "show isis summary", - SHOW_STR "IS-IS information\n" "IS-IS summary\n") + "show " PROTO_NAME " summary", + SHOW_STR PROTO_HELP "summary\n") { struct listnode *node, *node2; struct isis_area *area; int level; if (isis == NULL) { - vty_out(vty, "ISIS is not running\n"); + vty_out(vty, PROTO_NAME " is not running\n"); return CMD_SUCCESS; } @@ -1289,6 +1305,14 @@ DEFUN (show_isis_summary, vty_out(vty, "Area %s:\n", area->area_tag ? area->area_tag : "null"); + if (fabricd) { + uint8_t tier = fabricd_tier(area); + if (tier == ISIS_TIER_UNDEFINED) + vty_out(vty, " Tier: undefined\n"); + else + vty_out(vty, " Tier: %" PRIu8 "\n", tier); + } + if (listcount(area->area_addrs) > 0) { struct area_addr *area_addr; for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2, @@ -1471,10 +1495,10 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level) DEFUN (show_database, show_database_cmd, - "show isis database [detail] [WORD]", + "show " PROTO_NAME " database [detail] [WORD]", SHOW_STR - "IS-IS information\n" - "IS-IS link state database\n" + PROTO_HELP + "Link state database\n" "Detailed information\n" "LSP ID\n") { @@ -1491,9 +1515,9 @@ DEFUN (show_database, */ DEFUN_NOSH (router_isis, router_isis_cmd, - "router isis WORD", + "router " PROTO_NAME " WORD", ROUTER_STR - "ISO IS-IS\n" + PROTO_HELP "ISO Routing area tag\n") { int idx_word = 2; @@ -1505,8 +1529,11 @@ DEFUN_NOSH (router_isis, */ DEFUN (no_router_isis, no_router_isis_cmd, - "no router isis WORD", - "no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag\n") + "no router " PROTO_NAME " WORD", + NO_STR + ROUTER_STR + PROTO_HELP + "ISO Routing area tag\n") { int idx_word = 3; return isis_area_destroy(vty, argv[idx_word]->arg); @@ -1869,7 +1896,7 @@ int isis_config_write(struct vty *vty) for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { /* ISIS - Area name */ - vty_out(vty, "router isis %s\n", area->area_tag); + vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag); write++; /* ISIS - Net */ if (listcount(area->area_addrs) > 0) { @@ -1893,16 +1920,18 @@ int isis_config_write(struct vty *vty) write++; } /* ISIS - Metric-Style - when true displays wide */ - if (area->newmetric) { - if (!area->oldmetric) - vty_out(vty, " metric-style wide\n"); - else - vty_out(vty, - " metric-style transition\n"); - write++; - } else { - vty_out(vty, " metric-style narrow\n"); - write++; + if (!fabricd) { + if (area->newmetric) { + if (!area->oldmetric) + vty_out(vty, " metric-style wide\n"); + else + vty_out(vty, + " metric-style transition\n"); + write++; + } else { + vty_out(vty, " metric-style narrow\n"); + write++; + } } /* ISIS - overload-bit */ if (area->overload_bit) { @@ -1910,12 +1939,14 @@ int isis_config_write(struct vty *vty) write++; } /* ISIS - Area is-type (level-1-2 is default) */ - if (area->is_type == IS_LEVEL_1) { - vty_out(vty, " is-type level-1\n"); - write++; - } else if (area->is_type == IS_LEVEL_2) { - vty_out(vty, " is-type level-2-only\n"); - write++; + if (!fabricd) { + if (area->is_type == IS_LEVEL_1) { + vty_out(vty, " is-type level-1\n"); + write++; + } else if (area->is_type == IS_LEVEL_2) { + vty_out(vty, " is-type level-2-only\n"); + write++; + } } write += isis_redist_config_write(vty, area, AF_INET); write += isis_redist_config_write(vty, area, AF_INET6); @@ -1998,6 +2029,10 @@ int isis_config_write(struct vty *vty) vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu); write++; } + if (area->purge_originator) { + vty_out(vty, " purge-originator\n"); + write++; + } /* Minimum SPF interval. */ if (area->min_spf_interval[0] @@ -2116,6 +2151,7 @@ int isis_config_write(struct vty *vty) } write += area_write_mt_settings(area, vty); + write += fabricd_write_settings(area, vty); } isis_mpls_te_config_write_router(vty); } @@ -2123,12 +2159,12 @@ int isis_config_write(struct vty *vty) return write; } -struct cmd_node isis_node = {ISIS_NODE, "%s(config-router)# ", 1}; +struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1}; void isis_init() { /* Install IS-IS top node */ - install_node(&isis_node, isis_config_write); + install_node(&router_node, isis_config_write); install_element(VIEW_NODE, &show_isis_summary_cmd); @@ -2212,16 +2248,16 @@ void isis_init() install_element(CONFIG_NODE, &router_isis_cmd); install_element(CONFIG_NODE, &no_router_isis_cmd); - install_default(ISIS_NODE); + install_default(ROUTER_NODE); - install_element(ISIS_NODE, &net_cmd); - install_element(ISIS_NODE, &no_net_cmd); + install_element(ROUTER_NODE, &net_cmd); + install_element(ROUTER_NODE, &no_net_cmd); - install_element(ISIS_NODE, &isis_topology_cmd); - install_element(ISIS_NODE, &no_isis_topology_cmd); + install_element(ROUTER_NODE, &isis_topology_cmd); + install_element(ROUTER_NODE, &no_isis_topology_cmd); - install_element(ISIS_NODE, &log_adj_changes_cmd); - install_element(ISIS_NODE, &no_log_adj_changes_cmd); + install_element(ROUTER_NODE, &log_adj_changes_cmd); + install_element(ROUTER_NODE, &no_log_adj_changes_cmd); spf_backoff_cmd_init(); } diff --git a/isisd/isisd.h b/isisd/isisd.h index ce602e4402..864021428a 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -33,12 +33,32 @@ #include "isis_memory.h" #include "qobj.h" +#ifdef FABRICD +static const bool fabricd = true; +#define PROTO_TYPE ZEBRA_ROUTE_OPENFABRIC +#define PROTO_NAME "openfabric" +#define PROTO_HELP "OpenFabric routing protocol\n" +#define PROTO_REDIST_STR FRR_REDIST_STR_FABRICD +#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_FABRICD +#define ROUTER_NODE OPENFABRIC_NODE +#else +static const bool fabricd = false; +#define PROTO_TYPE ZEBRA_ROUTE_ISIS +#define PROTO_NAME "isis" +#define PROTO_HELP "IS-IS routing protocol\n" +#define PROTO_REDIST_STR FRR_REDIST_STR_ISISD +#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_ISISD +#define ROUTER_NODE ISIS_NODE +#endif + extern struct zebra_privs_t isisd_privs; /* uncomment if you are a developer in bug hunt */ /* #define EXTREME_DEBUG */ /* #define EXTREME_DICT_DEBUG */ +struct fabricd; + struct isis { unsigned long process_id; int sysid_set; @@ -93,6 +113,8 @@ struct isis_area { */ int lsp_regenerate_pending[ISIS_LEVELS]; + struct fabricd *fabricd; + /* * Configurables */ @@ -126,6 +148,7 @@ struct isis_area { /* multi topology settings */ struct list *mt_settings; int ipv6_circuits; + bool purge_originator; /* Counters */ uint32_t circuit_state_changes; struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT] @@ -168,7 +191,6 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level, const char *passwd, uint8_t snp_auth); int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level, const char *passwd, uint8_t snp_auth); -void isis_vty_init(void); /* Master of threads. */ extern struct thread_master *master; @@ -188,6 +210,7 @@ extern struct thread_master *master; #define DEBUG_PACKET_DUMP (1<<12) #define DEBUG_LSP_GEN (1<<13) #define DEBUG_LSP_SCHED (1<<14) +#define DEBUG_FABRICD_FLOODING (1<<15) #define lsp_debug(...) \ do { \ diff --git a/isisd/subdir.am b/isisd/subdir.am index 7b8be46167..7571255e59 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -6,35 +6,23 @@ if ISISD noinst_LIBRARIES += isisd/libisis.a sbin_PROGRAMS += isisd/isisd dist_examples_DATA += isisd/isisd.conf.sample +vtysh_scan += \ + $(top_srcdir)/isisd/isis_redist.c \ + $(top_srcdir)/isisd/isis_spf.c \ + $(top_srcdir)/isisd/isis_te.c \ + $(top_srcdir)/isisd/isis_vty_common.c \ + $(top_srcdir)/isisd/isis_vty_fabricd.c \ + $(top_srcdir)/isisd/isis_vty_isisd.c \ + $(top_srcdir)/isisd/isisd.c \ + # end +man8 += $(MANBUILD)/isisd.8 endif -isisd_libisis_a_SOURCES = \ - isisd/dict.c \ - isisd/isis_adjacency.c \ - isisd/isis_circuit.c \ - isisd/isis_csm.c \ - isisd/isis_dr.c \ - isisd/isis_dynhn.c \ - isisd/isis_errors.c \ - isisd/isis_events.c \ - isisd/isis_flags.c \ - isisd/isis_lsp.c \ - isisd/isis_lsp_hash.c \ - isisd/isis_memory.c \ - isisd/isis_misc.c \ - isisd/isis_mt.c \ - isisd/isis_pdu.c \ - isisd/isis_redist.c \ - isisd/isis_route.c \ - isisd/isis_routemap.c \ - isisd/isis_spf.c \ - isisd/isis_te.c \ - isisd/isis_tlvs.c \ - isisd/isis_vty.c \ - isisd/isis_zebra.c \ - isisd/isisd.c \ - isisd/iso_checksum.c \ - # end +if FABRICD +noinst_LIBRARIES += isisd/libfabric.a +sbin_PROGRAMS += isisd/fabricd +dist_examples_DATA += isisd/fabricd.conf.sample +endif noinst_HEADERS += \ isisd/dict.h \ @@ -49,7 +37,6 @@ noinst_HEADERS += \ isisd/isis_events.h \ isisd/isis_flags.h \ isisd/isis_lsp.h \ - isisd/isis_lsp_hash.h \ isisd/isis_memory.h \ isisd/isis_misc.h \ isisd/isis_mt.h \ @@ -59,17 +46,73 @@ noinst_HEADERS += \ isisd/isis_route.h \ isisd/isis_routemap.h \ isisd/isis_spf.h \ + isisd/isis_spf_private.h \ isisd/isis_te.h \ isisd/isis_tlvs.h \ + isisd/isis_tx_queue.h \ + isisd/isis_vty_common.h \ isisd/isis_zebra.h \ isisd/isisd.h \ isisd/iso_checksum.h \ + isisd/fabricd.h \ # end -isisd_isisd_LDADD = isisd/libisis.a lib/libfrr.la @LIBCAP@ -isisd_isisd_SOURCES = \ +LIBISIS_SOURCES = \ + isisd/dict.c \ + isisd/isis_adjacency.c \ + isisd/isis_circuit.c \ + isisd/isis_csm.c \ + isisd/isis_dr.c \ + isisd/isis_dynhn.c \ + isisd/isis_errors.c \ + isisd/isis_events.c \ + isisd/isis_flags.c \ + isisd/isis_lsp.c \ + isisd/isis_memory.c \ + isisd/isis_misc.c \ + isisd/isis_mt.c \ + isisd/isis_pdu.c \ + isisd/isis_redist.c \ + isisd/isis_route.c \ + isisd/isis_routemap.c \ + isisd/isis_spf.c \ + isisd/isis_te.c \ + isisd/isis_tlvs.c \ + isisd/isis_tx_queue.c \ + isisd/isis_vty_common.c \ + isisd/isis_zebra.c \ + isisd/isisd.c \ + isisd/iso_checksum.c \ + isisd/fabricd.c \ + # end + +ISIS_SOURCES = \ isisd/isis_bpf.c \ isisd/isis_dlpi.c \ isisd/isis_main.c \ isisd/isis_pfpacket.c \ # end + +ISIS_LDADD_COMMON = lib/libfrr.la @LIBCAP@ + +# Building isisd + +isisd_libisis_a_SOURCES = \ + $(LIBISIS_SOURCES) \ + isisd/isis_vty_isisd.c \ + #end +isisd_isisd_LDADD = isisd/libisis.a $(ISIS_LDADD_COMMON) +isisd_isisd_SOURCES = $(ISIS_SOURCES) + +# Building fabricd + +FABRICD_CPPFLAGS = -DFABRICD=1 $(AM_CPPFLAGS) + +isisd_libfabric_a_SOURCES = \ + $(LIBISIS_SOURCES) \ + isisd/isis_vty_fabricd.c \ + #end +isisd_libfabric_a_CPPFLAGS = $(FABRICD_CPPFLAGS) +isisd_fabricd_LDADD = isisd/libfabric.a $(ISIS_LDADD_COMMON) +isisd_fabricd_SOURCES = $(ISIS_SOURCES) +isisd_fabricd_CPPFLAGS = $(FABRICD_CPPFLAGS) diff --git a/ldpd/.gitignore b/ldpd/.gitignore index a2f4b51698..ec8a5c4086 100644 --- a/ldpd/.gitignore +++ b/ldpd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ldpd ldpd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/ldpd/adjacency.c b/ldpd/adjacency.c index 7e4f0fd78b..0bdd2423c7 100644 --- a/ldpd/adjacency.c +++ b/ldpd/adjacency.c @@ -60,11 +60,11 @@ adj_compare(const struct adj *a, const struct adj *b) 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)); diff --git a/ldpd/interface.c b/ldpd/interface.c index b25be43a5c..8b45703d22 100644 --- a/ldpd/interface.c +++ b/ldpd/interface.c @@ -45,7 +45,7 @@ RB_GENERATE(iface_head, iface, entry, iface_compare) 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 * diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c index 1cfeae3092..7f2e396a7f 100644 --- a/ldpd/l2vpn.c +++ b/ldpd/l2vpn.c @@ -119,7 +119,7 @@ l2vpn_exit(struct l2vpn *l2vpn) 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 * @@ -182,7 +182,7 @@ l2vpn_if_update(struct l2vpn_if *lif) 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 * diff --git a/ldpd/lde.c b/ldpd/lde.c index 03b62b482b..4f74d93044 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -1620,10 +1620,8 @@ lde_address_list_free(struct lde_nbr *ln) { struct lde_addr *lde_addr; - while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) { - TAILQ_REMOVE(&ln->addr_list, lde_addr, entry); + while ((lde_addr = TAILQ_POP_FIRST(&ln->addr_list, entry)) != NULL) free(lde_addr); - } } static void zclient_sync_init(unsigned short instance) @@ -1643,7 +1641,7 @@ 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); } diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 935e959596..137d9622d5 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -484,7 +484,7 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync) 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 { diff --git a/ldpd/pfkey.c b/ldpd/pfkey.c index 906737217c..a719d0cbb7 100644 --- a/ldpd/pfkey.c +++ b/ldpd/pfkey.c @@ -17,6 +17,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __OpenBSD__ #include <sys/types.h> #include <sys/socket.h> diff --git a/ldpd/subdir.am b/ldpd/subdir.am index 2d87be0cda..24e738d622 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -6,6 +6,8 @@ if LDPD noinst_LIBRARIES += ldpd/libldp.a sbin_PROGRAMS += ldpd/ldpd dist_examples_DATA += ldpd/ldpd.conf.sample +vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c +man8 += $(MANBUILD)/ldpd.8 endif ldpd_libldp_a_SOURCES = \ diff --git a/lib/.gitignore b/lib/.gitignore index 072146dbd5..6176b30f8d 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,26 +1,13 @@ -!Makefile -Makefile.in -*.o -*.lo -*.la -version.c -version.h -gitversion.h -gitversion.h.tmp -.deps -.nfs* -.libs -.arch-inventory -.arch-ids -*~ -*.loT -route_types.h -memtypes.h -command_lex.c -command_lex.h -command_parse.c -command_parse.h -refix -grammar_sandbox -clippy -defun_lex.c +/version.c +/version.h +/gitversion.h +/gitversion.h.tmp +/route_types.h +/memtypes.h +/command_lex.c +/command_lex.h +/command_parse.c +/command_parse.h +/grammar_sandbox +/clippy +/defun_lex.c diff --git a/lib/agentx.c b/lib/agentx.c index 8e6493d4d3..55bb9e99ec 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -142,23 +142,20 @@ static int agentx_log_callback(int major, int minor, void *serverarg, 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); diff --git a/lib/buffer.c b/lib/buffer.c index 1799c6b94f..bb2cdb7e54 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -332,7 +332,7 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, } 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, @@ -365,8 +365,9 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, 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; } @@ -377,8 +378,8 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, } #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. */ @@ -438,17 +439,16 @@ in one shot. */ 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; @@ -493,8 +493,8 @@ buffer_status_t buffer_write(struct buffer *b, int fd, const void *p, 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; } } diff --git a/lib/command.c b/lib/command.c index 1df6442107..e4e3d786ac 100644 --- a/lib/command.c +++ b/lib/command.c @@ -146,6 +146,7 @@ const char *node_names[] = { */ "bfd", /* BFD_NODE */ "bfd peer", /* BFD_PEER_NODE */ + "openfabric", // OPENFABRIC_NODE }; /* clang-format on */ @@ -617,8 +618,8 @@ static int cmd_try_do_shortcut(enum node_type node, char *first_word) */ 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); } @@ -1197,6 +1198,7 @@ static int handle_pipe_action(struct vty *vty, const char *cmd_in, /* retrieve action */ token = strsep(&working, " "); + assert(token); /* match result to known actions */ if (strmatch(token, "include")) { @@ -1435,6 +1437,7 @@ void cmd_exit(struct vty *vty) case LDP_NODE: case LDP_L2VPN_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case RMAP_NODE: case PBRMAP_NODE: @@ -1550,6 +1553,7 @@ DEFUN (config_end, case LDP_L2VPN_NODE: case LDP_PSEUDOWIRE_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case KEYCHAIN_KEY_NODE: case VTY_NODE: @@ -2417,7 +2421,7 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel) 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; } diff --git a/lib/command.h b/lib/command.h index 75b69507ec..8e51641b88 100644 --- a/lib/command.h +++ b/lib/command.h @@ -141,6 +141,7 @@ enum node_type { BGP_FLOWSPECV6_NODE, /* BGP IPv6 FLOWSPEC Address-Family */ BFD_NODE, /* BFD protocol mode. */ BFD_PEER_NODE, /* BFD peer configuration mode. */ + OPENFABRIC_NODE, /* OpenFabric router configuration node */ NODE_TYPE_MAX, /* maximum */ }; @@ -364,7 +365,6 @@ struct cmd_node { #define PREFIX_LIST_STR "Build a prefix list\n" #define OSPF6_DUMP_TYPE_LIST \ "<neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr>" -#define ISIS_STR "IS-IS information\n" #define AREA_TAG_STR "[area tag]\n" #define COMMUNITY_AANN_STR "Community number where AA and NN are (0-65535)\n" #define COMMUNITY_VAL_STR "Community number in AA:NN format (where AA and NN are (0-65535)) or local-AS|no-advertise|no-export|internet or additive\n" diff --git a/lib/command_lex.l b/lib/command_lex.l index 0d6e6ee7e5..3b18b58a2e 100644 --- a/lib/command_lex.l +++ b/lib/command_lex.l @@ -22,6 +22,11 @@ * 02111-1307, USA. */ +%top{ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +} %{ /* ignore flex generated code in static analyzer */ #ifndef __clang_analyzer__ diff --git a/lib/command_match.c b/lib/command_match.c index c165305d78..a1ae3ac6b9 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -195,7 +195,7 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline, 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 @@ -326,8 +326,8 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline, } 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) @@ -17,6 +17,11 @@ * with this program; see the file COPYING; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -563,6 +568,8 @@ void csv_decode(csv_t *csv, char *inbuf) csv_record_t *rec; buf = (inbuf) ? inbuf : csv->buf; + assert(buf); + pos = strpbrk(buf, "\n"); while (pos != NULL) { rec = calloc(1, sizeof(csv_record_t)); diff --git a/lib/defun_lex.l b/lib/defun_lex.l index d901c26a2e..6c0805a4fa 100644 --- a/lib/defun_lex.l +++ b/lib/defun_lex.l @@ -1,4 +1,3 @@ -%{ /* * clippy (CLI preparator in python) C pseudo-lexer * Copyright (C) 2016-2017 David Lamparter for NetDEF, Inc. @@ -34,6 +33,12 @@ * code documentation in it. */ +%top{ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +} +%{ /* ignore harmless bugs in old versions of flex */ #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wunused-value" diff --git a/lib/ferr.c b/lib/ferr.c index 35d0fe4ff4..afef196cec 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -14,6 +14,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <stdarg.h> #include <string.h> @@ -148,7 +152,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json) snprintf(pbuf, sizeof(pbuf), "\nError %"PRIu32" - %s", ref->code, ref->title); memset(ubuf, '=', strlen(pbuf)); - ubuf[strlen(pbuf) - 1] = '\0'; + ubuf[strlen(pbuf)] = '\0'; vty_out(vty, "%s\n%s\n", pbuf, ubuf); vty_out(vty, "Description:\n%s\n\n", ref->description); diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index c0aae5e52e..d48b23f38a 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -19,6 +19,9 @@ #include <zebra.h> #include <pthread.h> +#ifdef HAVE_PTHREAD_NP_H +#include <pthread_np.h> +#endif #include <sched.h> #include "frr_pthread.h" @@ -163,10 +166,14 @@ int frr_pthread_set_name(struct frr_pthread *fpt, const char *name, pthread_mutex_lock(&fpt->mtx); snprintf(fpt->os_name, OS_THREAD_NAMELEN, "%s", os_name); pthread_mutex_unlock(&fpt->mtx); -#ifdef GNU_LINUX +#ifdef HAVE_PTHREAD_SETNAME_NP +# ifdef GNU_LINUX ret = pthread_setname_np(fpt->thread, fpt->os_name); -#elif defined(OPEN_BSD) - ret = pthread_set_name_np(fpt->thread, fpt->os_name); +# else /* NetBSD */ + ret = pthread_setname_np(fpt->thread, fpt->os_name, NULL); +# endif +#elif defined(HAVE_PTHREAD_SET_NAME_NP) + pthread_set_name_np(fpt->thread, fpt->os_name); #endif } diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h index cc4fc74337..732e2925fe 100644 --- a/lib/frr_pthread.h +++ b/lib/frr_pthread.h @@ -234,4 +234,8 @@ void frr_pthread_yield(void); */ uint32_t frr_pthread_get_id(void); +#ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK +#define pthread_condattr_setclock(A, B) +#endif + #endif /* _FRR_PTHREAD_H */ diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c index 02d9b68bc1..cfea238d95 100644 --- a/lib/frr_zmq.c +++ b/lib/frr_zmq.c @@ -141,8 +141,8 @@ static int frrzmq_read_msg(struct thread *t) 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; @@ -255,8 +255,8 @@ static int frrzmq_write_msg(struct thread *t) 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; diff --git a/lib/frrstr.c b/lib/frrstr.c index 715e67b868..85d968182b 100644 --- a/lib/frrstr.c +++ b/lib/frrstr.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <ctype.h> #include <sys/types.h> diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 51e7a3987e..0d6200b006 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -23,6 +23,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "command.h" #include "memory_vty.h" #include "graph.h" @@ -311,7 +315,7 @@ static void cmd_graph_permute(struct list *out, struct graph_node **stack, 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); @@ -328,7 +332,7 @@ static void cmd_graph_permute(struct list *out, struct graph_node **stack, 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) diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c index 264c7c48f0..c9c942f9bf 100644 --- a/lib/grammar_sandbox_main.c +++ b/lib/grammar_sandbox_main.c @@ -23,6 +23,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "command.h" #include "memory_vty.h" diff --git a/lib/hook.c b/lib/hook.c index 935064f4d2..4fe305f282 100644 --- a/lib/hook.c +++ b/lib/hook.c @@ -20,6 +20,10 @@ * DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "memory.h" #include "hook.h" @@ -63,7 +63,7 @@ int ptm_enable = 0; * 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; @@ -99,8 +99,8 @@ int if_cmp_name_func(char *p1, char *p2) 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) @@ -121,7 +121,7 @@ int if_cmp_name_func(char *p1, char *p2) 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, @@ -371,37 +371,47 @@ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id) one. */ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty) { - struct interface *ifp; + struct interface *ifp = NULL; - ifp = if_lookup_by_name(name, vrf_id); - if (ifp) - return ifp; - /* Not Found on same VRF. If the interface command - * was entered in vty without a VRF (passed as VRF_DEFAULT), - * accept the ifp we found. If a vrf was entered and there is - * a mismatch, reject it if from vty. - */ - ifp = if_lookup_by_name_all_vrf(name); - if (!ifp) + if (vrf_is_mapped_on_netns(vrf_lookup_by_id(vrf_id))) { + ifp = if_lookup_by_name(name, vrf_id); + if (ifp) + return ifp; + if (vty) { + /* If the interface command was entered in vty without a + * VRF (passed as VRF_DEFAULT), search an interface with + * this name in all VRs + */ + if (vrf_id == VRF_DEFAULT) + return if_lookup_by_name_all_vrf(name); + return NULL; + } return if_create(name, vrf_id); - if (vty) { - if (vrf_id == VRF_DEFAULT) + } + /* vrf is based on vrf-lite */ + ifp = if_lookup_by_name_all_vrf(name); + if (ifp) { + if (ifp->vrf_id == vrf_id) return ifp; - return NULL; + /* Found a match on a different VRF. If the interface command + * was entered in vty without a VRF (passed as VRF_DEFAULT), + * accept the ifp we found. If a vrf was entered and there is a + * mismatch, reject it if from vty. If it came from the kernel + * or by way of zclient, believe it and update the ifp + * accordingly. + */ + if (vty) { + if (vrf_id == VRF_DEFAULT) + return ifp; + return NULL; + } + /* If it came from the kernel or by way of zclient, believe it + * and update the ifp accordingly. + */ + if_update_to_new_vrf(ifp, vrf_id); + return ifp; } - /* if vrf backend uses NETNS, then - * this should not be considered as an update - * then create the new interface - */ - if (ifp->vrf_id != vrf_id && vrf_is_mapped_on_netns( - vrf_lookup_by_id(vrf_id))) - return if_create(name, vrf_id); - /* If it came from the kernel - * or by way of zclient, believe it and update - * the ifp accordingly. - */ - if_update_to_new_vrf(ifp, vrf_id); - return ifp; + return if_create(name, vrf_id); } void if_set_index(struct interface *ifp, ifindex_t ifindex) @@ -619,7 +629,7 @@ DEFUN (no_interface_desc, * if not: * - no idea, just get the name in its entirety. */ -static struct interface *if_sunwzebra_get(char *name, vrf_id_t vrf_id) +static struct interface *if_sunwzebra_get(const char *name, vrf_id_t vrf_id) { struct interface *ifp; char *cp; @@ -1149,7 +1159,7 @@ const char *if_link_type_str(enum zebra_link_type llt) 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 } @@ -297,35 +297,31 @@ DECLARE_QOBJ_TYPE(interface) #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) \ @@ -455,7 +451,7 @@ struct nbr_connected { #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 diff --git a/lib/imsg-buffer.c b/lib/imsg-buffer.c index b83f1f76f2..c2f4052b8f 100644 --- a/lib/imsg-buffer.c +++ b/lib/imsg-buffer.c @@ -21,9 +21,9 @@ #include "queue.h" #include "imsg.h" -int ibuf_realloc(struct ibuf *, size_t); -void ibuf_enqueue(struct msgbuf *, struct ibuf *); -void ibuf_dequeue(struct msgbuf *, struct ibuf *); +static int ibuf_realloc(struct ibuf *, size_t); +static void ibuf_enqueue(struct msgbuf *, struct ibuf *); +static void ibuf_dequeue(struct msgbuf *, struct ibuf *); struct ibuf *ibuf_open(size_t len) { @@ -57,7 +57,7 @@ struct ibuf *ibuf_dynamic(size_t len, size_t max) return (buf); } -int ibuf_realloc(struct ibuf *buf, size_t len) +static int ibuf_realloc(struct ibuf *buf, size_t len) { uint8_t *b; @@ -183,6 +183,8 @@ void msgbuf_drain(struct msgbuf *msgbuf, size_t n) next = TAILQ_NEXT(buf, entry); if (buf->rpos + n >= buf->wpos) { n -= buf->wpos - buf->rpos; + + TAILQ_REMOVE(&msgbuf->bufs, buf, entry); ibuf_dequeue(msgbuf, buf); } else { buf->rpos += n; @@ -195,7 +197,7 @@ void msgbuf_clear(struct msgbuf *msgbuf) { struct ibuf *buf; - while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) + while ((buf = TAILQ_POP_FIRST(&msgbuf->bufs, entry)) != NULL) ibuf_dequeue(msgbuf, buf); } @@ -266,16 +268,15 @@ again: return (1); } -void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) +static void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) { TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); msgbuf->queued++; } -void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) +static void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) { - TAILQ_REMOVE(&msgbuf->bufs, buf, entry); - + /* TAILQ_REMOVE done by caller */ if (buf->fd != -1) close(buf->fd); diff --git a/lib/imsg.c b/lib/imsg.c index 5424140720..935d137727 100644 --- a/lib/imsg.c +++ b/lib/imsg.c @@ -299,11 +299,10 @@ int imsg_get_fd(struct imsgbuf *ibuf) int fd; struct imsg_fd *ifd; - if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + if ((ifd = TAILQ_POP_FIRST(&ibuf->fds, entry)) == NULL) return (-1); fd = ifd->fd; - TAILQ_REMOVE(&ibuf->fds, ifd, entry); free(ifd); return (fd); diff --git a/lib/lib_errors.c b/lib/lib_errors.c index 332a5b1d45..03ad974da6 100644 --- a/lib/lib_errors.c +++ b/lib/lib_errors.c @@ -18,90 +18,136 @@ * 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" @@ -114,5 +160,6 @@ static struct log_ref ferr_lib_err[] = { void lib_error_init(void) { + log_ref_add(ferr_lib_warn); log_ref_add(ferr_lib_err); } diff --git a/lib/lib_errors.h b/lib/lib_errors.h index 84f5b8dc10..e0f698a07d 100644 --- a/lib/lib_errors.h +++ b/lib/lib_errors.h @@ -24,20 +24,26 @@ #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); diff --git a/lib/libfrr.c b/lib/libfrr.c index 821c57f37b..69e6882617 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -262,6 +262,34 @@ bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, static struct frr_daemon_info *di = NULL; +static void frr_guard_daemon(void) +{ + int fd; + struct flock lock; + const char *path = di->pid_file; + + fd = open(path, O_RDWR); + if (fd != -1) { + memset(&lock, 0, sizeof(lock)); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + if (fcntl(fd, F_GETLK, &lock) < 0) { + flog_err_sys( + 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; @@ -517,13 +545,15 @@ static void frr_mkdir(const char *path, bool strip) 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; @@ -589,6 +619,9 @@ struct thread_master *frr_init(void) zprivs_init(di->privs); + /* Guard to prevent a second instance of this daemon */ + frr_guard_daemon(); + master = thread_master_create(NULL); signal_init(master, di->n_signals, di->signals); @@ -829,7 +862,7 @@ static void frr_terminal_close(int isexit) 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 { @@ -902,7 +935,7 @@ void frr_run(struct thread_master *master) } 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 { diff --git a/lib/linklist.c b/lib/linklist.c index effd384e46..bee9d05a2c 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -318,8 +318,8 @@ void list_sort(struct list *list, int (*cmp)(const void **, const void **)) 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); } @@ -634,7 +634,7 @@ void zlog_backtrace(int priority) 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))); @@ -642,7 +642,7 @@ void zlog_backtrace(int priority) } 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]); @@ -716,7 +716,7 @@ void _zlog_assert_failed(const char *assertion, const char *file, 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); @@ -872,7 +872,7 @@ int zlog_rotate(void) 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; @@ -925,7 +925,6 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_IMPORT_ROUTE_REGISTER), DESC_ENTRY(ZEBRA_IMPORT_ROUTE_UNREGISTER), DESC_ENTRY(ZEBRA_IMPORT_CHECK_UPDATE), - DESC_ENTRY(ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD), DESC_ENTRY(ZEBRA_BFD_DEST_REGISTER), DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER), DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE), @@ -946,6 +945,7 @@ static const struct zebra_desc_table command_types[] = { 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), @@ -990,8 +990,8 @@ static const struct zebra_desc_table *zroute_lookup(unsigned int zroute) 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) @@ -1005,9 +1005,8 @@ static const struct zebra_desc_table *zroute_lookup(unsigned int zroute) 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; } @@ -1024,8 +1023,8 @@ char zebra_route_char(unsigned int zroute) 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; @@ -1075,6 +1074,8 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; + else if (strmatch(s, "openfabric")) + return ZEBRA_ROUTE_OPENFABRIC; } if (afi == AFI_IP6) { if (strmatch(s, "kernel")) @@ -1103,6 +1104,8 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; + else if (strmatch(s, "openfabric")) + return ZEBRA_ROUTE_OPENFABRIC; } return -1; } @@ -90,6 +90,8 @@ extern void zlog_debug(const char *format, ...) PRINTF_ATTRIBUTE(1, 2); 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); diff --git a/lib/memory.c b/lib/memory.c index 695bbfe115..fee23a75ac 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -20,6 +20,9 @@ #ifdef HAVE_MALLOC_H #include <malloc.h> #endif +#ifdef HAVE_MALLOC_NP_H +#include <malloc_np.h> +#endif #ifdef HAVE_MALLOC_MALLOC_H #include <malloc/malloc.h> #endif diff --git a/lib/memory_vty.c b/lib/memory_vty.c index 73a18529a2..5fd9c3b900 100644 --- a/lib/memory_vty.c +++ b/lib/memory_vty.c @@ -28,7 +28,9 @@ #include <malloc/malloc.h> #endif #include <dlfcn.h> +#ifdef HAVE_LINK_H #include <link.h> +#endif #include "log.h" #include "memory.h" diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 33338ac89c..ef2f5dc953 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -219,7 +219,7 @@ static int ns_enable_internal(struct ns *ns, void (*func)(ns_id_t, void *)) } 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; @@ -227,9 +227,9 @@ static int ns_enable_internal(struct ns *ns, void (*func)(ns_id_t, void *)) /* 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) @@ -441,8 +441,8 @@ char *ns_netns_pathname(struct vty *vty, const char *name) 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; } @@ -452,7 +452,8 @@ char *ns_netns_pathname(struct vty *vty, const char *name) 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; } @@ -486,8 +487,8 @@ void ns_init_management(ns_id_t default_ns_id, ns_id_t internal_ns) 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()) { @@ -504,8 +505,8 @@ void ns_init_management(ns_id_t default_ns_id, ns_id_t internal_ns) /* 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); } } diff --git a/lib/network.c b/lib/network.c index 6d3350ad49..411661a5e1 100644 --- a/lib/network.c +++ b/lib/network.c @@ -22,6 +22,7 @@ #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) @@ -78,13 +79,15 @@ int set_nonblocking(int fd) 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; diff --git a/lib/openbsd-tree.c b/lib/openbsd-tree.c index 35bfce3a89..e8d13339b6 100644 --- a/lib/openbsd-tree.c +++ b/lib/openbsd-tree.c @@ -41,6 +41,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <lib/openbsd-tree.h> diff --git a/lib/pid_output.c b/lib/pid_output.c index c6120de861..b0643c4fe2 100644 --- a/lib/pid_output.c +++ b/lib/pid_output.c @@ -42,7 +42,7 @@ pid_t pid_output(const char *path) 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); @@ -59,7 +59,7 @@ pid_t pid_output(const char *path) 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); @@ -69,12 +69,12 @@ pid_t pid_output(const char *path) 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)); diff --git a/lib/plist.c b/lib/plist.c index 5746080127..ee68fbc0f1 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -930,7 +930,10 @@ static int vty_prefix_list_install(struct vty *vty, afi_t afi, const char *name, 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; @@ -1249,13 +1252,13 @@ static int vty_show_prefix_list_prefix(struct vty *vty, afi_t afi, 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); diff --git a/lib/prefix.c b/lib/prefix.c index a7f4fda1b2..21c3af7d49 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -657,9 +657,9 @@ void prefix_copy(struct prefix *dest, const struct prefix *src) 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); } } diff --git a/lib/privs.c b/lib/privs.c index 34905ca480..838ff8fc92 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -24,6 +24,7 @@ #include "log.h" #include "privs.h" #include "memory.h" +#include "lib_errors.h" #ifdef HAVE_CAPABILITIES @@ -288,7 +289,8 @@ zebra_privs_current_t zprivs_state_caps(void) 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; diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c index 69fd61e2a0..7f868beda4 100644 --- a/lib/ptm_lib.c +++ b/lib/ptm_lib.c @@ -17,6 +17,11 @@ * with this program; see the file COPYING; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <stdlib.h> #include <stdbool.h> diff --git a/lib/queue.h b/lib/queue.h index 04fbeee700..11e28b4c91 100644 --- a/lib/queue.h +++ b/lib/queue.h @@ -72,4 +72,17 @@ #include "freebsd-queue.h" #endif /* defined(__OpenBSD__) && !defined(STAILQ_HEAD) */ +#ifndef TAILQ_POP_FIRST +#define TAILQ_POP_FIRST(head, field) \ + ({ typeof((head)->tqh_first) _elm = TAILQ_FIRST(head); \ + if (_elm) { \ + if ((TAILQ_NEXT((_elm), field)) != NULL) \ + TAILQ_NEXT((_elm), field)->field.tqe_prev = \ + &TAILQ_FIRST(head); \ + else \ + (head)->tqh_last = &TAILQ_FIRST(head); \ + TAILQ_FIRST(head) = TAILQ_NEXT((_elm), field); \ + }; _elm; }) +#endif + #endif /* _FRR_QUEUE_H */ diff --git a/lib/route_types.txt b/lib/route_types.txt index 72f59a1b78..c5eff44ca7 100644 --- a/lib/route_types.txt +++ b/lib/route_types.txt @@ -82,6 +82,7 @@ ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, 1, "Babel" ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, 1, "SHARP" ZEBRA_ROUTE_PBR, pbr, pbrd, 'F', 1, 1, 0, "PBR" ZEBRA_ROUTE_BFD, bfd, bfdd, '-', 0, 0, 0, "BFD" +ZEBRA_ROUTE_OPENFABRIC, openfabric, fabricd, 'f', 1, 1, 1, "OpenFabric" ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, 0, "-" @@ -109,3 +110,4 @@ ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)" ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)" ZEBRA_ROUTE_PBR, "Policy Based Routing (PBR)" ZEBRA_ROUTE_BFD, "Bidirectional Fowarding Detection (BFD)" +ZEBRA_ROUTE_OPENFABRIC, "OpenFabric Routing Protocol" diff --git a/lib/routemap.c b/lib/routemap.c index e5613c2081..66c15b9f2b 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -30,6 +30,7 @@ #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") @@ -1445,7 +1446,8 @@ route_map_result_t route_map_apply(struct route_map *map, 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; diff --git a/lib/sigevent.c b/lib/sigevent.c index 0346027935..57b41503e1 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -84,7 +84,7 @@ int quagga_sigevent_process(void) 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; } @@ -329,7 +329,8 @@ static void trap_default_signals(void) } 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)); diff --git a/lib/skiplist.c b/lib/skiplist.c index a36bf47139..3933429c3b 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -183,8 +183,8 @@ int skiplist_insert(register struct skiplist *l, register void *key, /* 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; @@ -202,6 +202,7 @@ int skiplist_insert(register struct skiplist *l, register void *key, } k = randomLevel(); + assert(k >= 0); if (k > l->level) { k = ++l->level; update[k] = l->header; diff --git a/lib/sockopt.c b/lib/sockopt.c index 3febcb714d..ea04f2a43e 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -38,8 +38,9 @@ void setsockopt_so_recvbuf(int sock, int size) 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) @@ -51,8 +52,9 @@ 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) @@ -62,7 +64,7 @@ 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; @@ -92,13 +94,14 @@ int setsockopt_ipv6_pktinfo(int sock, int val) 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; } @@ -114,7 +117,7 @@ int setsockopt_ipv6_checksum(int sock, int val) 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; } @@ -126,7 +129,7 @@ int setsockopt_ipv6_multicast_hops(int sock, int val) 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; } @@ -138,7 +141,7 @@ int setsockopt_ipv6_unicast_hops(int sock, int val) 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; } @@ -150,11 +153,11 @@ int setsockopt_ipv6_hoplimit(int sock, int val) 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; } @@ -167,7 +170,7 @@ int setsockopt_ipv6_multicast_loop(int sock, int val) 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; } @@ -188,8 +191,9 @@ int setsockopt_ipv6_tclass(int sock, int tclass) 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; } @@ -391,7 +395,7 @@ int setsockopt_ipv4_multicast_loop(int sock, uint8_t val) 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; } @@ -403,13 +407,15 @@ static int setsockopt_ipv4_ifindex(int sock, ifindex_t val) #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." @@ -427,8 +433,9 @@ int setsockopt_ipv4_tos(int sock, int tos) 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; } @@ -445,7 +452,8 @@ int setsockopt_ifindex(int af, int sock, ifindex_t val) 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; } @@ -534,7 +542,8 @@ ifindex_t getsockopt_ifindex(int af, struct msghdr *msgh) 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; } } @@ -649,7 +658,7 @@ int sockopt_tcp_signature(int sock, union sockunion *su, const char *password) ret = 0; else flog_err_sys( - LIB_ERR_SYSTEM_CALL, + EC_LIB_SYSTEM_CALL, "sockopt_tcp_signature: setsockopt(%d): %s", sock, safe_strerror(errno)); } diff --git a/lib/sockunion.c b/lib/sockunion.c index bbbfbfc424..bee82a067e 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -140,9 +140,9 @@ int sockunion_socket(const union sockunion *su) 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; } @@ -235,7 +235,8 @@ int sockunion_stream_socket(union sockunion *su) 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; } @@ -273,9 +274,9 @@ int sockunion_bind(int sock, union sockunion *su, unsigned short port, 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; @@ -289,7 +290,8 @@ int sockopt_reuseaddr(int sock) 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; @@ -304,7 +306,8 @@ int sockopt_reuseport(int sock) 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; @@ -325,8 +328,9 @@ int sockopt_ttl(int family, int sock, int ttl) 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; @@ -336,7 +340,8 @@ int sockopt_ttl(int family, int sock, int ttl) 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; @@ -383,7 +388,8 @@ int sockopt_minttl(int family, int sock, int minttl) 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; @@ -394,7 +400,8 @@ int sockopt_minttl(int family, int sock, int minttl) 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; @@ -414,10 +421,10 @@ int sockopt_v6only(int family, int sock) 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; @@ -532,8 +539,9 @@ union sockunion *sockunion_getsockname(int fd) 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; } @@ -568,8 +576,8 @@ union sockunion *sockunion_getpeername(int fd) 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; } diff --git a/lib/srcdest_table.c b/lib/srcdest_table.c index 4497faf6fc..e49735192d 100644 --- a/lib/srcdest_table.c +++ b/lib/srcdest_table.c @@ -301,5 +301,5 @@ const char *srcdest_rnode2str(struct route_node *rn, char *str, int size) 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); } diff --git a/lib/stream.c b/lib/stream.c index 55e7f64358..6c187bd359 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -54,7 +54,8 @@ DEFINE_MTYPE_STATIC(LIB, STREAM_FIFO, "Stream FIFO") * 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) @@ -68,16 +69,16 @@ DEFINE_MTYPE_STATIC(LIB, STREAM_FIFO, "Stream FIFO") #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) @@ -85,7 +86,8 @@ DEFINE_MTYPE_STATIC(LIB, STREAM_FIFO, "Stream FIFO") #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); \ @@ -270,7 +272,7 @@ void stream_forward_endp(struct stream *s, size_t size) } /* Copy from stream to destination. */ -inline bool stream_get2(void *dst, struct stream *s, size_t size) +bool stream_get2(void *dst, struct stream *s, size_t size) { STREAM_VERIFY_SANE(s); @@ -299,7 +301,7 @@ void stream_get(void *dst, struct stream *s, size_t size) } /* Get next character from the stream. */ -inline bool stream_getc2(struct stream *s, uint8_t *byte) +bool stream_getc2(struct stream *s, uint8_t *byte) { STREAM_VERIFY_SANE(s); @@ -344,7 +346,7 @@ uint8_t stream_getc_from(struct stream *s, size_t from) return c; } -inline bool stream_getw2(struct stream *s, uint16_t *word) +bool stream_getw2(struct stream *s, uint16_t *word) { STREAM_VERIFY_SANE(s); @@ -465,7 +467,7 @@ void stream_get_from(void *dst, struct stream *s, size_t from, size_t size) memcpy(dst, s->data + from, size); } -inline bool stream_getl2(struct stream *s, uint32_t *l) +bool stream_getl2(struct stream *s, uint32_t *l) { STREAM_VERIFY_SANE(s); @@ -966,8 +968,8 @@ ssize_t stream_read_try(struct stream *s, int fd, size_t size) /* 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; } @@ -997,8 +999,8 @@ ssize_t stream_recvfrom(struct stream *s, int fd, size_t size, int flags, /* 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; } diff --git a/lib/strlcat.c b/lib/strlcat.c index be211f82a8..39773d9ac8 100644 --- a/lib/strlcat.c +++ b/lib/strlcat.c @@ -20,11 +20,13 @@ /* adapted for Quagga from glibc patch submission originally from * Florian Weimer <fweimer@redhat.com>, 2016-05-18 */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdint.h> #include <string.h> -#include "config.h" - #ifndef HAVE_STRLCAT #undef strlcat diff --git a/lib/strlcpy.c b/lib/strlcpy.c index b0c33ca7f4..71ee9f1a54 100644 --- a/lib/strlcpy.c +++ b/lib/strlcpy.c @@ -20,9 +20,11 @@ /* adapted for Quagga from glibc patch submission originally from * Florian Weimer <fweimer@redhat.com>, 2016-05-18 */ -#include <string.h> - +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + +#include <string.h> #ifndef HAVE_STRLCPY #undef strlcpy diff --git a/lib/subdir.am b/lib/subdir.am index ef6c8f8e55..499bb94920 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -84,6 +84,22 @@ lib_libfrr_la_SOURCES = \ lib/logicalrouter.c \ # end +vtysh_scan += \ + $(top_srcdir)/lib/distribute.c \ + $(top_srcdir)/lib/filter.c \ + $(top_srcdir)/lib/if.c \ + $(top_srcdir)/lib/if_rmap.c \ + $(top_srcdir)/lib/keychain.c \ + $(top_srcdir)/lib/logicalrouter.c \ + $(top_srcdir)/lib/nexthop_group.c \ + $(top_srcdir)/lib/plist.c \ + $(top_srcdir)/lib/routemap.c \ + $(top_srcdir)/lib/vrf.c \ + $(top_srcdir)/lib/vty.c \ + # end +# can be loaded as DSO - always include for vtysh +vtysh_scan += $(top_srcdir)/lib/agentx.c + lib/plist_clippy.c: $(CLIPPY_DEPS) lib/plist.lo: lib/plist_clippy.c lib/nexthop_group_clippy.c: $(CLIPPY_DEPS) @@ -152,6 +168,7 @@ pkginclude_HEADERS += \ lib/sha256.h \ lib/sigevent.h \ lib/skiplist.h \ + lib/smux.h \ lib/sockopt.h \ lib/sockunion.h \ lib/spf_backoff.h \ @@ -237,9 +254,10 @@ lib_grammar_sandbox_SOURCES = \ lib_grammar_sandbox_LDADD = \ lib/libfrr.la -lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY @SAN_CLIPPY_FLAGS@ -lib_clippy_CFLAGS = $(PYTHON_CFLAGS) @SAN_CLIPPY_FLAGS@ +lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY +lib_clippy_CFLAGS = $(PYTHON_CFLAGS) lib_clippy_LDADD = $(PYTHON_LIBS) +lib_clippy_LDFLAGS = -export-dynamic lib_clippy_SOURCES = \ lib/clippy.c \ lib/command_graph.c \ @@ -252,6 +270,26 @@ lib_clippy_SOURCES = \ lib/vector.c \ # end +# (global) clippy rules for all directories + +AM_V_CLIPPY = $(am__v_CLIPPY_$(V)) +am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY)) +am__v_CLIPPY_0 = @echo " CLIPPY " $@; +am__v_CLIPPY_1 = + +CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py + +SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h +.c_clippy.c: + @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || \ + $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } + $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $< + +## automake's "ylwrap" is a great piece of GNU software... not. +.l.c: + $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $< +.y.c: + $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $< # # generated sources & extra foo diff --git a/lib/termtable.c b/lib/termtable.c index ba85962cc9..4f5f9ff218 100644 --- a/lib/termtable.c +++ b/lib/termtable.c @@ -140,8 +140,8 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i, 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) @@ -395,7 +395,7 @@ char *ttable_dump(struct ttable *tt, const char *newline) 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; @@ -421,7 +421,7 @@ char *ttable_dump(struct ttable *tt, const char *newline) 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 */ @@ -443,7 +443,7 @@ char *ttable_dump(struct ttable *tt, const char *newline) 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 */ @@ -459,7 +459,7 @@ char *ttable_dump(struct ttable *tt, const char *newline) 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; @@ -483,7 +483,7 @@ char *ttable_dump(struct ttable *tt, const char *newline) 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); diff --git a/lib/thread.c b/lib/thread.c index 52bc79ffe6..2c3db27c7b 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -33,6 +33,7 @@ #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") @@ -1480,7 +1481,8 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) } /* 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; @@ -1617,7 +1619,8 @@ void thread_call(struct thread *thread) * 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); diff --git a/lib/thread.h b/lib/thread.h index 01ff4daf42..70090cf784 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -170,6 +170,8 @@ struct cpu_thread_history { #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 *); @@ -489,18 +489,24 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *), /* 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); } @@ -570,7 +576,7 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id, 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)) { @@ -584,7 +590,7 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id, 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; @@ -624,7 +630,8 @@ int vrf_handler_create(struct vty *vty, const char *vrfname, "%% 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; @@ -653,7 +660,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, "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; } @@ -665,7 +672,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, "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; @@ -683,7 +690,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, " 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; } @@ -699,7 +706,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, 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; } @@ -711,8 +718,6 @@ int vrf_is_mapped_on_netns(struct vrf *vrf) { if (!vrf || vrf->data.l.netns_name[0] == '\0') return 0; - if (vrf->vrf_id == VRF_DEFAULT) - return 0; return 1; } @@ -956,13 +961,13 @@ int vrf_getaddrinfo(const char *node, const char *service, 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; @@ -975,7 +980,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params) 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; } @@ -983,7 +988,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params) 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; @@ -997,13 +1002,13 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id, 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; @@ -111,8 +111,8 @@ extern vrf_id_t vrf_name_to_id(const char *); #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 { \ @@ -120,7 +120,7 @@ extern vrf_id_t vrf_name_to_id(const char *); } \ return CMD_WARNING; \ } \ - if (vrf->vrf_id == VRF_UNKNOWN) { \ + if (_vrf->vrf_id == VRF_UNKNOWN) { \ if (USE_JSON) { \ vty_out(vty, "{}\n"); \ } else { \ @@ -128,7 +128,7 @@ extern vrf_id_t vrf_name_to_id(const char *); } \ return CMD_WARNING; \ } \ - (V) = vrf->vrf_id; \ + (V) = _vrf->vrf_id; \ } while (0) /* @@ -201,7 +201,7 @@ extern int vrf_bitmap_check(vrf_bitmap_t, vrf_id_t); */ 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 @@ -314,8 +314,9 @@ static int vty_log_out(struct vty *vty, const char *level, /* 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 @@ -534,7 +535,8 @@ static int vty_command(struct vty *vty, char *buf) 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); } @@ -811,6 +813,7 @@ static void vty_end_config(struct vty *vty) case LDP_L2VPN_NODE: case LDP_PSEUDOWIRE_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case KEYCHAIN_KEY_NODE: case VTY_NODE: @@ -1210,6 +1213,7 @@ static void vty_stop_input(struct vty *vty) case LDP_L2VPN_NODE: case LDP_PSEUDOWIRE_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case KEYCHAIN_KEY_NODE: case VTY_NODE: @@ -1324,14 +1328,15 @@ static int vty_telnet_option(struct vty *vty, unsigned char *buf, int nbytes) 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); @@ -1446,7 +1451,8 @@ static int vty_read(struct thread *thread) } 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); @@ -1653,7 +1659,7 @@ static int vty_flush(struct thread *thread) 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); @@ -1900,7 +1906,8 @@ static int vty_accept(struct thread *thread) /* 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); @@ -1973,7 +1980,7 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port) 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); } @@ -2034,7 +2041,7 @@ static void vty_serv_un(const char *path) /* 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; @@ -2054,7 +2061,7 @@ static void vty_serv_un(const char *path) 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; @@ -2062,7 +2069,7 @@ static void vty_serv_un(const char *path) 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; @@ -2078,7 +2085,7 @@ static void vty_serv_un(const char *path) 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)); } @@ -2108,14 +2115,15 @@ static int vtysh_accept(struct thread *thread) (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; @@ -2146,8 +2154,8 @@ static int vtysh_flush(struct vty *vty) 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); @@ -2181,7 +2189,8 @@ static int vtysh_read(struct thread *thread) } 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)); } @@ -2411,9 +2420,8 @@ static void vty_read_file(FILE *confp) 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); @@ -2487,7 +2495,7 @@ bool vty_read_config(const char *config_file, char *config_default_dir) 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); @@ -2502,17 +2510,20 @@ bool vty_read_config(const char *config_file, char *config_default_dir) 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); } } @@ -2548,19 +2559,22 @@ bool vty_read_config(const char *config_file, char *config_default_dir) #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 @@ -3073,13 +3087,13 @@ static void vty_save_cwd(void) * 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); } diff --git a/lib/wheel.c b/lib/wheel.c index b1a3e89fc7..722b02424a 100644 --- a/lib/wheel.c +++ b/lib/wheel.c @@ -29,7 +29,9 @@ DEFINE_MTYPE_STATIC(LIB, TIMER_WHEEL_LIST, "Timer Wheel Slot List") 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; @@ -65,15 +67,29 @@ static int wheel_timer_thread(struct thread *t) 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; @@ -104,6 +120,7 @@ void wheel_delete(struct timer_wheel *wheel) THREAD_OFF(wheel->timer); XFREE(MTYPE_TIMER_WHEEL_LIST, wheel->wheel_slot_lists); + XFREE(MTYPE_TIMER_WHEEL, wheel->name); XFREE(MTYPE_TIMER_WHEEL, wheel); } diff --git a/lib/wheel.h b/lib/wheel.h index 1f9f95ed31..c8e83fafcb 100644 --- a/lib/wheel.h +++ b/lib/wheel.h @@ -21,6 +21,7 @@ #define __WHEEL_H__ struct timer_wheel { + char *name; struct thread_master *master; int slots; long long curr_slot; @@ -76,7 +77,8 @@ struct timer_wheel { */ 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 diff --git a/lib/zclient.c b/lib/zclient.c index c5a48c178a..e6626a178b 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -221,9 +221,9 @@ int zclient_socket_connect(struct zclient *zclient) 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; } @@ -249,7 +249,8 @@ static int zclient_flush_data(struct thread *thread) 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); @@ -273,8 +274,9 @@ int zclient_send_message(struct zclient *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: @@ -313,9 +315,10 @@ int zclient_read_header(struct stream *s, int sock, uint16_t *size, 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; } @@ -575,8 +578,8 @@ int zclient_start(struct zclient *zclient) } 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; @@ -771,9 +774,9 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) 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; } @@ -808,11 +811,6 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) 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 */ @@ -821,12 +819,12 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) 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; } @@ -871,8 +869,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) /* 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; } @@ -887,7 +886,8 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) 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; @@ -895,15 +895,17 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) 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)); @@ -912,7 +914,8 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) 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; @@ -922,7 +925,8 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) 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; @@ -933,8 +937,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) 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; } @@ -966,11 +971,6 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) 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 */ @@ -978,9 +978,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) 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; } @@ -1239,8 +1239,9 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr) } 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) @@ -1424,8 +1425,9 @@ struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id) /* 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; } @@ -1450,10 +1452,11 @@ static void link_params_set_value(struct stream *s, struct if_link_params *iflp) 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); @@ -1482,9 +1485,9 @@ struct interface *zebra_interface_link_params_read(struct stream *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; } @@ -1633,9 +1636,10 @@ struct connected *zebra_interface_address_read(int type, struct stream *s, /* 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; } @@ -1670,9 +1674,9 @@ struct connected *zebra_interface_address_read(int type, struct stream *s, /* 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)); @@ -1725,10 +1729,11 @@ zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id) /* 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; } @@ -1774,8 +1779,9 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s, /* 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; } @@ -1819,8 +1825,8 @@ static int zclient_read_sync_response(struct zclient *zclient, 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; } @@ -1833,24 +1839,29 @@ static int zclient_read_sync_response(struct zclient *zclient, * 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); @@ -1862,13 +1873,13 @@ int lm_label_manager_connect(struct zclient *zclient) 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; @@ -1876,8 +1887,11 @@ int lm_label_manager_connect(struct zclient *zclient) 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; @@ -1889,13 +1903,15 @@ int lm_label_manager_connect(struct zclient *zclient) /* 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); @@ -1984,15 +2000,13 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, 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; @@ -2013,13 +2027,13 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, /* 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); @@ -2029,15 +2043,16 @@ int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, /* 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; } @@ -2087,14 +2102,13 @@ int lm_release_label_chunk(struct zclient *zclient, uint32_t start, 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; @@ -2197,15 +2211,15 @@ int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size, 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; @@ -2291,8 +2305,7 @@ int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw) 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; } @@ -2394,23 +2407,25 @@ static int zclient_read(struct thread *thread) 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)); diff --git a/lib/zclient.h b/lib/zclient.h index b8ff85e80f..54f3635901 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -91,7 +91,6 @@ typedef enum { ZEBRA_IMPORT_ROUTE_REGISTER, ZEBRA_IMPORT_ROUTE_UNREGISTER, ZEBRA_IMPORT_CHECK_UPDATE, - ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD, ZEBRA_BFD_DEST_REGISTER, ZEBRA_BFD_DEST_DEREGISTER, ZEBRA_BFD_DEST_UPDATE, @@ -113,6 +112,7 @@ typedef enum { 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, @@ -573,7 +573,7 @@ extern int zclient_send_get_label_chunk( 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); diff --git a/lib/zebra.h b/lib/zebra.h index b12f6616ba..4e0e408ea6 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -28,7 +28,6 @@ #include "compiler.h" #ifdef SUNOS_5 -#define _XPG4_2 typedef unsigned int uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; @@ -334,18 +333,18 @@ struct in_pktinfo { #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 @@ -414,6 +413,7 @@ extern const char *zserv_command_string(unsigned int command); #define ZEBRA_FLAG_FIB_OVERRIDE 0x200 #define ZEBRA_FLAG_EVPN_ROUTE 0x400 #define ZEBRA_FLAG_RR_USE_DISTANCE 0x800 +#define ZEBRA_FLAG_ONLINK 0x1000 /* ZEBRA_FLAG_BLACKHOLE was 0x04 */ /* ZEBRA_FLAG_REJECT was 0x80 */ diff --git a/m4/.gitignore b/m4/.gitignore index 798188b0b9..357e65588d 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -1,8 +1,8 @@ -Makefile -Makefile.in -.arch-inventory -.arch-ids -*~ -*.loT +*.m4 + +!ax_compare_version.m4 +!ax_prog_perl_modules.m4 !ax_pthread.m4 !ax_sys_weak_alias.m4 +!ax_sys_weak_alias.m4 +!pkg.m4 @@ -109,7 +109,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $1 ($2)]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) diff --git a/nhrpd/.gitignore b/nhrpd/.gitignore index 3f47381278..3d4d56d589 100644 --- a/nhrpd/.gitignore +++ b/nhrpd/.gitignore @@ -1,2 +1 @@ -!Makefile nhrpd diff --git a/nhrpd/linux.c b/nhrpd/linux.c index 46a327b59f..85e941e7ba 100644 --- a/nhrpd/linux.c +++ b/nhrpd/linux.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <fcntl.h> #include <stdio.h> #include <unistd.h> diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c index af78b3d9ee..4c6827cb3d 100644 --- a/nhrpd/netlink_arp.c +++ b/nhrpd/netlink_arp.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <fcntl.h> #include <net/if.h> #include <netinet/if_ether.h> diff --git a/nhrpd/netlink_gre.c b/nhrpd/netlink_gre.c index 75ecaa70c1..3fdfa9c313 100644 --- a/nhrpd/netlink_gre.c +++ b/nhrpd/netlink_gre.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> diff --git a/nhrpd/nhrp_errors.c b/nhrpd/nhrp_errors.c index c557ba8a66..4c4f55be9e 100644 --- a/nhrpd/nhrp_errors.c +++ b/nhrpd/nhrp_errors.c @@ -26,13 +26,13 @@ /* 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" diff --git a/nhrpd/nhrp_errors.h b/nhrpd/nhrp_errors.h index c9e947eb2a..593714786a 100644 --- a/nhrpd/nhrp_errors.h +++ b/nhrpd/nhrp_errors.h @@ -24,8 +24,8 @@ #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); diff --git a/nhrpd/nhrp_event.c b/nhrpd/nhrp_event.c index 7ca9731765..9301c2d515 100644 --- a/nhrpd/nhrp_event.c +++ b/nhrpd/nhrp_event.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <sys/socket.h> #include <sys/un.h> diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index 3a42712748..ccca100db5 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <net/if_arp.h> #include "zebra.h" #include "linklist.h" diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index 737e70103e..f99e566399 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <unistd.h> #include "zebra.h" diff --git a/nhrpd/nhrp_packet.c b/nhrpd/nhrp_packet.c index e62ee1ef72..a983aa71bc 100644 --- a/nhrpd/nhrp_packet.c +++ b/nhrpd/nhrp_packet.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <netinet/if_ether.h> #include "nhrpd.h" #include "zbuf.h" diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 44271d68ac..203d4aa98c 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <netinet/if_ether.h> #include "zebra.h" @@ -810,8 +814,9 @@ static void nhrp_packet_debug(struct zbuf *zb, const char *dir) 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) diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 044529a5ca..e7b187f3b6 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "nhrpd.h" #include "table.h" #include "memory.h" diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 9ed2517069..84053b4b5d 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "nhrpd.h" #include "table.h" #include "memory.h" diff --git a/nhrpd/resolver.c b/nhrpd/resolver.c index dfa5dc3df0..830f0e1c84 100644 --- a/nhrpd/resolver.c +++ b/nhrpd/resolver.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <ares.h> #include <ares_version.h> @@ -194,9 +198,10 @@ void resolver_resolve(struct resolver_query *query, int af, 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; } diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am index d66e968224..758c22e2be 100644 --- a/nhrpd/subdir.am +++ b/nhrpd/subdir.am @@ -4,6 +4,8 @@ if NHRPD sbin_PROGRAMS += nhrpd/nhrpd +vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c +man8 += $(MANBUILD)/nhrpd.8 endif nhrpd_nhrpd_LDADD = lib/libfrr.la @LIBCAP@ @CARES_LIBS@ diff --git a/nhrpd/vici.c b/nhrpd/vici.c index 7cd703414a..3de4609a2b 100644 --- a/nhrpd/vici.c +++ b/nhrpd/vici.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <sys/socket.h> #include <sys/un.h> @@ -214,9 +218,10 @@ static void parse_sa_message(struct vici_message_ctx *ctx, 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; @@ -232,9 +237,10 @@ static void parse_sa_message(struct vici_message_ctx *ctx, 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; @@ -277,7 +283,7 @@ static void parse_cmd_response(struct vici_message_ctx *ctx, 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; @@ -336,7 +342,8 @@ static void vici_recv_message(struct vici_conn *vici, struct zbuf *msg) 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: diff --git a/nhrpd/zbuf.c b/nhrpd/zbuf.c index 6e7cad8aec..c662295083 100644 --- a/nhrpd/zbuf.c +++ b/nhrpd/zbuf.c @@ -7,7 +7,10 @@ * (at your option) any later version. */ -#define _GNU_SOURCE +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <unistd.h> #include <errno.h> diff --git a/nhrpd/znl.c b/nhrpd/znl.c index 01b2f433af..6030987a1b 100644 --- a/nhrpd/znl.c +++ b/nhrpd/znl.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <fcntl.h> #include <errno.h> #include <string.h> diff --git a/ospf6d/.gitignore b/ospf6d/.gitignore index 744af2d5ce..e398b1ca58 100644 --- a/ospf6d/.gitignore +++ b/ospf6d/.gitignore @@ -1,18 +1,2 @@ -!Makefile -Makefile.in -*.o -*.patch ospf6d ospf6d.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 7bccc78e00..586584c65c 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -918,9 +918,6 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) * 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, diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 5af88defeb..dc7a3f6d45 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -732,7 +732,8 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, ? 1 : 2, buf, listcount(route->paths), - listcount(route->nh_list)); + route->nh_list ? + listcount(route->nh_list) : 0); } if (listcount(route->paths)) { diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 8b720b6d84..40b3522c3d 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -130,7 +130,7 @@ uint8_t ospf6_lstype_debug(uint16_t type) { const struct ospf6_lsa_handler *handler; handler = ospf6_get_lsa_handler(type); - return handler->debug; + return handler->lh_debug; } /* RFC2328: Section 13.2 */ @@ -844,13 +844,13 @@ DEFUN (debug_ospf6_lsa_type, if (argc == 5) { if (strmatch(argv[idx_type]->text, "originate")) - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_ORIGINATE); else if (strmatch(argv[idx_type]->text, "examine")) - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN); else if (strmatch(argv[idx_type]->text, "flooding")) - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD); } else - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG); return CMD_SUCCESS; } @@ -896,13 +896,14 @@ DEFUN (no_debug_ospf6_lsa_type, if (argc == 6) { if (strmatch(argv[idx_type]->text, "originate")) - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); + UNSET_FLAG(handler->lh_debug, + OSPF6_LSA_DEBUG_ORIGINATE); if (strmatch(argv[idx_type]->text, "examine")) - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN); if (strmatch(argv[idx_type]->text, "flooding")) - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD); } else - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG); return CMD_SUCCESS; } @@ -924,16 +925,16 @@ int config_write_ospf6_debug_lsa(struct vty *vty) handler = vector_slot(ospf6_lsa_handler_vector, i); if (handler == NULL) continue; - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG)) vty_out(vty, "debug ospf6 lsa %s\n", ospf6_lsa_handler_name(handler)); - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_ORIGINATE)) vty_out(vty, "debug ospf6 lsa %s originate\n", ospf6_lsa_handler_name(handler)); - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN)) vty_out(vty, "debug ospf6 lsa %s examine\n", ospf6_lsa_handler_name(handler)); - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD)) vty_out(vty, "debug ospf6 lsa %s flooding\n", ospf6_lsa_handler_name(handler)); } diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index e88d10ad7e..d871a8842e 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -137,21 +137,14 @@ struct ospf6_lsa { #define OSPF6_LSA_SEQWRAPPED 0x20 struct ospf6_lsa_handler { - const struct { - uint16_t type; /* host byte order */ - const char *name; - const char *short_name; - int (*show)(struct vty *, struct ospf6_lsa *); - char *(*get_prefix_str)(struct ospf6_lsa *, char *buf, - int buflen, int pos); - } s; -#define lh_type s.type -#define lh_name s.name -#define lh_short_name s.short_name -#define lh_show s.show -#define lh_get_prefix_str s.get_prefix_str - uint8_t debug; -#define lh_debug debug + uint16_t lh_type; /* host byte order */ + const char *lh_name; + const char *lh_short_name; + int (*lh_show)(struct vty *, struct ospf6_lsa *); + char *(*lh_get_prefix_str)(struct ospf6_lsa *, char *buf, + int buflen, int pos); + + uint8_t lh_debug; }; #define OSPF6_LSA_IS_KNOWN(t) \ diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 228a525e76..cd688bbf89 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1559,8 +1559,7 @@ int ospf6_receive(struct thread *thread) /* 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; } @@ -1708,7 +1707,7 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst, /* 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) diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 0cc7294d67..4c24f47131 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -921,7 +921,7 @@ DEFUN (no_debug_ospf6, handler = vector_slot(ospf6_lsa_handler_vector, i); if (handler != NULL) { - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG); } } diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index 8988a53e5d..8df5f1cc47 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -118,7 +118,7 @@ int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option) 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; diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index a099eead49..bba3c0db5e 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -574,8 +574,9 @@ static void route_table_assert(struct ospf6_route_table *table) 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)) { @@ -732,7 +733,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, route->next = next; if (node->info == next) { - assert(next->rnode == node); + assert(next && next->rnode == node); node->info = route; UNSET_FLAG(next->flag, OSPF6_ROUTE_BEST); SET_FLAG(route->flag, OSPF6_ROUTE_BEST); diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 9c13c51b1f..d9ddc1bb83 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -273,8 +273,8 @@ static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v, 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; } diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index fde47c74fe..ca1a65ff0b 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -425,19 +425,6 @@ DEFUN(no_ospf6_router_id, return CMD_SUCCESS; } -#if CONFDATE > 20180828 -CPP_NOTICE("ospf6: `router-id A.B.C.D` deprecated 2017/08/28") -#endif -ALIAS_HIDDEN(ospf6_router_id, ospf6_router_id_hdn_cmd, "router-id A.B.C.D", - "Configure OSPF6 Router-ID\n" V4NOTATION_STR) - -#if CONFDATE > 20180828 -CPP_NOTICE("ospf6: `no router-id A.B.C.D` deprecated 2017/08/28") -#endif -ALIAS_HIDDEN(no_ospf6_router_id, no_ospf6_router_id_hdn_cmd, - "no router-id [A.B.C.D]", - NO_STR "Configure OSPF6 Router-ID\n" V4NOTATION_STR) - DEFUN (ospf6_log_adjacency_changes, ospf6_log_adjacency_changes_cmd, "log-adjacency-changes", @@ -1144,8 +1131,6 @@ void ospf6_top_init(void) install_default(OSPF6_NODE); install_element(OSPF6_NODE, &ospf6_router_id_cmd); install_element(OSPF6_NODE, &no_ospf6_router_id_cmd); - install_element(OSPF6_NODE, &ospf6_router_id_hdn_cmd); - install_element(OSPF6_NODE, &no_ospf6_router_id_hdn_cmd); install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd); install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd); install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 06a84dcb93..c968b35d90 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -363,10 +363,10 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) 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; } diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index f95381084d..36f3c2233f 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -72,12 +72,12 @@ extern struct thread_master *master; #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) diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index 8a6c4a5ccf..d9c29f2651 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -6,9 +6,27 @@ if OSPF6D noinst_LIBRARIES += ospf6d/libospf6.a sbin_PROGRAMS += ospf6d/ospf6d dist_examples_DATA += ospf6d/ospf6d.conf.sample +vtysh_scan += \ + $(top_srcdir)/ospf6d/ospf6_abr.c \ + $(top_srcdir)/ospf6d/ospf6_asbr.c \ + $(top_srcdir)/ospf6d/ospf6_area.c \ + $(top_srcdir)/ospf6d/ospf6_bfd.c \ + $(top_srcdir)/ospf6d/ospf6_flood.c \ + $(top_srcdir)/ospf6d/ospf6_interface.c \ + $(top_srcdir)/ospf6d/ospf6_intra.c \ + $(top_srcdir)/ospf6d/ospf6_lsa.c \ + $(top_srcdir)/ospf6d/ospf6_message.c \ + $(top_srcdir)/ospf6d/ospf6_neighbor.c \ + $(top_srcdir)/ospf6d/ospf6_route.c \ + $(top_srcdir)/ospf6d/ospf6_spf.c \ + $(top_srcdir)/ospf6d/ospf6_top.c \ + $(top_srcdir)/ospf6d/ospf6_zebra.c \ + $(top_srcdir)/ospf6d/ospf6d.c \ + # end if SNMP module_LTLIBRARIES += ospf6d/ospf6d_snmp.la endif +man8 += $(MANBUILD)/ospf6d.8 endif ospf6d_libospf6_a_SOURCES = \ diff --git a/ospfclient/.gitignore b/ospfclient/.gitignore index 1740b04fbc..9be70451f0 100644 --- a/ospfclient/.gitignore +++ b/ospfclient/.gitignore @@ -1,16 +1 @@ -!Makefile -Makefile.in -*.o ospfclient -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -refix diff --git a/ospfclient/subdir.am b/ospfclient/subdir.am index 834d4aaba7..df7d85a1f5 100644 --- a/ospfclient/subdir.am +++ b/ospfclient/subdir.am @@ -5,6 +5,7 @@ if OSPFCLIENT lib_LTLIBRARIES += ospfclient/libfrrospfapiclient.la sbin_PROGRAMS += ospfclient/ospfclient +man8 += $(MANBUILD)/ospfclient.8 endif ospfclient_libfrrospfapiclient_la_LDFLAGS = -version-info 0:0:0 diff --git a/ospfd/.gitignore b/ospfd/.gitignore index 752c875a62..fc65db33ee 100644 --- a/ospfd/.gitignore +++ b/ospfd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ospfd ospfd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 0ff9d0da51..870037efc0 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -49,6 +49,7 @@ #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) { @@ -742,7 +743,8 @@ void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost, 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; @@ -764,7 +766,8 @@ void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost, 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; } @@ -1132,7 +1135,8 @@ static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, uint32_t cost, 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; } diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 57e0ae5ec9..0f76527950 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -54,6 +54,7 @@ #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" @@ -152,7 +153,8 @@ int ospf_apiserver_init(void) 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]"); } @@ -867,7 +869,8 @@ int ospf_apiserver_register_opaque_type(struct ospf_apiserver *apiserv, 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; } @@ -1662,7 +1665,8 @@ int ospf_apiserver_originate1(struct ospf_lsa *lsa) /* 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; } @@ -1773,7 +1777,8 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa) /* 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; diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 8e8f655305..ba2e04bf76 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -135,11 +135,12 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance, 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; } diff --git a/ospfd/ospf_errors.c b/ospfd/ospf_errors.c index 2927f7cb14..566fc29202 100644 --- a/ospfd/ospf_errors.c +++ b/ospfd/ospf_errors.c @@ -23,62 +23,160 @@ #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); } diff --git a/ospfd/ospf_errors.h b/ospfd/ospf_errors.h index c3f1018550..cea649a6f4 100644 --- a/ospfd/ospf_errors.h +++ b/ospfd/ospf_errors.h @@ -24,14 +24,29 @@ #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); diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index f6ed9b81b9..316019c159 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -62,6 +62,7 @@ #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. */ @@ -136,7 +137,8 @@ int ospf_ext_init(void) 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; } @@ -157,7 +159,8 @@ int ospf_ext_init(void) 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; } @@ -174,12 +177,8 @@ int ospf_ext_init(void) 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); @@ -316,8 +315,9 @@ static void set_prefix_sid(struct ext_itf *exti, uint8_t algorithm, 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; } @@ -538,8 +538,6 @@ static int ospf_ext_link_new_if(struct interface *ifp) 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; } @@ -573,7 +571,8 @@ static int ospf_ext_link_del_if(struct interface *ifp) 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 : "-"); } @@ -590,11 +589,8 @@ static void ospf_ext_link_ism_change(struct ospf_interface *oi, int old_status) /* 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) { @@ -623,7 +619,8 @@ static void ospf_ext_pref_ism_change(struct ospf_interface *oi, int old_status) /* 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; } @@ -660,13 +657,15 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status) /* 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; } @@ -761,7 +760,8 @@ static int ospf_ext_link_lsa_update(struct ospf_lsa *lsa) { /* 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; } @@ -794,7 +794,8 @@ static int ospf_ext_pref_lsa_update(struct ospf_lsa *lsa) /* 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; } @@ -929,10 +930,6 @@ static struct ospf_lsa *ospf_ext_pref_lsa_new(struct ospf_area *area, /* 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); @@ -1007,10 +1004,6 @@ static struct ospf_lsa *ospf_ext_link_lsa_new(struct ospf_area *area, /* 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 :-) */ @@ -1069,13 +1062,15 @@ static int ospf_ext_pref_lsa_originate1(struct ospf_area *area, /* 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; } @@ -1121,13 +1116,15 @@ static int ospf_ext_link_lsa_originate1(struct ospf_area *area, /* 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; } @@ -1193,9 +1190,9 @@ static int ospf_ext_pref_lsa_originate(void *arg) 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); @@ -1251,9 +1248,9 @@ static int ospf_ext_link_lsa_originate(void *arg) 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); @@ -1303,14 +1300,16 @@ static struct ospf_lsa *ospf_ext_pref_lsa_refresh(struct ospf_lsa *lsa) /* 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); @@ -1328,7 +1327,8 @@ static struct ospf_lsa *ospf_ext_pref_lsa_refresh(struct ospf_lsa *lsa) 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); @@ -1345,7 +1345,8 @@ static struct ospf_lsa *ospf_ext_pref_lsa_refresh(struct ospf_lsa *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; } @@ -1386,14 +1387,16 @@ static struct ospf_lsa *ospf_ext_link_lsa_refresh(struct ospf_lsa *lsa) /* 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); } @@ -1409,7 +1412,8 @@ static struct ospf_lsa *ospf_ext_link_lsa_refresh(struct ospf_lsa *lsa) /* 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); @@ -1417,7 +1421,8 @@ static struct ospf_lsa *ospf_ext_link_lsa_refresh(struct ospf_lsa *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; } @@ -1464,9 +1469,9 @@ static void ospf_ext_pref_lsa_schedule(struct ext_itf *exti, /* 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); @@ -1494,9 +1499,6 @@ static void ospf_ext_pref_lsa_schedule(struct ext_itf *exti, UNSET_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED); ospf_opaque_lsa_flush_schedule(&lsa); break; - default: - zlog_warn("EXT (%s): Unknown opcode", __func__); - break; } } @@ -1528,9 +1530,9 @@ static void ospf_ext_link_lsa_schedule(struct ext_itf *exti, /* 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); @@ -1558,9 +1560,6 @@ static void ospf_ext_link_lsa_schedule(struct ext_itf *exti, UNSET_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED); ospf_opaque_lsa_flush_schedule(&lsa); break; - default: - zlog_warn("EXT (%s): Unknown opcode", __func__); - break; } } diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index b4e9dda58a..8078455930 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -539,7 +539,6 @@ static int ospf_flood_through_interface(struct ospf_interface *oi, 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)) diff --git a/ospfd/ospf_ia.c b/ospfd/ospf_ia.c index 86d15480a3..f1ba8a31e8 100644 --- a/ospfd/ospf_ia.c +++ b/ospfd/ospf_ia.c @@ -589,23 +589,19 @@ static void ospf_examine_transit_summaries(struct ospf_area *area, 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"); @@ -694,8 +690,6 @@ void ospf_ia_routing(struct ospf *ospf, struct route_table *rt, break; } } else { - struct listnode *node; - if (IS_DEBUG_OSPF_EVENT) zlog_debug( "ospf_ia_routing():not ABR, considering all areas"); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 24584f6713..2ad36ae364 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -1033,7 +1033,7 @@ static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v) * 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) { diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 7c8a68994f..a752630a35 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -50,7 +50,7 @@ #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) { @@ -398,7 +398,8 @@ struct ospf_neighbor *ospf_nbr_lookup_ptop(struct ospf_interface *oi) /* 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; } @@ -446,7 +447,8 @@ static char link_info_set(struct stream **s, struct in_addr id, } 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)); @@ -1817,12 +1819,11 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, } 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; } @@ -1918,11 +1919,10 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, } 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; } @@ -2043,19 +2043,28 @@ int ospf_external_lsa_originate_timer(struct thread *thread) 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; } @@ -2522,15 +2531,8 @@ void ospf_discard_from_db(struct ospf *ospf, struct ospf_lsdb *lsdb, { 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); @@ -2841,11 +2843,13 @@ static int ospf_maxage_lsa_remover(struct thread *thread) 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 diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c index ef965a5f91..f39bea9768 100644 --- a/ospfd/ospf_lsdb.c +++ b/ospfd/ospf_lsdb.c @@ -142,19 +142,8 @@ void ospf_lsdb_delete(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) 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; diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 8853802d07..9fb0e0ad13 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -216,8 +216,8 @@ int main(int argc, char **argv) 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); } diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c index d647525eaa..a58bd93b6e 100644 --- a/ospfd/ospf_neighbor.c +++ b/ospfd/ospf_neighbor.c @@ -269,9 +269,10 @@ void ospf_nbr_add_self(struct ospf_interface *oi, struct in_addr router_id) 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; diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 1fb930659e..e30bb0ffe1 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -51,7 +51,8 @@ int ospf_if_add_allspfrouters(struct ospf *top, struct prefix *p, 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?", @@ -76,11 +77,11 @@ int ospf_if_drop_allspfrouters(struct ospf *top, struct prefix *p, 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( @@ -101,7 +102,8 @@ int ospf_if_add_alldrouters(struct ospf *top, struct prefix *p, 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?", @@ -124,11 +126,11 @@ int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p, 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.", @@ -145,8 +147,9 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex) /* 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; @@ -154,19 +157,20 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex) 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; @@ -190,7 +194,8 @@ int ospf_sock_init(struct ospf *ospf) 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); } @@ -200,8 +205,9 @@ int ospf_sock_init(struct ospf *ospf) 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; } @@ -211,21 +217,23 @@ int ospf_sock_init(struct ospf *ospf) 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); diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 1e72e3db63..91d187f412 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -48,6 +48,7 @@ #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), @@ -713,7 +714,7 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) 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) @@ -795,7 +796,8 @@ int ospf_nsm_event(struct thread *thread) * 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), diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index be62eb3906..bbc559ca37 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -54,6 +54,7 @@ #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") @@ -352,7 +353,8 @@ static struct list *ospf_get_opaque_funclist(uint8_t lsa_type) 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; } @@ -377,27 +379,21 @@ int ospf_register_opaque_functab( { 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)); @@ -418,10 +414,8 @@ int ospf_register_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) @@ -573,7 +567,8 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab, 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); @@ -618,7 +613,8 @@ static void free_opaque_info_owner(void *val) 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. */ } @@ -662,27 +658,31 @@ lookup_opaque_info_by_type(struct ospf_lsa *lsa) 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; } @@ -1286,9 +1286,10 @@ void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, int *delay0) 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. */ @@ -1296,7 +1297,7 @@ void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, int *delay0) 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) @@ -1443,9 +1444,6 @@ void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, int *delay0) if (delay0 != NULL) *delay0 = delay; - -out: - return; } static int ospf_opaque_type9_lsa_originate(struct thread *t) @@ -1524,7 +1522,8 @@ static void ospf_opaque_lsa_reoriginate_resume(struct list *listtop, void *arg) 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; @@ -1564,7 +1563,8 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc) } /* 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; } @@ -1576,14 +1576,16 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc) 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; @@ -1591,12 +1593,14 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc) 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; } @@ -1668,13 +1672,14 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, 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; @@ -1682,9 +1687,9 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, 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; } @@ -1692,24 +1697,24 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, 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; } @@ -1717,17 +1722,17 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, 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; } @@ -1739,9 +1744,9 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, 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; } @@ -1761,19 +1766,17 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, 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; } @@ -1844,14 +1847,16 @@ static int ospf_opaque_type9_lsa_reoriginate_timer(struct thread *t) 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; } @@ -1894,14 +1899,16 @@ static int ospf_opaque_type10_lsa_reoriginate_timer(struct thread *t) 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; } @@ -1948,14 +1955,15 @@ static int ospf_opaque_type11_lsa_reoriginate_timer(struct thread *t) 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; } @@ -1991,14 +1999,16 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) 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; } @@ -2025,7 +2035,8 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) 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; @@ -2077,13 +2088,15 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0) 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; } @@ -2099,7 +2112,8 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0) 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; @@ -2156,7 +2170,8 @@ void ospf_opaque_self_originated_lsa_received(struct ospf_neighbor *nbr, 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; @@ -2175,7 +2190,8 @@ struct ospf *oi_to_top(struct ospf_interface *oi) 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; } diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 56b83d22d5..c4c4d2f030 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -35,7 +35,7 @@ #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" @@ -50,6 +50,7 @@ #include "ospfd/ospf_spf.h" #include "ospfd/ospf_flood.h" #include "ospfd/ospf_dump.h" +#include "ospfd/ospf_errors.h" /* * OSPF Fragmentation / fragmented writes @@ -232,7 +233,7 @@ void ospf_packet_add(struct ospf_interface *oi, struct ospf_packet *op) { 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", @@ -256,7 +257,7 @@ static void ospf_packet_add_top(struct ospf_interface *oi, { 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", @@ -291,7 +292,7 @@ struct ospf_packet *ospf_packet_dup(struct ospf_packet *op) 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); @@ -341,8 +342,8 @@ static int ospf_check_md5_digest(struct ospf_interface *oi, 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; } @@ -351,7 +352,8 @@ static int ospf_check_md5_digest(struct ospf_interface *oi, 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)); @@ -367,7 +369,8 @@ static int ospf_check_md5_digest(struct ospf_interface *oi, /* 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; } @@ -433,7 +436,8 @@ static int ospf_make_md5_digest(struct ospf_interface *oi, 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); @@ -596,7 +600,8 @@ static void ospf_write_frags(int fd, struct ospf_packet *op, struct ip *iph, 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, @@ -799,7 +804,8 @@ static int ospf_write(struct thread *thread) 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, @@ -915,7 +921,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, 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); @@ -924,11 +931,12 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, /* 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; } @@ -936,7 +944,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, 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), @@ -961,7 +970,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, * 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; } @@ -973,7 +983,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, * 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. */ @@ -989,7 +1000,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, && 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); @@ -1006,7 +1018,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, 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); @@ -1123,7 +1136,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi, /* 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; @@ -1131,7 +1145,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi, 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; @@ -1144,7 +1159,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi, 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 @@ -1271,7 +1287,7 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, 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; } @@ -1279,7 +1295,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, /* 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); @@ -1318,7 +1335,7 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, * 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; } @@ -1342,7 +1359,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, 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)); @@ -1396,7 +1414,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, /* 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; } @@ -1416,10 +1435,9 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, 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. */ @@ -1454,7 +1472,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, /* 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) @@ -1478,7 +1497,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, /* 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; @@ -1489,7 +1509,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, && 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); @@ -1539,7 +1560,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, 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; } @@ -1565,7 +1587,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, 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; } @@ -1576,9 +1599,9 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, /* 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; @@ -1669,7 +1692,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, length = ntohs(lsah->length); if (length > size) { - zlog_warn( + flog_warn( + EC_OSPF_PACKET, "Link State Update: LSA length exceeds packet size."); break; } @@ -1683,7 +1707,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, * 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), @@ -1693,7 +1718,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, /* 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; } @@ -1717,7 +1743,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, * 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; } @@ -1736,7 +1763,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, 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; } @@ -1806,7 +1834,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, /* 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; } @@ -1917,18 +1946,18 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, 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); @@ -1971,7 +2000,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, * 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); @@ -2087,7 +2116,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, 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)); @@ -2200,7 +2230,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, 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; } @@ -2270,12 +2301,14 @@ static struct stream *ospf_recv_packet(struct ospf *ospf, int fd, 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)); @@ -2321,7 +2354,8 @@ static struct stream *ospf_recv_packet(struct ospf *ospf, int fd, *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); @@ -2427,7 +2461,8 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) 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, @@ -2436,7 +2471,8 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) } 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)); @@ -2447,7 +2483,8 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) 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, @@ -2457,13 +2494,15 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) 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)); @@ -2474,7 +2513,8 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) 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, @@ -2483,7 +2523,8 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) } 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; @@ -2498,14 +2539,16 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) 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; @@ -2854,14 +2897,16 @@ static int ospf_verify_header(struct stream *ibuf, struct ospf_interface *oi, { /* 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; @@ -3006,12 +3051,14 @@ int ospf_read(struct thread *thread) */ 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], @@ -3036,7 +3083,8 @@ int ospf_read(struct thread *thread) */ 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)); @@ -3099,7 +3147,8 @@ int ospf_read(struct thread *thread) 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; } @@ -3830,7 +3879,8 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update, 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'" @@ -3858,12 +3908,12 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update, 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; } @@ -4019,10 +4069,12 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag, 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); @@ -4037,7 +4089,7 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag, 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); diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index c9d0a53c8d..e95fc43aab 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -57,6 +57,7 @@ #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 { @@ -185,7 +186,8 @@ static int ospf_router_info_register(uint8_t scope) 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; } @@ -200,8 +202,8 @@ static int ospf_router_info_unregister() 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; } @@ -742,10 +744,8 @@ static struct ospf_lsa *ospf_router_info_lsa_new() 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 @@ -814,11 +814,7 @@ static int ospf_router_info_lsa_originate1(void *arg) } /* 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 */ @@ -832,7 +828,8 @@ static int ospf_router_info_lsa_originate1(void *arg) /* 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; @@ -881,7 +878,8 @@ static int ospf_router_info_lsa_originate(void *arg) } } 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 */ @@ -912,7 +910,8 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *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; } @@ -925,11 +924,7 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa) } /* 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; @@ -937,7 +932,8 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa) /* 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; } @@ -985,7 +981,8 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode) 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); } @@ -1015,10 +1012,6 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode) 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; @@ -1030,7 +1023,8 @@ static int ospf_router_info_lsa_update(struct ospf_lsa *lsa) /* 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; } @@ -1452,7 +1446,10 @@ DEFUN (router_info, /* 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; } diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index c5ec1db336..54009639fc 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -40,6 +40,7 @@ #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) @@ -392,7 +393,8 @@ static void *route_set_metric_compile(const char *arg) 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; } diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 19d2e6a952..755634a2f1 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -995,7 +995,6 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, if (len <= 0) type_next = 1; else { - len = 1; type_next = 0; *type = *offset; } diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index e3c729f65e..7896fb632a 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -47,6 +47,7 @@ #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 */ @@ -859,7 +860,8 @@ static void ospf_spf_next(struct vertex *v, struct ospf *ospf, 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 { diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 23dae6b087..33ec09b9f3 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -24,6 +24,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <math.h> #include <stdio.h> #include <stdlib.h> @@ -233,10 +237,6 @@ static int ospf_sr_start(struct ospf *ospf) 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; @@ -821,9 +821,9 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh) 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; } @@ -1102,8 +1102,8 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) 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; } @@ -1113,18 +1113,18 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) /* 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; } @@ -1167,8 +1167,9 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) /* 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; @@ -1213,8 +1214,8 @@ void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa) /* 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; } @@ -1223,18 +1224,17 @@ void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa) /* 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; } @@ -1260,8 +1260,8 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa) /* 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; } @@ -1272,9 +1272,9 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa) /* 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; } @@ -1312,8 +1312,8 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa) /* 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; } @@ -1326,8 +1326,9 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa) * 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; } @@ -1343,11 +1344,11 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa) 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)); } } @@ -1370,8 +1371,8 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa) /* 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; } @@ -1382,9 +1383,9 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa) /* 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; } @@ -1423,8 +1424,8 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa) /* 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; } @@ -1437,8 +1438,9 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa) * 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; } @@ -1453,9 +1455,9 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa) 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)); } @@ -1702,10 +1704,7 @@ DEFUN(ospf_sr_enable, /* 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) @@ -1990,7 +1989,7 @@ DEFUN (sr_prefix_sid, * 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); @@ -2311,7 +2310,7 @@ DEFUN (show_ip_opsf_srdb, int idx = 0; struct in_addr rid; struct sr_node *srn; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL, *json_node_array = NULL; if (!OspfSR.enabled) { diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index a9dc1c18e3..f45682c770 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -61,6 +61,7 @@ #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. @@ -102,7 +103,8 @@ int ospf_mpls_te_init(void) 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; } @@ -139,7 +141,8 @@ static int ospf_mpls_te_register(enum inter_as_mode mode) 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; } @@ -231,7 +234,7 @@ static struct mpls_te_link *lookup_linkparams_by_instance(struct ospf_lsa *lsa) 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; } @@ -783,7 +786,7 @@ static void initialize_linkparams(struct mpls_te_link *lp) 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; @@ -816,18 +819,21 @@ static int is_mandated_params_set(struct mpls_te_link *lp) 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; } @@ -842,19 +848,14 @@ static int is_mandated_params_set(struct mpls_te_link *lp) 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)); @@ -882,9 +883,7 @@ static int ospf_mpls_te_new_if(struct interface *ifp) 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) @@ -925,7 +924,8 @@ void ospf_mpls_te_update_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; @@ -969,14 +969,16 @@ static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_state) 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; @@ -986,7 +988,8 @@ static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_state) && !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"); @@ -1146,10 +1149,7 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf, 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 :-) */ @@ -1223,14 +1223,16 @@ static int ospf_mpls_te_lsa_originate1(struct ospf_area *area, /* 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; } @@ -1286,7 +1288,7 @@ static int ospf_mpls_te_lsa_originate_area(void *arg) 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); } @@ -1294,7 +1296,7 @@ static int ospf_mpls_te_lsa_originate_area(void *arg) } 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; @@ -1323,7 +1325,8 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top, /* 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; } @@ -1331,7 +1334,8 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top, /* 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; } @@ -1385,7 +1389,8 @@ static int ospf_mpls_te_lsa_originate_as(void *arg) } 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; @@ -1432,7 +1437,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa) /* 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); @@ -1441,7 +1447,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *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. */ @@ -1457,7 +1464,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa) /* 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); @@ -1470,7 +1478,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *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; } @@ -1524,7 +1533,8 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode) 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; } @@ -1567,7 +1577,8 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode) 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; } diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index b6968ff8c8..8a7f38b743 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -152,10 +152,6 @@ static int ospf_interface_delete(int command, struct zclient *zclient, 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", @@ -1195,7 +1191,6 @@ static void ospf_filter_update(struct access_list *access) /* 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]; @@ -1285,7 +1280,6 @@ void ospf_prefix_list_update(struct prefix_list *plist) */ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { struct list *red_list; - struct listnode *node; struct ospf_redist *red; red_list = ospf->redist[type]; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index d311b4da6b..d481e9e4c8 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -308,12 +308,8 @@ static struct ospf *ospf_new(unsigned short instance, const char *name) 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; @@ -328,7 +324,8 @@ static struct ospf *ospf_new(unsigned short instance, const char *name) 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; @@ -722,8 +719,6 @@ static void ospf_finish_final(struct ospf *ospf) 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; @@ -759,7 +754,6 @@ static void ospf_finish_final(struct ospf *ospf) 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]; diff --git a/ospfd/subdir.am b/ospfd/subdir.am index cd659a9bc9..83074b5ac0 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -6,9 +6,20 @@ if OSPFD noinst_LIBRARIES += ospfd/libfrrospf.a sbin_PROGRAMS += ospfd/ospfd dist_examples_DATA += ospfd/ospfd.conf.sample +vtysh_scan += \ + $(top_srcdir)/ospfd/ospf_bfd.c \ + $(top_srcdir)/ospfd/ospf_dump.c \ + $(top_srcdir)/ospfd/ospf_opaque.c \ + $(top_srcdir)/ospfd/ospf_ri.c \ + $(top_srcdir)/ospfd/ospf_routemap.c \ + $(top_srcdir)/ospfd/ospf_te.c \ + $(top_srcdir)/ospfd/ospf_sr.c \ + $(top_srcdir)/ospfd/ospf_vty.c \ + # end if SNMP module_LTLIBRARIES += ospfd/ospfd_snmp.la endif +man8 += $(MANBUILD)/ospfd.8 endif ospfd_libfrrospf_a_SOURCES = \ diff --git a/pbrd/.gitignore b/pbrd/.gitignore index ff95d88527..86622ea174 100644 --- a/pbrd/.gitignore +++ b/pbrd/.gitignore @@ -1,15 +1 @@ -!Makefile -Makefile.in -libpbr.a pbrd -tags -TAGS -.deps -*.o -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index a8cefce84f..7376e3e95b 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -586,13 +586,13 @@ struct pbr_nexthop_group_cache *pbr_nht_add_group(const char *name) 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; } } diff --git a/pbrd/subdir.am b/pbrd/subdir.am index 42ab393218..7947559034 100644 --- a/pbrd/subdir.am +++ b/pbrd/subdir.am @@ -6,6 +6,11 @@ if PBRD noinst_LIBRARIES += pbrd/libpbr.a sbin_PROGRAMS += pbrd/pbrd dist_examples_DATA += pbrd/pbrd.conf.sample +vtysh_scan += \ + $(top_srcdir)/pbrd/pbr_vty.c \ + $(top_srcdir)/pbrd/pbr_debug.c \ + # end +man8 += $(MANBUILD)/pbrd.8 endif pbrd_libpbr_a_SOURCES = \ diff --git a/pimd/.gitignore b/pimd/.gitignore index 1f56cfaecd..b1780df758 100644 --- a/pimd/.gitignore +++ b/pimd/.gitignore @@ -1,17 +1,3 @@ -!Makefile -Makefile.in -libpim.a pimd mtracebis test_igmpv3_join -tags -TAGS -.deps -*.o -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/pimd/mtracebis.c b/pimd/mtracebis.c index c0d95aeed9..65c495eff0 100644 --- a/pimd/mtracebis.c +++ b/pimd/mtracebis.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __linux__ #include "pim_igmp_mtrace.h" diff --git a/pimd/mtracebis_netlink.c b/pimd/mtracebis_netlink.c index b4bf6bada3..47b5f7e52c 100644 --- a/pimd/mtracebis_netlink.c +++ b/pimd/mtracebis_netlink.c @@ -10,6 +10,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __linux__ #include <stdio.h> @@ -239,7 +243,7 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, 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 @@ -248,7 +252,7 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth, fprintf(stderr, "ERROR truncated\n"); } else { - errno = -err->error; + errno = -merr->error; perror("RTNETLINK answers"); } return -1; @@ -375,12 +379,12 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, } 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, diff --git a/pimd/mtracebis_routeget.c b/pimd/mtracebis_routeget.c index 8c1cd8d963..8d974403ac 100644 --- a/pimd/mtracebis_routeget.c +++ b/pimd/mtracebis_routeget.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __linux__ #include <asm/types.h> diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 918eaf2fdb..26932eea20 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -432,7 +432,7 @@ static void pim_show_membership_helper(struct vty *vty, json_object_object_add(json_iface, ch_grp_str, json_row); } static void pim_show_membership(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; @@ -549,7 +549,7 @@ static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp, } static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct interface *ifp; time_t now; @@ -634,7 +634,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, static void igmp_show_interfaces_single(struct pim_instance *pim, struct vty *vty, const char *ifname, - uint8_t uj) + bool uj) { struct igmp_sock *igmp; struct interface *ifp; @@ -894,7 +894,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty) static void pim_show_interfaces_single(struct pim_instance *pim, struct vty *vty, const char *ifname, - uint8_t uj) + bool uj) { struct in_addr ifaddr; struct interface *ifp; @@ -1187,8 +1187,9 @@ static void pim_show_interfaces_single(struct pim_instance *pim, 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); @@ -1295,7 +1296,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim, } static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty, - const char *ifname, uint8_t uj) + const char *ifname, bool uj) { struct interface *ifp; struct igmp_stats rx_stats; @@ -1365,7 +1366,7 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty, } static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct interface *ifp; struct listnode *upnode; @@ -1458,7 +1459,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, } static void pim_show_interface_traffic(struct pim_instance *pim, - struct vty *vty, uint8_t uj) + struct vty *vty, bool uj) { struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; @@ -1538,7 +1539,7 @@ static void pim_show_interface_traffic(struct pim_instance *pim, static void pim_show_interface_traffic_single(struct pim_instance *pim, struct vty *vty, - const char *ifname, uint8_t uj) + const char *ifname, bool uj) { struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; @@ -1627,7 +1628,7 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim, static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp, struct pim_ifchannel *ch, json_object *json, - time_t now, uint8_t uj) + time_t now, bool uj) { char ch_src_str[INET_ADDRSTRLEN]; char ch_grp_str[INET_ADDRSTRLEN]; @@ -1690,7 +1691,7 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp, } } -static void pim_show_join(struct pim_instance *pim, struct vty *vty, uint8_t uj) +static void pim_show_join(struct pim_instance *pim, struct vty *vty, bool uj) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; @@ -1724,7 +1725,7 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, uint8_t uj) } static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty, - const char *neighbor, uint8_t uj) + const char *neighbor, bool uj) { struct listnode *neighnode; struct interface *ifp; @@ -1933,8 +1934,7 @@ static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty, } static void pim_show_state(struct pim_instance *pim, struct vty *vty, - const char *src_or_group, const char *group, - uint8_t uj) + const char *src_or_group, const char *group, bool uj) { struct channel_oil *c_oil; struct listnode *node; @@ -2135,7 +2135,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty, } static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *neighnode; struct interface *ifp; @@ -2331,7 +2331,7 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state, } static void pim_show_upstream(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *upnode; struct pim_upstream *up; @@ -2476,7 +2476,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim, struct vty *vty, struct pim_interface *pim_ifp, struct pim_ifchannel *ch, - json_object *json, uint8_t uj) + json_object *json, bool uj) { struct pim_upstream *up = ch->upstream; json_object *json_group = NULL; @@ -2532,7 +2532,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim, } static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; @@ -2568,7 +2568,7 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, } static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *upnode; struct pim_upstream *up; @@ -2701,7 +2701,7 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty, uptime_mroute_del, (long long)pim->mroute_del_events); } -static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, uint8_t uj) +static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj) { struct listnode *up_node; struct pim_upstream *up; @@ -2821,8 +2821,7 @@ static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty) hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd); } -static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, - uint8_t uj) +static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj) { struct interface *ifp; time_t now; @@ -4496,7 +4495,7 @@ DEFUN (show_ip_multicast_vrf_all, } static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill, - uint8_t uj) + bool uj) { struct listnode *node; struct channel_oil *c_oil; @@ -5549,7 +5548,7 @@ DEFUN (no_ip_pim_ssm_prefix_list_name, } static void ip_pim_ssm_show_group_range(struct pim_instance *pim, - struct vty *vty, uint8_t uj) + struct vty *vty, bool uj) { struct pim_ssm *ssm = pim->ssm_info; const char *range_str = @@ -5589,7 +5588,7 @@ DEFUN (show_ip_pim_ssm_range, } static void ip_pim_ssm_show_group_type(struct pim_instance *pim, - struct vty *vty, uint8_t uj, + struct vty *vty, bool uj, const char *group) { struct in_addr group_addr; @@ -5642,27 +5641,6 @@ DEFUN (show_ip_pim_group_type, return CMD_SUCCESS; } -DEFUN_HIDDEN (ip_multicast_routing, - ip_multicast_routing_cmd, - "ip multicast-routing", - IP_STR - "Enable IP multicast forwarding\n") -{ - return CMD_SUCCESS; -} - -DEFUN_HIDDEN (no_ip_multicast_routing, - no_ip_multicast_routing_cmd, - "no ip multicast-routing", - NO_STR - IP_STR - "Enable IP multicast forwarding\n") -{ - vty_out(vty, - "Command is Disabled and will be removed in a future version\n"); - return CMD_SUCCESS; -} - DEFUN (ip_ssmpingd, ip_ssmpingd_cmd, "ip ssmpingd [A.B.C.D]", @@ -5789,7 +5767,7 @@ static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp) 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); @@ -6400,7 +6378,7 @@ static int pim_cmd_interface_add(struct interface *ifp) 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; } @@ -6433,16 +6411,12 @@ DEFUN_HIDDEN (interface_ip_pim_ssm, return CMD_SUCCESS; } -DEFUN (interface_ip_pim_sm, - interface_ip_pim_sm_cmd, - "ip pim sm", - IP_STR - PIM_STR - IFACE_PIM_SM_STR) +static int interface_ip_pim_helper(struct vty *vty) { struct pim_interface *pim_ifp; VTY_DECLVAR_CONTEXT(interface, ifp); + if (!pim_cmd_interface_add(ifp)) { vty_out(vty, "Could not enable PIM SM on interface\n"); return CMD_WARNING_CONFIG_FAILED; @@ -6455,6 +6429,25 @@ DEFUN (interface_ip_pim_sm, return CMD_SUCCESS; } +DEFUN_HIDDEN (interface_ip_pim_sm, + interface_ip_pim_sm_cmd, + "ip pim sm", + IP_STR + PIM_STR + IFACE_PIM_SM_STR) +{ + return interface_ip_pim_helper(vty); +} + +DEFUN (interface_ip_pim, + interface_ip_pim_cmd, + "ip pim", + IP_STR + PIM_STR) +{ + return interface_ip_pim_helper(vty); +} + static int pim_cmd_interface_delete(struct interface *ifp) { struct pim_interface *pim_ifp = ifp->info; @@ -6480,13 +6473,7 @@ static int pim_cmd_interface_delete(struct interface *ifp) return 1; } -DEFUN_HIDDEN (interface_no_ip_pim_ssm, - interface_no_ip_pim_ssm_cmd, - "no ip pim ssm", - NO_STR - IP_STR - PIM_STR - IFACE_PIM_STR) +static int interface_no_ip_pim_helper(struct vty *vty) { VTY_DECLVAR_CONTEXT(interface, ifp); if (!pim_cmd_interface_delete(ifp)) { @@ -6497,7 +6484,18 @@ DEFUN_HIDDEN (interface_no_ip_pim_ssm, return CMD_SUCCESS; } -DEFUN (interface_no_ip_pim_sm, +DEFUN_HIDDEN (interface_no_ip_pim_ssm, + interface_no_ip_pim_ssm_cmd, + "no ip pim ssm", + NO_STR + IP_STR + PIM_STR + IFACE_PIM_STR) +{ + return interface_no_ip_pim_helper(vty); +} + +DEFUN_HIDDEN (interface_no_ip_pim_sm, interface_no_ip_pim_sm_cmd, "no ip pim sm", NO_STR @@ -6505,13 +6503,17 @@ DEFUN (interface_no_ip_pim_sm, PIM_STR IFACE_PIM_SM_STR) { - VTY_DECLVAR_CONTEXT(interface, ifp); - if (!pim_cmd_interface_delete(ifp)) { - vty_out(vty, "Unable to delete interface information\n"); - return CMD_WARNING_CONFIG_FAILED; - } + return interface_no_ip_pim_helper(vty); +} - return CMD_SUCCESS; +DEFUN (interface_no_ip_pim, + interface_no_ip_pim_cmd, + "no ip pim", + NO_STR + IP_STR + PIM_STR) +{ + return interface_no_ip_pim_helper(vty); } /* boundaries */ @@ -7468,7 +7470,7 @@ DEFUN (interface_pim_use_source, interface_pim_use_source_cmd, "ip pim use-source A.B.C.D", IP_STR - "pim multicast routing\n" + PIM_STR "Configure primary IP address\n" "source ip address\n") { @@ -7480,7 +7482,7 @@ DEFUN (interface_no_pim_use_source, "no ip pim use-source [A.B.C.D]", NO_STR IP_STR - "pim multicast routing\n" + PIM_STR "Delete source IP address\n" "source ip address\n") { @@ -7908,7 +7910,7 @@ static void print_empty_json_obj(struct vty *vty) } static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *mbrnode; struct pim_msdp_mg_mbr *mbr; @@ -8030,7 +8032,7 @@ DEFUN (show_ip_msdp_mesh_group_vrf_all, } static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *mpnode; struct pim_msdp_peer *mp; @@ -8084,7 +8086,7 @@ static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty, } static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty, - const char *peer, uint8_t uj) + const char *peer, bool uj) { struct listnode *mpnode; struct pim_msdp_peer *mp; @@ -8262,8 +8264,7 @@ DEFUN (show_ip_msdp_peer_detail_vrf_all, return CMD_SUCCESS; } -static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, - uint8_t uj) +static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8340,7 +8341,7 @@ static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, const char *src_str, const char *grp_str, struct vty *vty, - uint8_t uj, json_object *json) + bool uj, json_object *json) { char rp_str[INET_ADDRSTRLEN]; char peer_str[INET_ADDRSTRLEN]; @@ -8404,7 +8405,7 @@ static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, } static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8487,7 +8488,7 @@ DEFUN (show_ip_msdp_sa_detail_vrf_all, } static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty, - const char *addr, uint8_t uj) + const char *addr, bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8516,7 +8517,7 @@ static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty, } static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty, - const char *src, const char *grp, uint8_t uj) + const char *src, const char *grp, bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8637,8 +8638,6 @@ void pim_cmd_init(void) install_node(&debug_node, pim_debug_config_write); - install_element(CONFIG_NODE, &ip_multicast_routing_cmd); - install_element(CONFIG_NODE, &no_ip_multicast_routing_cmd); install_element(CONFIG_NODE, &ip_pim_rp_cmd); install_element(VRF_NODE, &ip_pim_rp_cmd); install_element(CONFIG_NODE, &no_ip_pim_rp_cmd); @@ -8724,6 +8723,8 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd); + install_element(INTERFACE_NODE, &interface_ip_pim_cmd); + install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd); diff --git a/pimd/pim_errors.c b/pimd/pim_errors.c index d154752bdc..0674a4e994 100644 --- a/pimd/pim_errors.c +++ b/pimd/pim_errors.c @@ -26,13 +26,13 @@ /* 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" diff --git a/pimd/pim_errors.h b/pimd/pim_errors.h index ad9c95a93d..d73caa3f8f 100644 --- a/pimd/pim_errors.h +++ b/pimd/pim_errors.h @@ -24,8 +24,8 @@ #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); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 72ccf3ab1e..249b24c0d7 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -108,7 +108,8 @@ static int pim_sec_addr_comp(const void *p1, const void *p2) 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; @@ -175,7 +176,7 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim) pim_sock_reset(ifp); - pim_if_add_vif(ifp); + pim_if_add_vif(ifp, ispimreg); return pim_ifp; } @@ -626,7 +627,7 @@ void pim_if_addr_add(struct connected *ifc) 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); } @@ -759,7 +760,7 @@ void pim_if_addr_add_all(struct interface *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); @@ -924,7 +925,7 @@ static int pim_iface_next_vif_index(struct interface *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; @@ -946,8 +947,7 @@ int pim_if_add_vif(struct interface *ifp) } 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); @@ -1468,7 +1468,7 @@ void pim_if_create_pimreg(struct pim_instance *pim) 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); } } diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 02926a6973..a7dc097f88 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -154,7 +154,8 @@ struct pim_interface { 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); @@ -163,7 +164,7 @@ void pim_if_addr_del_all(struct interface *ifp); 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); diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 3137345037..a3d6a2e658 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -1115,7 +1115,8 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, 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", diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 270f1e3f27..64537cfa84 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -98,7 +98,7 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, 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); @@ -700,7 +700,7 @@ static void sock_close(struct igmp_sock *igmp) 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)); diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c index 95d0278a34..1fb624a6a0 100644 --- a/pimd/pim_igmp_mtrace.c +++ b/pimd/pim_igmp_mtrace.c @@ -615,7 +615,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, static uint32_t qry_id, qry_src; char mtrace_buf[MTRACE_HDR_SIZE + MTRACE_MAX_HOPS * MTRACE_RSP_SIZE]; struct interface *ifp; - struct interface *out_ifp; + struct interface *out_ifp = NULL; struct pim_interface *pim_ifp; struct pim_instance *pim; struct igmp_mtrace *mtracep; diff --git a/pimd/pim_igmp_stats.c b/pimd/pim_igmp_stats.c index 428816e1f0..40851a4529 100644 --- a/pimd/pim_igmp_stats.c +++ b/pimd/pim_igmp_stats.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "pim_igmp_stats.h" void igmp_stats_init(struct igmp_stats *stats) diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 7b21376c99..430cba76b0 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -1585,7 +1585,7 @@ void igmp_v3_send_query(struct igmp_group *group, int fd, const char *ifname, 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); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index c69e2939e4..436e0508f3 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -154,12 +154,12 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp, * 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; } @@ -179,6 +179,26 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp, 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) { diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 7fcf42e8ce..5a75ed329c 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -519,7 +519,7 @@ static void pim_msdp_sa_local_del_on_up_del(struct pim_instance *pim, * 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; diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index 65232aafa2..39e39b9557 100644 --- a/pimd/pim_msdp_packet.c +++ b/pimd/pim_msdp_packet.c @@ -147,7 +147,7 @@ static void pim_msdp_connect_check(struct pim_msdp_peer *mp) /* 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; @@ -484,9 +484,9 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) 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) { diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index feac42cf53..7997d3138a 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -43,7 +43,7 @@ static void pim_msdp_update_sock_send_buffer_size(int fd) 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; @@ -52,7 +52,7 @@ static void pim_msdp_update_sock_send_buffer_size(int fd) 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)); } @@ -74,8 +74,8 @@ static int pim_msdp_sock_accept(struct thread *thread) /* 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; @@ -85,7 +85,7 @@ static int pim_msdp_sock_accept(struct thread *thread) /* 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; } @@ -95,9 +95,9 @@ static int pim_msdp_sock_accept(struct thread *thread) 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; @@ -141,8 +141,7 @@ int pim_msdp_sock_listen(struct pim_instance *pim) 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; } @@ -161,14 +160,14 @@ int pim_msdp_sock_listen(struct pim_instance *pim) 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); @@ -182,7 +181,7 @@ int pim_msdp_sock_listen(struct pim_instance *pim) } 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); @@ -191,7 +190,7 @@ int pim_msdp_sock_listen(struct pim_instance *pim) 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; @@ -232,7 +231,7 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) /* 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; @@ -242,13 +241,13 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) 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); @@ -267,7 +266,7 @@ int pim_msdp_sock_connect(struct pim_msdp_peer *mp) /* 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); diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 11d8476362..bff1e7ff13 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -801,7 +801,7 @@ void pim_neighbor_update(struct pim_neighbor *neigh, 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); } diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index d5ee30fb2e..0696a680e7 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -116,9 +116,9 @@ void pim_sock_delete(struct interface *ifp, const char *delete_message) 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; } @@ -573,8 +573,6 @@ int pim_msg_send(int fd, struct in_addr src, struct in_addr dst, 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", diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 3db5015e73..51ca0945b9 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -113,8 +113,8 @@ void pim_rp_init(struct pim_instance *pim) 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); @@ -236,7 +236,7 @@ static struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, 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; @@ -625,7 +625,7 @@ int pim_rp_del(struct pim_instance *pim, const char *rp, 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) { @@ -951,8 +951,7 @@ int pim_rp_check_is_my_ip_address(struct pim_instance *pim, return 0; } -void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, - uint8_t uj) +void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) { struct rp_info *rp_info; struct rp_info *prev_rp_info = NULL; diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index e0631b27be..672a696319 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -68,7 +68,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group); #define RP(P, G) pim_rp_g ((P), (G)) void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, - uint8_t uj); + bool uj); void pim_resolve_rp_nh(struct pim_instance *pim); int pim_rp_list_cmp(void *v1, void *v2); #endif diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index 1f584a2f9a..c4538a4ac5 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -151,7 +151,7 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp, } #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); @@ -289,7 +289,7 @@ int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr, 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; diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c index 8347878d3f..dfc7063fd0 100644 --- a/pimd/pim_ssm.c +++ b/pimd/pim_ssm.c @@ -73,9 +73,9 @@ static int pim_is_grp_standard_ssm(struct prefix *group) 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; } diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c index be30d9c73e..a5082608b8 100644 --- a/pimd/pim_ssmpingd.c +++ b/pimd/pim_ssmpingd.c @@ -83,7 +83,7 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl) 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; @@ -127,7 +127,7 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl) } #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); diff --git a/pimd/pim_time.c b/pimd/pim_time.c index 029e551167..23c85c2fa8 100644 --- a/pimd/pim_time.c +++ b/pimd/pim_time.c @@ -35,7 +35,7 @@ static int gettime_monotonic(struct timeval *tv) 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)); } @@ -52,7 +52,7 @@ int64_t pim_time_monotonic_sec() 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; @@ -71,7 +71,7 @@ int64_t pim_time_monotonic_dsec() 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; @@ -89,7 +89,7 @@ int64_t pim_time_monotonic_usec(void) 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; diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 15cbf6fbc3..cc255a51e2 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1764,15 +1764,18 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim, 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; diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 88be195bee..a4aec710e9 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -267,7 +267,7 @@ int pim_interface_config_write(struct vty *vty) struct pim_interface *pim_ifp = ifp->info; if (PIM_IF_TEST_PIM(pim_ifp->options)) { - vty_out(vty, " ip pim sm\n"); + vty_out(vty, " ip pim\n"); ++writes; } diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index ab6258ad36..4ff9bd6bdc 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -112,7 +112,7 @@ static int pim_zebra_if_add(int command, struct zclient *zclient, 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; } @@ -1044,9 +1044,14 @@ void igmp_source_forward_start(struct pim_instance *pim, 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. diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index baa07a8ec6..48a228c744 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -123,8 +123,8 @@ void zclient_lookup_new(void) { 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; } @@ -170,9 +170,9 @@ static int zclient_read_nexthop(struct pim_instance *pim, 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; } @@ -315,9 +315,9 @@ static int zclient_lookup_nexthop_once(struct pim_instance *pim, /* 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; } @@ -338,14 +338,14 @@ static int zclient_lookup_nexthop_once(struct pim_instance *pim, 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); @@ -516,7 +516,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) 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; @@ -535,9 +535,9 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) 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; } @@ -553,7 +553,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) 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); diff --git a/pimd/pimd.c b/pimd/pimd.c index dd0c7e3c2a..5d3018b2fd 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -86,7 +86,7 @@ void pim_init() { 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)); diff --git a/pimd/subdir.am b/pimd/subdir.am index 55d56ece97..fef8e36577 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -8,6 +8,9 @@ sbin_PROGRAMS += pimd/pimd bin_PROGRAMS += pimd/mtracebis noinst_PROGRAMS += pimd/test_igmpv3_join dist_examples_DATA += pimd/pimd.conf.sample +vtysh_scan += $(top_srcdir)/pimd/pim_cmd.c +man8 += $(MANBUILD)/pimd.8 +man8 += $(MANBUILD)/mtracebis.8 endif pimd_libpim_a_SOURCES = \ diff --git a/pkgsrc/.gitignore b/pkgsrc/.gitignore index 63e9a66d8f..c97f963b3d 100644 --- a/pkgsrc/.gitignore +++ b/pkgsrc/.gitignore @@ -1,8 +1 @@ -Makefile -Makefile.in *.sh -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/ports/.gitignore b/ports/.gitignore deleted file mode 100644 index dd5bf7c67c..0000000000 --- a/ports/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.arch-inventory -.arch-ids - -*~ -*.loT - diff --git a/ports/files/.gitignore b/ports/files/.gitignore deleted file mode 100644 index dd5bf7c67c..0000000000 --- a/ports/files/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.arch-inventory -.arch-ids - -*~ -*.loT - diff --git a/ports/pkg/.gitignore b/ports/pkg/.gitignore deleted file mode 100644 index dd5bf7c67c..0000000000 --- a/ports/pkg/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.arch-inventory -.arch-ids - -*~ -*.loT - diff --git a/python/clidef.py b/python/clidef.py index 4134f4c94e..a140ce3d54 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -96,7 +96,7 @@ class IP4Handler(IPBase): code = Template('_fail = !inet_aton(argv[_i]->arg, &$varname);') class IP6Handler(IPBase): argtype = 'struct in6_addr' - decl = Template('struct in6_addr $varname = IN6ADDR_ANY_INIT;') + decl = Template('struct in6_addr $varname = {};') code = Template('_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);') class IPGenHandler(IPBase): argtype = 'const union sockunion *' diff --git a/qpb/.gitignore b/qpb/.gitignore deleted file mode 100644 index 17e90443e9..0000000000 --- a/qpb/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -!Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/qpb/qpb_allocator.c b/qpb/qpb_allocator.c index 7e5ba5b0ce..aca611ba19 100644 --- a/qpb/qpb_allocator.c +++ b/qpb/qpb_allocator.c @@ -22,6 +22,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "linear_allocator.h" #include "qpb_allocator.h" diff --git a/qpb/subdir.am b/qpb/subdir.am index 3c006fd221..75a733f8fc 100644 --- a/qpb/subdir.am +++ b/qpb/subdir.am @@ -2,24 +2,45 @@ if HAVE_PROTOBUF lib_LTLIBRARIES += qpb/libfrr_pb.la endif -qpb_libfrr_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \ - $(Q_PROTOBUF_C_CLIENT_INCLUDES) +qpb_libfrr_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS) +qpb_libfrr_pb_la_LIBADD = $(PROTOBUF_C_LIBS) qpb_libfrr_pb_la_LDFLAGS = -version-info 0:0:0 qpb_libfrr_pb_la_SOURCES = \ + qpb/qpb.c \ + qpb/qpb_allocator.c \ + # end +nodist_qpb_libfrr_pb_la_SOURCES = \ + qpb/qpb.pb-c.c \ + # end + +noinst_HEADERS += \ qpb/linear_allocator.h \ qpb/qpb.h \ - qpb/qpb.c \ qpb/qpb_allocator.h \ # end -if HAVE_PROTOBUF -qpb_libfrr_pb_la_SOURCES += qpb/qpb_allocator.c -nodist_qpb_libfrr_pb_la_SOURCES = qpb/qpb.pb-c.c CLEANFILES += \ qpb/qpb.pb-c.c \ qpb/qpb.pb-c.h \ # end -endif EXTRA_DIST += qpb/qpb.proto + +if HAVE_PROTOBUF + +# Rules +.proto.pb.h: + $(PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^ + +AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V)) +am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY)) +am__v_PROTOC_C_0 = @echo " PROTOC_C" $@; +am__v_PROTOC_C_1 = + +.proto.pb-c.c: + $(AM_V_PROTOC_C)$(PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^ +.pb-c.c.pb-c.h: + @/bin/true + +endif # HAVE_PROTOBUF diff --git a/redhat/.gitignore b/redhat/.gitignore index a38f1c06e3..15804cea0f 100644 --- a/redhat/.gitignore +++ b/redhat/.gitignore @@ -1,10 +1,2 @@ zebra.spec frr.spec -Makefile -Makefile.in -.nfs* -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/redhat/README.rpm_build.md b/redhat/README.rpm_build.md index c461e543d2..a3f095786d 100644 --- a/redhat/README.rpm_build.md +++ b/redhat/README.rpm_build.md @@ -3,16 +3,15 @@ Building your own FRRouting RPM (Tested on CentOS 6, CentOS 7 and Fedora 24.) 1. On CentOS 6 (which doesn't provide a bison/automake/autoconf of a recent enough version): - - Check out ../doc/Building_FRR_on_CentOS6.md for details on installing + - Check out ../doc/developer/building-frr-for-centos6.rst for details on installing a bison/automake/autoconf to support frr building. Newer automake/autoconf/bison is only needed to build the rpm and is **not** needed to install the binary rpm package -2. Install the build packages as documented in doc/Building_on_xxxxx.md - and the following additional packages: +2. Install the build packages as documented in doc/developer/building-frr-for-xxxxx.rst and the following additional packages: - yum install rpm-build net-snmp-devel pam-devel + yum install rpm-build net-snmp-devel pam-devel libcap-devel Additionally, on systems with systemd (CentOS 7, Fedora) @@ -28,8 +27,9 @@ Building your own FRRouting RPM cd frr ./bootstrap.sh - ./configure --with-pkg-extra-version=-MyRPMVersion - make SPHINXBUILD=sphinx-build2.7 dist + ./configure --with-pkg-extra-version=-MyRPMVersion \ + SPHINXBUILD=sphinx-build2.7 + make dist Note: configure parameters are not important for the RPM building - except the `with-pkg-extra-version` if you want to give the RPM a specific name to mark your own unoffical build diff --git a/redhat/daemons b/redhat/daemons index de708cf4fd..c301a1c23a 100644 --- a/redhat/daemons +++ b/redhat/daemons @@ -53,6 +53,7 @@ sharpd=no pbrd=no staticd=no bfdd=no +fabricd=no # # Command line options for the daemons @@ -73,6 +74,7 @@ sharpd_options=("-A 127.0.0.1") pbrd_options=("-A 127.0.0.1") staticd_options=("-A 127.0.0.1") bfdd_options=("-A 127.0.0.1") +fabricd_options=("-A 127.0.0.1") # # If the vtysh_enable is yes, then the unified config is read diff --git a/redhat/frr.init b/redhat/frr.init index 2e33aee173..47a92eed32 100755 --- a/redhat/frr.init +++ b/redhat/frr.init @@ -33,7 +33,7 @@ V_PATH=/var/run/frr # Local Daemon selection may be done by using /etc/frr/daemons. # See /usr/share/doc/frr/README.Debian.gz for further information. # Keep zebra first and do not list watchfrr! -DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd pbrd ldpd nhrpd eigrpd babeld staticd sharpd bfdd" +DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd pbrd ldpd nhrpd eigrpd babeld staticd sharpd bfdd fabricd" MAX_INSTANCES=5 RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py diff --git a/redhat/frr.logrotate b/redhat/frr.logrotate index 654d355fd7..df7c5da54e 100644 --- a/redhat/frr.logrotate +++ b/redhat/frr.logrotate @@ -93,3 +93,11 @@ /bin/kill -USR1 `cat /var/run/frr/bfdd.pid 2> /dev/null` 2> /dev/null || true endscript } + +/var/log/frr/fabricd.log { + notifempty + missingok + postrotate + /bin/kill -USR1 `cat /var/run/frr/fabricd.pid 2> /dev/null` 2> /dev/null || true + endscript +} diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index 25b48506a6..bff0b40515 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -86,7 +86,7 @@ %{!?frr_gid: %global frr_gid 92 } %{!?vty_gid: %global vty_gid 85 } -%define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd staticd bfdd +%define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd staticd bfdd fabricd %if %{with_ldpd} %define daemon_ldpd ldpd @@ -343,22 +343,23 @@ developing OSPF-API and frr applications. --disable-rpki \ %endif %if %{with_bfdd} - --enable-bfdd + --enable-bfdd \ %else - --disable-bfdd + --disable-bfdd \ %endif + SPHINXBUILD=%{sphinx} -make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" SPHINXBUILD=%{sphinx} +make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" pushd doc -make SPHINXBUILD=%{sphinx} info +make info popd %install mkdir -p %{buildroot}%{_sysconfdir}/{frr,sysconfig,logrotate.d,pam.d,default} \ %{buildroot}%{_localstatedir}/log/frr %{buildroot}%{_infodir} -make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" SPHINXBUILD=%{sphinx} install +make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install # Remove this file, as it is uninstalled and causes errors when building on RH9 rm -rf %{buildroot}/usr/share/info/dir @@ -459,6 +460,7 @@ zebra_spec_add_service isisd 2608/tcp "ISISd vty" %if %{with_bfdd} zebra_spec_add_service bfdd 2617/tcp "BFDd vty" %endif +zebra_spec_add_service fabricd 2618/tcp "Fabricd vty" %if "%{initsystem}" == "systemd" for daemon in %all_daemons ; do @@ -559,9 +561,9 @@ fi %files -%doc */*.sample* AUTHORS COPYING +%doc */*.sample* COPYING %doc doc/mpls -%doc ChangeLog NEWS README +%doc README.md %if 0%{?frr_user:1} %dir %attr(751,%{frr_user},%{frr_user}) %{configdir} %dir %attr(750,%{frr_user},%{frr_user}) %{_localstatedir}/log/frr @@ -594,6 +596,7 @@ fi %{_sbindir}/pbrd %endif %{_sbindir}/isisd +%{_sbindir}/fabricd %if %{with_ldpd} %{_sbindir}/ldpd %endif diff --git a/ripd/.gitignore b/ripd/.gitignore index 177250ca61..f149501d61 100644 --- a/ripd/.gitignore +++ b/ripd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ripd ripd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ripd/rip_errors.c b/ripd/rip_errors.c index 363b1b7fb5..b6fc43ee7c 100644 --- a/ripd/rip_errors.c +++ b/ripd/rip_errors.c @@ -24,16 +24,13 @@ #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) { diff --git a/ripd/rip_errors.h b/ripd/rip_errors.h index 6b5f5c0169..feadf430ef 100644 --- a/ripd/rip_errors.h +++ b/ripd/rip_errors.h @@ -24,7 +24,7 @@ #include "lib/ferr.h" enum rip_log_refs { - RIP_ERR_PACKET = RIP_FERR_START, + EC_RIP_PACKET = RIP_FERR_START, RIP_ERR_CONFIG, }; diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 364e23c5e6..bbac1a0a00 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -712,7 +712,7 @@ static int rip_enable_network_lookup_if(struct interface *ifp) for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) { struct prefix *p; - struct route_node *node; + struct route_node *n; p = connected->address; @@ -721,10 +721,10 @@ static int rip_enable_network_lookup_if(struct interface *ifp) 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; } } @@ -865,7 +865,7 @@ static int rip_interface_wakeup(struct thread *t) /* 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; diff --git a/ripd/ripd.c b/ripd/ripd.c index 02ead6fde2..94c3d4bc9c 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -436,8 +436,6 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, /* 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); @@ -1058,9 +1056,10 @@ static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri, /* 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; } @@ -1341,7 +1340,7 @@ static int rip_create_socket(void) /* 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); } diff --git a/ripd/subdir.am b/ripd/subdir.am index 612db1a7ab..0d06e7e653 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -6,9 +6,18 @@ if RIPD noinst_LIBRARIES += ripd/librip.a sbin_PROGRAMS += ripd/ripd dist_examples_DATA += ripd/ripd.conf.sample +vtysh_scan += \ + $(top_srcdir)/ripd/rip_debug.c \ + $(top_srcdir)/ripd/rip_interface.c \ + $(top_srcdir)/ripd/rip_offset.c \ + $(top_srcdir)/ripd/rip_zebra.c \ + $(top_srcdir)/ripd/ripd.c \ + # end + if SNMP module_LTLIBRARIES += ripd/ripd_snmp.la endif +man8 += $(MANBUILD)/ripd.8 endif ripd_librip_a_SOURCES = \ diff --git a/ripngd/.gitignore b/ripngd/.gitignore index 213384d139..e6a8ee6be2 100644 --- a/ripngd/.gitignore +++ b/ripngd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ripngd ripngd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index d7d3d245d6..a1d25f2961 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -643,7 +643,7 @@ static int ripng_interface_wakeup(struct thread *t) /* 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; diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index d1341d67b7..fbc06b0348 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -95,7 +95,7 @@ static int ripng_make_socket(void) 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; } @@ -199,14 +199,13 @@ int ripng_send_packet(caddr_t buf, int bufsize, struct sockaddr_in6 *to, 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; @@ -706,8 +705,6 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, /* 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); @@ -1618,8 +1615,6 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, /* 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); @@ -1636,8 +1631,6 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, /* 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); @@ -1724,7 +1717,6 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, /* Interface route-map */ if (ri->routemap[RIPNG_FILTER_OUT]) { - int ret; struct ripng_info newinfo; /* let's cast the aggregate structure to diff --git a/ripngd/subdir.am b/ripngd/subdir.am index 1f7ff09d6e..8f834a1d29 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -5,6 +5,14 @@ if RIPNGD noinst_LIBRARIES += ripngd/libripng.a sbin_PROGRAMS += ripngd/ripngd +vtysh_scan += \ + $(top_srcdir)/ripngd/ripng_debug.c \ + $(top_srcdir)/ripngd/ripng_interface.c \ + $(top_srcdir)/ripngd/ripng_offset.c \ + $(top_srcdir)/ripngd/ripng_zebra.c \ + $(top_srcdir)/ripngd/ripngd.c \ + # end +man8 += $(MANBUILD)/ripngd.8 endif ripngd_libripng_a_SOURCES = \ diff --git a/sharpd/.gitignore b/sharpd/.gitignore index cc33cfc188..91b9f2e902 100644 --- a/sharpd/.gitignore +++ b/sharpd/.gitignore @@ -1,17 +1,2 @@ -Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT sharpd sharpd.conf diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 956da9d4ed..797e336c2d 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -81,13 +81,14 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, DEFPY (install_routes, install_routes_cmd, - "sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes [instance (0-255)$instance]", + "sharp install routes A.B.C.D$start nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6> (1-1000000)$routes [instance (0-255)$instance]", "Sharp routing Protocol\n" "install some routes\n" "Routes to install\n" "Address to start /32 generation at\n" - "Nexthop to use\n" - "Nexthop address\n" + "Nexthop to use(Can be an IPv4 or IPv6 address)\n" + "V4 Nexthop address to use\n" + "V6 Nexthop address to use\n" "How many to create\n" "Instance to use\n" "Instance\n") @@ -107,8 +108,13 @@ DEFPY (install_routes, p.prefixlen = 32; p.u.prefix4 = start; - nhop.gate.ipv4 = nexthop; - nhop.type = NEXTHOP_TYPE_IPV4; + if (nexthop4.s_addr != INADDR_ANY) { + nhop.gate.ipv4 = nexthop4; + nhop.type = NEXTHOP_TYPE_IPV4; + } else { + memcpy(&nhop.gate.ipv6, &nexthop6, IPV6_MAX_BYTELEN); + nhop.type = NEXTHOP_TYPE_IPV6; + } zlog_debug("Inserting %ld routes", routes); @@ -185,6 +191,18 @@ DEFPY (remove_routes, return CMD_SUCCESS; } +DEFUN_NOSH (show_debugging_sharpd, + show_debugging_sharpd_cmd, + "show debugging [sharp]", + SHOW_STR + DEBUG_STR + "Sharp Information\n") +{ + vty_out(vty, "Sharp debugging status\n"); + + return CMD_SUCCESS; +} + void sharp_vty_init(void) { install_element(ENABLE_NODE, &install_routes_cmd); @@ -192,5 +210,8 @@ void sharp_vty_init(void) install_element(ENABLE_NODE, &vrf_label_cmd); install_element(ENABLE_NODE, &watch_nexthop_v6_cmd); install_element(ENABLE_NODE, &watch_nexthop_v4_cmd); + + install_element(VIEW_NODE, &show_debugging_sharpd_cmd); + return; } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index fcb555170b..286f320874 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -193,7 +193,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh) api_nh = &api.nexthops[0]; api_nh->vrf_id = VRF_DEFAULT; - api_nh->gate.ipv4 = nh->gate.ipv4; + api_nh->gate = nh->gate; api_nh->type = nh->type; api_nh->ifindex = nh->ifindex; api.nexthop_num = 1; diff --git a/sharpd/subdir.am b/sharpd/subdir.am index 490a2ba787..2a34aecfb3 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -6,6 +6,8 @@ if SHARPD noinst_LIBRARIES += sharpd/libsharp.a sbin_PROGRAMS += sharpd/sharpd dist_examples_DATA += sharpd/sharpd.conf.sample +vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c +man8 += $(MANBUILD)/sharpd.8 endif sharpd_libsharp_a_SOURCES = \ diff --git a/snapcraft/.gitignore b/snapcraft/.gitignore index ac7860290b..a4796fd730 100644 --- a/snapcraft/.gitignore +++ b/snapcraft/.gitignore @@ -3,4 +3,3 @@ parts prime stage frr*.snap -!*/Makefile diff --git a/solaris/.gitignore b/solaris/.gitignore index a249b61996..3f1a0385a4 100644 --- a/solaris/.gitignore +++ b/solaris/.gitignore @@ -17,6 +17,3 @@ depend.smf frr.init *.pkg *.pkg.gz -*~ -*.loT -*.a diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 771d8d1de3..f697969a72 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -88,8 +88,8 @@ static struct list *static_list; static int static_list_compare_helper(const char *s1, const char *s2) { - /* Are Both NULL */ - if (s1 == s2) + /* extra (!s1 && !s2) to keep SA happy */ + if (s1 == s2 || (!s1 && !s2)) return 0; if (!s1 && s2) @@ -1390,6 +1390,18 @@ DEFPY(ipv6_route_vrf, table_str); } +DEFUN_NOSH (show_debugging_staticd, + show_debugging_staticd_cmd, + "show debugging [static]", + SHOW_STR + DEBUG_STR + "Static Information\n") +{ + vty_out(vty, "Static debugging status\n"); + + return CMD_SUCCESS; +} + void static_vty_init(void) { install_element(CONFIG_NODE, &ip_mroute_dist_cmd); @@ -1408,6 +1420,8 @@ void static_vty_init(void) install_element(CONFIG_NODE, &ipv6_route_cmd); install_element(VRF_NODE, &ipv6_route_vrf_cmd); + install_element(VIEW_NODE, &show_debugging_staticd_cmd); + static_list = list_new(); static_list->cmp = (int (*)(void *, void *))static_list_compare; static_list->del = (void (*)(void *))static_list_delete; diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 4692dc00d7..c540942a8d 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -385,6 +385,9 @@ extern void static_zebra_route_add(struct route_node *rn, 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: diff --git a/staticd/subdir.am b/staticd/subdir.am index 3b06a92e22..33cc0e2050 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -6,6 +6,8 @@ if STATICD noinst_LIBRARIES += staticd/libstatic.a sbin_PROGRAMS += staticd/staticd dist_examples_DATA += staticd/staticd.conf.sample +vtysh_scan += $(top_srcdir)/staticd/static_vty.c +man8 += $(MANBUILD)/staticd.8 endif staticd_libstatic_a_SOURCES = \ diff --git a/tests/.gitignore b/tests/.gitignore index c8368b39b6..37cd245de0 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,24 +1,6 @@ -Makefile -Makefile.in -*.o -tags -TAGS -.cache -.deps -.nfs* -*~ -*.loT -*.lo -*.la -*.libs -*.bak *.log *.sum *.xml -*.pyc -.arch-inventory -.arch-ids -__pycache__ .pytest_cache /bgpd/test_aspath /bgpd/test_bgp_table diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000000..dd4594febe --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C .. check +%: ALWAYS + @$(MAKE) -s -C .. tests/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index a7dec67348..0000000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,235 +0,0 @@ -include ../common.am - -PYTHON ?= python - -AUTOMAKE_OPTIONS = subdir-objects -AM_CPPFLAGS += \ - -I.. \ - -I$(top_srcdir) \ - -I$(top_srcdir)/lib \ - -I$(top_builddir)/lib \ - -I$(top_srcdir)/tests/helpers/c \ - -I$(top_builddir)/tests/helpers/c \ - -O -DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" - -if BGPD -TESTS_BGPD = \ - bgpd/test_aspath \ - bgpd/test_capability \ - bgpd/test_packet \ - bgpd/test_peer_attr \ - bgpd/test_ecommunity \ - bgpd/test_mp_attr \ - bgpd/test_mpath \ - bgpd/test_bgp_table -else -TESTS_BGPD = -endif - -if ISISD -if SOLARIS -TESTS_ISISD = -else -TESTS_ISISD = \ - isisd/test_fuzz_isis_tlv \ - isisd/test_isis_vertex_queue \ - # end -endif -else -TESTS_ISISD = -endif - -if OSPF6D -TESTS_OSPF6D = \ - ospf6d/test_lsdb \ - # end -else -TESTS_OSPF6D = -endif - -if ENABLE_BGP_VNC -BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a -else -BGP_VNC_RFP_LIB = -endif - -lib/cli/test_cli.o: lib/cli/test_cli_clippy.c -ospf6d/test_lsdb.o: ospf6d/test_lsdb_clippy.c - -check_PROGRAMS = \ - lib/test_buffer \ - lib/test_checksum \ - lib/test_heavy_thread \ - lib/test_heavy_wq \ - lib/test_heavy \ - lib/test_memory \ - lib/test_nexthop_iter \ - lib/test_privs \ - lib/test_ringbuf \ - lib/test_srcdest_table \ - lib/test_segv \ - lib/test_sig \ - lib/test_stream \ - lib/test_table \ - lib/test_timer_correctness \ - lib/test_timer_performance \ - lib/test_ttable \ - lib/test_zlog \ - lib/test_graph \ - lib/cli/test_cli \ - lib/cli/test_commands \ - $(TESTS_BGPD) \ - $(TESTS_ISISD) \ - $(TESTS_OSPF6D) \ - # end - -if ZEROMQ -check_PROGRAMS += \ - lib/test_zmq \ - # end -endif - -../vtysh/vtysh_cmd.c: - $(MAKE) -C ../vtysh vtysh_cmd.c - -lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c - sed \ - -e 's/"vtysh\.h"/"tests.h"/' \ - -e 's/vtysh_init_cmd/test_init_cmd/' \ - -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \ - < ../vtysh/vtysh_cmd.c \ - > "$@" - -isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz - gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@" - -noinst_HEADERS = \ - ./helpers/c/prng.h \ - ./helpers/c/tests.h \ - ./lib/cli/common_cli.h - -lib_test_buffer_SOURCES = lib/test_buffer.c -lib_test_checksum_SOURCES = lib/test_checksum.c -lib_test_heavy_thread_SOURCES = lib/test_heavy_thread.c helpers/c/main.c -lib_test_heavy_wq_SOURCES = lib/test_heavy_wq.c helpers/c/main.c -lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c -lib_test_memory_SOURCES = lib/test_memory.c -lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c -lib_test_privs_SOURCES = lib/test_privs.c -lib_test_ringbuf_SOURCES = lib/test_ringbuf.c -lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \ - helpers/c/prng.c -lib_test_segv_SOURCES = lib/test_segv.c -lib_test_sig_SOURCES = lib/test_sig.c -lib_test_stream_SOURCES = lib/test_stream.c -lib_test_table_SOURCES = lib/test_table.c -lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \ - helpers/c/prng.c -lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \ - helpers/c/prng.c -lib_test_ttable_SOURCES = lib/test_ttable.c -lib_test_zlog_SOURCES = lib/test_zlog.c -lib_test_graph_SOURCES = lib/test_graph.c -lib_test_zmq_SOURCES = lib/test_zmq.c -lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS) -lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c -lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \ - lib/cli/test_commands.c \ - helpers/c/prng.c -bgpd_test_aspath_SOURCES = bgpd/test_aspath.c -bgpd_test_capability_SOURCES = bgpd/test_capability.c -bgpd_test_packet_SOURCES = bgpd/test_packet.c -bgpd_test_peer_attr_SOURCES = bgpd/test_peer_attr.c -bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c -bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c -bgpd_test_mpath_SOURCES = bgpd/test_mpath.c -bgpd_test_bgp_table_SOURCES = bgpd/test_bgp_table.c -isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c -nodist_isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv_tests.h -BUILT_SOURCES=isisd/test_fuzz_isis_tlv_tests.h -CLEANFILES=isisd/test_fuzz_isis_tlv_tests.h -isisd_test_fuzz_isis_tlv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/tests/isisd -isisd_test_isis_vertex_queue_SOURCES = isisd/test_isis_vertex_queue.c - -ospf6d_test_lsdb_SOURCES = ospf6d/test_lsdb.c lib/cli/common_cli.c - -ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@ -BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm -ISISD_TEST_LDADD = ../isisd/libisis.a $(ALL_TESTS_LDADD) -OSPF6_TEST_LDADD = ../ospf6d/libospf6.a $(ALL_TESTS_LDADD) - -lib_test_buffer_LDADD = $(ALL_TESTS_LDADD) -lib_test_checksum_LDADD = $(ALL_TESTS_LDADD) -lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_memory_LDADD = $(ALL_TESTS_LDADD) -lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD) -lib_test_privs_LDADD = $(ALL_TESTS_LDADD) -lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD) -lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD) -lib_test_segv_LDADD = $(ALL_TESTS_LDADD) -lib_test_sig_LDADD = $(ALL_TESTS_LDADD) -lib_test_stream_LDADD = $(ALL_TESTS_LDADD) -lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) -lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) -lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) -lib_test_zlog_LDADD = $(ALL_TESTS_LDADD) -lib_test_graph_LDADD = $(ALL_TESTS_LDADD) -lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS) -lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) -lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) -bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD) -bgpd_test_capability_LDADD = $(BGP_TEST_LDADD) -bgpd_test_packet_LDADD = $(BGP_TEST_LDADD) -bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD) -bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD) -bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD) -bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD) -bgpd_test_bgp_table_LDADD = $(BGP_TEST_LDADD) -isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD) -isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD) -ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD) - -EXTRA_DIST = \ - runtests.py \ - bgpd/test_aspath.py \ - bgpd/test_capability.py \ - bgpd/test_ecommunity.py \ - bgpd/test_mp_attr.py \ - bgpd/test_mpath.py \ - bgpd/test_peer_attr.py \ - helpers/python/frrsix.py \ - helpers/python/frrtest.py \ - isisd/test_fuzz_isis_tlv.py \ - isisd/test_fuzz_isis_tlv_tests.h.gz \ - isisd/test_isis_vertex_queue.py \ - lib/cli/test_commands.in \ - lib/cli/test_commands.py \ - lib/cli/test_commands.refout \ - lib/cli/test_cli.in \ - lib/cli/test_cli.py \ - lib/cli/test_cli.refout \ - lib/test_nexthop_iter.py \ - lib/test_ringbuf.py \ - lib/test_srcdest_table.py \ - lib/test_stream.py \ - lib/test_stream.refout \ - lib/test_table.py \ - lib/test_timer_correctness.py \ - lib/test_ttable.py \ - lib/test_ttable.refout \ - lib/test_zlog.py \ - lib/test_graph.py \ - lib/test_graph.refout \ - ospf6d/test_lsdb.py \ - ospf6d/test_lsdb.in \ - ospf6d/test_lsdb.refout \ - # end - -.PHONY: tests.xml -tests.xml: $(check_PROGRAMS) - $(PYTHON) $(srcdir)/runtests.py --junitxml=$@ -v $(srcdir) -check: tests.xml diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c index 452245ec16..e40fba2457 100644 --- a/tests/bgpd/test_peer_attr.c +++ b/tests/bgpd/test_peer_attr.c @@ -1388,7 +1388,7 @@ static void bgp_startup(void) 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(); } diff --git a/tests/helpers/python/frrtest.py b/tests/helpers/python/frrtest.py index da9e447fc0..60bee5c88c 100644 --- a/tests/helpers/python/frrtest.py +++ b/tests/helpers/python/frrtest.py @@ -176,8 +176,14 @@ class TestRefOut(object): basedir = os.path.dirname(inspect.getsourcefile(type(self))) program = os.path.join(basedir, self.program) - refin = program + '.in' - refout = program + '.refout' + if getattr(self, 'built_refin', False): + refin = binpath(program) + '.in' + else: + refin = program + '.in' + if getattr(self, 'built_refout', False): + refout = binpath(program) + '.refout' + else: + refout = program + '.refout' intext = '' if os.path.exists(refin): diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index 67a1593500..b75c1002d4 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "test_fuzz_isis_tlv_tests.h" #include <zebra.h> @@ -114,7 +118,11 @@ static int test(FILE *input, FILE *output) const char *s_tlvs = isis_format_tlvs(tlvs); fprintf(output, "Unpacked TLVs:\n%s", s_tlvs); + struct isis_item *orig_auth = tlvs->isis_auth.head; + tlvs->isis_auth.head = NULL; + s_tlvs = isis_format_tlvs(tlvs); struct isis_tlvs *tlv_copy = isis_copy_tlvs(tlvs); + tlvs->isis_auth.head = orig_auth; isis_free_tlvs(tlvs); struct stream *s2 = stream_new(TEST_STREAM_SIZE); diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz Binary files differindex 4abbe81499..4a89bda84e 100644 --- a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz +++ b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz diff --git a/tests/isisd/test_isis_vertex_queue.c b/tests/isisd/test_isis_vertex_queue.c index 3e31b83351..869dd732eb 100644 --- a/tests/isisd/test_isis_vertex_queue.c +++ b/tests/isisd/test_isis_vertex_queue.c @@ -16,42 +16,46 @@ static size_t vertex_count; static void setup_test_vertices(void) { - union isis_N nid, nip = { - .ip.dest.family = AF_UNSPEC + struct isis_spftree t = { }; + struct prefix_pair p = { + }; + uint8_t node_id[7]; vertices = XMALLOC(MTYPE_TMP, sizeof(*vertices) * 16); - nip.ip.dest.family = AF_INET; - nip.ip.dest.prefixlen = 24; - inet_pton(AF_INET, "192.168.1.0", &nip.ip.dest.u.prefix4); - vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE); + p.dest.family = AF_INET; + p.dest.prefixlen = 24; + inet_pton(AF_INET, "192.168.1.0", &p.dest.u.prefix4); + vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE); vertices[vertex_count]->d_N = 20; vertex_count++; - nip.ip.dest.family = AF_INET; - nip.ip.dest.prefixlen = 24; - inet_pton(AF_INET, "192.168.2.0", &nip.ip.dest.u.prefix4); - vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE); + p.dest.family = AF_INET; + p.dest.prefixlen = 24; + inet_pton(AF_INET, "192.168.2.0", &p.dest.u.prefix4); + vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE); vertices[vertex_count]->d_N = 20; vertex_count++; - memset(nid.id, 0, sizeof(nid.id)); - nid.id[6] = 1; - vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_PSEUDO_TE_IS); + memset(node_id, 0, sizeof(node_id)); + node_id[6] = 1; + vertices[vertex_count] = isis_vertex_new(&t, node_id, + VTYPE_PSEUDO_TE_IS); vertices[vertex_count]->d_N = 15; vertex_count++; - memset(nid.id, 0, sizeof(nid.id)); - nid.id[5] = 2; - vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_NONPSEUDO_TE_IS); + memset(node_id, 0, sizeof(node_id)); + node_id[5] = 2; + vertices[vertex_count] = isis_vertex_new(&t, node_id, + VTYPE_NONPSEUDO_TE_IS); vertices[vertex_count]->d_N = 15; vertex_count++; - nip.ip.dest.family = AF_INET; - nip.ip.dest.prefixlen = 24; - inet_pton(AF_INET, "192.168.3.0", &nip.ip.dest.u.prefix4); - vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE); + p.dest.family = AF_INET; + p.dest.prefixlen = 24; + inet_pton(AF_INET, "192.168.3.0", &p.dest.u.prefix4); + vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE); vertices[vertex_count]->d_N = 20; vertex_count++; }; diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c index 4cc15ba23f..8f062d8b5e 100644 --- a/tests/lib/cli/test_cli.c +++ b/tests/lib/cli/test_cli.c @@ -41,7 +41,7 @@ DUMMY_DEFUN(cmd13, "alt a X:X::X:X"); DUMMY_DEFUN(cmd14, "pat g { foo A.B.C.D$foo|foo|bar X:X::X:X$bar| baz } [final]"); -#include "lib/cli/test_cli_clippy.c" +#include "tests/lib/cli/test_cli_clippy.c" DEFPY(magic_test, magic_test_cmd, "magic (0-100) {ipv4net A.B.C.D/M|X:X::X:X$ipv6}", diff --git a/tests/lib/cli/test_cli.py b/tests/lib/cli/test_cli.py index e3c31c2d91..7371db283a 100644 --- a/tests/lib/cli/test_cli.py +++ b/tests/lib/cli/test_cli.py @@ -2,3 +2,4 @@ import frrtest class TestCli(frrtest.TestRefOut): program = './test_cli' + built_refout = True diff --git a/tests/lib/cli/test_commands.c b/tests/lib/cli/test_commands.c index 2a8d263175..a8b42ba789 100644 --- a/tests/lib/cli/test_commands.c +++ b/tests/lib/cli/test_commands.c @@ -265,10 +265,10 @@ static void test_run(struct prng *prng, struct vty *vty, const char *cmd, 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); } diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c index e717da15b3..70db69aadf 100644 --- a/tests/lib/test_srcdest_table.c +++ b/tests/lib/test_srcdest_table.c @@ -289,7 +289,6 @@ static void test_state_verify(struct test_state *test) 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); diff --git a/tests/ospf6d/test_lsdb.c b/tests/ospf6d/test_lsdb.c index ec0835c719..24821febe6 100644 --- a/tests/ospf6d/test_lsdb.c +++ b/tests/ospf6d/test_lsdb.c @@ -29,7 +29,7 @@ #include "ospf6d/ospf6_lsdb.h" #include "tests/lib/cli/common_cli.h" -#include "ospf6d/test_lsdb_clippy.c" +#include "tests/ospf6d/test_lsdb_clippy.c" static struct ospf6_lsdb *lsdb; diff --git a/tests/subdir.am b/tests/subdir.am new file mode 100644 index 0000000000..739a0e86fe --- /dev/null +++ b/tests/subdir.am @@ -0,0 +1,295 @@ +# +# tests +# + +PYTHON ?= python + +if BGPD +TESTS_BGPD = \ + tests/bgpd/test_aspath \ + tests/bgpd/test_capability \ + tests/bgpd/test_packet \ + tests/bgpd/test_peer_attr \ + tests/bgpd/test_ecommunity \ + tests/bgpd/test_mp_attr \ + tests/bgpd/test_mpath \ + tests/bgpd/test_bgp_table +else +TESTS_BGPD = +endif + +if ISISD +if SOLARIS +TESTS_ISISD = +else +TESTS_ISISD = \ + tests/isisd/test_fuzz_isis_tlv \ + tests/isisd/test_isis_vertex_queue \ + # end +endif +else +TESTS_ISISD = +endif + +if OSPF6D +TESTS_OSPF6D = \ + tests/ospf6d/test_lsdb \ + # end +else +TESTS_OSPF6D = +endif + +tests/lib/cli/tests_lib_cli_test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c +tests/lib/cli/test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c +tests/ospf6d/tests_ospf6d_test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c +tests/ospf6d/test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c + +check_PROGRAMS = \ + tests/lib/test_buffer \ + tests/lib/test_checksum \ + tests/lib/test_heavy_thread \ + tests/lib/test_heavy_wq \ + tests/lib/test_heavy \ + tests/lib/test_memory \ + tests/lib/test_nexthop_iter \ + tests/lib/test_privs \ + tests/lib/test_ringbuf \ + tests/lib/test_srcdest_table \ + tests/lib/test_segv \ + tests/lib/test_sig \ + tests/lib/test_stream \ + tests/lib/test_table \ + tests/lib/test_timer_correctness \ + tests/lib/test_timer_performance \ + tests/lib/test_ttable \ + tests/lib/test_zlog \ + tests/lib/test_graph \ + tests/lib/cli/test_cli \ + tests/lib/cli/test_commands \ + $(TESTS_BGPD) \ + $(TESTS_ISISD) \ + $(TESTS_OSPF6D) \ + # end + +if ZEROMQ +check_PROGRAMS += \ + tests/lib/test_zmq \ + # end +endif + +tests/lib/cli/test_commands_defun.c: vtysh/vtysh_cmd.c + sed \ + -e 's%"vtysh/vtysh\.h"%"tests/helpers/c/tests.h"%' \ + -e 's/vtysh_init_cmd/test_init_cmd/' \ + -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \ + < vtysh/vtysh_cmd.c \ + > "$@" + +tests/isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz + gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@" +CLEANFILES += tests/isisd/test_fuzz_isis_tlv_tests.h + +tests/isisd/tests_isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \ + tests/isisd/test_fuzz_isis_tlv_tests.h +tests/isisd/test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \ + tests/isisd/test_fuzz_isis_tlv_tests.h + +noinst_HEADERS += \ + tests/helpers/c/prng.h \ + tests/helpers/c/tests.h \ + tests/lib/cli/common_cli.h \ + # end + +# +# *sigh* - there is no way to get CPPFLAGS or CFLAGS for a group of files :( +# + +TESTS_CPPFLAGS = $(AM_CPPFLAGS) \ + -I$(top_srcdir)/tests/helpers/c \ + -I$(top_builddir)/tests/helpers/c \ + # end +TESTS_CFLAGS = $(SAN_FLAGS) +# note no -Werror + +ALL_TESTS_LDADD = lib/libfrr.la @LIBCAP@ +BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) -lm +ISISD_TEST_LDADD = isisd/libisis.a $(ALL_TESTS_LDADD) +OSPF6_TEST_LDADD = ospf6d/libospf6.a $(ALL_TESTS_LDADD) + +tests_bgpd_test_aspath_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_aspath_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_aspath_SOURCES = tests/bgpd/test_aspath.c +tests_bgpd_test_bgp_table_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_bgp_table_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_bgp_table_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_bgp_table_SOURCES = tests/bgpd/test_bgp_table.c +tests_bgpd_test_capability_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_capability_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_capability_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_capability_SOURCES = tests/bgpd/test_capability.c +tests_bgpd_test_ecommunity_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_ecommunity_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_ecommunity_SOURCES = tests/bgpd/test_ecommunity.c +tests_bgpd_test_mp_attr_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_mp_attr_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_mp_attr_SOURCES = tests/bgpd/test_mp_attr.c +tests_bgpd_test_mpath_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_mpath_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_mpath_SOURCES = tests/bgpd/test_mpath.c +tests_bgpd_test_packet_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_packet_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_packet_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_packet_SOURCES = tests/bgpd/test_packet.c +tests_bgpd_test_peer_attr_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_peer_attr_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c + +tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd +tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd +tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD) +tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c +nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h +tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS) +tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD) +tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c + +tests_lib_cli_test_cli_CFLAGS = $(TESTS_CFLAGS) +tests_lib_cli_test_cli_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) +tests_lib_cli_test_cli_SOURCES = tests/lib/cli/test_cli.c tests/lib/cli/common_cli.c +tests_lib_cli_test_commands_CFLAGS = $(TESTS_CFLAGS) +tests_lib_cli_test_commands_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) +tests_lib_cli_test_commands_SOURCES = tests/lib/cli/test_commands_defun.c tests/lib/cli/test_commands.c tests/helpers/c/prng.c +tests_lib_test_buffer_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_buffer_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_buffer_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_buffer_SOURCES = tests/lib/test_buffer.c +tests_lib_test_checksum_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_checksum_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_checksum_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_checksum_SOURCES = tests/lib/test_checksum.c +tests_lib_test_graph_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_graph_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_graph_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_graph_SOURCES = tests/lib/test_graph.c +tests_lib_test_heavy_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_heavy_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_heavy_SOURCES = tests/lib/test_heavy.c tests/helpers/c/main.c +tests_lib_test_heavy_thread_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_heavy_thread_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_heavy_thread_SOURCES = tests/lib/test_heavy_thread.c tests/helpers/c/main.c +tests_lib_test_heavy_wq_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_heavy_wq_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_heavy_wq_SOURCES = tests/lib/test_heavy_wq.c tests/helpers/c/main.c +tests_lib_test_memory_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_memory_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_memory_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_memory_SOURCES = tests/lib/test_memory.c +tests_lib_test_nexthop_iter_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_nexthop_iter_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_nexthop_iter_SOURCES = tests/lib/test_nexthop_iter.c tests/helpers/c/prng.c +tests_lib_test_privs_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_privs_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_privs_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_privs_SOURCES = tests/lib/test_privs.c +tests_lib_test_ringbuf_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_ringbuf_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_ringbuf_SOURCES = tests/lib/test_ringbuf.c +tests_lib_test_segv_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_segv_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_segv_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_segv_SOURCES = tests/lib/test_segv.c +tests_lib_test_sig_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_sig_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_sig_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_sig_SOURCES = tests/lib/test_sig.c +tests_lib_test_srcdest_table_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_srcdest_table_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_srcdest_table_SOURCES = tests/lib/test_srcdest_table.c tests/helpers/c/prng.c +tests_lib_test_stream_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_stream_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_stream_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_stream_SOURCES = tests/lib/test_stream.c +tests_lib_test_table_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_table_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_table_SOURCES = tests/lib/test_table.c +tests_lib_test_timer_correctness_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_timer_correctness_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_timer_correctness_SOURCES = tests/lib/test_timer_correctness.c tests/helpers/c/prng.c +tests_lib_test_timer_performance_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_timer_performance_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_timer_performance_SOURCES = tests/lib/test_timer_performance.c tests/helpers/c/prng.c +tests_lib_test_ttable_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_ttable_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_ttable_SOURCES = tests/lib/test_ttable.c +tests_lib_test_zlog_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_zlog_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_zlog_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_zlog_SOURCES = tests/lib/test_zlog.c +tests_lib_test_zmq_CFLAGS = $(TESTS_CFLAGS) $(ZEROMQ_CFLAGS) +tests_lib_test_zmq_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_zmq_LDADD = lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS) +tests_lib_test_zmq_SOURCES = tests/lib/test_zmq.c + +tests_ospf6d_test_lsdb_CFLAGS = $(TESTS_CFLAGS) +tests_ospf6d_test_lsdb_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD) +tests_ospf6d_test_lsdb_SOURCES = tests/ospf6d/test_lsdb.c tests/lib/cli/common_cli.c + +EXTRA_DIST += \ + tests/runtests.py \ + tests/bgpd/test_aspath.py \ + tests/bgpd/test_capability.py \ + tests/bgpd/test_ecommunity.py \ + tests/bgpd/test_mp_attr.py \ + tests/bgpd/test_mpath.py \ + tests/bgpd/test_peer_attr.py \ + tests/helpers/python/frrsix.py \ + tests/helpers/python/frrtest.py \ + tests/isisd/test_fuzz_isis_tlv.py \ + tests/isisd/test_fuzz_isis_tlv_tests.h.gz \ + tests/isisd/test_isis_vertex_queue.py \ + tests/lib/cli/test_commands.in \ + tests/lib/cli/test_commands.py \ + tests/lib/cli/test_commands.refout \ + tests/lib/cli/test_cli.in \ + tests/lib/cli/test_cli.py \ + tests/lib/cli/test_cli.refout \ + tests/lib/test_nexthop_iter.py \ + tests/lib/test_ringbuf.py \ + tests/lib/test_srcdest_table.py \ + tests/lib/test_stream.py \ + tests/lib/test_stream.refout \ + tests/lib/test_table.py \ + tests/lib/test_timer_correctness.py \ + tests/lib/test_ttable.py \ + tests/lib/test_ttable.refout \ + tests/lib/test_zlog.py \ + tests/lib/test_graph.py \ + tests/lib/test_graph.refout \ + tests/ospf6d/test_lsdb.py \ + tests/ospf6d/test_lsdb.in \ + tests/ospf6d/test_lsdb.refout \ + # end + +.PHONY: tests/tests.xml +tests/tests.xml: $(check_PROGRAMS) + ( cd tests; $(PYTHON) ../$(srcdir)/tests/runtests.py --junitxml=tests.xml -v ../$(srcdir)/tests; ) +check: tests/tests.xml diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c index c751c0b12d..9d1c05436c 100644 --- a/tests/test_lblmgr.c +++ b/tests/test_lblmgr.c @@ -21,6 +21,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "lib/stream.h" #include "lib/zclient.h" @@ -55,7 +59,7 @@ static int zebra_send_label_manager_connect() 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", diff --git a/tools/.gitignore b/tools/.gitignore index 7bf3be9dbf..d400dfe8fa 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1,10 +1,2 @@ -!Makefile -.arch-inventory -.arch-ids - -*~ -*.loT -.libs -*.o /permutations /ssd diff --git a/tools/etc/iproute2/rt_protos.d/frr.conf b/tools/etc/iproute2/rt_protos.d/frr.conf index 4c6968ac27..bbb358fc6c 100644 --- a/tools/etc/iproute2/rt_protos.d/frr.conf +++ b/tools/etc/iproute2/rt_protos.d/frr.conf @@ -11,3 +11,4 @@ 194 sharp 195 pbr 196 static +197 openfabric @@ -587,6 +587,7 @@ case "$1" in ip route flush proto 194 ip route flush proto 195 ip route flush proto 196 + ip route flush proto 197 else [ -n "$dmn" ] && eval "${dmn/-/_}=0" start_watchfrr diff --git a/tools/permutations.c b/tools/permutations.c index 80441753e7..f51d4a4ec9 100644 --- a/tools/permutations.c +++ b/tools/permutations.c @@ -20,6 +20,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "command.h" #include "graph.h" #include "vector.h" @@ -35,7 +39,8 @@ int main(int argc, char *argv[]) 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(); diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c index de58e0a20e..8daeda7402 100644 --- a/tools/start-stop-daemon.c +++ b/tools/start-stop-daemon.c @@ -25,12 +25,17 @@ * the whole automake/config.h dance. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef HAVE_LXC #define _GNU_SOURCE #include <sched.h> #endif /* HAVE_LXC */ #include <stddef.h> +#undef VERSION #define VERSION "1.9.18" #define MIN_POLL_INTERVAL 20000 /*us*/ @@ -602,7 +607,7 @@ static int pid_is_exec(pid_t pid, const struct stat *esb) struct stat sb; char buf[32]; - sprintf(buf, "/proc/%d/exe", pid); + sprintf(buf, "/proc/%ld/exe", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino); @@ -614,7 +619,7 @@ static int pid_is_user(pid_t pid, uid_t uid) struct stat sb; char buf[32]; - sprintf(buf, "/proc/%d", pid); + sprintf(buf, "/proc/%ld", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_uid == uid); @@ -627,7 +632,7 @@ static int pid_is_cmd(pid_t pid, const char *name) FILE *f; int c; - sprintf(buf, "/proc/%d/stat", pid); + sprintf(buf, "/proc/%ld/stat", (long)pid); f = fopen(buf, "r"); if (!f) return 0; @@ -659,12 +664,12 @@ static void check(pid_t pid) static void do_pidfile(const char *name) { FILE *f; - pid_t pid; + long pid; f = fopen(name, "r"); if (f) { - if (fscanf(f, "%d", &pid) == 1) - check(pid); + if (fscanf(f, "%ld", &pid) == 1) + check((pid_t)pid); fclose(f); } else if (errno != ENOENT) fatal("open pidfile %s: %s", name, strerror(errno)); @@ -677,7 +682,7 @@ static void do_procinit(void) DIR *procdir; struct dirent *entry; int foundany; - pid_t pid; + long pid; procdir = opendir("/proc"); if (!procdir) @@ -685,10 +690,10 @@ static void do_procinit(void) foundany = 0; while ((entry = readdir(procdir)) != NULL) { - if (sscanf(entry->d_name, "%d", &pid) != 1) + if (sscanf(entry->d_name, "%ld", &pid) != 1) continue; foundany++; - check(pid); + check((pid_t)pid); } closedir(procdir); if (!foundany) @@ -723,21 +728,21 @@ static void do_stop(int signal_nr, int quietmode, int *n_killed, for (p = found; p; p = p->next) { if (testmode) - printf("Would send signal %d to %d.\n", signal_nr, - p->pid); + printf("Would send signal %d to %ld.\n", signal_nr, + (long)p->pid); else if (kill(p->pid, signal_nr) == 0) { push(&killed, p->pid); (*n_killed)++; } else { - printf("%s: warning: failed to kill %d: %s\n", progname, - p->pid, strerror(errno)); + printf("%s: warning: failed to kill %ld: %s\n", + progname, (long)p->pid, strerror(errno)); (*n_notkilled)++; } } if (quietmode < 0 && killed) { printf("Stopped %s (pid", what_stop); for (p = killed; p; p = p->next) - printf(" %d", p->pid); + printf(" %ld", (long)p->pid); putchar(')'); if (retry_nr > 0) printf(", retry #%d", retry_nr); @@ -1025,7 +1030,9 @@ int main(int argc, char **argv) /* 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("/"); @@ -1050,7 +1057,7 @@ int main(int argc, char **argv) if (pidf == NULL) fatal("Unable to open pidfile `%s' for writing: %s", pidfile, strerror(errno)); - fprintf(pidf, "%d\n", pidt); + fprintf(pidf, "%ld\n", (long)pidt); fclose(pidf); } set_namespaces(); diff --git a/vtysh/.gitignore b/vtysh/.gitignore index 5856eac253..c1a39b8a12 100644 --- a/vtysh/.gitignore +++ b/vtysh/.gitignore @@ -1,16 +1,3 @@ -Makefile -Makefile.in -*.o vtysh -tags -TAGS -.deps vtysh_cmd.c -.nfs* extract.pl -.libs -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/vtysh/Makefile b/vtysh/Makefile new file mode 100644 index 0000000000..07e093b0f5 --- /dev/null +++ b/vtysh/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C .. vtysh/vtysh +%: ALWAYS + @$(MAKE) -s -C .. vtysh/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am deleted file mode 100644 index 936640c83a..0000000000 --- a/vtysh/Makefile.am +++ /dev/null @@ -1,178 +0,0 @@ -## Process this file with Automake to create Makefile.in - -include ../common.am - -if ENABLE_BGP_VNC -BGP_VNC_RFP_SRCDIR = @top_srcdir@/@LIBRFP@ -BGP_VNC_RFP_INCDIR = -I$(BGP_VNC_RFP_SRCDIR) -BGP_VNC_RFP_SRC = $(BGP_VNC_RFP_SRCDIR)/*.c -BGP_VNC_RFAPI_SRCDIR = @top_srcdir@/bgpd/rfapi -BGP_VNC_RFAPI_INCDIR = -I$(BGP_VNC_RFAPI_SRCDIR) -I$(top_srcdir)/bgpd -BGP_VNC_RFAPI_SRC = $(BGP_VNC_RFAPI_SRCDIR)/*.c -else -BGP_VNC_RFP_INCDIR = -BGP_VNC_RFP_SRCDIR = -BGP_VNC_RFP_SRC = -BGP_VNC_RFAPI_INCDIR = -BGP_VNC_RFAPI_SRCDIR = -BGP_VNC_RFAPI_SRC = -endif -AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INCDIR) $(BGP_VNC_RFP_INCDIR) -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" - -LIBS = @LIBS@ @CURSES@ @LIBPAM@ - -bin_PROGRAMS = vtysh - -vtysh_SOURCES = vtysh_main.c vtysh.c vtysh_user.c vtysh_config.c -nodist_vtysh_SOURCES = vtysh_cmd.c -CLEANFILES = vtysh_cmd.c -noinst_HEADERS = vtysh.h vtysh_user.h -vtysh_LDADD = ../lib/libfrr.la @LIBCAP@ @LIBREADLINE@ - -examplesdir = $(exampledir) -dist_examples_DATA = vtysh.conf.sample - -EXTRA_DIST = extract.pl - -vtysh_scan = - -if PIMD -vtysh_scan += $(top_srcdir)/pimd/pim_cmd.c -endif - -if BGPD -vtysh_scan += $(top_srcdir)/bgpd/bgp_bfd.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_debug.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_dump.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_evpn_vty.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_filter.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_mplsvpn.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_nexthop.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_route.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_routemap.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_vty.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_flowspec_vty.c -endif - -if RPKI -vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c -endif - -if ISISD -vtysh_scan += $(top_srcdir)/isisd/isis_redist.c -vtysh_scan += $(top_srcdir)/isisd/isis_spf.c -vtysh_scan += $(top_srcdir)/isisd/isis_te.c -vtysh_scan += $(top_srcdir)/isisd/isis_vty.c -vtysh_scan += $(top_srcdir)/isisd/isisd.c -endif - -if OSPFD -vtysh_scan += $(top_srcdir)/ospfd/ospf_bfd.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_dump.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_opaque.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_ri.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_routemap.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_te.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_sr.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_vty.c -endif - -if OSPF6D -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_abr.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_asbr.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_area.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_bfd.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_flood.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_interface.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_intra.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_lsa.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_message.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_neighbor.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_route.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_spf.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_top.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_zebra.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6d.c -endif - -if RIPD -vtysh_scan += $(top_srcdir)/ripd/rip_debug.c -vtysh_scan += $(top_srcdir)/ripd/rip_interface.c -vtysh_scan += $(top_srcdir)/ripd/rip_offset.c -vtysh_scan += $(top_srcdir)/ripd/rip_zebra.c -vtysh_scan += $(top_srcdir)/ripd/ripd.c -endif - -if RIPNGD -vtysh_scan += $(top_srcdir)/ripngd/ripng_debug.c -vtysh_scan += $(top_srcdir)/ripngd/ripng_interface.c -vtysh_scan += $(top_srcdir)/ripngd/ripng_offset.c -vtysh_scan += $(top_srcdir)/ripngd/ripng_zebra.c -vtysh_scan += $(top_srcdir)/ripngd/ripngd.c -endif - -if LDPD -vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c -endif - -if NHRPD -vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c -endif - -if EIGRPD -vtysh_scan += $(top_srcdir)/eigrpd/eigrp_dump.c -#vtysh_scan += $(top_srcdir)/eigrpd/eigrp_routemap.c -vtysh_scan += $(top_srcdir)/eigrpd/eigrp_vty.c -endif - -if BABELD -vtysh_scan += $(top_srcdir)/babeld/babel_interface.c -vtysh_scan += $(top_srcdir)/babeld/babel_zebra.c -vtysh_scan += $(top_srcdir)/babeld/babeld.c -endif - -if SHARPD -vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c -endif - -if SNMP -vtysh_scan += $(top_srcdir)/lib/agentx.c -endif - -if PBRD -vtysh_scan += $(top_srcdir)/pbrd/pbr_vty.c -vtysh_scan += $(top_srcdir)/pbrd/pbr_debug.c -endif - -if STATICD -vtysh_scan += $(top_srcdir)/staticd/static_vty.c -endif - -if BFDD -vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c -endif - -vtysh_cmd_FILES = $(vtysh_scan) \ - $(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \ - $(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \ - $(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \ - $(top_srcdir)/lib/vrf.c $(top_srcdir)/lib/if.c \ - $(top_srcdir)/lib/vty.c $(top_srcdir)/zebra/debug.c \ - $(top_srcdir)/lib/logicalrouter.c \ - $(top_srcdir)/lib/nexthop_group.c \ - $(top_srcdir)/zebra/interface.c \ - $(top_srcdir)/zebra/irdp_interface.c \ - $(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \ - $(top_srcdir)/zebra/zserv.c $(top_srcdir)/zebra/router-id.c \ - $(top_srcdir)/zebra/zebra_routemap.c \ - $(top_srcdir)/zebra/zebra_fpm.c \ - $(top_srcdir)/zebra/zebra_ptm.c \ - $(top_srcdir)/zebra/zebra_mpls_vty.c \ - $(top_srcdir)/zebra/zebra_pw.c \ - $(top_srcdir)/watchfrr/watchfrr_vty.c \ - $(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC) - -vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl - ./extract.pl $(vtysh_cmd_FILES) > vtysh_cmd.c diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 92b5686a94..0f68e58d62 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -29,16 +29,18 @@ print <<EOF; #include "command.h" #include "linklist.h" -#include "vtysh.h" +#include "vtysh/vtysh.h" EOF my $cli_stomp = 0; -foreach (@ARGV) { - $file = $_; +sub scan_file { + my ( $file, $fabricd) = @_; + + $cppadd = $fabricd ? "-DFABRICD=1" : ""; - open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -I@top_builddir@ -I@srcdir@/ -I@srcdir@/.. -I@top_srcdir@/lib -I@top_builddir@/lib -I@top_srcdir@/bgpd -I@top_srcdir@/@LIBRFP@ -I@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $file |"); + open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $cppadd $file |"); local $/; undef $/; $line = <FH>; close (FH); @@ -77,6 +79,10 @@ foreach (@ARGV) { $cmd =~ s/^\s+//g; $cmd =~ s/\s+$//g; + if ($fabricd) { + $cmd = "fabricd_" . $cmd; + } + # $protocol is VTYSH_PROTO format for redirection of user input if ($file =~ /lib\/keychain\.c$/) { $protocol = "VTYSH_RIPD"; @@ -107,9 +113,9 @@ foreach (@ARGV) { } elsif ($file =~ /lib\/plist\.c$/) { if ($defun_array[1] =~ m/ipv6/) { - $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_BABELD|VTYSH_ISISD"; + $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"; } else { - $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD"; + $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"; } } elsif ($file =~ /lib\/distribute\.c$/) { @@ -132,6 +138,9 @@ foreach (@ARGV) { elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) { $protocol = "VTYSH_BGPD"; } + elsif ($fabricd) { + $protocol = "VTYSH_FABRICD"; + } else { ($protocol) = ($file =~ /^.*\/([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/); $protocol = "VTYSH_" . uc $protocol; @@ -170,6 +179,10 @@ foreach (@ARGV) { $ecmd =~ s/^\s+//g; $ecmd =~ s/\s+$//g; + if ($fabricd) { + $ecmd = "fabricd_" . $ecmd; + } + # Register $ecmd if (defined ($cmd2str{$ecmd})) { my ($key); @@ -187,6 +200,24 @@ foreach (@ARGV) { } } +foreach (@ARGV) { + if (/\/isisd\//) { + # We scan all the IS-IS files twice, once for isisd, + # once for fabricd. Exceptions are made for the files + # that are not shared between the two. + if (/isis_vty_isisd.c/) { + scan_file($_, 0); + } elsif (/isis_vty_fabricd.c/) { + scan_file($_, 1); + } else { + scan_file($_, 0); + scan_file($_, 1); + } + } else { + scan_file($_, 0); + } +} + # When we have cli commands that map to the same function name, we # can introduce subtle bugs due to code not being called when # we think it is. diff --git a/vtysh/subdir.am b/vtysh/subdir.am new file mode 100644 index 0000000000..932429a87c --- /dev/null +++ b/vtysh/subdir.am @@ -0,0 +1,37 @@ +# +# vtysh +# + +if VTYSH +bin_PROGRAMS += vtysh/vtysh +dist_examples_DATA += vtysh/vtysh.conf.sample +man1 += $(MANBUILD)/vtysh.1 +endif + +vtysh_vtysh_SOURCES = \ + vtysh/vtysh_main.c \ + vtysh/vtysh.c \ + vtysh/vtysh_user.c \ + vtysh/vtysh_config.c \ + # end +nodist_vtysh_vtysh_SOURCES = \ + vtysh/vtysh_cmd.c \ + # end +CLEANFILES += vtysh/vtysh_cmd.c + +noinst_HEADERS += \ + vtysh/vtysh.h \ + vtysh/vtysh_user.h \ + # end + +vtysh_vtysh_LDADD = lib/libfrr.la @LIBCAP@ @LIBREADLINE@ @LIBS@ @CURSES@ @LIBPAM@ + +EXTRA_DIST += vtysh/extract.pl + +AM_V_EXTRACT = $(am__v_EXTRACT_$(V)) +am__v_EXTRACT_ = $(am__v_EXTRACT_$(AM_DEFAULT_VERBOSITY)) +am__v_EXTRACT_0 = @echo " EXTRACT " $@; +am__v_EXTRACT_1 = + +vtysh/vtysh_cmd.c: $(vtysh_scan) vtysh/extract.pl + $(AM_V_EXTRACT) vtysh/extract.pl $(vtysh_scan) > vtysh/vtysh_cmd.c diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index c249115fd3..6a92b90813 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -132,6 +132,7 @@ struct vtysh_client vtysh_client[] = { {.fd = -1, .name = "eigrpd", .flag = VTYSH_EIGRPD, .next = NULL}, {.fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .next = NULL}, {.fd = -1, .name = "sharpd", .flag = VTYSH_SHARPD, .next = NULL}, + {.fd = -1, .name = "fabricd", .flag = VTYSH_FABRICD, .next = NULL}, {.fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL}, {.fd = -1, .name = "pbrd", .flag = VTYSH_PBRD, .next = NULL}, {.fd = -1, .name = "staticd", .flag = VTYSH_STATICD, .next = NULL}, @@ -1112,7 +1113,7 @@ static char *command_generator(const char *text, int state) return NULL; } -static char **new_completion(char *text, int start, int end) +static char **new_completion(const char *text, int start, int end) { char **matches; @@ -1141,6 +1142,10 @@ static struct cmd_node isis_node = { ISIS_NODE, "%s(config-router)# ", }; +static struct cmd_node openfabric_node = { + OPENFABRIC_NODE, "%s(config-router)# ", +}; + static struct cmd_node interface_node = { INTERFACE_NODE, "%s(config-if)# ", }; @@ -1252,9 +1257,7 @@ struct cmd_node link_params_node = { LINK_PARAMS_NODE, "%s(config-link-params)# ", }; -#if defined(HAVE_RPKI) static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1}; -#endif #if HAVE_BFDD > 0 static struct cmd_node bfd_node = { @@ -1424,7 +1427,6 @@ DEFUNSH(VTYSH_BGPD, address_family_ipv6_labeled_unicast, return CMD_SUCCESS; } -#if defined(HAVE_RPKI) DEFUNSH(VTYSH_BGPD, rpki, rpki_cmd, @@ -1435,8 +1437,6 @@ DEFUNSH(VTYSH_BGPD, return CMD_SUCCESS; } -#endif - DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd, "address-family <l2vpn evpn>", "Enter Address Family command mode\n" @@ -1653,6 +1653,15 @@ DEFUNSH(VTYSH_ISISD, router_isis, router_isis_cmd, "router isis WORD", return CMD_SUCCESS; } +DEFUNSH(VTYSH_FABRICD, router_openfabric, router_openfabric_cmd, "router openfabric WORD", + ROUTER_STR + "OpenFabric routing protocol\n" + "ISO Routing area tag\n") +{ + vty->node = OPENFABRIC_NODE; + return CMD_SUCCESS; +} + DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd, "route-map WORD <deny|permit> (1-65535)", "Create route-map or enter route-map command mode\n" @@ -1767,6 +1776,7 @@ static int vtysh_exit(struct vty *vty) case LDP_NODE: case LDP_L2VPN_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case RMAP_NODE: case PBRMAP_NODE: case VTY_NODE: @@ -1869,7 +1879,6 @@ DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc", } -#if defined(HAVE_RPKI) DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit", "Exit current mode and down to previous mode\n") { @@ -1882,7 +1891,6 @@ DEFUNSH(VTYSH_BGPD, rpki_quit, rpki_quit_cmd, "quit", { return rpki_exit(self, vty, argc, argv); } -#endif /* HAVE_RPKI */ DEFUNSH(VTYSH_PIMD|VTYSH_ZEBRA, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf", "Exit from VRF configuration mode\n") @@ -2042,6 +2050,18 @@ ALIAS(vtysh_exit_bfdd, vtysh_quit_bfdd_cmd, "quit", "Exit current mode and down to previous mode\n") #endif +DEFUNSH(VTYSH_FABRICD, vtysh_exit_fabricd, vtysh_exit_fabricd_cmd, "exit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit(vty); +} + +DEFUNSH(VTYSH_FABRICD, vtysh_quit_fabricd, vtysh_quit_fabricd_cmd, "quit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit_fabricd(self, vty, argc, argv); +} + DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit", "Exit current mode and down to previous mode\n") { @@ -2245,7 +2265,7 @@ DEFUN (vtysh_show_work_queues, DEFUN (vtysh_show_work_queues_daemon, vtysh_show_work_queues_daemon_cmd, - "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pbrd>", + "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pbrd|fabricd>", SHOW_STR "Work Queue information\n" "For the zebra daemon\n" @@ -2255,7 +2275,8 @@ DEFUN (vtysh_show_work_queues_daemon, "For the ospfv6 daemon\n" "For the bgp daemon\n" "For the isis daemon\n" - "For the pbr daemon\n") + "For the pbr daemon\n" + "For the fabricd daemon\n") { int idx_protocol = 2; unsigned int i; @@ -2593,7 +2614,7 @@ DEFUNSH(VTYSH_ALL, no_vtysh_config_enable_password, DEFUN (vtysh_write_terminal, vtysh_write_terminal_cmd, - "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]", + "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|fabricd|pimd>]", "Write running configuration to memory, network, or terminal\n" "Write to terminal\n" "For the zebra daemon\n" @@ -2604,6 +2625,7 @@ DEFUN (vtysh_write_terminal, "For the ldpd daemon\n" "For the bgp daemon\n" "For the isis daemon\n" + "For the fabricd daemon\n" "For the pim daemon\n") { unsigned int i; @@ -2630,7 +2652,7 @@ DEFUN (vtysh_write_terminal, DEFUN (vtysh_show_running_config, vtysh_show_running_config_cmd, - "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]", + "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|fabricd|pimd>]", SHOW_STR "Current operating configuration\n" "For the zebra daemon\n" @@ -2641,6 +2663,7 @@ DEFUN (vtysh_show_running_config, "For the ldp daemon\n" "For the bgp daemon\n" "For the isis daemon\n" + "For the fabricd daemon\n" "For the pim daemon\n") { return vtysh_write_terminal(self, vty, argc, argv); @@ -3386,8 +3409,7 @@ void vtysh_readline_init(void) rl_initialize(); rl_bind_key('?', (rl_command_func_t *)vtysh_rl_describe); rl_completion_entry_function = vtysh_completion_entry_function; - rl_attempted_completion_function = - (rl_completion_func_t *)new_completion; + rl_attempted_completion_function = new_completion; } char *vtysh_prompt(void) @@ -3494,10 +3516,9 @@ void vtysh_init_vty(void) install_node(&keychain_node, NULL); install_node(&keychain_key_node, NULL); install_node(&isis_node, NULL); + install_node(&openfabric_node, NULL); install_node(&vty_node, NULL); -#if defined(HAVE_RPKI) install_node(&rpki_node, NULL); -#endif #if HAVE_BFDD > 0 install_node(&bfd_node, NULL); install_node(&bfd_peer_node, NULL); @@ -3588,6 +3609,8 @@ void vtysh_init_vty(void) #endif install_element(ISIS_NODE, &vtysh_exit_isisd_cmd); install_element(ISIS_NODE, &vtysh_quit_isisd_cmd); + install_element(OPENFABRIC_NODE, &vtysh_exit_fabricd_cmd); + install_element(OPENFABRIC_NODE, &vtysh_quit_fabricd_cmd); install_element(KEYCHAIN_NODE, &vtysh_exit_ripd_cmd); install_element(KEYCHAIN_NODE, &vtysh_quit_ripd_cmd); install_element(KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd); @@ -3648,6 +3671,7 @@ void vtysh_init_vty(void) install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd); install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd); install_element(ISIS_NODE, &vtysh_end_all_cmd); + install_element(OPENFABRIC_NODE, &vtysh_end_all_cmd); install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd); install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd); install_element(RMAP_NODE, &vtysh_end_all_cmd); @@ -3697,6 +3721,7 @@ void vtysh_init_vty(void) install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd); #endif install_element(CONFIG_NODE, &router_isis_cmd); + install_element(CONFIG_NODE, &router_openfabric_cmd); install_element(CONFIG_NODE, &router_bgp_cmd); install_element(BGP_NODE, &address_family_vpnv4_cmd); install_element(BGP_NODE, &address_family_vpnv6_cmd); @@ -3732,12 +3757,10 @@ void vtysh_init_vty(void) install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd); install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd); -#if defined(HAVE_RPKI) install_element(CONFIG_NODE, &rpki_cmd); install_element(RPKI_NODE, &rpki_exit_cmd); install_element(RPKI_NODE, &rpki_quit_cmd); install_element(RPKI_NODE, &vtysh_end_all_cmd); -#endif /* EVPN commands */ install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd); diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 5bff01a506..ee980d5128 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -41,6 +41,7 @@ DECLARE_MGROUP(MVTYSH) #define VTYSH_PBRD 0x04000 #define VTYSH_STATICD 0x08000 #define VTYSH_BFDD 0x10000 +#define VTYSH_FABRICD 0x20000 #define VTYSH_WAS_ACTIVE (-2) @@ -49,9 +50,9 @@ DECLARE_MGROUP(MVTYSH) /* watchfrr is not in ALL since library CLI functions should not be * run on it (logging & co. should stay in a fixed/frozen config, and * things like prefix lists are not even initialised) */ -#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD -#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD -#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD +#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD|VTYSH_FABRICD +#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD|VTYSH_FABRICD +#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD|VTYSH_FABRICD #define VTYSH_NS VTYSH_ZEBRA #define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 42f08342c0..9f6e20f2be 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -245,6 +245,9 @@ void vtysh_config_parse_line(void *arg, const char *line) else if (strncmp(line, "router isis", strlen("router isis")) == 0) config = config_get(ISIS_NODE, line); + else if (strncmp(line, "router openfabric", strlen("router openfabric")) + == 0) + config = config_get(OPENFABRIC_NODE, line); else if (strncmp(line, "route-map", strlen("route-map")) == 0) config = config_get(RMAP_NODE, line); else if (strncmp(line, "pbr-map", strlen("pbr-map")) == 0) diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 86fa62f474..777eed7b5d 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -30,6 +30,16 @@ #include <readline/readline.h> #include <readline/history.h> +/* + * The append_history function only appears in newer versions + * of the readline library it appears like. Since we don't + * need this just silently ignore the code on these + * ancient platforms. + */ +#if !defined HAVE_APPEND_HISTORY +#define append_history(A, B) +#endif + #include <lib/version.h> #include "getopt.h" #include "command.h" @@ -586,7 +596,6 @@ int main(int argc, char **argv, char **env) vtysh_execute("enable"); while (cmd != NULL) { - int ret; char *eol; while ((eol = strchr(cmd->line, '\n')) != NULL) { @@ -652,7 +661,7 @@ int main(int argc, char **argv, char **env) /* 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, diff --git a/watchfrr/.gitignore b/watchfrr/.gitignore index b8c020c04c..b3f5a6cd91 100644 --- a/watchfrr/.gitignore +++ b/watchfrr/.gitignore @@ -1,16 +1 @@ -!Makefile -Makefile.in -*.o watchfrr -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am index 931f11ef63..f0b49c9a84 100644 --- a/watchfrr/subdir.am +++ b/watchfrr/subdir.am @@ -4,6 +4,8 @@ if WATCHFRR sbin_PROGRAMS += watchfrr/watchfrr +vtysh_scan += $(top_srcdir)/watchfrr/watchfrr_vty.c +man8 += $(MANBUILD)/watchfrr.8 endif noinst_HEADERS += \ diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index 07a29ca6d5..9bbe04c338 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -249,7 +249,7 @@ static pid_t run_background(char *shell_cmd) 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; @@ -265,14 +265,14 @@ static pid_t run_background(char *shell_cmd) 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; @@ -334,7 +334,7 @@ static void sigchild(void) 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: @@ -359,7 +359,7 @@ static void sigchild(void) 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)"; @@ -381,7 +381,7 @@ static void sigchild(void) 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(); @@ -493,9 +493,9 @@ static int wakeup_init(struct thread *t_wakeup) 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; @@ -504,8 +504,8 @@ static int wakeup_init(struct thread *t_wakeup) 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)) @@ -698,7 +698,7 @@ static int try_connect(struct daemon *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)); @@ -706,13 +706,13 @@ static int try_connect(struct daemon *dmn) } 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); @@ -751,9 +751,9 @@ static int try_connect(struct daemon *dmn) 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; } @@ -867,10 +867,10 @@ static int wakeup_unresponsive(struct thread *t_wakeup) 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); @@ -884,10 +884,10 @@ static int wakeup_no_answer(struct thread *t_wakeup) 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; diff --git a/watchfrr/watchfrr_errors.c b/watchfrr/watchfrr_errors.c index 662e7f654d..c720b65099 100644 --- a/watchfrr/watchfrr_errors.c +++ b/watchfrr/watchfrr_errors.c @@ -26,7 +26,7 @@ /* 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" diff --git a/watchfrr/watchfrr_errors.h b/watchfrr/watchfrr_errors.h index 4652f950f4..93103b6551 100644 --- a/watchfrr/watchfrr_errors.h +++ b/watchfrr/watchfrr_errors.h @@ -24,7 +24,7 @@ #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); diff --git a/zebra/.gitignore b/zebra/.gitignore index 4a06756a2d..41a86e7d75 100644 --- a/zebra/.gitignore +++ b/zebra/.gitignore @@ -1,15 +1,3 @@ -!Makefile -Makefile.in -*.o zebra zebra.conf client -tags -TAGS -.deps -.nfs* -.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/zebra/connected.c b/zebra/connected.c index 57bfcc4d16..54f4394a56 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -40,6 +40,7 @@ #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) @@ -236,7 +237,8 @@ void connected_up(struct interface *ifp, 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; } @@ -309,7 +311,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, /* 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)); @@ -320,7 +323,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *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, @@ -334,7 +338,7 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, } 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); @@ -343,7 +347,7 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, /* 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); @@ -527,8 +531,9 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr, 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); } } diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c index 176bb2bbad..f581ebc6bd 100644 --- a/zebra/if_ioctl.c +++ b/zebra/if_ioctl.c @@ -38,6 +38,7 @@ #include "zebra/interface.h" #include "zebra/rib.h" #include "zebra/rt.h" +#include "zebra/zebra_errors.h" #include <ifaddrs.h> @@ -57,8 +58,9 @@ static int interface_list_ioctl(void) /* 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; } @@ -86,7 +88,8 @@ static int interface_list_ioctl(void) 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. */ @@ -177,7 +180,7 @@ static int if_getaddrs(void) 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; } @@ -185,7 +188,7 @@ static int if_getaddrs(void) 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)")); @@ -194,9 +197,9 @@ static int if_getaddrs(void) 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; } diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c index 5a58fe1751..1955881f28 100644 --- a/zebra/if_ioctl_solaris.c +++ b/zebra/if_ioctl_solaris.c @@ -39,6 +39,8 @@ #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 *); @@ -55,7 +57,6 @@ static int interface_list_ioctl(int af) struct lifconf lifconf; struct interface *ifp; int n; - int save_errno; size_t needed, lastneeded = 0; char *buf = NULL; @@ -64,9 +65,9 @@ static int interface_list_ioctl(int af) } 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; } @@ -76,13 +77,12 @@ calculate_lifc_len: lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */ ret = ioctl(sock, SIOCGLIFNUM, &lifn); - save_errno = errno; - } if (ret < 0) { - 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; } @@ -115,7 +115,8 @@ calculate_lifc_len: 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; } @@ -206,7 +207,8 @@ static int if_get_index(struct interface *ifp) 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; } @@ -268,8 +270,9 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr, 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; @@ -288,8 +291,9 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr, 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; } @@ -319,7 +323,7 @@ static void interface_info_ioctl(struct interface *ifp) 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); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 0dcf5082a2..47a101e619 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -67,6 +67,7 @@ #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; @@ -81,7 +82,7 @@ static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, && (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 { @@ -91,7 +92,7 @@ static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, 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); @@ -112,8 +113,8 @@ static void netlink_interface_update_hw_addr(struct rtattr **tb, 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]), @@ -312,8 +313,8 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, 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; } @@ -334,9 +335,9 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, /* 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; } @@ -349,7 +350,8 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, 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; } @@ -531,7 +533,8 @@ static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id, /* 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)) @@ -896,9 +899,10 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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; } @@ -920,7 +924,7 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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; @@ -1002,8 +1006,9 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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) @@ -1018,8 +1023,9 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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) { @@ -1044,67 +1050,6 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) return 0; } -/* helper function called by if_netlink_change - * to delete interfaces in case the interface moved - * to an other netns - */ -static void if_netlink_check_ifp_instance_consistency(uint16_t cmd, - struct interface *ifp, - ns_id_t ns_id) -{ - struct interface *other_ifp; - - /* - * look if interface name is also found on other netns - * - only if vrf backend is netns - * - do not concern lo interface - * - then remove previous one - * - for new link case, check found interface is not active - */ - if (!vrf_is_backend_netns() || - !strcmp(ifp->name, "lo")) - return; - other_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name); - if (!other_ifp) - return; - /* because previous interface may be inactive, - * interface is moved back to default vrf - * then one may find the same pointer; ignore - */ - if (other_ifp == ifp) - return; - if ((cmd == RTM_NEWLINK) - && (CHECK_FLAG(other_ifp->status, ZEBRA_INTERFACE_ACTIVE))) - return; - if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_NEWLINK) { - zlog_debug("RTM_NEWLINK %s(%u, VRF %u) replaces %s(%u, VRF %u)\n", - ifp->name, - ifp->ifindex, - ifp->vrf_id, - other_ifp->name, - other_ifp->ifindex, - other_ifp->vrf_id); - } else if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_DELLINK) { - zlog_debug("RTM_DELLINK %s(%u, VRF %u) is replaced by %s(%u, VRF %u)\n", - ifp->name, - ifp->ifindex, - ifp->vrf_id, - other_ifp->name, - other_ifp->ifindex, - other_ifp->vrf_id); - } - /* the found interface replaces the current one - * remove it - */ - if (cmd == RTM_DELLINK) - if_delete(ifp); - else - if_delete(other_ifp); - /* the found interface is replaced by the current one - * suppress it - */ -} - int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) { int len; @@ -1130,16 +1075,17 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) /* 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; } @@ -1248,7 +1194,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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; @@ -1278,8 +1224,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex); - if_netlink_check_ifp_instance_consistency(RTM_NEWLINK, - ifp, ns_id); } else if (ifp->vrf_id != vrf_id) { /* VRF change for an interface. */ if (IS_ZEBRA_DEBUG_KERNEL) @@ -1303,7 +1247,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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; @@ -1353,14 +1297,14 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex); - if_netlink_check_ifp_instance_consistency(RTM_NEWLINK, - ifp, ns_id); } } else { /* Delete interface notification from kernel */ 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; } @@ -1378,8 +1322,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (!IS_ZEBRA_IF_VRF(ifp)) if_delete_update(ifp); - if_netlink_check_ifp_instance_consistency(RTM_DELLINK, - ifp, ns_id); } return 0; diff --git a/zebra/if_sysctl.c b/zebra/if_sysctl.c index 39b7204e8e..3f918c361a 100644 --- a/zebra/if_sysctl.c +++ b/zebra/if_sysctl.c @@ -37,6 +37,7 @@ #include "zebra/rt.h" #include "zebra/kernel_socket.h" #include "zebra/rib.h" +#include "zebra/zebra_errors.h" void ifstat_update_sysctl(void) { @@ -52,7 +53,8 @@ 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; } @@ -61,7 +63,8 @@ void ifstat_update_sysctl(void) /* 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; } @@ -95,13 +98,15 @@ void interface_list(struct zebra_ns *zns) 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; } @@ -110,7 +115,9 @@ void interface_list(struct zebra_ns *zns) /* 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; } diff --git a/zebra/interface.c b/zebra/interface.c index 32ee1a566a..ca90c18cf2 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -49,6 +49,7 @@ #include "zebra/rt_netlink.h" #include "zebra/interface.h" #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_errors.h" #define ZEBRA_PTM_SUPPORT @@ -202,7 +203,6 @@ struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp) if (rn->info) { ifp = (struct interface *)rn->info; route_unlock_node(rn); /* get */ - ifp->node = rn; return ifp; } @@ -253,30 +253,6 @@ struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns, return NULL; } -/* this function must be used only if the vrf backend - * is a netns backend - */ -struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id, - const char *ifname) -{ - struct interface *ifp; - struct ns *ns; - - RB_FOREACH (ns, ns_head, &ns_tree) { - if (ns->ns_id == ns_id) - continue; - /* if_delete_update has removed interface - * from zns->if_table - * so to look for interface, use the vrf list - */ - ifp = if_lookup_by_name(ifname, (vrf_id_t)ns->ns_id); - if (!ifp) - continue; - return ifp; - } - return NULL; -} - const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex) { struct interface *ifp; @@ -336,9 +312,9 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc) /* 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); @@ -350,7 +326,8 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc) * 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; @@ -496,7 +473,8 @@ static void if_addr_wakeup(struct interface *ifp) 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; @@ -518,7 +496,8 @@ static void if_addr_wakeup(struct interface *ifp) 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; @@ -720,7 +699,7 @@ void if_delete_update(struct interface *ifp) 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; @@ -753,8 +732,12 @@ void if_delete_update(struct interface *ifp) ifp->node = NULL; /* if the ifp is in a vrf, move it to default so vrf can be deleted if - * desired */ - if (ifp->vrf_id) + * desired. This operation is not done for netns implementation to avoid + * collision with interface with the same name in the default vrf (can + * occur with this implementation whereas it is not possible with + * vrf-lite). + */ + if (ifp->vrf_id && !vrf_is_backend_netns()) if_handle_vrf_change(ifp, VRF_DEFAULT); /* Reset some zebra interface params to default values. */ @@ -908,7 +891,8 @@ void if_up(struct interface *ifp) /* 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; } @@ -2917,13 +2901,13 @@ static int link_params_config_write(struct vty *vty, struct interface *ifp) 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; diff --git a/zebra/interface.h b/zebra/interface.h index 956d430cf9..02a05e6146 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -328,8 +328,6 @@ extern void zebra_if_init(void); extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t); extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *, const char *); -extern struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id, - const char *ifname); extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *); extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int); diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 0469bc38c0..87e98032a2 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -33,6 +33,7 @@ #include "zebra/rib.h" #include "zebra/rt.h" #include "zebra/interface.h" +#include "zebra/zebra_errors.h" #ifndef SUNOS_5 @@ -396,7 +397,7 @@ void if_get_flags(struct interface *ifp) 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; @@ -415,7 +416,7 @@ void if_get_flags(struct interface *ifp) /* 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 */ diff --git a/zebra/ioctl_solaris.c b/zebra/ioctl_solaris.c index 260911ce67..fc554219bc 100644 --- a/zebra/ioctl_solaris.c +++ b/zebra/ioctl_solaris.c @@ -37,6 +37,7 @@ #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; @@ -380,7 +381,7 @@ int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc) { 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); @@ -391,7 +392,7 @@ int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc) { 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); diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c index 3a766b1ea9..8f44c377b3 100644 --- a/zebra/ipforward_proc.c +++ b/zebra/ipforward_proc.c @@ -25,7 +25,6 @@ #include "log.h" #include "privs.h" -#include "lib_errors.h" #include "zebra/ipforward.h" diff --git a/zebra/ipforward_solaris.c b/zebra/ipforward_solaris.c index b06baa04a9..1bb743059c 100644 --- a/zebra/ipforward_solaris.c +++ b/zebra/ipforward_solaris.c @@ -29,6 +29,7 @@ #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 @@ -70,7 +71,7 @@ static int solaris_nd(const int cmd, const char *parameter, const int value) 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__); @@ -84,15 +85,16 @@ static int solaris_nd(const int cmd, const char *parameter, const int value) 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); @@ -102,7 +104,7 @@ static int solaris_nd(const int cmd, const char *parameter, const int value) 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; diff --git a/zebra/ipforward_sysctl.c b/zebra/ipforward_sysctl.c index 74a178e59c..cc9421c275 100644 --- a/zebra/ipforward_sysctl.c +++ b/zebra/ipforward_sysctl.c @@ -24,6 +24,7 @@ #include "privs.h" #include "zebra/ipforward.h" +#include "zebra/zebra_errors.h" #include "log.h" #include "lib_errors.h" @@ -42,7 +43,8 @@ int ipforward(void) 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; @@ -56,7 +58,8 @@ int ipforward_on(void) 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; } } @@ -71,7 +74,8 @@ int ipforward_off(void) 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; } } @@ -95,7 +99,8 @@ int ipforward_ipv6(void) 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; } } @@ -111,7 +116,8 @@ int ipforward_ipv6_on(void) 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; } } @@ -127,7 +133,8 @@ int ipforward_ipv6_off(void) 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; } } diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index f02ba1fa2f..5fdaae4fe5 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -41,12 +41,14 @@ #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" @@ -124,7 +126,8 @@ static int if_group(struct interface *ifp, int sock, uint32_t group, 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; } @@ -133,10 +136,10 @@ static int if_group(struct interface *ifp, int sock, uint32_t group, 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; } @@ -215,14 +218,14 @@ static void irdp_if_start(struct interface *ifp, int multicast, 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; @@ -233,7 +236,8 @@ static void irdp_if_start(struct interface *ifp, int multicast, 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? */ @@ -242,7 +246,8 @@ static void irdp_if_start(struct interface *ifp, int multicast, 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); } } @@ -290,12 +295,12 @@ static void irdp_if_stop(struct interface *ifp) 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; } @@ -319,7 +324,7 @@ static void irdp_if_shutdown(struct interface *ifp) 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; } @@ -341,7 +346,7 @@ static void irdp_if_no_shutdown(struct interface *ifp) 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; } diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index 771ae796e1..9300ba6034 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -59,6 +59,7 @@ #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" @@ -89,24 +90,24 @@ int irdp_sock_init(void) } 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; }; diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index c36c958973..2b5bf04ade 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -52,6 +52,7 @@ #include "thread.h" #include "vty.h" #include "zclient.h" +#include "lib_errors.h" #include "zebra_memory.h" #include "zebra/interface.h" @@ -95,15 +96,15 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) 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; } @@ -112,9 +113,9 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) + 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; } @@ -122,7 +123,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) /* 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; @@ -134,10 +136,10 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) 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; } @@ -145,16 +147,15 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) && (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; } @@ -172,7 +173,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) 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)); } @@ -198,16 +200,18 @@ static int irdp_recvmsg(int sock, uint8_t *buf, int size, int *ifindex) 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; } @@ -232,7 +236,7 @@ int irdp_read_raw(struct thread *r) 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) @@ -311,7 +315,7 @@ void send_packet(struct interface *ifp, struct stream *s, uint32_t dst, 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) { @@ -319,7 +323,7 @@ void send_packet(struct interface *ifp, struct stream *s, uint32_t dst, 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) @@ -351,7 +355,7 @@ void send_packet(struct interface *ifp, struct stream *s, uint32_t dst, 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); */ } diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 545b4d9d6d..d35230d7bd 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -163,7 +163,7 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize) 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; @@ -179,7 +179,7 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize) 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; @@ -187,7 +187,7 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize) 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; @@ -234,7 +234,7 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups, 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; @@ -286,10 +286,10 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, * 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; @@ -453,8 +453,8 @@ static void netlink_install_filter(int sock, __u32 pid) 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, @@ -641,8 +641,9 @@ static void netlink_parse_extended_ack(struct nlmsghdr *h) * 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)); } } @@ -652,7 +653,8 @@ static void netlink_parse_extended_ack(struct nlmsghdr *h) 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); } } @@ -708,9 +710,9 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), 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 @@ -721,14 +723,14 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), } 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; } @@ -801,10 +803,9 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), 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; } @@ -857,7 +858,7 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), 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), @@ -890,21 +891,22 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), 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; } } @@ -969,7 +971,7 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), } 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; } @@ -992,7 +994,7 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n) /* 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; } @@ -1087,7 +1089,7 @@ void kernel_init(struct zebra_ns *zns) /* 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) diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 78e25e7626..8df5a37640 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -409,9 +409,9 @@ int ifm_read(struct if_msghdr *ifm) /* 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; } @@ -502,8 +502,8 @@ int ifm_read(struct if_msghdr *ifm) * 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; } @@ -586,7 +586,7 @@ int ifm_read(struct if_msghdr *ifm) */ { 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, @@ -709,7 +709,7 @@ static void ifam_read_mesg(struct ifa_msghdr *ifm, union sockunion *addr, /* 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. */ @@ -728,7 +728,8 @@ int ifam_read(struct ifa_msghdr *ifam) 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; } @@ -822,10 +823,10 @@ static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest, /* 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)); @@ -860,7 +861,7 @@ static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest, /* 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; } @@ -1182,7 +1183,8 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask, 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; @@ -1250,8 +1252,8 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask, 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; @@ -1333,8 +1335,8 @@ static int kernel_read(struct thread *thread) 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; } @@ -1350,7 +1352,7 @@ static int kernel_read(struct thread *thread) * 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; @@ -1390,7 +1392,7 @@ static void routing_socket(struct zebra_ns *zns) } 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; } diff --git a/zebra/label_manager.c b/zebra/label_manager.c index e53764c770..2b0508099f 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -83,12 +83,28 @@ static int relay_response_back(void) 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; @@ -104,7 +120,7 @@ static int relay_response_back(void) 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; @@ -119,9 +135,9 @@ static int relay_response_back(void) /* 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, @@ -139,6 +155,11 @@ static int lm_zclient_read(struct thread *t) /* 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; } @@ -187,8 +208,8 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, 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; } @@ -209,16 +230,17 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, /* 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; } @@ -227,8 +249,9 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, 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; @@ -239,9 +262,9 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, /* 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; } @@ -269,17 +292,15 @@ static int lm_zclient_connect(struct thread *t) 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; } @@ -401,9 +422,9 @@ struct label_manager_chunk *assign_label_chunk(uint8_t proto, ->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; } @@ -441,8 +462,8 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, 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; @@ -452,8 +473,8 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, 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; } diff --git a/zebra/main.c b/zebra/main.c index 8db1c48f22..c46f8bb95d 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -292,7 +292,7 @@ int main(int argc, char **argv) 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; diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 640d58e17e..f48fc6addb 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -43,6 +43,7 @@ #include "zebra/zapi_msg.h" #include "zebra/zebra_memory.h" #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_errors.h" #define ZEBRA_PTM_SUPPORT @@ -166,7 +167,8 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, 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; } @@ -236,7 +238,8 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p, 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; } @@ -275,14 +278,15 @@ void zebra_redistribute_add(ZAPI_HANDLER_ARGS) 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; } @@ -321,14 +325,15 @@ void zebra_redistribute_delete(ZAPI_HANDLER_ARGS) 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; } @@ -444,7 +449,8 @@ void zebra_interface_address_add_update(struct interface *ifp, } 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); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 3683596b41..b600a7db50 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -64,6 +64,7 @@ #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 @@ -99,7 +100,7 @@ static inline int is_selfroute(int proto) || (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP) || (proto == RTPROT_LDP) || (proto == RTPROT_BABEL) || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP) - || (proto == RTPROT_PBR)) { + || (proto == RTPROT_PBR) || (proto == RTPROT_OPENFABRIC)) { return 1; } @@ -146,6 +147,9 @@ static inline int zebra2proto(int proto) case ZEBRA_ROUTE_PBR: proto = RTPROT_PBR; break; + case ZEBRA_ROUTE_OPENFABRIC: + proto = RTPROT_OPENFABRIC; + break; default: /* * When a user adds a new protocol this will show up @@ -153,8 +157,9 @@ static inline int zebra2proto(int proto) * 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; } @@ -203,6 +208,9 @@ static inline int proto2zebra(int proto, int family) case RTPROT_PBR: proto = ZEBRA_ROUTE_PBR; break; + case RTPROT_OPENFABRIC: + proto = ZEBRA_ROUTE_OPENFABRIC; + break; default: /* * When a user adds a new protocol this will show up @@ -210,9 +218,9 @@ static inline int proto2zebra(int proto, int family) * 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; } @@ -426,8 +434,10 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, 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; } @@ -575,7 +585,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, for (;;) { struct nexthop *nh = NULL; - vrf_id_t nh_vrf_id; + if (len < (int)sizeof(*rtnh) || rtnh->rtnh_len > len) break; @@ -594,7 +604,8 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, 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); @@ -817,14 +828,18 @@ int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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; } @@ -1752,6 +1767,7 @@ skip: 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 { @@ -1777,7 +1793,23 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in) 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); @@ -1951,10 +1983,10 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) 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; } @@ -1963,15 +1995,15 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) 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, @@ -2167,9 +2199,9 @@ static int netlink_macfdb_update(struct interface *ifp, vlanid_t vid, 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; } @@ -2252,10 +2284,10 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) 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; } @@ -2265,7 +2297,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) /* 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) @@ -2277,7 +2309,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) 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; @@ -2311,7 +2343,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) 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), @@ -2473,9 +2505,10 @@ int netlink_neigh_change(struct nlmsghdr *h, ns_id_t ns_id) 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; } diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index c4f21d1504..cefd1996a9 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -54,6 +54,7 @@ #define RTPROT_SHARP 194 #define RTPROT_PBR 195 #define RTPROT_ZSTATIC 196 +#define RTPROT_OPENFABRIC 197 void rt_netlink_init(void); diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index c0ad87ce39..a6de84d56f 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -40,6 +40,7 @@ #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; @@ -72,10 +73,10 @@ static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label, 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; } @@ -213,7 +214,7 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, 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; @@ -227,7 +228,7 @@ static int kernel_rtm_ipv4(int cmd, const struct prefix *p, 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, @@ -399,7 +400,8 @@ enum dp_req_result kernel_route_rib(struct route_node *rn, 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; } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 43dfca10e6..f9bd5ad1bb 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -44,6 +44,7 @@ #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; @@ -181,7 +182,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp) 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); } @@ -374,7 +375,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp) 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)); @@ -468,12 +469,12 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len, 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; @@ -483,21 +484,24 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len, 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); } @@ -505,7 +509,8 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len, 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); } @@ -513,7 +518,8 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len, 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); } @@ -543,7 +549,8 @@ static void rtadv_process_packet(uint8_t *buf, unsigned int len, /* 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; } @@ -563,8 +570,8 @@ static void rtadv_process_packet(uint8_t *buf, unsigned int len, /* 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; } @@ -573,15 +580,15 @@ static void rtadv_process_packet(uint8_t *buf, unsigned int len, /* 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; } @@ -614,8 +621,9 @@ static int rtadv_read(struct thread *thread) &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; } @@ -822,15 +830,17 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable) /* 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; } @@ -1757,8 +1767,10 @@ static int if_join_all_router(int sock, struct interface *ifp) 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( @@ -1781,8 +1793,10 @@ static int if_leave_all_router(int sock, struct interface *ifp) 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( diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index b3aeaf2f76..c1bd68f9dc 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -28,9 +28,12 @@ #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 @@ -118,8 +121,8 @@ void route_read(struct zebra_ns *zns) 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; } @@ -140,7 +143,8 @@ void route_read(struct zebra_ns *zns) 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; } @@ -152,8 +156,9 @@ void route_read(struct zebra_ns *zns) 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; } @@ -166,10 +171,10 @@ void route_read(struct zebra_ns *zns) 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; } @@ -181,7 +186,7 @@ void route_read(struct zebra_ns *zns) || 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; } @@ -210,20 +215,21 @@ void route_read(struct zebra_ns *zns) 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); diff --git a/zebra/rtread_sysctl.c b/zebra/rtread_sysctl.c index fba67e3d0c..f88586a6ea 100644 --- a/zebra/rtread_sysctl.c +++ b/zebra/rtread_sysctl.c @@ -31,6 +31,7 @@ #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) @@ -47,7 +48,8 @@ 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; } @@ -56,7 +58,8 @@ void route_read(struct zebra_ns *zns) /* 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; } diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c index 87d3769a5a..518d81dd6e 100644 --- a/zebra/rule_netlink.c +++ b/zebra/rule_netlink.c @@ -40,6 +40,7 @@ #include "zebra/kernel_netlink.h" #include "zebra/rule_netlink.h" #include "zebra/zebra_pbr.h" +#include "zebra/zebra_errors.h" /* definitions */ @@ -205,7 +206,8 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) 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; diff --git a/zebra/rule_socket.c b/zebra/rule_socket.c index 620410de04..11d9e00ebb 100644 --- a/zebra/rule_socket.c +++ b/zebra/rule_socket.c @@ -41,18 +41,19 @@ #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; } diff --git a/zebra/subdir.am b/zebra/subdir.am index 5dc3750315..a87fcec41f 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -5,6 +5,22 @@ if ZEBRA sbin_PROGRAMS += zebra/zebra dist_examples_DATA += zebra/zebra.conf.sample +vtysh_scan += \ + $(top_srcdir)/zebra/debug.c \ + $(top_srcdir)/zebra/interface.c \ + $(top_srcdir)/zebra/router-id.c \ + $(top_srcdir)/zebra/rtadv.c \ + $(top_srcdir)/zebra/zebra_mpls_vty.c \ + $(top_srcdir)/zebra/zebra_ptm.c \ + $(top_srcdir)/zebra/zebra_pw.c \ + $(top_srcdir)/zebra/zebra_routemap.c \ + $(top_srcdir)/zebra/zebra_vty.c \ + $(top_srcdir)/zebra/zserv.c \ + # end + +# can be loaded as DSO - always include for vtysh +vtysh_scan += $(top_srcdir)/zebra/irdp_interface.c +vtysh_scan += $(top_srcdir)/zebra/zebra_fpm.c if IRDP module_LTLIBRARIES += zebra/zebra_irdp.la @@ -16,6 +32,7 @@ if FPM module_LTLIBRARIES += zebra/zebra_fpm.la endif +man8 += $(MANBUILD)/zebra.8 ## endif ZEBRA endif @@ -132,10 +149,11 @@ zebra_zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic zebra_zebra_snmp_la_LIBADD = lib/libfrrsnmp.la zebra_zebra_fpm_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -zebra_zebra_fpm_la_LIBADD = $(Q_FPM_PB_CLIENT_LDOPTS) +zebra_zebra_fpm_la_LIBADD = zebra_zebra_fpm_la_SOURCES = zebra/zebra_fpm.c zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_netlink.c if HAVE_PROTOBUF +zebra_zebra_fpm_la_LIBADD += fpm/libfrrfpm_pb.la qpb/libfrr_pb.la $(PROTOBUF_C_LIBS) zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_protobuf.c if DEV_BUILD zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_dt.c diff --git a/zebra/table_manager.c b/zebra/table_manager.c index 43b5c7d59e..91b45f3f07 100644 --- a/zebra/table_manager.c +++ b/zebra/table_manager.c @@ -147,9 +147,8 @@ struct table_manager_chunk *assign_table_chunk(uint8_t proto, uint16_t instance, #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; } @@ -186,8 +185,8 @@ int release_table_chunk(uint8_t proto, uint16_t instance, uint32_t start, 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; @@ -196,8 +195,8 @@ int release_table_chunk(uint8_t proto, uint16_t instance, uint32_t start, 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; } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index d95f78109c..b9897bea03 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -62,6 +62,7 @@ #include "zebra/zebra_pbr.h" #include "zebra/table_manager.h" #include "zebra/zapi_msg.h" +#include "zebra/zebra_errors.h" /* Encoding helpers -------------------------------------------------------- */ @@ -1042,7 +1043,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS) 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; @@ -1051,7 +1052,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS) 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; @@ -1060,7 +1061,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS) 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; @@ -1126,7 +1127,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS) 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; @@ -1135,7 +1136,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS) 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; @@ -1144,7 +1145,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS) 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; @@ -1181,7 +1182,7 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS) */ 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; @@ -1193,7 +1194,7 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS) 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; @@ -1202,7 +1203,7 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS) 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; @@ -1241,7 +1242,7 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS) */ 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; @@ -1256,7 +1257,7 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS) 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; @@ -1265,7 +1266,7 @@ static void zread_fec_unregister(ZAPI_HANDLER_ARGS) 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; @@ -1318,7 +1319,8 @@ void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, 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); } @@ -1481,7 +1483,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) } 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); @@ -1521,7 +1524,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) 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); @@ -1563,7 +1567,8 @@ static void zread_route_del(ZAPI_HANDLER_ARGS) 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; } @@ -1703,7 +1708,7 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS) 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; @@ -1714,7 +1719,7 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS) 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; @@ -1722,8 +1727,8 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS) 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); @@ -1781,9 +1786,9 @@ static void zread_table_manager_connect(struct zserv *client, /* 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; } @@ -1821,10 +1826,11 @@ static void zread_label_manager_connect(struct zserv *client, /* 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", @@ -1842,33 +1848,12 @@ static void zread_label_manager_connect(struct zserv *client, " 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) @@ -1889,21 +1874,16 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg, 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); @@ -1927,12 +1907,7 @@ static void zread_release_label_chunk(struct zserv *client, struct stream *msg) 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; @@ -1940,8 +1915,8 @@ stream_failure: 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) @@ -1949,16 +1924,10 @@ static void zread_label_manager_request(ZAPI_HANDLER_ARGS) 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)); @@ -1983,9 +1952,9 @@ static void zread_get_table_chunk(struct zserv *client, struct stream *msg, 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); @@ -2023,7 +1992,7 @@ static void zread_table_manager_request(ZAPI_HANDLER_ARGS) /* 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; } @@ -2077,7 +2046,8 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS) 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; @@ -2087,7 +2057,8 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS) 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; } @@ -2097,7 +2068,8 @@ static void zread_pseudowire(ZAPI_HANDLER_ARGS) 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; } @@ -2440,6 +2412,7 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [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, @@ -2509,8 +2482,8 @@ void zserv_handle_commands(struct zserv *client, struct stream *msg) 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; } diff --git a/zebra/zebra_errors.c b/zebra/zebra_errors.c index 198e1cce23..17163e2182 100644 --- a/zebra/zebra_errors.c +++ b/zebra/zebra_errors.c @@ -26,246 +26,675 @@ /* 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, } }; diff --git a/zebra/zebra_errors.h b/zebra/zebra_errors.h index f8a00bce0d..43e37c6e5b 100644 --- a/zebra/zebra_errors.h +++ b/zebra/zebra_errors.h @@ -18,56 +18,107 @@ * 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__ */ diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 1cb14abbf9..35a5d69ee3 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -1518,9 +1518,8 @@ static inline void zfpm_init_message_format(const char *format) 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; @@ -1530,7 +1529,7 @@ static inline void zfpm_init_message_format(const char *format) 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; } @@ -1538,7 +1537,8 @@ static inline void zfpm_init_message_format(const char *format) return; } - zlog_warn("Unknown fpm format '%s'", format); + flog_warn(EC_ZEBRA_FPM_FORMAT_UNKNOWN, "Unknown fpm format '%s'", + format); } /** diff --git a/zebra/zebra_fpm_protobuf.c b/zebra/zebra_fpm_protobuf.c index ebd632270c..be0f6a23be 100644 --- a/zebra/zebra_fpm_protobuf.c +++ b/zebra/zebra_fpm_protobuf.c @@ -129,6 +129,7 @@ static inline int add_nexthop(qpb_allocator_t *allocator, Fpm__AddRoute *msg, } // TODO: Use src. + (void)src; return 1; } diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 8f48cc5191..c19aeb6260 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -919,7 +919,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) 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: @@ -936,7 +936,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) 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: @@ -976,7 +976,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) 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: @@ -1055,8 +1055,8 @@ static int lsp_processq_add(zebra_lsp_t *lsp) 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; } @@ -1698,8 +1698,8 @@ static int mpls_processq_init(struct zebra_t *zebra) { 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; } @@ -1728,7 +1728,8 @@ void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum dp_results res) 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); @@ -1746,7 +1747,8 @@ void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum dp_results res) 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; } } @@ -1835,7 +1837,7 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, 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; @@ -1915,9 +1917,9 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p, 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; } @@ -2047,8 +2049,8 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p, 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; } @@ -2095,8 +2097,8 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p) 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; } @@ -2945,7 +2947,8 @@ void zebra_mpls_init(void) 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; } diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c index 542de27e83..71679f26d6 100644 --- a/zebra/zebra_mpls_openbsd.c +++ b/zebra/zebra_mpls_openbsd.c @@ -26,6 +26,7 @@ #include "zebra/rt.h" #include "zebra/zebra_mpls.h" #include "zebra/debug.h" +#include "zebra/zebra_errors.h" #include "privs.h" #include "prefix.h" @@ -122,7 +123,7 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label, } 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; @@ -229,7 +230,7 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label, } 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; @@ -256,11 +257,11 @@ static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp) && (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; } @@ -359,8 +360,8 @@ static int kmpw_install(struct zebra_pw *pw) 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; } @@ -381,8 +382,8 @@ static int kmpw_install(struct zebra_pw *pw) 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, @@ -397,7 +398,7 @@ static int kmpw_install(struct zebra_pw *pw) 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; } @@ -415,7 +416,7 @@ static int kmpw_uninstall(struct zebra_pw *pw) 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; } @@ -430,13 +431,13 @@ int mpls_kernel_init(void) 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; } @@ -445,7 +446,8 @@ int mpls_kernel_init(void) 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 diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 2e02b12311..796aa3f666 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -339,7 +339,7 @@ DEFUN (show_mpls_table, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_mpls_print_lsp_table(vty, zvrf, uj); @@ -357,7 +357,7 @@ DEFUN (show_mpls_table_lsp, { uint32_t label; struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); label = atoi(argv[3]->arg); diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index 3af3cd5bb2..583b666e66 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -50,7 +50,8 @@ void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS) 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); diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index a3278c4780..b26c0515f1 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -88,7 +88,7 @@ static int send_receive(int sock, struct nlmsghdr *nlh, unsigned int seq, 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; } @@ -109,20 +109,20 @@ static int send_receive(int sock, struct nlmsghdr *nlh, unsigned int seq, }; 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; @@ -176,7 +176,7 @@ ns_id_t zebra_ns_id_get(const char *netnspath) /* 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; @@ -187,7 +187,7 @@ ns_id_t zebra_ns_id_get(const char *netnspath) 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); @@ -263,13 +263,13 @@ ns_id_t zebra_ns_id_get(const char *netnspath) 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; @@ -337,7 +337,8 @@ static void zebra_ns_create_netns_directory(void) /* 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; } } diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 12207805d9..2608ffd7a1 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -42,6 +42,7 @@ #include "zebra_netns_notify.h" #include "zebra_netns_id.h" +#include "zebra_errors.h" #ifdef HAVE_NETLINK @@ -85,13 +86,14 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name) /* 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; } @@ -100,7 +102,8 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name) 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; @@ -130,9 +133,8 @@ static int zebra_ns_delete(char *name) 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. */ @@ -237,8 +239,9 @@ static int zebra_ns_notify_read(struct thread *t) 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]; @@ -254,12 +257,14 @@ static int zebra_ns_notify_read(struct thread *t) 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; } @@ -283,7 +288,8 @@ void zebra_ns_notify_parse(void) 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) { @@ -293,13 +299,15 @@ void zebra_ns_notify_parse(void) || 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)) { @@ -321,13 +329,16 @@ void zebra_ns_notify_init(void) 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); diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 456253cc30..c5e88daf79 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -26,7 +26,6 @@ #include "lib/logicalrouter.h" #include "lib/prefix.h" #include "lib/memory.h" -#include "lib/lib_errors.h" #include "rtadv.h" #include "zebra_ns.h" @@ -276,8 +275,7 @@ int zebra_ns_disable(ns_id_t ns_id, void **info) 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); diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index e2217a5d2b..275e045d43 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -464,8 +464,8 @@ void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule) 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) @@ -581,8 +581,9 @@ void zebra_pbr_destroy_ipset(struct zebra_ns *zns, 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 { @@ -665,8 +666,8 @@ void zebra_pbr_del_ipset_entry(struct zebra_ns *zns, 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) @@ -716,8 +717,8 @@ void zebra_pbr_del_iptable(struct zebra_ns *zns, } 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__); } /* diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index 0db33d1f8c..12c712e4cd 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -187,7 +187,6 @@ extern enum dp_req_result kernel_del_pbr_rule(struct zebra_pbr_rule *rule); */ extern void kernel_read_pbr_rules(struct zebra_ns *zns); -enum dp_results; /* * Handle success or failure of rule (un)install in the kernel. */ diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 39cb073b77..b711241611 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -34,6 +34,7 @@ #include "version.h" #include "vrf.h" #include "vty.h" +#include "lib_errors.h" #include "zebra/debug.h" #include "zebra/interface.h" @@ -116,13 +117,13 @@ void zebra_ptm_init(void) 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; } @@ -180,8 +181,8 @@ static int zebra_ptm_flush_messages(struct thread *thread) 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); @@ -206,8 +207,8 @@ static int zebra_ptm_send_message(char *data, int size) 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); @@ -504,17 +505,17 @@ static int zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, 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; } } @@ -608,7 +609,8 @@ static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt) 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; } @@ -647,8 +649,9 @@ int zebra_ptm_sock_read(struct thread *thread) 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; @@ -1032,8 +1035,8 @@ int zebra_ptm_bfd_client_deregister(struct zserv *client) 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; @@ -1269,7 +1272,7 @@ static void zebra_ptm_send_bfdd(struct stream *msg) /* 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; } @@ -1283,7 +1286,7 @@ static void zebra_ptm_send_bfdd(struct stream *msg) /* 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; } } @@ -1301,7 +1304,7 @@ static void zebra_ptm_send_clients(struct stream *msg) /* 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; } @@ -1324,7 +1327,7 @@ static void zebra_ptm_send_clients(struct stream *msg) /* 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; } } @@ -1366,7 +1369,7 @@ static int _zebra_ptm_bfd_client_deregister(struct zserv *zs) /* 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; } @@ -1429,7 +1432,7 @@ static void _zebra_ptm_reroute(struct zserv *zs, struct stream *msg, */ 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; } @@ -1528,7 +1531,7 @@ void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS) */ 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; } diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index c6db1463f2..fb9a40fe3d 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -248,8 +248,8 @@ static int zebra_pw_check_reachability(struct zebra_pw *pw) &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; } @@ -260,8 +260,8 @@ static int zebra_pw_check_reachability(struct zebra_pw *pw) 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; } } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ab07549ec2..5853bdd465 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -266,7 +266,8 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, There was a crash because ifp here was coming to be NULL */ if (ifp) if (connected_is_unnumbered(ifp) - || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) { + || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE) + || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); } @@ -303,8 +304,10 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re, nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; nexthop->gate.ipv6 = *ipv6; nexthop->ifindex = ifindex; - if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE) + || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); + } route_entry_nexthop_add(re, nexthop); @@ -428,8 +431,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re, /* Skip nexthops that have been filtered out due to route-map */ /* The nexthops are specific to this route and so the same */ /* nexthop for a different route may not have this flag set */ - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Nexthop Filtered", + __PRETTY_FUNCTION__); return 0; + } /* * Check to see if we should trust the passed in information @@ -438,13 +445,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re, */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); - if (ifp && connected_is_unnumbered(ifp)) { + if ((ifp && connected_is_unnumbered(ifp)) + || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) { if (if_is_operative(ifp)) return 1; - else + else { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Onlink and interface %s is not operative", + __PRETTY_FUNCTION__, ifp->name); return 0; - } else + } + } else { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Interface %s is not unnumbered", + __PRETTY_FUNCTION__, + ifp ? ifp->name : "Unknown"); return 0; + } } /* Make lookup prefix. */ @@ -466,8 +485,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re, } /* Lookup table. */ table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id); - if (!table) + if (!table) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Table not found", + __PRETTY_FUNCTION__); return 0; + } rn = route_node_match(table, (struct prefix *)&p); while (rn) { @@ -480,15 +503,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re, */ if (top && rn == top) if (((afi == AFI_IP) && (rn->p.prefixlen != 32)) - || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) + || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Matched against ourself and prefix length is not max bit length", + __PRETTY_FUNCTION__); return 0; + } /* Pick up selected route. */ /* However, do not resolve over default route unless explicitly * allowed. */ if (is_default_prefix(&rn->p) - && !rnh_resolve_via_default(p.family)) + && !rnh_resolve_via_default(p.family)) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t:%s: Resolved against default route", + __PRETTY_FUNCTION__); return 0; + } dest = rib_dest_from_rnode(rn); if (dest && dest->selected_fib @@ -540,6 +573,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re, } if (resolved && set) re->nexthop_mtu = match->mtu; + if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Recursion failed to find", + __PRETTY_FUNCTION__); return resolved; } else if (re->type == ZEBRA_ROUTE_STATIC) { resolved = 0; @@ -558,6 +594,11 @@ static int nexthop_active(afi_t afi, struct route_entry *re, } if (resolved && set) re->nexthop_mtu = match->mtu; + + if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Static route unable to resolve", + __PRETTY_FUNCTION__); return resolved; } else { return 0; @@ -900,8 +941,12 @@ static unsigned nexthop_active_check(struct route_node *rn, default: break; } - if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Unable to find a active nexthop", + __PRETTY_FUNCTION__); return 0; + } /* XXX: What exactly do those checks do? Do we support * e.g. IPv4 routes with IPv6 nexthops or vice versa? */ @@ -1046,8 +1091,9 @@ void kernel_route_rib_pass_fail(struct route_node *rn, const struct prefix *p, 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: /* @@ -1070,8 +1116,9 @@ void kernel_route_rib_pass_fail(struct route_node *rn, const struct prefix *p, * 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; @@ -1127,12 +1174,12 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, 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: @@ -1167,12 +1214,12 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) 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: @@ -1965,8 +2012,8 @@ void rib_queue_add(struct route_node *rn) } 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; } @@ -2021,8 +2068,8 @@ static void rib_queue_init(struct zebra_t *zebra) 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; } @@ -2035,8 +2082,8 @@ static void rib_queue_init(struct zebra_t *zebra) 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; @@ -2209,7 +2256,6 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, union prefixconstptr src_pp, const struct route_entry *re) { - const struct prefix *p = pp.p; const struct prefix *src_p = src_pp.p; bool is_srcdst = src_p && src_p->prefixlen; char straddr[PREFIX_STRLEN]; @@ -2232,10 +2278,34 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, re->nexthop_num, re->nexthop_active_num); for (ALL_NEXTHOPS(re->ng, nexthop)) { - inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN); - zlog_debug("%s: %s %s[%u] vrf %u with flags %s%s%s", func, + struct interface *ifp; + struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); + + switch (nexthop->type) { + case NEXTHOP_TYPE_BLACKHOLE: + sprintf(straddr, "Blackhole"); + break; + case NEXTHOP_TYPE_IFINDEX: + ifp = if_lookup_by_index(nexthop->ifindex, + nexthop->vrf_id); + sprintf(straddr, "%s", ifp ? ifp->name : "Unknown"); + break; + case NEXTHOP_TYPE_IPV4: + /* fallthrough */ + case NEXTHOP_TYPE_IPV4_IFINDEX: + inet_ntop(AF_INET, &nexthop->gate, straddr, + INET6_ADDRSTRLEN); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + inet_ntop(AF_INET6, &nexthop->gate, straddr, + INET6_ADDRSTRLEN); + break; + } + zlog_debug("%s: %s %s[%u] vrf %s(%u) with flags %s%s%s", func, (nexthop->rparent ? " NH" : "NH"), straddr, - nexthop->ifindex, nexthop->vrf_id, + nexthop->ifindex, vrf ? vrf->name : "Unknown", + nexthop->vrf_id, (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""), @@ -2263,9 +2333,9 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) /* 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; } @@ -2311,9 +2381,9 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id) 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; } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 0b585af6a0..30062a0728 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -118,7 +118,8 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type, 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; @@ -249,7 +250,7 @@ static void addr2hostprefix(int af, const union g_addr *addr, 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; } } @@ -870,9 +871,9 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, 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) { diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 9aced13a4f..469aceafb9 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -79,7 +79,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]); static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, struct ipaddr *ip, uint8_t flags, - uint16_t cmd); + uint32_t seq, uint16_t cmd); static unsigned int neigh_hash_keymake(void *p); static int neigh_cmp(const void *p1, const void *p2); static void *zvni_neigh_alloc(void *p); @@ -93,7 +93,7 @@ static void zvni_neigh_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip); static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, - uint8_t flags); + uint8_t flags, uint32_t seq); static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, uint8_t flags); @@ -147,7 +147,7 @@ static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, uint32_t flags); static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr); static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, - uint8_t flags); + uint8_t flags, uint32_t seq); static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, uint8_t flags); static zebra_vni_t *zvni_map_vlan(struct interface *ifp, @@ -207,9 +207,12 @@ 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; } } @@ -282,7 +285,8 @@ static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt) 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; @@ -296,47 +300,60 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) struct vty *vty; char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; + const char *type_str; + const char *state_str; + bool flags_present = false; ipaddr2str(&n->ip, buf2, sizeof(buf2)); prefix_mac2str(&n->emac, buf1, sizeof(buf1)); + type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? + "local" : "remote"; + state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive"; vty = (struct vty *)ctxt; if (json == NULL) { vty_out(vty, "IP: %s\n", ipaddr2str(&n->ip, buf2, sizeof(buf2))); - vty_out(vty, " MAC: %s", + vty_out(vty, " Type: %s\n", type_str); + vty_out(vty, " State: %s\n", state_str); + vty_out(vty, " MAC: %s\n", prefix_mac2str(&n->emac, buf1, sizeof(buf1))); } else { json_object_string_add(json, "ip", buf2); + json_object_string_add(json, "type", type_str); + json_object_string_add(json, "state", state_str); json_object_string_add(json, "mac", buf1); } if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { if (json == NULL) { - vty_out(vty, " Remote VTEP: %s", + vty_out(vty, " Remote VTEP: %s\n", inet_ntoa(n->r_vtep_ip)); } else json_object_string_add(json, "remoteVtep", inet_ntoa(n->r_vtep_ip)); } - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { - if (!json) { - vty_out(vty, "\n"); - vty_out(vty, " State: %s", - IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active" - : "Inactive"); - } - } if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) { - if (!json) - vty_out(vty, " Default-gateway"); - else + if (!json) { + vty_out(vty, " Flags: Default-gateway"); + flags_present = true; + } else json_object_boolean_true_add(json, "defaultGateway"); } if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) { - if (!json) - vty_out(vty, " Router"); + if (!json) { + vty_out(vty, + flags_present ? " ,Router" : " Flags: Router"); + flags_present = true; + } + } + if (json == NULL) { + if (flags_present) + vty_out(vty, "\n"); + vty_out(vty, " Local Seq: %u Remote Seq: %u\n", + n->loc_seq, n->rem_seq); + } else { + json_object_int_add(json, "localSequence", n->loc_seq); + json_object_int_add(json, "remoteSequence", n->rem_seq); } - if (json == NULL) - vty_out(vty, "\n"); } /* @@ -350,6 +367,7 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt) char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; struct neigh_walk_ctx *wctx = ctxt; + const char *state_str; vty = wctx->vty; json_vni = wctx->json; @@ -360,55 +378,58 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt) prefix_mac2str(&n->emac, buf1, sizeof(buf1)); ipaddr2str(&n->ip, buf2, sizeof(buf2)); - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) - && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) { + state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive"; + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { + if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) + return; + if (json_vni == NULL) { - vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width, - buf2, "local", buf1); + vty_out(vty, "%*s %-6s %-8s %-17s\n", + -wctx->addr_width, buf2, "local", + state_str, buf1); } else { json_object_string_add(json_row, "type", "local"); + json_object_string_add(json_row, "state", state_str); json_object_string_add(json_row, "mac", buf1); + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) + json_object_boolean_true_add( + json_row, "defaultGateway"); + json_object_int_add(json_row, "localSequence", + n->loc_seq); + json_object_int_add(json_row, "remoteSequence", + n->rem_seq); } wctx->count++; - } else { - if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) { - if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) { - if (json_vni == NULL) { - if (wctx->count == 0) - vty_out(vty, - "%*s %-6s %-17s %-21s\n", - -wctx->addr_width, - "Neighbor", "Type", - "MAC", "Remote VTEP"); - vty_out(vty, "%*s %-6s %-17s %-21s\n", - -wctx->addr_width, buf2, - "remote", buf1, - inet_ntoa(n->r_vtep_ip)); - } else { - json_object_string_add(json_row, "type", - "remote"); - json_object_string_add(json_row, "mac", - buf1); - json_object_string_add( - json_row, "remoteVtep", - inet_ntoa(n->r_vtep_ip)); - } - wctx->count++; - } + } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { + if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) && + !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) + return; + + if (json_vni == NULL) { + if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) && + (wctx->count == 0)) + vty_out(vty, + "%*s %-6s %-8s %-17s %-21s\n", + -wctx->addr_width, "Neighbor", "Type", + "State", "MAC", "Remote VTEP"); + vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n", + -wctx->addr_width, buf2, "remote", state_str, + buf1, inet_ntoa(n->r_vtep_ip)); } else { - if (json_vni == NULL) { - vty_out(vty, "%*s %-6s %-17s %-21s\n", - -wctx->addr_width, buf2, "remote", buf1, - inet_ntoa(n->r_vtep_ip)); - } else { - json_object_string_add(json_row, "type", - "remote"); - json_object_string_add(json_row, "mac", buf1); - json_object_string_add(json_row, "remoteVtep", - inet_ntoa(n->r_vtep_ip)); - } - wctx->count++; + json_object_string_add(json_row, "type", "remote"); + json_object_string_add(json_row, "state", state_str); + json_object_string_add(json_row, "mac", buf1); + json_object_string_add(json_row, "remoteVtep", + inet_ntoa(n->r_vtep_ip)); + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) + json_object_boolean_true_add(json_row, + "defaultGateway"); + json_object_int_add(json_row, "localSequence", + n->loc_seq); + json_object_int_add(json_row, "remoteSequence", + n->rem_seq); } + wctx->count++; } if (json_vni) @@ -461,8 +482,9 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet, hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx); if (json == NULL) { - vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", - "Type", "MAC", "Remote VTEP"); + vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n", + -wctx.addr_width, "IP", "Type", + "State", "MAC", "Remote VTEP"); } hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx); @@ -535,6 +557,8 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty, inet_ntoa(zrmac->fwd_info.r_vtep_ip)); json_object_int_add(json, "refCount", rb_host_count(&zrmac->host_rb)); + json_object_int_add(json, "localSequence", zrmac->loc_seq); + json_object_int_add(json, "remoteSequence", zrmac->rem_seq); RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb) json_object_array_add( json_hosts, @@ -588,6 +612,10 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt) vty_out(vty, " Remote-gateway Mac "); vty_out(vty, "\n"); + vty_out(vty, " Local Seq: %u Remote Seq: %u", + mac->loc_seq, mac->rem_seq); + vty_out(vty, "\n"); + /* print all the associated neigh */ vty_out(vty, " Neighbors:\n"); if (!listcount(mac->neigh_list)) @@ -596,11 +624,8 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt) for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) { vty_out(vty, " %s %s\n", ipaddr2str(&n->ip, buf2, sizeof(buf2)), - CHECK_FLAG(n->flags, ZEBRA_MAC_LOCAL) - ? (IS_ZEBRA_NEIGH_ACTIVE(n) - ? "Active" - : "Inactive") - : ""); + (IS_ZEBRA_NEIGH_ACTIVE(n) + ? "Active" : "Inactive")); } } @@ -627,13 +652,15 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt) if (json_mac_hdr) json_mac = json_object_new_object(); - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) - && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) { + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { struct zebra_ns *zns; ifindex_t ifindex; struct interface *ifp; vlanid_t vid; + if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) + return; + zns = zebra_ns_lookup(NS_DEFAULT); ifindex = mac->fwd_info.local.ifindex; ifp = if_lookup_by_index_per_ns(zns, ifindex); @@ -653,59 +680,46 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt) else json_object_int_add(json_mac, "vlan", vid); } - if (json_mac_hdr == NULL) + if (json_mac_hdr == NULL) { vty_out(vty, "\n"); - else + } else { + json_object_int_add(json_mac, "localSequence", + mac->loc_seq); + json_object_int_add(json_mac, "remoteSequence", + mac->rem_seq); json_object_object_add(json_mac_hdr, buf1, json_mac); + } + wctx->count++; + } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { - if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) { - if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, - &wctx->r_vtep_ip)) { - if (wctx->count == 0) { - if (json_mac_hdr == NULL) { - vty_out(vty, "\nVNI %u\n\n", - wctx->zvni->vni); - vty_out(vty, - "%-17s %-6s %-21s %-5s\n", - "MAC", "Type", - "Intf/Remote VTEP", - "VLAN"); - } - } - if (json_mac_hdr == NULL) - vty_out(vty, "%-17s %-6s %-21s\n", buf1, - "remote", - inet_ntoa(mac->fwd_info - .r_vtep_ip)); - else { - json_object_string_add(json_mac, "type", - "remote"); - json_object_string_add( - json_mac, "remoteVtep", - inet_ntoa(mac->fwd_info - .r_vtep_ip)); - json_object_object_add(json_mac_hdr, - buf1, json_mac); - } - wctx->count++; + + if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) && + !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, + &wctx->r_vtep_ip)) + return; + + if (json_mac_hdr == NULL) { + if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) && + (wctx->count == 0)) { + vty_out(vty, "\nVNI %u\n\n", wctx->zvni->vni); + vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", + "Type", "Intf/Remote VTEP", "VLAN"); } + vty_out(vty, "%-17s %-6s %-21s\n", buf1, "remote", + inet_ntoa(mac->fwd_info.r_vtep_ip)); } else { - if (json_mac_hdr == NULL) - vty_out(vty, "%-17s %-6s %-21s\n", buf1, - "remote", - inet_ntoa(mac->fwd_info.r_vtep_ip)); - else { - json_object_string_add(json_mac, "type", - "remote"); - json_object_string_add( - json_mac, "remoteVtep", + json_object_string_add(json_mac, "type", "remote"); + json_object_string_add(json_mac, "remoteVtep", inet_ntoa(mac->fwd_info.r_vtep_ip)); - json_object_object_add(json_mac_hdr, buf1, - json_mac); - } - wctx->count++; + json_object_object_add(json_mac_hdr, buf1, json_mac); + json_object_int_add(json_mac, "localSequence", + mac->loc_seq); + json_object_int_add(json_mac, "remoteSequence", + mac->rem_seq); } + + wctx->count++; } } @@ -1166,7 +1180,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]) */ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, struct ipaddr *ip, uint8_t flags, - uint16_t cmd) + uint32_t seq, uint16_t cmd) { char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; @@ -1197,7 +1211,10 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, } else stream_putl(s, 0); /* Just MAC. */ - stream_putc(s, flags); /* sticky mac/gateway mac */ + if (cmd == ZEBRA_MACIP_ADD) { + stream_putc(s, flags); /* sticky mac/gateway mac */ + stream_putl(s, seq); /* sequence number */ + } /* Write packet size. */ @@ -1205,10 +1222,10 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s", + "Send MACIP %s flags 0x%x MAC %s IP %s seq %u L2-VNI %u to %s", (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags, prefix_mac2str(macaddr, buf, sizeof(buf)), - ipaddr2str(ip, buf2, sizeof(buf2)), vni, + ipaddr2str(ip, buf2, sizeof(buf2)), seq, vni, zebra_route_string(client->proto)); if (cmd == ZEBRA_MACIP_ADD) @@ -1393,106 +1410,100 @@ static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip) return n; } -/* Process all neigh associated to a mac upon local mac add event */ -static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni, - zebra_mac_t *zmac) +/* + * Process all neighbors associated with a MAC upon the MAC being learnt + * locally or undergoing any other change (such as sequence number). + */ +static void zvni_process_neigh_on_local_mac_change(zebra_vni_t *zvni, + zebra_mac_t *zmac, + bool seq_change) { zebra_neigh_t *n = NULL; struct listnode *node = NULL; char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Processing neighbors on local MAC %s %s, VNI %u", + prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)), + seq_change ? "CHANGE" : "ADD", zvni->vni); + + /* Walk all neighbors and mark any inactive local neighbors as + * active and/or update sequence number upon a move, and inform BGP. + * The action for remote neighbors is TBD. + * NOTE: We can't simply uninstall remote neighbors as the kernel may + * accidentally end up deleting a just-learnt local neighbor. + */ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { - /* MAC is learnt locally, program all inactive neigh - * pointing to this mac */ - if (IS_ZEBRA_NEIGH_INACTIVE(n)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); - + if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change) { ZEBRA_NEIGH_SET_ACTIVE(n); + n->loc_seq = zmac->loc_seq; zvni_neigh_send_add_to_client( - zvni->vni, &n->ip, &n->emac, n->flags); - } else { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); + zvni->vni, &n->ip, &n->emac, + n->flags, n->loc_seq); } - } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { - /* TODO: assume the neigh has moved too ?? */ } } } -/* Process all neigh associated to a mac upon local mac del event */ +/* + * Process all neighbors associated with a local MAC upon the MAC being + * deleted. + */ static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; struct listnode *node = NULL; char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u", + prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)), + zvni->vni); + + /* Walk all local neighbors and mark as inactive and inform + * BGP, if needed. + * TBD: There is currently no handling for remote neighbors. We + * don't expect them to exist, if they do, do we install the MAC + * as a remote MAC and the neighbor as remote? + */ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { if (IS_ZEBRA_NEIGH_ACTIVE(n)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); - ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); } - } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) - && IS_ZEBRA_DEBUG_VXLAN) { - zlog_debug( - "local MAC %s getting deleted on VNI %u has remote neigh %s", - prefix_mac2str(&n->emac, buf, sizeof(buf)), - zvni->vni, - ipaddr2str(&n->ip, buf2, sizeof(buf2))); } } } -/* process all neigh associated to a mac entry upon remote mac add */ +/* + * Process all neighbors associated with a MAC upon the MAC being remotely + * learnt. + */ static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; struct listnode *node = NULL; char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u", + prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)), + zvni->vni); + + /* Walk all local neighbors and mark as inactive and inform + * BGP, if needed. + */ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { if (IS_ZEBRA_NEIGH_ACTIVE(n)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); - ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); } @@ -1500,25 +1511,14 @@ static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni, } } -/* process all neigh associated to mac entry upon remote mac del */ +/* + * Process all neighbors associated with a remote MAC upon the MAC being + * deleted. + */ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni, zebra_mac_t *zmac) { - zebra_neigh_t *n = NULL; - struct listnode *node = NULL; - char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; - - for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) - && IS_ZEBRA_DEBUG_VXLAN) { - zlog_debug( - "remote MAC %s getting deleted on VNI %u has local neigh %s", - prefix_mac2str(&n->emac, buf, sizeof(buf)), - zvni->vni, - ipaddr2str(&n->ip, buf2, sizeof(buf2))); - } - } + /* NOTE: Currently a NO-OP. */ } /* @@ -1526,7 +1526,8 @@ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni, */ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, - uint8_t neigh_flags) + uint8_t neigh_flags, + uint32_t seq) { uint8_t flags = 0; @@ -1537,7 +1538,7 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags, - ZEBRA_MACIP_ADD); + seq, ZEBRA_MACIP_ADD); } /* @@ -1547,7 +1548,7 @@ static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, uint8_t flags) { return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags, - ZEBRA_MACIP_DEL); + 0, ZEBRA_MACIP_DEL); } /* @@ -1578,6 +1579,7 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n) flags = NTF_EXT_LEARNED; if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG) flags |= NTF_ROUTER; + ZEBRA_NEIGH_SET_ACTIVE(n); ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags); #endif return ret; @@ -1596,8 +1598,8 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n) 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; } @@ -1609,6 +1611,8 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n) if (!vlan_if) return -1; + ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; return kernel_del_neigh(vlan_if, &n->ip); } @@ -1769,10 +1773,10 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, 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; } } @@ -1790,7 +1794,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, 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)), @@ -1802,6 +1806,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, /* Set "local" forwarding info. */ SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW); + ZEBRA_NEIGH_SET_ACTIVE(n); /* Set Router flag (R-bit) */ if (ip->ipa_type == IPADDR_V6) SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); @@ -1819,7 +1824,8 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, prefix_mac2str(macaddr, buf, sizeof(buf)), ipaddr2str(ip, buf2, sizeof(buf2)), n->flags); - zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags); + zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, + n->flags, n->loc_seq); return 0; } @@ -1843,9 +1849,9 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, /* 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; } @@ -1963,11 +1969,15 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, char buf2[INET6_ADDRSTRLEN]; zebra_neigh_t *n = NULL; zebra_mac_t *zmac = NULL, *old_zmac = NULL; + uint32_t old_mac_seq = 0, mac_new_seq = 0; + bool upd_mac_seq = false; + bool neigh_mac_change = false; bool check_rbit = false; - /* create a dummy MAC if the MAC is not already present */ + /* Check if the MAC exists. */ zmac = zvni_mac_lookup(zvni, macaddr); if (!zmac) { + /* create a dummy MAC if the MAC is not already present */ if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "AUTO MAC %s created for neigh %s on VNI %u", @@ -1976,24 +1986,49 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, 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; } memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info)); memset(&zmac->flags, 0, sizeof(uint32_t)); SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO); + } else { + if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) { + /* + * We don't change the MAC to local upon a neighbor + * learn event, we wait for the explicit local MAC + * learn. However, we have to compute its sequence + * number in preparation for when it actually turns + * local. + */ + upd_mac_seq = true; + } } - /* If same entry already exists, it might be a change or it might be a - * move from remote to local. - */ + /* Check if the neighbor exists. */ n = zvni_neigh_lookup(zvni, ip); - if (n) { + if (!n) { + /* New neighbor - create */ + n = zvni_neigh_add(zvni, ip, macaddr); + if (!n) { + flog_err( + 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)), + ifp->name, ifp->ifindex, zvni->vni); + return -1; + } + /* Set "local" forwarding info. */ + SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); + n->ifindex = ifp->ifindex; + check_rbit = true; + } else { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { - + /* If there is no MAC change, BGP isn't interested. */ if (router_flag != (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0)) @@ -2007,16 +2042,26 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, n->ifindex = ifp->ifindex; } else { - /* If the MAC has changed, - * need to issue a delete first - * as this means a different MACIP route. - * Also, need to do some unlinking/relinking. + /* If the MAC has changed, need to issue a + * delete first as this means a different + * MACIP route. Also, need to do some + * unlinking/relinking. We also need to + * update the MAC's sequence number + * in different situations. */ - zvni_neigh_send_del_to_client(zvni->vni, &n->ip, - &n->emac, 0); + if (IS_ZEBRA_NEIGH_ACTIVE(n)) + zvni_neigh_send_del_to_client( + zvni->vni, &n->ip, &n->emac, 0); old_zmac = zvni_mac_lookup(zvni, &n->emac); if (old_zmac) { - listnode_delete(old_zmac->neigh_list, n); + old_mac_seq = + CHECK_FLAG(old_zmac->flags, + ZEBRA_MAC_REMOTE) ? + old_zmac->rem_seq : + old_zmac->loc_seq; + neigh_mac_change = upd_mac_seq = true; + listnode_delete( + old_zmac->neigh_list, n); zvni_deref_ip2mac(zvni, old_zmac, 0); } @@ -2028,14 +2073,21 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, listnode_add_sort(zmac->neigh_list, n); } - } else - /* Neighbor has moved from remote to local. */ - { - /* If MAC has changed, do the unlink/link */ + } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { + /* + * Neighbor has moved from remote to local. Its + * MAC could have also changed as part of the move. + */ if (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) != 0) { old_zmac = zvni_mac_lookup(zvni, &n->emac); if (old_zmac) { + old_mac_seq = CHECK_FLAG( + old_zmac->flags, + ZEBRA_MAC_REMOTE) ? + old_zmac->rem_seq : + old_zmac->loc_seq; + neigh_mac_change = upd_mac_seq = true; listnode_delete(old_zmac->neigh_list, n); zvni_deref_ip2mac(zvni, old_zmac, 0); @@ -2053,22 +2105,19 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, n->ifindex = ifp->ifindex; check_rbit = true; } - } else { - /* New neighbor - create */ - n = zvni_neigh_add(zvni, ip, macaddr); - if (!n) { - flog_err( - ZEBRA_ERR_MAC_ADD_FAILED, - "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - ifp->name, ifp->ifindex, zvni->vni); - return -1; - } - /* Set "local" forwarding info. */ - SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); - n->ifindex = ifp->ifindex; - check_rbit = true; + } + + /* If MAC was previously remote, or the neighbor had a different + * MAC earlier, recompute the sequence number. + */ + if (upd_mac_seq) { + uint32_t seq1, seq2; + + seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE) ? + zmac->rem_seq + 1 : zmac->loc_seq; + seq2 = neigh_mac_change ? old_mac_seq + 1 : 0; + mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ? + MAX(seq1, seq2) : zmac->loc_seq; } /*Mark Router flag (R-bit) */ @@ -2078,38 +2127,40 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); /* Before we program this in BGP, we need to check if MAC is locally - * learnt as well + * learnt. If not, force neighbor to be inactive and reset its seq. */ if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Skipping neigh %s add to client as MAC %s is not local on VNI %u with flags 0x%x", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni, n->flags); - + ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; + zmac->loc_seq = mac_new_seq; return 0; } - if (!check_rbit) { + if (!check_rbit) + return 0; + + /* If the MAC's sequence number has changed, inform the MAC and all + * neighbors associated with the MAC to BGP, else just inform this + * neighbor. + */ + if (upd_mac_seq && zmac->loc_seq != mac_new_seq) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Skipping neigh %s with MAC %s on VNI %u add to client as router flag is not set.", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni); + zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u", + prefix_mac2str(macaddr, buf, sizeof(buf)), + zvni->vni, zmac->loc_seq, mac_new_seq); + zmac->loc_seq = mac_new_seq; + if (zvni_mac_send_add_to_client(zvni->vni, macaddr, + zmac->flags, zmac->loc_seq)) + return -1; + zvni_process_neigh_on_local_mac_change(zvni, zmac, 1); return 0; } - /* Inform BGP. */ - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u with flags 0x%x", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni, n->flags); ZEBRA_NEIGH_SET_ACTIVE(n); + n->loc_seq = zmac->loc_seq; - return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags); + return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, + n->flags, n->loc_seq); } static int zvni_remote_neigh_update(zebra_vni_t *zvni, @@ -2142,7 +2193,7 @@ static int zvni_remote_neigh_update(zebra_vni_t *zvni, */ 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)), @@ -2325,7 +2376,7 @@ static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac) * Inform BGP about local MAC addition. */ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, - uint8_t mac_flags) + uint8_t mac_flags, uint32_t seq) { uint8_t flags = 0; @@ -2335,7 +2386,7 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags, - ZEBRA_MACIP_ADD); + seq, ZEBRA_MACIP_ADD); } /* @@ -2352,7 +2403,7 @@ static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags, - ZEBRA_MACIP_DEL); + 0, ZEBRA_MACIP_DEL); } /* @@ -2575,8 +2626,8 @@ static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local) 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; } @@ -2903,7 +2954,7 @@ static void zvni_build_hash_table() /* 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; @@ -2911,7 +2962,7 @@ static void zvni_build_hash_table() 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; @@ -3034,8 +3085,8 @@ static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip) 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; } @@ -3225,7 +3276,7 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) 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); @@ -3256,7 +3307,7 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, struct ethaddr *rmac, 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, @@ -3420,7 +3471,7 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip, 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)), @@ -3883,9 +3934,9 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, /* 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 { @@ -3976,6 +4027,379 @@ static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni, return 0; } +/* Process a remote MACIP add from BGP. */ +static void process_remote_macip_add(vni_t vni, + struct ethaddr *macaddr, + uint16_t ipa_len, + struct ipaddr *ipaddr, + uint8_t flags, + uint32_t seq, + struct in_addr vtep_ip) +{ + zebra_vni_t *zvni; + zebra_vtep_t *zvtep; + zebra_mac_t *mac, *old_mac; + zebra_neigh_t *n = NULL; + int update_mac = 0, update_neigh = 0; + char buf[ETHER_ADDR_STRLEN]; + char buf1[INET6_ADDRSTRLEN]; + struct interface *ifp = NULL; + struct zebra_if *zif = NULL; + uint32_t tmp_seq; + uint8_t sticky = 0; + uint8_t remote_gw = 0; + uint8_t router_flag = 0; + + /* Locate VNI hash entry - expected to exist. */ + zvni = zvni_lookup(vni); + if (!zvni) { + zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni); + return; + } + + ifp = zvni->vxlan_if; + if (ifp) + zif = ifp->info; + if (!ifp || + !if_is_operative(ifp) || + !zif || + !zif->brslave_info.br_if) { + zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info", + vni); + return; + } + + /* The remote VTEP specified should normally exist, but it is + * possible that when peering comes up, peer may advertise MACIP + * routes before advertising type-3 routes. + */ + zvtep = zvni_vtep_find(zvni, &vtep_ip); + if (!zvtep) { + if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { + flog_err( + 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); + + mac = zvni_mac_lookup(zvni, macaddr); + + /* Ignore if the mac is already present as a gateway mac */ + if (mac && + CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) && + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC", + vni, + prefix_mac2str(macaddr, buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, buf1, sizeof(buf1)) : ""); + return; + } + + /* check if the remote MAC is unknown or has a change. + * If so, that needs to be updated first. Note that client could + * install MAC and MACIP separately or just install the latter. + */ + if (!mac + || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) + || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0) != sticky + || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0) + != remote_gw + || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip) + || seq != mac->rem_seq) + update_mac = 1; + + if (update_mac) { + if (!mac) { + mac = zvni_mac_add(zvni, macaddr); + if (!mac) { + zlog_warn( + "Failed to add MAC %s VNI %u Remote VTEP %s", + prefix_mac2str(macaddr, buf, + sizeof(buf)), + vni, inet_ntoa(vtep_ip)); + return; + } + + /* Is this MAC created for a MACIP? */ + if (ipa_len) + SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + } else { + const char *mac_type; + + /* When host moves but changes its (MAC,IP) + * binding, BGP may install a MACIP entry that + * corresponds to "older" location of the host + * in transient situations (because {IP1,M1} + * is a different route from {IP1,M2}). Check + * the sequence number and ignore this update + * if appropriate. + */ + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { + tmp_seq = mac->loc_seq; + mac_type = "local"; + } else { + tmp_seq = mac->rem_seq; + mac_type = "remote"; + } + if (seq < tmp_seq) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u", + vni, + prefix_mac2str(macaddr, + buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, + buf1, sizeof(buf1)) : "", + mac_type, + tmp_seq); + return; + } + } + + /* Set "auto" and "remote" forwarding info. */ + UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); + memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); + mac->fwd_info.r_vtep_ip = vtep_ip; + + if (sticky) + SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + else + UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + + if (remote_gw) + SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); + else + UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); + + zvni_process_neigh_on_remote_mac_add(zvni, mac); + + /* Install the entry. */ + zvni_mac_install(zvni, mac); + } + + /* Update seq number. */ + mac->rem_seq = seq; + + /* If there is no IP, return after clearing AUTO flag of MAC. */ + if (!ipa_len) { + UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + return; + } + + /* Check if the remote neighbor itself is unknown or has a + * change. If so, create or update and then install the entry. + */ + n = zvni_neigh_lookup(zvni, ipaddr); + if (!n + || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) + || (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) + || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip) + || ((CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0) + != router_flag) + || seq != n->rem_seq) + update_neigh = 1; + + if (update_neigh) { + if (!n) { + n = zvni_neigh_add(zvni, ipaddr, macaddr); + if (!n) { + zlog_warn( + "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s", + ipaddr2str(ipaddr, buf1, + sizeof(buf1)), + prefix_mac2str(macaddr, buf, + sizeof(buf)), + vni, inet_ntoa(vtep_ip)); + return; + } + + } else { + const char *n_type; + + /* When host moves but changes its (MAC,IP) + * binding, BGP may install a MACIP entry that + * corresponds to "older" location of the host + * in transient situations (because {IP1,M1} + * is a different route from {IP1,M2}). Check + * the sequence number and ignore this update + * if appropriate. + */ + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { + tmp_seq = n->loc_seq; + n_type = "local"; + } else { + tmp_seq = n->rem_seq; + n_type = "remote"; + } + if (seq < tmp_seq) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u", + vni, + prefix_mac2str(macaddr, + buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, + buf1, sizeof(buf1)) : "", + n_type, + tmp_seq); + return; + } + if (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) { + /* MAC change, send a delete for old + * neigh if learnt locally. + */ + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) && + IS_ZEBRA_NEIGH_ACTIVE(n)) + zvni_neigh_send_del_to_client( + zvni->vni, &n->ip, + &n->emac, 0); + + /* update neigh list for macs */ + old_mac = zvni_mac_lookup(zvni, &n->emac); + if (old_mac) { + listnode_delete(old_mac->neigh_list, n); + zvni_deref_ip2mac(zvni, old_mac, 1); + } + listnode_add_sort(mac->neigh_list, n); + memcpy(&n->emac, macaddr, ETH_ALEN); + } + } + + /* Set "remote" forwarding info. */ + UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); + n->r_vtep_ip = vtep_ip; + SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE); + + /* Set router flag (R-bit) to this Neighbor entry */ + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG)) + SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); + else + UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); + + /* Install the entry. */ + zvni_neigh_install(zvni, n); + } + + /* Update seq number. */ + n->rem_seq = seq; +} + +/* Process a remote MACIP delete from BGP. */ +static void process_remote_macip_del(vni_t vni, + struct ethaddr *macaddr, + uint16_t ipa_len, + struct ipaddr *ipaddr, + struct in_addr vtep_ip) +{ + zebra_vni_t *zvni; + zebra_mac_t *mac = NULL; + zebra_neigh_t *n = NULL; + struct interface *ifp = NULL; + struct zebra_if *zif = NULL; + char buf[ETHER_ADDR_STRLEN]; + char buf1[INET6_ADDRSTRLEN]; + + /* Locate VNI hash entry - expected to exist. */ + zvni = zvni_lookup(vni); + if (!zvni) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni); + return; + } + + ifp = zvni->vxlan_if; + if (ifp) + zif = ifp->info; + if (!ifp || + !if_is_operative(ifp) || + !zif || + !zif->brslave_info.br_if) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info", + vni); + return; + } + + /* The remote VTEP specified is normally expected to exist, but + * it is possible that the peer may delete the VTEP before deleting + * any MACs referring to the VTEP, in which case the handler (see + * remote_vtep_del) would have already deleted the MACs. + */ + if (!zvni_vtep_find(zvni, &vtep_ip)) + return; + + mac = zvni_mac_lookup(zvni, macaddr); + if (ipa_len) + n = zvni_neigh_lookup(zvni, ipaddr); + + if (n && !mac) { + zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ipaddr2str(ipaddr, buf1, sizeof(buf1)), vni); + return; + } + + /* If the remote mac or neighbor doesn't exist there is nothing + * more to do. Otherwise, uninstall the entry and then remove it. + */ + if (!mac && !n) + return; + + /* Ignore the delete if this mac is a gateway mac-ip */ + if (mac + && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) + && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) { + zlog_warn( + "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC", + vni, + prefix_mac2str(macaddr, buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, buf1, sizeof(buf1)) : ""); + return; + } + + /* Uninstall remote neighbor or MAC. */ + if (n) { + /* When the MAC changes for an IP, it is possible the + * client may update the new MAC before trying to delete the + * "old" neighbor (as these are two different MACIP routes). + * Do the delete only if the MAC matches. + */ + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) + && (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0)) { + zvni_neigh_uninstall(zvni, n); + zvni_neigh_del(zvni, n); + zvni_deref_ip2mac(zvni, mac, 1); + } + } else { + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { + zvni_process_neigh_on_remote_mac_del(zvni, mac); + + if (list_isempty(mac->neigh_list)) { + zvni_mac_uninstall(zvni, mac, 0); + zvni_mac_del(zvni, mac); + } else + SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + } + } +} + + /* Public functions */ int is_l3vni_for_prefix_routes_only(vni_t vni) @@ -4301,7 +4725,6 @@ void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json) json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } - return; } /* @@ -4360,6 +4783,7 @@ void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf, zl3vni_rmac2str(zl3vni, buf, sizeof(buf))); } else { json_object *json_vrf = NULL; + json_vrf = json_object_new_object(); json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf)); json_object_int_add(json_vrf, "vni", zl3vni->vni); @@ -4419,8 +4843,9 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, vty_out(vty, "Number of ARPs (local and remote) known for this VNI: %u\n", num_neigh); - vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", - "Type", "MAC", "Remote VTEP"); + vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n", + -wctx.addr_width, "IP", "Type", + "State", "MAC", "Remote VTEP"); } else json_object_int_add(json, "numArpNd", num_neigh); @@ -4779,7 +5204,7 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, } /* Display all global details for EVPN */ -void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj) +void zebra_vxlan_print_evpn(struct vty *vty, bool uj) { int num_l2vnis = 0; int num_l3vnis = 0; @@ -4901,7 +5326,7 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, 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; @@ -4920,7 +5345,7 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, 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)), @@ -5013,14 +5438,9 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) struct ethaddr macaddr; struct ipaddr ip; struct in_addr vtep_ip; - zebra_vni_t *zvni; - zebra_mac_t *mac; - zebra_neigh_t *n; - unsigned short l = 0, ipa_len; + uint16_t l = 0, ipa_len; char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; - struct interface *ifp = NULL; - struct zebra_if *zif = NULL; memset(&macaddr, 0, sizeof(struct ethaddr)); memset(&ip, 0, sizeof(struct ipaddr)); @@ -5033,8 +5453,6 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) /* Message contains VNI, followed by MAC followed by IP (if any) * followed by remote VTEP IP. */ - mac = NULL; - n = NULL; memset(&ip, 0, sizeof(ip)); STREAM_GETL(s, vni); STREAM_GET(&macaddr.octet, s, ETH_ALEN); @@ -5050,103 +5468,16 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s", + "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s", + vni, prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni, + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(&ip, buf1, sizeof(buf1)) : "", inet_ntoa(vtep_ip), zebra_route_string(client->proto)); - /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(vni); - if (!zvni) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Failed to locate VNI hash upon remote MACIP DEL, " - "VNI %u", - vni); - continue; - } - ifp = zvni->vxlan_if; - if (!ifp) { - zlog_warn( - "VNI %u hash %p doesn't have intf upon remote MACIP DEL", - vni, zvni); - continue; - } - zif = ifp->info; - - /* If down or not mapped to a bridge, we're done. */ - if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - continue; - - /* The remote VTEP specified is normally expected to exist, but - * it is - * possible that the peer may delete the VTEP before deleting - * any MACs - * referring to the VTEP, in which case the handler (see - * remote_vtep_del) - * would have already deleted the MACs. - */ - if (!zvni_vtep_find(zvni, &vtep_ip)) - continue; - - mac = zvni_mac_lookup(zvni, &macaddr); - if (ipa_len) - n = zvni_neigh_lookup(zvni, &ip); - - if (n && !mac) { - zlog_warn("Failed to locate MAC %s for neigh %s VNI %u", - prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni); - continue; - } - - /* If the remote mac or neighbor doesn't exist there is nothing - * more - * to do. Otherwise, uninstall the entry and then remove it. - */ - if (!mac && !n) - continue; - - /* Ignore the delete if this mac is a gateway mac-ip */ - if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) - && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) { - zlog_warn( - "%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway", - zvrf_id(zvrf), - prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni); - continue; - } - - /* Uninstall remote neighbor or MAC. */ - if (n) { - /* When the MAC changes for an IP, it is possible the - * client may - * update the new MAC before trying to delete the "old" - * neighbor - * (as these are two different MACIP routes). Do the - * delete only - * if the MAC matches. - */ - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) - && (memcmp(n->emac.octet, macaddr.octet, ETH_ALEN) - == 0)) { - zvni_neigh_uninstall(zvni, n); - zvni_neigh_del(zvni, n); - zvni_deref_ip2mac(zvni, mac, 1); - } - } else { - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { - zvni_process_neigh_on_remote_mac_del(zvni, mac); - - if (list_isempty(mac->neigh_list)) { - zvni_mac_uninstall(zvni, mac, 0); - zvni_mac_del(zvni, mac); - } else - SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - } - } + process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip); } stream_failure: @@ -5165,29 +5496,18 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) struct ethaddr macaddr; struct ipaddr ip; struct in_addr vtep_ip; - zebra_vni_t *zvni; - zebra_vtep_t *zvtep; - zebra_mac_t *mac, *old_mac; - zebra_neigh_t *n; - unsigned short l = 0, ipa_len; - int update_mac = 0, update_neigh = 0; + uint16_t l = 0, ipa_len; + uint8_t flags = 0; + uint32_t seq; char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; - uint8_t sticky = 0; - uint8_t remote_gw = 0; - uint8_t router_flag = 0; - uint8_t flags = 0; - struct interface *ifp = NULL; - struct zebra_if *zif = NULL; memset(&macaddr, 0, sizeof(struct ethaddr)); memset(&ip, 0, sizeof(struct ipaddr)); memset(&vtep_ip, 0, sizeof(struct in_addr)); if (!EVPN_ENABLED(zvrf)) { - zlog_warn( - "%s: EVPN Not turned on yet we have received a remote_macip add zapi callback", - __PRETTY_FUNCTION__); + zlog_debug("EVPN not enabled, ignoring remote MACIP ADD"); return; } @@ -5198,9 +5518,6 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) /* Message contains VNI, followed by MAC followed by IP (if any) * followed by remote VTEP IP. */ - update_mac = update_neigh = 0; - mac = NULL; - n = NULL; memset(&ip, 0, sizeof(ip)); STREAM_GETL(s, vni); STREAM_GET(&macaddr.octet, s, ETH_ALEN); @@ -5216,188 +5533,23 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) /* Get flags - sticky mac and/or gateway mac */ STREAM_GETC(s, flags); - sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY); - remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW); - router_flag = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); l++; + STREAM_GETL(s, seq); + l += 4; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s", + "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s", + vni, prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni, - inet_ntoa(vtep_ip), flags, + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(&ip, buf1, sizeof(buf1)) : "", + flags, seq, inet_ntoa(vtep_ip), zebra_route_string(client->proto)); - /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(vni); - if (!zvni) { - zlog_warn( - "Failed to locate VNI hash upon remote MACIP ADD, VNI %u", - vni); - continue; - } - ifp = zvni->vxlan_if; - if (!ifp) { - zlog_warn( - "VNI %u hash %p doesn't have intf upon remote MACIP add", - vni, zvni); - continue; - } - zif = ifp->info; - - /* If down or not mapped to a bridge, we're done. */ - if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - continue; - - /* The remote VTEP specified should normally exist, but it is - * possible - * that when peering comes up, peer may advertise MACIP routes - * before - * advertising type-3 routes. - */ - zvtep = zvni_vtep_find(zvni, &vtep_ip); - if (!zvtep) { - if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { - flog_err( - ZEBRA_ERR_VTEP_ADD_FAILED, - "Failed to add remote VTEP, VNI %u zvni %p", - vni, zvni); - continue; - } - - zvni_vtep_install(zvni, &vtep_ip); - } - - mac = zvni_mac_lookup(zvni, &macaddr); - - /* Ignore the update if the mac is already present - as a gateway mac */ - if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) - && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac", - zvrf_id(zvrf), - prefix_mac2str(&macaddr, buf, - sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), - vni); - continue; - } - - /* check if the remote MAC is unknown or has a change. - * If so, that needs to be updated first. Note that client could - * install MAC and MACIP separately or just install the latter. - */ - if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) - || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0) - != sticky - || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0) - != remote_gw - || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)) - update_mac = 1; - - if (update_mac) { - if (!mac) { - mac = zvni_mac_add(zvni, &macaddr); - if (!mac) { - zlog_warn( - "Failed to add MAC %s VNI %u Remote VTEP %s", - prefix_mac2str(&macaddr, buf, - sizeof(buf)), - vni, inet_ntoa(vtep_ip)); - return; - } - - /* Is this MAC created for a MACIP? */ - if (ipa_len) - SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - } - - /* Set "auto" and "remote" forwarding info. */ - UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); - SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); - mac->fwd_info.r_vtep_ip = vtep_ip; - - if (sticky) - SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - else - UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - - if (remote_gw) - SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); - else - UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); - - zvni_process_neigh_on_remote_mac_add(zvni, mac); - - /* Install the entry. */ - zvni_mac_install(zvni, mac); - } - - /* If there is no IP, continue - after clearing AUTO flag of - * MAC. */ - if (!ipa_len) { - UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - continue; - } - - /* Check if the remote neighbor itself is unknown or has a - * change. - * If so, create or update and then install the entry. - */ - n = zvni_neigh_lookup(zvni, &ip); - if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) - || ((CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0) - != router_flag) - || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0) - || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip)) - update_neigh = 1; - - if (update_neigh) { - if (!n) { - n = zvni_neigh_add(zvni, &ip, &macaddr); - if (!n) { - zlog_warn( - "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s", - ipaddr2str(&ip, buf1, - sizeof(buf1)), - prefix_mac2str(&macaddr, buf, - sizeof(buf)), - vni, inet_ntoa(vtep_ip)); - return; - } - - } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr)) - != 0) { - /* MAC change, update neigh list for old and new - * mac */ - old_mac = zvni_mac_lookup(zvni, &n->emac); - if (old_mac) { - listnode_delete(old_mac->neigh_list, n); - zvni_deref_ip2mac(zvni, old_mac, 1); - } - listnode_add_sort(mac->neigh_list, n); - memcpy(&n->emac, &macaddr, ETH_ALEN); - } - - /* Set "remote" forwarding info. */ - UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); - /* TODO: Handle MAC change. */ - n->r_vtep_ip = vtep_ip; - SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE); - - /* Set router flag (R-bit) to this Neighbor entry */ - if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG)) - SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); - else - UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); - - /* Install the entry. */ - zvni_neigh_install(zvni, n); - } + process_remote_macip_add(vni, &macaddr, ipa_len, &ip, + flags, seq, vtep_ip); } stream_failure: @@ -5537,13 +5689,14 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, 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; } if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u", + zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vid, zvni->vni); @@ -5556,12 +5709,12 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) return 0; - /* Remove MAC from BGP. */ - zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags); - /* Update all the neigh entries associated with this mac */ zvni_process_neigh_on_local_mac_del(zvni, mac); + /* Remove MAC from BGP. */ + zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags); + /* * If there are no neigh associated with the mac delete the mac * else mark it as AUTO for forward reference @@ -5587,8 +5740,9 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, zebra_vni_t *zvni; zebra_mac_t *mac; char buf[ETHER_ADDR_STRLEN]; - int add = 1; - uint8_t mac_sticky; + bool mac_sticky = false; + bool inform_client = false; + bool upd_neigh = false; /* We are interested in MACs only on ports or (port, VLAN) that * map to a VNI. @@ -5605,31 +5759,54 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, } 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; } - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u", - sticky ? "sticky " : "", - prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, - ifp->ifindex, vid, zvni->vni); - - /* If same entry already exists, nothing to do. */ + /* Check if we need to create or update or it is a NO-OP. */ mac = zvni_mac_lookup(zvni, macaddr); - if (mac) { - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { - mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) - ? 1 - : 0; + if (!mac) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u", + sticky ? "sticky " : "", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, vid, zvni->vni); + mac = zvni_mac_add(zvni, macaddr); + if (!mac) { + flog_err( + 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); + return -1; + } + SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); + mac->fwd_info.local.ifindex = ifp->ifindex; + mac->fwd_info.local.vid = vid; + if (sticky) + SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + inform_client = true; + + } else { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x", + sticky ? "sticky " : "", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, vid, zvni->vni, + mac->flags); + + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) + mac_sticky = true; /* - * return if nothing has changed. - * inform bgp if sticky flag has changed - * update locally and do not inform bgp if local - * parameters like interface has changed + * Update any changes and if changes are relevant to + * BGP, note it. */ if (mac_sticky == sticky && mac->fwd_info.local.ifindex == ifp->ifindex @@ -5644,61 +5821,75 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, ifp->name, ifp->ifindex, vid, zvni->vni); return 0; - } else if (mac_sticky != sticky) { - add = 1; - } else { - add = 0; /* This is an update of local - interface. */ } - } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { + if (mac_sticky != sticky) { + if (sticky) + SET_FLAG(mac->flags, + ZEBRA_MAC_STICKY); + else + UNSET_FLAG(mac->flags, + ZEBRA_MAC_STICKY); + inform_client = true; + } + + memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + mac->fwd_info.local.ifindex = ifp->ifindex; + mac->fwd_info.local.vid = vid; + + } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) || + CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) { + /* - * If we have already learned the MAC as a remote sticky - * MAC, - * this is a operator error and we must log a warning + * MAC has either moved or was "internally" created due + * to a neighbor learn and is now actually learnt. If + * it was learnt as a remote sticky MAC, this is an + * operator error. */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) { - zlog_warn( - "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d", + 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), zvni->vni); return 0; } - } - } - if (!mac) { - mac = zvni_mac_add(zvni, macaddr); - if (!mac) { - flog_err(ZEBRA_ERR_MAC_ADD_FAILED, - "Failed to add MAC %s intf %s(%u) VID %u", - prefix_mac2str(macaddr, buf, sizeof(buf)), - ifp->name, ifp->ifindex, vid); - return -1; + /* If an actual move, compute MAC's seq number */ + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) + mac->loc_seq = MAX(mac->rem_seq + 1, + mac->loc_seq); + UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); + UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); + memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + mac->fwd_info.local.ifindex = ifp->ifindex; + mac->fwd_info.local.vid = vid; + if (sticky) + SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + else + UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + /* + * We have to inform BGP of this MAC as well as process + * all neighbors. + */ + inform_client = true; + upd_neigh = true; } } - /* Set "local" forwarding info. */ - UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); - UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); - mac->fwd_info.local.ifindex = ifp->ifindex; - mac->fwd_info.local.vid = vid; - - if (sticky) - SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - else - UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - /* Inform BGP if required. */ - if (add) { - zvni_process_neigh_on_local_mac_add(zvni, mac); - return zvni_mac_send_add_to_client(zvni->vni, macaddr, - mac->flags); + if (inform_client) { + if (zvni_mac_send_add_to_client(zvni->vni, macaddr, + mac->flags, mac->loc_seq)) + return -1; } + /* Process all neighbors associated with this MAC, if required. */ + if (upd_neigh) + zvni_process_neigh_on_local_mac_change(zvni, mac, 0); + return 0; } @@ -5717,15 +5908,15 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) 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; } @@ -5756,7 +5947,7 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) 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; @@ -5801,15 +5992,15 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) 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; } @@ -5831,7 +6022,7 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) 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; @@ -5840,7 +6031,7 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) 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; @@ -5858,9 +6049,9 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) 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; } @@ -5911,8 +6102,8 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, 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; } @@ -5959,8 +6150,8 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, 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; } @@ -6056,7 +6247,7 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) 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; @@ -6119,7 +6310,7 @@ int zebra_vxlan_if_down(struct interface *ifp) /* 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; @@ -6185,7 +6376,7 @@ int zebra_vxlan_if_up(struct interface *ifp) /* 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; @@ -6256,7 +6447,7 @@ int zebra_vxlan_if_del(struct interface *ifp) /* 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; @@ -6279,9 +6470,9 @@ int zebra_vxlan_if_del(struct interface *ifp) /* 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; } } @@ -6367,7 +6558,7 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) /* 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; @@ -6496,7 +6687,7 @@ int zebra_vxlan_if_add(struct interface *ifp) 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; @@ -6699,8 +6890,8 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS) 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; } @@ -6762,8 +6953,8 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS) 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; } @@ -6867,7 +7058,8 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) 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; } diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 6b2b57371c..5097757b1d 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -69,7 +69,7 @@ extern int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf); extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf); extern void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni, struct ipaddr *ip, bool uj); -extern void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj); +extern void zebra_vxlan_print_evpn(struct vty *vty, bool uj); extern void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni, struct ethaddr *rmac, bool use_json); diff --git a/zebra/zebra_vxlan_null.c b/zebra/zebra_vxlan_null.c index afc59774c9..00c849a3d0 100644 --- a/zebra/zebra_vxlan_null.c +++ b/zebra/zebra_vxlan_null.c @@ -83,7 +83,7 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf) { } -void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj) +void zebra_vxlan_print_evpn(struct vty *vty, bool uj) { } diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index e86967041b..44163eb331 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -260,6 +260,10 @@ struct zebra_mac_t_ { struct in_addr r_vtep_ip; } fwd_info; + /* Mobility sequence numbers associated with this entry. */ + uint32_t rem_seq; + uint32_t loc_seq; + /* List of neigh associated with this mac */ struct list *neigh_list; @@ -338,6 +342,16 @@ struct zebra_neigh_t_ { /* Remote VTEP IP - applicable only for remote neighbors. */ struct in_addr r_vtep_ip; + /* + * Mobility sequence numbers associated with this entry. The rem_seq + * represents the sequence number from the client (BGP) for the most + * recent add or update of this entry while the loc_seq represents + * the sequence number informed (or to be informed) by zebra to BGP + * for this entry. + */ + uint32_t rem_seq; + uint32_t loc_seq; + /* list of hosts pointing to this remote NH entry */ struct host_rb_tree_entry host_rb; }; diff --git a/zebra/zserv.c b/zebra/zserv.c index 4a341bfe1b..2f4bb22ffe 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -61,6 +61,7 @@ #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 */ @@ -171,7 +172,8 @@ static void zserv_log_message(const char *errmsg, struct stream *msg, */ 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, @@ -270,7 +272,8 @@ static int zserv_write(struct thread *thread) 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; @@ -741,8 +744,8 @@ static int zserv_accept(struct thread *thread) 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; } @@ -772,10 +775,8 @@ void zserv_start(char *path) /* 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; } @@ -797,10 +798,8 @@ void zserv_start(char *path) 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; @@ -808,10 +807,9 @@ void zserv_start(char *path) 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; |
