diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2018-09-12 21:58:39 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2018-09-12 21:58:39 +0200 |
commit | e991eff5b5773e8a85c3f4c4f92c09fe30cf680b (patch) | |
tree | ab98bf44cfc7611ad7cc699396674554f150db43 | |
parent | zebra: fix includes (diff) | |
parent | Merge pull request #3005 from patrasar/indentation_warnings (diff) | |
download | frr-e991eff5b5773e8a85c3f4c4f92c09fe30cf680b.tar.xz frr-e991eff5b5773e8a85c3f4c4f92c09fe30cf680b.zip |
Merge remote-tracking branch 'frr/master' into warnings
Conflicts:
zebra/if_ioctl_solaris.c
zebra/rtread_getmsg.c
Signed-off-by: David Lamparter <equinox@diac24.net>
245 files changed, 6961 insertions, 7477 deletions
diff --git a/.gitignore b/.gitignore index c5fd0ced9..8c62f0553 100644 --- a/.gitignore +++ b/.gitignore @@ -1,87 +1,87 @@ -compile -config.log -config.h -config.cache -config.status -config.guess -config.sub -ltmain.sh -stamp-h -stamp-h[0-9]* +### autoconf/automake root stuff + +/compile +/config.log +/config.h +/config.cache +/config.status +/config.guess +/config.sub +/ltmain.sh +/stamp-h +/stamp-h[0-9]* *-stamp -Makefile -INSTALL +/INSTALL +/depcomp +/missing +/install-sh +/mkinstalldirs +/ylwrap +/autom4te*.cache +/configure.lineno +/configure +/config.h.in +/confdefs.h +/conftest +/conftest.err +/aclocal.m4 +/libtool + +/Makefile +/Makefile.in + +### autoconf/automake subdir stuff + .deps -depcomp -missing -install-sh -mkinstalldirs -ylwrap -autom4te*.cache -configure.lineno -configure -config.h.in -confdefs.h -conftest -conftest.err -aclocal.m4 -Makefile.in -*.tar.gz -*.tar.gz.asc +.libs + +### build outputs + +*.o +*.lo +*.a +*.la +*.so +*.loT +*.pb.h +*.pb-c.h +*.pb-c.c +*_clippy.c + +### dist + *.tar.?z +*.tar.?z.asc +*.tar.asc +*.deb +*.ddeb +*.dsc +*.changes + +### other garbage + .nfs* -libtool -.libs .arch-inventory .arch-ids {arch} build +.cache .msg .rebase-* *~ -*.o -*.loT -m4/*.m4 -!m4/ax_sys_weak_alias.m4 -!m4/ax_compare_version.m4 -!m4/ax_prog_perl_modules.m4 -!m4/pkg.m4 -debian/autoreconf.after -debian/autoreconf.before -debian/files -debian/frr-dbg.debhelper.log -debian/frr-dbg.substvars -debian/frr-dbg/ -debian/frr-doc.debhelper.log -debian/frr-doc.substvars -debian/frr-doc/ -debian/frr.debhelper.log -debian/frr.postinst.debhelper -debian/frr.postrm.debhelper -debian/frr.prerm.debhelper -debian/frr.substvars -debian/frr/ -debian/tmp/ -*.deb -*.ddeb -*.dsc -*.changes -*.pyc +*.bak *.swp +*.pyc +__pycache__ +*.patch +*.diff cscope.* -*.pb.h -*.pb-c.h -*.pb-c.c TAGS tags GTAGS GSYMS GRTAGS GPATH -*.la -*.lo compile_commands.json .dirstamp - -# clippy generated source -*_clippy.c +refix diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 61867a860..000000000 --- a/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -Kunihiro Ishiguro <kunihiro@zebra.org> -Toshiaki Takada <takada@zebra.org> -Yasuhiro Ohara <yasu@sfc.wide.ad.jp> -Alex D. Zinin <azinin@hotmail.com> -Gleb Natapov <gleb@nbase.co.il> -Akihiro Mizutani <mizutani@dml.com> diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index ec7e6cdde..000000000 --- a/ChangeLog +++ /dev/null @@ -1,4 +0,0 @@ -ChangeLog information for FRRouting is for now recorded in source-code -management system. Please see: - - http://www.frrouting.org/ diff --git a/Makefile.am b/Makefile.am index b9003b835..fb052a8de 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,19 @@ ## Process this file with automake to produce Makefile.in. AUTOMAKE_OPTIONS = subdir-objects 1.12 -include common.am +ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \ - -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib +AM_CFLAGS = \ + $(SAN_FLAGS) \ + $(WERROR) \ + # end +AM_CPPFLAGS = \ + -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \ + -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib +AM_LDFLAGS = \ + -export-dynamic \ + $(SAN_FLAGS) \ + # end DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE) LIBCAP = @LIBCAP@ @@ -83,6 +92,7 @@ pkginclude_HEADERS = nodist_pkginclude_HEADERS = dist_examples_DATA = man_MANS = +vtysh_scan = ## libtool, the self-made GNU scourge ## ... this should fix relinking @@ -106,6 +116,9 @@ include tools/subdir.am include debianpkg/subdir.am include solaris/subdir.am +include bgpd/subdir.am +include bgpd/rfp-example/librfp/subdir.am +include bgpd/rfp-example/rfptest/subdir.am include ripd/subdir.am include ripngd/subdir.am include ospfd/subdir.am @@ -122,16 +135,8 @@ include pbrd/subdir.am include staticd/subdir.am include bfdd/subdir.am -SUBDIRS = . @LIBRFP@ @RFPTEST@ \ - @BGPD@ \ - @VTYSH@ \ - tests - -DIST_SUBDIRS = . bgpd \ - vtysh tests \ - bgpd/rfp-example/librfp \ - bgpd/rfp-example/rfptest \ - # end +include vtysh/subdir.am +include tests/subdir.am if PKGSRC rcdir=@pkgsrcrcdir@ @@ -147,6 +152,7 @@ endif EXTRA_DIST += \ aclocal.m4 \ + README.md \ m4/README.txt \ \ python/clidef.py \ @@ -169,17 +175,37 @@ EXTRA_DIST += \ snapcraft/helpers \ snapcraft/snap \ \ - vtysh/Makefile.am \ - vtysh/Makefile.in \ - \ + babeld/Makefile \ + bgpd/Makefile \ + bgpd/rfp-example/librfp/Makefile \ + bgpd/rfp-example/rfptest/Makefile \ doc/Makefile \ doc/developer/Makefile \ doc/manpages/Makefile \ doc/user/Makefile \ + eigrpd/Makefile \ + fpm/Makefile \ + isisd/Makefile \ + ldpd/Makefile \ + lib/Makefile \ + nhrpd/Makefile \ + ospf6d/Makefile \ + ospfclient/Makefile \ + ospfd/Makefile \ + pbrd/Makefile \ + pimd/Makefile \ + ports/Makefile \ + qpb/Makefile \ + ripd/Makefile \ + ripngd/Makefile \ + staticd/Makefile \ + tests/Makefile \ + tools/Makefile \ + vtysh/Makefile \ + watchfrr/Makefile \ + zebra/Makefile \ # end -ACLOCAL_AMFLAGS = -I m4 - noinst_HEADERS += defaults.h indent: @@ -1,2574 +0,0 @@ -Note: this file lists major user-visible changes only. - -* Changes in Quagga 0.99.24 - -User-visible changes: -- [pimd] New daemon: pimd provides IPv4 PIM-SSM multicast routing. -- [bgpd] New feature: "next-hop-self all" to override nexthop on iBGP route - reflector setups. -- [bgpd] route-maps have a new action "set ipv6 next-hop peer-address" -- [bgpd] route-maps have a new action "set as-path prepend last-as" -- [bgpd] Update validity checking (particularly MP-BGP / IPv6 routes) was - touched up significantly. Please report possible bugs. -- [ripd] New feature: RIP for IPv4 now supports equal-cost multipath (ECMP) -- [zebra] Multicast RIB support has been extended. It still is IPv4 only. -- [zebra] "no link-detect" is now printed in configurations since it won't - be the default anymore soon. To retain current behaviour, re-save your - configuration after updating to 0.99.24. - -Distributor-visible changes: -- --enable-pimd is added to enable pimd. It is considered experimental, though - unless the distribution target is embedded systems with little flash, there - is no reason to not include it in packages. -- --disable-ipv6 no longer exists as an option. It's 2015, your C library - really needs to have IPv6 support by now. -- --disable-netlink no longer exists as an option. It didn't work anyway. -- --disable-solaris no longer exists as an option. It only controlled some - init scripts. -- --enable-isisd is now the default. -- mrlg.cgi is no longer included (it was severely outdated). It can be found - independently at http://mrlg.op-sec.us/ -- build on Linux with the musl C library should now work - -* Changes in Quagga 0.99.23 - -Known issues: -- [bgpd] setting an extcommunity in a route map on a route that already has - an extcommunity attribute will cause bgpd to crash. This issue will be - fixed in a followup minor release. - -User-visible changes: -- [lib] Performance enhancements on hashes and timers. -- [bgpd] New feature: iBGP TTL security. -- [bgpd] New feature: relaxed bestpath criteria for multipath and improved - display of multipath routes in "show ip bgp". Scripts parsing this output - may need to be updated. -- [bgpd] Multiprotocol peerings over IPv6 now try to find a more appropriate - IPv4 nexthop by looking at the interface. -- [ospf6d] A large amount of changes has been merged for ospf6d. Careful - evaluation prior to deployment is recommended. -- [zebra] Recursive route support has been overhauled. Scripts parsing - "show ip route" output may need adaptation. -- [zebra] IPv6 address management has been improved regarding tentative - addresses. This is visible in that a freshly configured address will not - immediately be marked as usable. -- [*] a lot of bugs have been fixed, please refer to the git log - -* Changes in Quagga 0.99.22 - -- [bgpd] The semantics of default-originate route-map have changed. - The route-map is now used to advertise the default route conditionally. - The old behaviour which allowed to set attributes on the originated - default route is no longer supported. -- [bgpd] There is now a replace-as option to neighbor ... local-as ... - no-prepend. For details, refer to the user documentation. -- [zebra] An FPM interface has been added. This provides an alternate - interface to routing information and is geared at OpenFlow & co. -- [snmp] AgentX is now supported; the old smux backend is considered - deprecated. ospf6d has also had OSPFV3-MIB added. -- [*] several issues with configuration save/load/apply have been fixed, - in particular on ospf "max-metric router-lsa administrative" and - "distribute-list", bgpd "no neighbor activate", isisd "metric-style", -- [*] a lot of bugs have been fixed, please refer to the git log - -* Changes in Quagga 0.99.21 - -- [bgpd] BGP multipath support has been merged -- [bgpd] SAFI (Multicast topology) support has been extended to propagate - the topology to zebra. -- [bgpd] AS path limit functionality has been removed -- [babeld] a new routing daemon implementing the BABEL ad-hoc mesh routing - protocol has been merged. -- [isisd] a major overhaul has been picked up. Please note that isisd is - STILL NOT SUITABLE FOR PRODUCTION USE. -- [*] a lot of bugs have been fixed, please refer to the git log - -* Changes in Quagga 0.99.10 - -- [bgpd] 4-byte AS support added -- [bgpd] MRT format changes to version 2. Those relying on - bgpd MRT table dumps may need to update their tools. -- [bgpd] Added new route-map set statement: "as-path exclude" -- Zebra RIB updates queue has evolved into a multi-level - structure to address RIB consistency issues. - -* Changes in Quagga 0.99.2 - -- [bgpd] Work queues added to bgpd to split up update processing, - particularly beneficial when a peer session goes down. AS_PATH - parsing rewritten to be clearer, more robust and ready for 4-byte. - -- [ripd] Simple authentication is no longer the default authentication - mode for ripd. The default is now no-authentication. Any setups which - used simple authentication will probably need to update their - configuration manually. - -- [ospfd] 1s dead-interval with sub-second Hellos feature added. - SPF timers now specified in milliseconds, and with adaptive - hold-time support. RFC3137 Stub-router support added. Default ABR - type is now 'cisco'. - -- Solaris least privileges support added. - -* Changes in Quagga 0.99.1 - -- Zserv is now buffered via threads and non-blocking in most cases for both - clients and zebra, which should improve responsiveness of daemons when - they must send many messages to zebra. - -- 'show thread cpu' now displays both cpu+system and wall-clock time, - where getrusage() is available. - -- Background threads added and workqueue API added, with a - 'show work-queues' command. Thread scheduling improved slightly. - -- Zebra now has a work-queue for RIB processing. See 'show work-queues' in - the zebra daemon vty. - -- Support for interface renaming on Linux netlink systems. - -- GNU Zebra bgpd merges, including BGP Graceful-restart and "match ip - route-source" command. - -- Automatic logging of backtraces should daemons crash to assist in - diagnosis. See the documentation for more information on configuring - logging correctly, and set --enable-gcc-rdynamic if compiling with gcc. - -* Changes in Quagga 0.98.0 - -- Logging facilities upgraded. One can now specify a severity level - for each logging destination. And a new "show logging" command gives - thorough information on the current logging system configuration. - -- Watchquagga daemon added. This is not well tested yet. Please try - monitor mode first before enabling restart features. It is important - to make sure that the various timers are configured with appropriate - values for your site. - -- BGP route-server support added. See the texinfo documentation. - -- OSPF API initialisation is disabled by default even if compiled in. You - can enable it with -a/--apiserver command line switch. - -- "write-config integrated" vtysh command replaced with "service - integrated-vtysh-config" command. - -- Router id is now handled by zebra daemon and all daemons receive changes - from it. Router id can be overriden in daemons' configurations of course. - To fix common router id in zebra daemon you can either install non-127 - address on loopback or use "router-id x.x.x.x" command. - -- "secondary" keyword is removed from ip address configuration. All - supported OS'es have their own vision what's secondary address and - how to handle it. - -- Zebra no longer enables forwarding by default. If you rely on zebra to - enable forwarding make sure to add '<ip|ip6> forwarding' statements - to your zebra configuration file. - -- All libraries are built and used shared, on platforms where libtool - supports shared libraries. - -- Router advertisement syntax is changed. In usual cases (if you didn't do - any fancy stuff) it's enough to change lines in configuration from: - "ipv6 nd prefix-advertisement X:X:X:X::/X 2592000 604800 autoconfig on-link" - to: - "ipv6 nd prefix X:X:X:X::/X" - - All router advertisement options are documented in texi documentation. - -- --enable-nssa configure switch is removed. NSSA support is stable enough. - -- Daemons don't look at current directory for config file any more. - -* Changes in Quagga 0.96.5 - -- include files are installed in $(prefix)/include/quagga. Programs - building against these includes should -I$(prefix)/include and e.g. - #include <quagga/routemap.h> - -- New option --enable-exampledir puts example files in a separate - directory from $(sysconfdir), easing NetBSD pkgsrc hierarchy rules - compliance. - -- New configure options --enable-configfile-mask and - --enable-logfile-mask to set umask values for config and log - values. Masks default to 0600, matching previous behavior. - -- Import current CVS isisd from SourceForge, then merge it with - the Quagga's Framework. - -* Changes in Quagga 0.96.4 - -- Further fixes to ospfd, some relating to the PtP revert. Interface -lookups should be a lot more robust now. - -- Fix for a remote triggerable crash in vty layer. - -- Improvements to ripd, and addition of split horizon support. - -- Improved bgpd table support, now dumps at time of day intervals rather -than time from startup intervals. Much improved support for IPv6 table -dumps. show commands for views improved. - -* Changes in Quagga 0.96.3 - -- revert the 'generic PtP' patch. Means Quagga will no longer work with -FreeSWAN, however, on the plus side this gets rid of a lot of niggly bugs -which the PtP patch introduced. - -* Changes in Quagga 0.96.2 - -- Fix crash in ospfd - -* Changes in Quagga 0.96.1 - -- Iron out problem with the privileges definitions - -* Changes in Quagga 0.96 - -- Privilege support, daemons now run with the minimal privileges needed, see - the documentation for details. - -- NSSA ABR support in ospfd. - -- OSPF-API support merged in. - -- 6WIND patch merged in. - -* Changes in zebra-0.93 - -* Changes in bgpd - -** Configuration is changed to new format. - -* Changes in ospfd - -** Crush bugs which reported on Zebra ML is fixed. - -** Opaque LSA and TE LSA support is added by KDD R&D Laboratories, - Inc. - -* Chages in ospf6d - -** Many bugs are fixed. - -* Changes in zebra-0.92a - -* Changes in bgpd - -** Fix "^$" community list bug. - -** Below command's Address Family specific configurations are added - - nexthop-self - route-reflector-client - route-server-client - soft-reconfiguration inbound - -* Changes in zebra - -** Treat kernel type routes as EGP routes. - -* Changes in zebra-0.92 - -** Overall security is improved. Default umask is 0077. - -* Changes in ripd - -** If output interface is in simple password authentication mode, -substruct one from rtemax. - -* Changes in bgpd - -** IPv4 multicast and IPv6 unicast configuration is changed to so -called new config. All of AFI and SAFI specific configuration is -moved to "address-family" node. When you have many IPv6 only -configuration, you will see many "no neighbor X:X::X:X activate" line -in your configuration to disable IPv4 unicast NLRI exchange. In that -case please use "no bgp default ipv4-unicast" command to suppress the -output. Until zebra-0.93, old config is still left for compatibility. - -Old config -========== -router bgp 7675 - bgp router-id 10.0.0.1 - redistribute connected - network 192.168.0.0/24 - neighbor 10.0.0.2 remote-as 7675 - ipv6 bgp network 3ffe:506::/33 - ipv6 bgp network 3ffe:1800:e800::/40 - ipv6 bgp aggregate-address 3ffe:506::/32 - ipv6 bgp redistribute connected - ipv6 bgp neighbor 3ffe:506:1000::2 remote-as 1 - -New config -========== -router bgp 7675 - bgp router-id 10.0.0.1 - network 192.168.0.0/24 - redistribute connected - neighbor 10.0.0.2 remote-as 7675 - neighbor 3ffe:506:1000::2 remote-as 1 - no neighbor 3ffe:506:1000::2 activate -! - address-family ipv6 - network 3ffe:506::/33 - network 3ffe:1800:e800::/40 - aggregate-address 3ffe:506::/32 - redistribute connected - neighbor 3ffe:506:1000::2 activate - exit-address-family - -* Changes in ospfd - -** Internal interface treatment is changed. Now ospfd can handle -multiple IP address for an interface. - -** Redistribution of loopback interface's address works fine. - -* Changes in zebra-0.91 - -** --enable-oldrib configure option is removed. - -** HAVE_IF_PSEUDO part is removed. Same feature is now supported by -default. - -* Changes in ripd - -** When redistributed route is withdrawn, perform poisoned reverse. - -* Changes in zebra - -** When interface's address is removed, kernel route pointing out to -the address is removed. - -** IPv6 RIB is now based upon new RIB code. - -** zebra can handle same connected route to one interface. - -** New command for interface address. Currently this commands are -only supported on GNU/Linux with netlink interface. - -"ip address A.B.C.D secondary" -"ip address A.B.C.D label LABEL" - -* Changes in bgpd - -** BGP flap dampening bugs are fixed. - -** BGP non-blocking TCP connection bug is fixed. - -** "show ip bgp summary" shows AS path and community entry number. - -** New commands have been added. - "show ip bgp cidr-only" - "show ip bgp ipv4 (unicast|multicast) cidr-only" - "show ip bgp A.B.C.D/M longer-prefixes" - "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M longer-prefixes" - "show ipv6 bgp X:X::X:X/M longer-prefixes" - "show ipv6 mbgp X:X::X:X/M longer-prefixes" - -** IPv6 IBGP nexthop change is monitored. - -** Unknown transitive attribute is passed with partial flag bit on. - -* Changes in ospfd - -** Fix bug of LSA MaxAge flood. - -** Fix bug of NSSA codes. - -* Changes in zebra-0.90 - -** From this beta release, --enable-unixdomain and --enable-newrib -becomes default. So both options are removed from configure.in. To -revert old behavior please specify below option. - ---enable-tcp-zebra # TCP/IP socket is used for protocol daemon and zebra. ---enable-oldrib # Turn on old RIB implementation. - -Old RIB implementation will be removed in zebra-0.91. - -** From this beta release --enable-multipath is supported. This -option is only effective on GNU/Linux kernel with -CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_ROUTE_MULTIPATH is set. - ---enable-multipath=ARG # ARG must be digit. When ARG is 0 unlimit multipath number. - -** From this release we do not include guile files. - -* Changes in lib - -** newlist.[ch] is merged with linklist.[ch]. - -** Now Zebra works on MacOS X public beta. - -** Access-list can have remark. "access-list WORD remark LINE" define -remark for specified access-list. - -** Key of key-chain is sorted by it's idetifier value. - -** prefix-list rule is slightly changed. The rule of "len <= ge-value -<= le-value" is changed to "len < ge-value <= le-value". - -** According to above prefix-list rule change, add automatic -conversion function of an old rule. ex.) 10.0.0.0/8 ge 8 -> 10.0.0.0/8 -le 32 - -** SMUX can handle SNMP trap. - -** In our event library, event thread is executed before any other -thread like timer, read and write event. - -** Robust method for writing configuration file and recover from -backing up config file. - -** Display "end" at the end of configuration. - -** Fix memory leak in vtysh_read(). - -** Fix memroy leak about access-list and prefix-list name. - -* Changes in zebra - -** UNIX domain socket server of zebra protocol is added. - -** Fix PointoPoint interface network bug. The destination network -should be installed into routing table instead of local network. - -** Metric value is reflected to kernel routing table. - -** "show ip route" display uptime of RIP,OSPF,BGP routes. - -** New RIB implementation is added. - -Now we have enhanced RIB (routing information base) implementation in -zebra. New RIB has many new features and fixed some bugs which exist -in old RIB code. - -*** Static route with distance value - - Static route can be specified with administrative distance. The - distance value 255 means it is not installed into the kernel. - Default value of distance for static route is 1. - - ip route A.B.C.D/M A.B.C.D <1-255> - ip route A.B.C.D/M IFNAME <1-255> - - If the least distance value's route's nexthop are unreachable, - select the least distance value route which has reachable nexthop is - selected. - - ip route 0.0.0.0/0 10.0.0.1 - ip route 0.0.0.0/0 11.0.0.1 2 - - In this case, when 10.0.0.1 is unreachable and 11.0.0.1 is - reachable. The route with nexthop 11.0.0.1 will be installed into - forwarding table. - - zebra> show ip route - S>* 0.0.0.0/0 [2/0] via 11.0.0.1 - S 0.0.0.0/0 [1/0] via 10.0.0.1 inactive - - If the nexthop is unreachable "inactive" is displayed. You can - specify any string to IFNAME. There is no need of the interface is - there when you configure the route. - - ip route 1.1.1.1/32 ppp0 - - When ppp0 comes up, the route is installed properly. - -*** Multiple nexthop routes for one prefix - - Multiple nexthop routes can be specified for one prefix. Even the - kernel support only one nexthop for one prefix user can configure - multiple nexthop. - - When you configure routes like below, prefix 10.0.0.1 has three - nexthop. - - ip route 10.0.0.1/32 10.0.0.2 - ip route 10.0.0.1/32 10.0.0.3 - ip route 10.0.0.1/32 eth0 - - If there is no route to 10.0.0.2 and 10.0.0.3. And interface eth0 - is reachable, then the last route is installed into the kernel. - - zebra> show ip route - S> 10.0.0.1/32 [1/0] via 10.0.0.2 inactive - via 10.0.0.3 inactive - * is directly connected, eth0 - - '*' means this nexthop is installed into the kernel. - -*** Multipath (more than one nexthop for one prefix) can be installed into the kernel. - - When the kernel support multipath, zebra can install multipath - routes into the kernel. Before doing that please make it sure that - setting --enable-multipath=ARG to configure script. ARG must be digit - value. When specify 0 to ARG, there is no limitation of the number - of the multipath. Currently only GNU/Linux with netlink interface is - supported. - - ip route 10.0.0.1/32 10.0.0.2 - ip route 10.0.0.1/32 10.0.0.3 - ip route 10.0.0.1/32 eth0 - - zebra> show ip route - S>* 10.0.0.1/32 [1/0] via 10.0.0.2 - * via 10.0.0.3 - is directly connected, eth0 - -*** Kernel message delete installed route. - - After zebra install static or dynamic route into the kernel. - - R>* 0.0.0.0/0 [120/3] via 10.0.0.1 - - If you delete this route outside zebra, old zebra does not reinstall - route again. Now the route is re-processed and properly reinstall the - static or dynamic route into the kernel. - -** GNU/Linux netlink socket handling is improved to fix race condition -between kernel message and user command responce. - -* Changes in bgpd - -** Add show neighbor's routes command. - - "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes" - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) routes" - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) routes" - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) routes" - -** BGP passive peer support problem is fixed. - -** Redistributed IGP nexthop is passed to BGP nexthop. - -** On multiaccess media, if the nexthop is reachable nexthop is passed -as it is. - -** Remove zebra-0.88 compatibility commands. - - "match ip prefix-list WORD" - "match ipv6 prefix-list WORD" - - Instead of above please use below commands. - - "match ip address prefix-list WORD" - "match ipv6 address prefix-list WORD" - -** Fix bug of holdtimer is not reset when bgp cleared. - -** "show ip bgp summary" display peer establish/drop count. - -** Change "match ip next-hop" argument from IP address to access-list -name. - -** When "bgp enforce-first-as" is enabled, check EBGP peer's update -has it's AS number in the first AS number in AS sequence. - -** New route-map command "set community-delete COMMUNITY-LIST" is -added. Community matched the CoMMUNITY-LIST is removed from the -community. - -** BGP-MIB implementation is finished. - -** When BGP connection comes from unconfigured IP address, close -socket immediately. - -** Do not compare router ID when the routes comes from EBGP peer. -When originator ID is same, take shorter cluster-list route. If -cluster-list is same take smaller IP address neighbor's route. - -** Add "bgp bestpath as-path ignore" command. When this option is -set, do not concider AS path length when route selection. - -** Add "bgp bestpath compare-routerid". When this option is set, -compare router ID when the routes comes from EBGP peer. - -** Add "bgp deterministic-med" process. - -** BGP flap dampening feature is added. - -** When IBGP nexthop is changed, it is reflected to RIB. - -** Change "neighbor route-refresh" command to "neighbor capability -route-refresh". - -* Changes in ripd - -** Change "match ip next-hop" argument from IP address to access-list -name. - -** "no ip rip (send|receive)" command accept version number argument. - -** Memory leak related classfull network generation is fixed. - -** When a route is in garbage collection process (invalid with metric -16) and a router receives the same route with valid metric then route -was not installed into zebra rib, but only into ripd rib. Moreover , -it will never get into zebra rib, because ripd wrongly assumes it's -already there. - -* Change in ospfd - -** Fix bug of refreshing default route. - -** --enable-nssa turn on undergoing NSSA feature. - -** Fix bug of Hello packet's option is not properly set when interface -comes up. - -** Reduce unconditional logging. - -** Add nexthop to OSPF path only when it is not there. - -** When there is no DR on network (suppose you have only one router -with interface priority 0). It's router LSA does not contain the link -information about this network. - -** When you change a priority of interface from/to 0 -ISM_NeighborChange event should be scheduled in order to elect new -DR/BDR on the network. - -** When we add some LSA into retransmit list we need to check whether -the present old LSA in retransmit list is not more recent than the new -one. - -** In states Loading and Full the slave must resend its last Database -Description packet in response to duplicate Database Description -packets received from the master. For this reason the slave must wait -RouterDeadInterval seconds before freeing the last Database -Description packet. Reception of a Database Description packet from -the master after this interval will generate a SeqNumberMismatch -neighbor event. RFC2328 Section 10.8 - -** Virtual link can not configured in stub area. - -** Clear a ls_upd_queue queue of the interface when interface goes -down. - -** "no router ospf" unregister redistribution requests from zebra. - -** New command for virtual-link configuration is added. - - "area A.B.C.D virtual-link A.B.C.D" - "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535>" - "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535> authentication-key AUTH_KEY" - "area A.B.C.D virtual-link A.B.C.D authentication-key AUTH_KEY" - "area A.B.C.D virtual-link A.B.C.D hello-interval <1-65535> retransmit-interval <3-65535> transmit-delay <1-65535> dead-interval <1-65535> message-digest-key <1-255> md5 KEY" - "area A.B.C.D virtual-link A.B.C.D message-digest-key <1-255> md5 KEY" - -** Clear cryptographic sequence number when neighbor status is changed -to NSM down. - -** Make Summary LSA's origination and refreshment as same as other -type of LSA. - -** New OSPF pakcet read method. Now maximum packet length may be 65535 -bytes (maximum IP packet length). - -** Checking the age of the found LSA and if the LSA is MAXAGE we -should call refresh instead of originate. - -** Install multipath information to zebra. - -** Fix socket descriptor leak when system call failed. - -* Changes in ospf6d - -** Whole functionality has been rewritten as new code. new command -"show ipv6 ospf6 spf node", "show ipv6 ospf6 spf tree", "show ipv6 -ospf6 spf table" has been added. - -** Change to do not send garbage route whose nexthop is not linklocal -address. - -** "redistribute ospf6" was generated in "router ospf6" in config -file. It is fixed. - -** LSDB sync bug is fixed. - -** Fix bug of using unavailable route. - -* Changes in vtysh - -** route-map and access-list configuration is merged into one -configuration. - -** /usr/local/etc/Zebra.conf is integrated configuration file. "write -memory" in vtysh will write whole configuration to this file. - -** When -b option is specified to vtysh, vtysh read -/usr/local/etc/Zebra.conf file then pass the confuguration to proper -protocol daemon. So make all protocol daemon's configuration file -empty then invoke all daemon. After that vtysh -b will setup saved -configuration. - -zebrastart.sh -============= -/usr/local/sbin/zebra -d -/usr/local/sbin/ripd -d -/usr/local/sbin/ospfd -d -/usr/local/sbin/bgpd -d -/usr/local/bin/vtysh -b - -* Changes in zebra-0.89 - -* Changes in lib - -** distribute-list can set all interface's access-list and prefix-list -configuration. - -* Changes in ripd - -** "show ip protocols" display proper distribute-list settings and -distance settings. - -** When metric infinity route received withdraw the route from kernel -immediately it used to be wait garbage collection. - -** key-chain can be used for simple password authentication. - -** RIPv2 MIB getnext interface bug is fixed. - -* Changes in vtysh - -** --with-libpam enable PAM authentication for vtysh. - -** Now vtysh read vtysh.conf. This file should be -${SYSCONFDIR}/etc/vtysh.conf for security reason. Usually it is -/usr/local/etc/vtysh.conf. - -** "username WORD nopassword" command is added to vtysh. - -* Chagees in ospfd - -** NBMA interface support is added. - -** OSPF area is sorted by area ID. - -** New implementation of OSPF refreesh. - -** OSPF-MIB read function is partly added. - -* Changes in bgpd - -** When the peering is done by ebgp-multihop, nexthop is looked up -like IBGP routes. - -** "show ip mbgp" commands are changed to "show ip bgp ipv4 -multicast". - -** New terminal commands are added. - "show ip bgp ipv4 (unicast|multicast) filter-list WORD" - "show ip bgp ipv4 (unicast|multicast) community" - "show ip bgp ipv4 (unicast|multicast) community-list WORD" - "show ip bgp ipv4 (unicast|multicast) community-list WORD exact-match" - -** MBGP soft-reconfiguration command is added. - "clear ip bgp x.x.x.x ipv4 (unicast|multicast) in" - "clear ip bgp x.x.x.x ipv4 (unicast|multicast) out" - "clear ip bgp x.x.x.x ipv4 (unicast|multicast) soft" - "clear ip bgp <1-65535> ipv4 (unicast|multicast) in" - "clear ip bgp <1-65535> ipv4 (unicast|multicast) out" - "clear ip bgp <1-65535> ipv4 (unicast|multicast) soft" - "clear ip bgp * ipv4 (unicast|multicast) in" - "clear ip bgp * ipv4 (unicast|multicast) out" - "clear ip bgp * ipv4 (unicast|multicast) soft" - -** MED related commands are added. - "bgp deterministic-med" - "bgp bestpath med confed" - "bgp bestpath med missing-as-worst" - -** "bgp default local-preference" command is added. - -** BGP confederation peer's routes are passed to zebra like IBGP route. - -** Community match command is added. - "show ip bgp community <val>" - "show ip bgp community <val> exact-match" - -** EBGP multihop route treatment bug is fixed. Now nexthop is -resolved by IGP routes. - -** Some commands are added to show routes by filter-list and community -value. - "show ip bgp ipv4 (unicast|multicast) filter-list WORD" - "show ip bgp ipv4 (unicast|multicast) community" - "show ip bgp ipv4 (unicast|multicast) community-list WORD" - "show ip bgp ipv4 (unicast|multicast) community-list WORD exact-match" - -* Changes in zebra - -** zebra read interface's address information using getifaddrs() when -it is available. - -** Reflect IPv6 interface's address change to protocol daemons. - -* Changes in zebra-0.88 - -* Changes in lib - -** "exact-match" option is added to "access-list" and "ipv6 -access-list" command. If this option is specified, the prefix and -prefix length is compared as exact match mode. - -* Changes in zebra - -** New Zebra message ZEBRA_REDISTRIBUTE_DEFAULT_ADD and -ZEBRA_REDISTRIBUTE_DEFAULT_DELTE are added. - -** Default administrative distance value is changed. - - Old New ------------------------------------------- -system 10 0 -kernel 20 0 -connected 30 0 -static 40 1 -rip 50 120 -ripng 50 120 -ospf 60 110 -ospf6 49 110 -bgp 70 200(iBGP) 20(eBGP) ------------------------------------------- - -** Distance value can be passed from protocol daemon to zebra. - -** "show ip route" shows [metric/distance] value pair. - -** Zebra Protocol is changed to support multi-path route and distance -value. - -* Changes in ospfd - -** "default-information originate [always]" command is added. - -** "default-metric <0-16777214>" command is added. - -** "show ip ospf database" command is integrated. LS-ID and AdvRouter can - be specifed. The commands are - - show ip ospf database TYPE LS-ID - show ip ospf database TYPE LS-ID ADV-ROUTER - show ip ospf database TYPE LS-ID self-originate - show ip ospf database TYPE self-originate - -** route-map support for `redistribute' command are added. - Supported `match' statements are - - match interface - match ip address - match next-hop - - Supported `set' statements are - - set metric - set metric-type - -** Pass OSPF metric value to zebra daemon. - -* Changes in ripd - -** When specified route-map does not exist, it means all deny. - -** "default-metric <1-16>" command is added. - -** "offset-list ACCESS-LIST-NAME <0-16>" and "offset-list -ACCESS-LIST-NAME <0-16> IFNAME" commands are added. - -** "redistribute ROUTE-TYPE metric <0-16>" command is added. - -** "default-information originate" command is added. - -** "ip split-horizon" and "no ip split-horizon" is added to interface -configuration. - -** "no router rip" command is added. - -** "ip rip authentication mode (md5|text)" is added to interface -configuration. - -** "ip rip authentication key-chain KEY-CHAIN" is added to interface -configuration. - -** Pass RIP metric value to zebra daemon. - -** Distance manipulation functions are added. - -* Changes in bgpd - -** Fix bug of next hop treatment for MPLS-VPN route exchange. - -** BGP peer MIB is updated. - -** Aggregated route has origin IGP, atomic-aggregate and proper -aggregator attribute. - -** Suppressed route now installed into BGP table. It is only -suppressed from announcement. - -** BGP router-id is properly set after "no router bgp ASN" and "router -bgp ASN". - -** Add check for nexthop is accessible or not for IBGP routes. - -** Add cehck for nexthop is on connected or not for EBGP routes. - -** "dump bgp route" command is changed to "dump bgp route-mrt" for -generating MRT compatible dump output. - -** Soft reconfiguration inbound and outbound is supported. - -** Route refresh feature is supported. - -* Changes in vtysh - -** VTY shell is now included into the distribution. - -* Changes in zebra-0.87 - -* Changes in lib - -** "show startup-config" command is added. - -** "show history" command is added. - -** Memory statistics command is changed. New command - - show memory all - show memory lib - show memory rip - show memory ospf - show memory bgp - -are added. - -** Filters can be removed only specify it's name. New command - - no access-list NAME - no ip community-list NAME - no ip as-path access-list NAME - no route-map NAME - -are added. - -** At any node, user can view/save user configuration. - - write terminal - write file - wirte memory - -are added to every node in default. - -** LCD completion is added. For example both "ip" and "ipv6" command -are exist, "i" then press TAB will be expanded to "ip". - -* Changes in bgpd - -** "show ip bgp" family shows total number of prefixes. - -** "no bgp default ipv4-unicast" command is added. - -** Extended Communities support is added. - -** "no neighbor PEER send-community extended" command is added. - -** MPLS-VPN PE-RR support is added. - - New address family vpnv4 unicast is introduced. - - ! - address-family vpnv4 unicast - neighobr PEER activate - network A.B.C.D rd RD tag TAG - exit-address-family - ! - - To make it route-reflector, please configure it under normal router -bgp ASN. - - ! - router bgp 7675 - no bgp default ipv4-unicast - bgp router-id 10.0.0.100 - bgp cluster-id 10.0.0.100 - neighbor 10.0.0.1 remote-as 65535 - neighbor 10.0.0.1 route-reflector-client - neighbor 10.0.0.2 remote-as 65535 - neighbor 10.0.0.2 route-reflector-client - neighbor 10.0.0.3 remote-as 65535 - neighbor 10.0.0.3 route-reflector-client - ! - address-family vpnv4 unicast - neighbor 10.0.0.1 activate - neighbor 10.0.0.2 activate - neighbor 10.0.0.3 activate - exit-address-family - ! - -* Changes in ospfd - -** Many many bugs are fixed. - -* Changes in ripd - -** Better interface up/down event handle. - -* Changes in zebra - -** Better interface up/down event handle. - -* Changes in zebra-0.86 - -* Changes in lib - -** Fix bug of exec-timeout command which may cause crush. - -** Multiple same policy for "access-list", "ip prefix-list, "as-path -access-list", "ip community-list" is not duplicated. - -** It used to be "ip prefix-list A.B.C.D/M" match routes which mask >= -M. Now default behavior is exact match so it only match routes which -mask == M. - -* Changes in bgpd - -** "match ip address prefix-list" is added to route-map. - -** A route without local preference is evaluated as 100 local preference. - -** Select smaller router-id route when other values are same. - -** Compare MED only both routes comes from same neighboring AS. - -** "bgp always-compare-med" command is added. - -** Now MED value is passed to IBGP peer. - -** When neighbor's filter is configured with non-existent access-list, -as-path access-list, ip prefix-list, route-map. The behavior is -changed from all permit to all deny. - -* Changes in ospfd - -** Fix bug of external route tag byte order. - -** OSPF Neighbor deletion bug which cause crush is fixed. - -** Some route calculation bug are fixed. - -** Add sanity check with router routing table. - -** Fix bug of memory leak about linklist. - -** Fix bug of 1-WayReceived in NSM. - -** Take care of BIGENDIAN architecture. - -** Fix bug of NSM state flapping between ExStart and Exchange. - -** Fix bug of Network-LSA originated in stub network. - -** Fix bug of MS flag unset. - -** Add to schedule router_lsa origination when the interface cost -changes. - -** Increment LS age by configured interface transmit_delay. - -** distribute-list is reimplemented. - -** Fix bug of refresh never occurs. - -** Fix bug of summary-LSAs reorigination. Correctly copy -OSPF_LSA_APPROVED flag to new LSA. when summary-LSA is reoriginatd. - -** Fix bug of re-origination when a neighbor disappears. - -** Fix bug of segmentation fault with DD retransmission. - -** Fix network-LSA re-origination problem. - -** Fix problem of remaining withdrawn routes on zebra. - -* Changes in ripd - -** Do not leave from multicast group when interface goes down bug is -fixed. - -* Changes in zebra - -** Remove client structure when client dies. - -** Take care static route when interface goes up/down. - -* Changes in zebra-0.85 - -* Changes in bgpd - -** "transparent-nexthop" and "transparenet-as" commands are added. - -** Route reflector's originator-id bug is fixed. - -* Changes in ospfd - -** Fix bug of OSPF LSA memory leak. - -** Fix bug of OSPF external route memory leak. - -** AS-external-LSA origination bug was fixed. - -** LS request treatment is completely rewritten. Now performance is -drastically improved. - -* Changes in ripd - -** RIPv1 update is done by class-full manner. - -* Changes in zebra-0.84b - -* Changes in lib - -** Fix bug of inet_pton return value handling - -* Changes in bgpd - -** Fix bug of BGP-4+ link-local address nexthop check for IBGP peer. - -** Don't allocate whole buffer for displaying "show ip bgp". Now it -consume only one screen size memory. - -* Changes in ripd - -** Fix debug output string. - -** Add RIP peer handling. RIP peer are shown by "show ip protocols". - -* Changes in zebra-0.84a - -* Changes in bgpd - -** Fix serious bug of BGP-4+ peering under IPv6 link-local address. - Due to the bug BGP-4+ peering may not be established. - -* Changes in zebra-0.84 - -* Changes in lib - -** IPv6 address and prefix parser is added to VTY by Toshiaki Takada - <takada@zebra.org>. DEFUN string is "X:X::X:X" for IPv6 address, - "X:X::X:X/M" for IPv6 prefix. You can use it like this. - - DEFUN (func, cmd, "neighbor (A.B.C.D|X:X::X:X) remote-as <1-65535>") - -** VTY configuration is locked during configuration. This is for - avoiding unconditional crush from two terminals modify the - configuration at the same time. "who" command shows which termnal - lock the configuration. VTY which has '*' character at the head of - line is locking the configuration. - -** Old logging functions are removed. Functions like - log_open,log_close,openlog are deleted. Instead of that please use - zlog_* functions. zvlog_* used in ospf6d are deleted also. - -** "terminal monitor" command is added. "no terminal monitor" is for - disabling. This command simply display logging information to the - VTY. - -** dropline.[ch] files are deleted. - -* Changes in bgpd - -** BGP neighbor configuration are sorted by it's IP address. - -** BGP peer configuration and actual peer is separated. This is - preparation for Route Server support. - -** "no neighbor PEER" command is added. You can delete neighbor - without specifying AS number. - -** "no neighbor ebgp-multihop" command is added. - -** "no neighbor port PORT" command is added. - -** To conform RFC1771, "neighbor PEER send-community" is default - behavior. If you want to disable sending community attribute, - please specify "no neighbor PEER send-community" to the peer. - -** "neighbor maximum-prefix NUMBER" command is added. - -** Multi-protocol extention NLRI is proceeded only when the peer is - configured proper Address Family and Subsequent Address Family. If - not, those NLRI are simply ignored. - -** Aggregate-address support is improved. Currently below commands - works. - - "aggregate-address" - "aggregate-address summary-only" - "no aggregate-address" - "no aggregate-address summary-only" - - "ipv6 bgp aggregate-address" - "ipv6 bgp aggregate-address summary-only" - "no ipv6 bgp aggregate-address" - "no ipv6 bgp aggregate-address summary-only" - -** redistribute route-map bug is fixed. - -** MBGP support becomes default. "configure" option --enable-mbgp is - removed. - -** New command "neighbor PEER timers connect <1-65535>" is added. - -** New command "neighbor PEER override-capability" is added. - -** New command "show ip bgp neighbor A.B.C.D advertised-route" is added. - -** New command "show ip bgp neighbor A.B.C.D routes" is added. To use - this command, you have to configure neighbor with - "neighbor A.B.C.D soft-reconfiguration inbound" beforehand. - - -* Changes in zebra-0.83 - -* bgpd - -** Serious bug fix about fetching global and link-local address at the -same time. Due to this bug, corrupted IPv6 prefix is generated. If -you uses bgpd for BGP-4+ please update to this version. The bug is -introduced in zebra-0.82. - -** When bgpd send Notify message, don't use thread manager. It is now -send to neighbor immediately. - -* Changes in zebra-0.82 - -** Solaris 2.6 support is added by Michael Handler -<handler@sub-rosa.com>. - -** MBGP support is added by Robert Olsson <Robert.Olsson@data.slu.se>. -Please specify --enable-mbgp to configure script. This option will be -removed in the future and MBGP support will be default. - -* Changes in zebra - -** When interface goes down, withdraw connected routes from routing -table. When interface goes up, restore the routes to the routing -table. - -** `show interface' show interface's statistics on Linux and BSD with -routing socket. - -** Now zebra can get MTU value on BSDI/OS. - -* Changes in bgpd - -** Add capability option support based upon -draft-ietf-idr-bgp4-cap-neg-04.txt. - -** Add `show ipv6 bgp prefix-list' command. - -** Check self AS appeared in received routes. - -** redistribute route-map support is added. - -** BGP packet dump feature compatible with MRT. - -* Changes in ripd - -** Fix bug of `timers basic' command's argument format. - -* Changes in ripngd - -** Calculate max RTE using interface's MTU value. - -* Changes in ospfd - -** Some correction to LSU processing. - -** Add check for lsa->refresh_list. - -* Changes in ospf6d - -** Many debug feature is added. - -* Changes in zebra-0.81 - -** SNMP support is disabled in default.--enable-snmp option is added -to configure script. - -* Changes in bgpd - -** Fix FSM bug which introduced in zebra-0.80. - -* Changes in zebra-0.80 - -* access-list - - New access-list name space `ipv6 access-list' is added. At the same - time, `access-list' statemant only accepts IPv4 prefix. Please be - careful if you use IPv6 filtering. You will need to change your - configuration. For IPv6 filtering please use `ipv6 access-list'. - - As of zebra-0.7x, user can use `access-list' for both IPv4 and IPv6 - filtering. - - ! zebra-0.7x - access-list DML-net permit 203.181.89.0/24 - access-list DML-net permit 3ffe:506::0/32 - access-list DML-net deny any - ! - - Above configuration is not valid for zebra-08x. Please add `ipv6' - before 'access-list' when you configure IPv6 filtering. - - ! zebra-0.8x - access-list DML-net permit 203.181.89.0/24 - access-list DML-net deny any - ! - ipv6 access-list DML-net permit 3ffe:506::0/32 - ipv6 access-list DML-net deny any - ! - -* prefix-list - - And also new prefix-list name space `ipv6 prefix-list' is added. It - is the same as the change of `access-list'. `ip prefix-list' now only - accept IPv4 prefix. It was source of confusion that `ip prefix-list' - can be used both IPv4 and IPv6 filtering. Now name space is separated - to clear the meaning of the filter. - - If you use `ip prefix-list' for IPv6 filtering, please change the - stetement. - - ! zebra-0.7x - ip prefix-list 6bone-filter seq 5 permit 3ffe::/17 le 24 ge 24 - ip prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 le 28 ge 28 - ip prefix-list 6bone-filter seq 12 deny 3ffe::/16 - ip prefix-list 6bone-filter seq 15 permit 2000::/3 le 16 ge 16 - ip prefix-list 6bone-filter seq 20 permit 2001::/16 le 35 ge 35 - ip prefix-list 6bone-filter seq 30 deny any - ! - - Now user can explicitly configure it as IPv6 prefix-list. - - ! zebra-0.8x - ipv6 prefix-list 6bone-filter seq 5 permit 3ffe::/17 le 24 ge 24 - ipv6 prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 le 28 ge 28 - ipv6 prefix-list 6bone-filter seq 12 deny 3ffe::/16 - ipv6 prefix-list 6bone-filter seq 15 permit 2000::/3 le 16 ge 16 - ipv6 prefix-list 6bone-filter seq 20 permit 2001::/16 le 35 ge 35 - ipv6 prefix-list 6bone-filter seq 30 deny any - ! - -* RIP configuration - - If you want to filter only default route (0.0.0.0/0) and permit other - routes, it was hard to do that. Now `ip prefix-list' can be used for - RIP route filtering. - - New statement: - - `distribute-list prefix PLIST_NAME (in|out) IFNAME' - - is added to ripd. So you can configure on eth0 interface accept all - routes other than default routes. - - ! - router rip - distribute-list prefix filter-default in eth0 - ! - ip prefix-list filter-default deny 0.0.0.0/0 le 0 - ip prefix-list filter-default permit any - ! - -* RIPng configuration - - Same change is done for ripngd. You can use `ipv6 prefix-list' for - filtering. - - ! - router ripng - distribute-list prefix filter-default in eth0 - ! - ipv6 prefix-list filter-default deny ::/0 le 0 - ipv6 prefix-list filter-default permit any - ! - -* BGP configuration - - So far, Multiprotocol Extensions for BGP-4 (RFC2283) configuration is - done with traditional IPv4 peering statement like blow. - - ! - router bgp 7675 - neighbor 3ffe:506::1 remote-as 2500 - neighbor 3ffe:506::1 prefix-list 6bone-filter out - ! - - For separating configuration IPv4 and IPv6, and for retaining Cisco - configuration compatibility, now IPv6 configuration is done by IPv6 - specific statement. IPv6 BGP configuration is done by statement which - start from `ipv6 bgp'. - - ! - router bgp 7675 - ! - ipv6 bgp neighbor 3ffe:506::1 remote-as 2500 - ipv6 bgp neighbor 3ffe:506::1 prefix-list 6bone-filter out - ! - - At the same time some IPv6 specific commands are deleted from IPv4 - configuration. - - o redistribute ripng - o redistribute ospf6 - o neighbor PEER version BGP_VERSION - o neighbor PEER interface IFNAME - - Those commands are only accepted as like below. - - o ipv6 bgp redistribute ripng - o ipv6 bgp redistribute ospf6 - o ipv6 bgp neighbor PEER version BGP_VERSION - o ipv6 bgp neighbor PEER interface IFNAME - - And below new commands are added. - - o ipv6 bgp network IPV6_PREFIX - o ipv6 bgp redistribute static - o ipv6 bgp redistribute connected - o ipv6 bgp neighbor PEER remote-as <1-65535> [passive] - o ipv6 bgp neighbor PEER ebgp-multihop [TTL] - o ipv6 bgp neighbor PEER description DESCRIPTION - o ipv6 bgp neighbor PEER shutdown - o ipv6 bgp neighbor PEER route-reflector-client - o ipv6 bgp neighbor PEER update-source IFNAME - o ipv6 bgp neighbor PEER next-hop-self - o ipv6 bgp neighbor PEER timers holdtime <0-65535> - o ipv6 bgp neighbor PEER timers keepalive <0-65535> - o ipv6 bgp neighbor PEER send-community - o ipv6 bgp neighbor PEER weight <0-65535> - o ipv6 bgp neighbor PEER default-originate - o ipv6 bgp neighbor PEER filter-list FILTER_LIST_NAME (in|out) - o ipv6 bgp neighbor PEER prefix-list PREFIX_LIST_NAME (in|out) - o ipv6 bgp neighbor PEER distribute-list AS_LIST_NAME (in|out) - o ipv6 bgp neighbor PEER route-map ROUTE_MAP_NAME (in|out) - - And some utility commands are introduced. - - o clear ipv6 bgp [PEER] - o show ipv6 bgp neighbors [PEER] - o show ipv6 bgp summary - - I hope these changes are easy to understand for current Zebra users... - -* To restrict connection to VTY interface. - - It used to be both IPv4 and IPv6 filter can be specified with one - access-list. Then the access-list can be appried to VTY interface - with `access-class' stetement in `line vty' node. Below is example in - zebra-0.7x. - - ! - access-list local-only permit 127.0.0.1/32 - access-list local-only permit ::1/128 - access-list local-only deny any - ! - line vty - access-class local-only - ! - - Now IPv4 and IPv6 filter have each name space. It is not possible to - specify IPv4 and IPv6 filter with one access-list. For setting IPv6 - access-list in `line vty', `ipv6 access-class' statement is - introduced. Let me show the configuration in zebra-0.8x. - - ! - access-list local-only permit 127.0.0.1/32 - access-list local-only deny any - ! - ipv6 access-list local-only permit ::1/128 - ipv6 access-list local-only dny any - ! - line vty - access-class local-only - ipv6 access-class local-only - ! - -* route-map - - New IPv6 related route-map match commands are added. - - o match ipv6 address - o match ipv6 next-hop - - Please change your configuration if you use IP match statement for - IPv6 route. - - zebra-0.7x config - ================= - ! - access-list all permit any - ! - route-map set-nexthop permit 10 - match ip address all - set ipv6 next-hop global 3ffe:506::1 - set ipv6 next-hop local fe80::cbb5:591a - ! - - zebra-0.8x config - ================= - ! - ipv6 access-list all permit any - ! - route-map set-nexthop permit 10 - match ipv6 address all - set ipv6 next-hop global 3ffe:506::1 - set ipv6 next-hop local fe80::cbb5:591a - ! - -* zebra connection - - Protocol daemon such as ripd, bgpd, ospfd will reconnect zebra daemon - when the connection fail. Those daemons try to connect zebra every 10 - seconds first three trial, then the interval changed to 60 seconds. - After all, if ten connections are fail, protocol daemon give up the - connection to the zebra daemon. - -* SNMP support (is not yet finished) - - Zebra uses SMUX protocol (RFC1227) for making communication with SNMP - agent. Currently lib/smux.c can be compiled only with ucd-snmp-4.0.1 - and http://ucd-snmp.ucdavis.edu/patches/012.patch. It can not be - compiled with ucd-snmp-3.6.2. - - After applying the patch to ucd-snmp-4.0.1, please configure it with - SMUX module. - - % configure --with-mib-modules=smux - - After compile & install ucd-snmp-4.0.1, you will need to configure - smuxpeer. I'm now using below configuration. - - /usr/local/share/snmp/snmpd.conf - ================================ - smuxpeer 1.3.6.1.6.3.1 test - - Above 1.3.6.1.6.3.1 and test is temporary configuration which is hard - coded in lib/smux.c. Yes, I know it is bad, I'll change it ASAP. - -* HUP signal treatment - - From zebra-0.80, ripd will reload it's configuration file when ripd - receives HUP signal. Other daemon such as bgpd, ospfd will support - HUP signal treatment soon. - -* Changes in zebra-0.79 - -* Changes in zebra - -** Broadcast address setting on Linux box bug is fixed. - -** Protocol daemon can install connected IPv6 route into the kernel. - -** Now zebra can handle blackhole route. - -* Changes in ripd - -** Add route-map feature for RIP protocol. - -** In case of RIP version 2 routing table entry has IPv4 address and -netmask pair which host part bit is on, ignore the entry. - -* Changes in ripngd - -** Change CMSG_DATA cast from (u_char *) to (int *). (u_char *) does -not work for NetBSD-currnet on SparcStation 10. - -* Changes in ospfd - -** MaxAge LSA treatment is added. - -** ABR/ASBR functionality is added. - -** Virtual Link funtionality is added. - -** ABR behaviors IBM/Cisco/Shortcut is added. - -* Changes in ospf6d - -** Enclosed KAME specific part with #ifdef #endif - -* Changes in zebra-0.78 - -* Changes in lib - -** SNMP support is started. - -** Now Zebra can work on BSD/OS 4.X. - -** Now Zebra can compiled on vanilla OpenBSD 2.5 but not yet working correcltly. - -* Changes in zebra - -** Interface index detection using ioctl() bug is fixed. - -** Interface information protocol is changed. Now interface -addition/deletion and interface's address addition/deletion is -separated. - -* Changes in bgpd - -** BGP hold timer bug is fixed. - -** BGP keepavlie timer becomes configurable. - -* Changes in ripd - -** When making reply to rip's REQUEST message, fill in -RIP_METRIC_INFINITY with network byte order using htonl (). - -** Pass host byte order address to IN_CLASSC and IN_CLASSB macro. - -* Changes in ospfd - -** LSA flooding works. - -** Fix bug of DD processing. - -** Fix bug of originating router-LSA bug is fixed. - -** LSA structure is changed to support LSA aging. - -* Changes in ospf6d - -** `ip6' statement in configuration is changed to `ipv6'. - -* Changes in zebra-0.77 - -* Changes in lib - -** SIGUSR1 reopen logging file. - -** route-map is extended to support multi-protocol routing -information. - -** When compiling under GNU libc 2.1 environment don't use inet6-apps. - -* Changes in zebra - -** Basic IPv6 router advertisement codes added. It is not yet usable. - -** Fix IPv6 route addition/deletion bug is fixed. - -** `show ip route A.B.C.D' works - -* Changes in bgpd - -** When invalid unfeasible routes length comes, bgpd send notify then -continue to process the packet. Now bgpd stop parsing invalid packet -then return to main loop. - -** BGP-4+ withdrawn routes parse bug is fixed. - -** When BGP-4+ information passed to non shared network's peer, trim -link-local next-hop information. - -** `no redistribute ROUTE_TYPE' withdraw installed routes from BGP -routing information. - -** `show ipv6 route IPV6ADDR' command added. - -** BGP start timer has jitter. - -** Holdtimer configuration bug is fixed. Now configuration does not -show unconfigured hold time value. - -* Changes in ripngd - -** Now update timer (default 30 seconds) has +/- 50% jitter value. - -** Add timers basic command. - -** `network' configuration is dynamically reflected. - -** `timers basic <update> <timeout> <garbage>' added. - -* Changes in ripd - -** Reconstruct almost codes. - -** `network' configuration is dynamically reflected. - -** RIP timers now conforms to RFC2453. So user can configure update, -timeout, garbage timer. - -** `timers basic <update> <timeout> <garbage>' works. - -* Changes in ospfd - -** Bug of originating network LSA is fixed. - -** `no router ospf' core dump bug is fixed. - -* Changes in ospf6d - -** Redistribute route works. - -* Changes in zebra-0.76 - -* Changes in lib - -** configure.in Linux IPv6 detection problem is fixed. - -** Include SERVICES file to the distribution - -** Update zebra.texi to zebra-0.76. - -* Changes in zebra-0.75 - -* Changes in lib - -** `termnal length 0' bug is fixed. - -* Changes in zebra - -** When zebra starts up, sweep all zebra installed routes. If -k or ---keep_kernel option is specified to zebra dameon. This function is -not performed. - -* Changes in ripngd - -** Aggreagte address command supported. In router ripngd, -`aggregate-address IPV6PREFIX' works. - -* Changes in bgpd - -** Input route-map's bug which cause segmentation violation is fixed. - -** route-map method improved. - -** BGP-4+ nexthop detection improved. - -** BGP-4+ route re-selection bug is fixed. - -** BGP-4+ iBGP route's nexthop calculation works. - -** After connection Established `show ip bgp neighbor' display BGP TCP -connection's source and destination address. - -** In case of BGP-4+ `show ip bgp neighbor' display BGP-4+ global and -local nexthop which used for originated route. This address will be -used when `next-hop-self'. - -* Changes in ospfd - -** Fix bug of DR election. - -** Set IP precedence field with IPTOS_PREC_INTERNET_CONTROL. - -** Schedule NeighborChange event if NSM status change. - -** Never include a neighbor in Hello packet, when the neighbor goes -down. - -* Changes in zebra-0.74 - -* Changes in lib - -** Now `terminal length 0' means no line output control. - -** `line LINES' command deleted. Instead of this please use `terminal -length <0-512>'. - -** `terminal length <0-512>' is each vty specific configuration so it -can not be configured in the configuration file. If you want to -configure system wide line control, please use `service -terminal-length <0-512>'. This configuration affects to the all vty -interface. - -* Changes in zebra - -** Installation of IPv6 route bug is fixed. - -* Changes in bgpd - -** Very serious bug of bgp_stop () is fixed. When multiple route to -the same destination exist, bgpd try to announce the information to -stopped peer. Then add orphan write thread is added. This cause -many strange behavior of bgpd. - -** Router-id parsing bug is fixed. - -** With BGP-4+ nexthop installation was done with global address but -it should be link-local address. This bug is fixed now. - -** When incoming route-map prepend AS, old AS path remained. Now bgpd -free old AS path. - -** `neighbor PEER weight <0-65535>' command added. - -* Changes in ripngd - -** Almost codes are rewritten to conform to RFC2080. - -* Changes in ospfd - -** SPF calculation timer is added. Currently it is set to 30 seconds. - -** SPF calculation works now. - -** OSPF routing table codes are added. - -** OSPF's internal routes installed into the kernel routing table. - -** Now `ospfd' works as non-area, non-external route support OSPF -router. - -** Call of log_rotate() is removed. - -* Changes in ospf6d - -** LSA data structure is changed. - -** Call of log_rotate() is removed. - -* Changes in zebra-0.73 - -* Changes in lib - -** `config terminal' is changed to `configure terminal'. - -** `terminal length <0-512>' command is added. - -** Variable length argument was specified by `...'. Now all strings -started with character `.' is variable length argument. - -* Changes in zebra - -** Internal route (such as iBGP, internal OSPF route) handling works -correctly. - -** In interface node, `ipv6 address' and `no ipv6 address' works. - -** Interface's address remain after `no ip address' bug is fixed. - -** Host route such as IPv4 with /32 mask and IPv6 with /128 mask -didn't set RTF_GATEWAY even it has gateway. This bug if fixed now. - -* Changes in bgpd - -** `match as-path' argument is used to be specify AS PATH value itself -directly (e.g. ^$). But it is changed to specify `ip as-apth -access-list' name. - -** iBGP route handle works without getting error from the kernel. - -** `set aggregator as AS A.B.C.D' command is added to route-map. - -** `set atomic-aggregate' command is added to bgpd's routemap. - -** Announcement of atomic aggregate attribute and aggregator attribute -works. - -** `update-source' bug is fixed. - -** When a route learned from eBGP is announced to iBGP, local -preference was set to zero. But now it set to -DEFAULT_LOCAL_PREF(100). - -* Changes in ripd - -** RIPv1 route filter bug is fixed. - -** Some memory leak is fixed. - -* Changes in ospfd - -** Fix bug of DR Election. - -** Fix bug of adjacency forming. - -* Changes in ospf6d - -** Clean up logging message. - -** Reflect routing information to zebra daemon. - -* Changes in zebra-0.72 - -* Changes in lib - -** When getsockname return IPv4 mapped IPv6 address. Convert it to -IPv4 address. - -* Changes in bgpd - -** Change route-map's next-hop related settings. - -set ip nexthop -> set ip next-hop -set ipv6 nexthop global -> set ipv6 next-hop global -set ipv6 nexthop local -> set ipv6 next-hop local - -** Add `next-hop-self' command. - -* Changes in ospfd - -** Fix bug of multiple `network area' directive crashes. - -* Changes in zebra-0.71 - -* Changes in lib - -** `log syslog' command is added. - -** Use getaddrinfo function to bind IPv4/IPv6 server socket. - -** `no banner motd' will suppress motd output when user connect to VTY. - -** Bind `quit' command to major nodes. - -* Changes in zebra - -** Point-to-point link address handling bug is fixed. - -* Changes in bgpd - -** AS path validity check is added. If malformed AS path is received -NOTIFY Malformed AS path is send to the peer. - -** Use getaddrinfo function to bind IPv4/IPv6 server socket. - -* Changes in ripd - -** Connected network announcement bug is fixed. - -** `broadcast' command is deleted. - -** `network' command is added. - -** `neighbor' command is added. - -** `redistribute' command is added. - -** `timers basic' command is added. - -** `route' command is added. - -* Changes in ripngd - -** Fix metric calculation bug. - -* Changes in ospfd - -** Check sum bug is fixed. - -* Chanegs in ospf6d - -** Routing table code is rewritten. - -* Changes in zebra-0.70 - -* Changes in zebra - -** Critical routing information base calculation bug check is fixed. - -** zebra ipv4 message is extended to support external/internal route -flavor. - -** Now if internal route doesn't has direct connected nexthop, then -nexthop is calculated by looking up IGP routing table. - -* Changes in bgpd - -** `neighbor PEER update-source IFNAME' command added as ALIAS to -`neighbor PEER interface IFNAME'. - -* Changes in ospfd - -** DD null pointer bug is fixed. - -* Changes in zebra-0.69 - -* Changes in zebra - -** zebra redistirbution supports dynamic notification of the route -change. If you add static route while running zebra, it will be -reflected to other protocol daemon which set `redistribute static'. - -** If static route installation is failed due to the error. The -static route is not added to the configuration and zebra routing -table. - -** zebra sets forwarding flag to on when it starts up. - -** `no ip forwarding' turn off IPv4 forwarding. - -** `no ipv6 forwarding' turn off IPv6 forwarding. - -** Change `show ipforward' command to `show ip forwarding'. - -** Change `show ipv6forward' command to `show ipv6 forwarding'. - -** `ip route A.B.C.D/M INTERFACE' works. So you can set `ip route -10.0.0.0/8 eth0'. - -* Changes in bgpd - -** `neighbor PEER send-community' command is added. If the option is -set, bgpd will send community attribute to the peer. - -** When a BGP route has no-export community attribute and -send-community is set to the peer, the route is not announced to the -peer. - -* Changes in ripngd - -** When ripngd terminates, delete all installed route. - -** `redistribute static', `redistribute connected' works. - -** Change `debug ripng event' to `debug ripng events'. - -** Change `show debug ripng' to `show debugging ripng'. - -** Bug of static route deletion is fixed. - -* Changes in ospfd - -** LS request and LS update can be send and received. - -* Changes in zebra-0.68 - -* Changes in lib - -** DEFUN() is extended to support (a|b|c) statement. - -** Input buffer overflow bug is fixed. - -* Changes in bgpd - -** `ip community-list' is added. - -** set community and match community is added to route-map statement. - -** aggregate-address A.B.C.D/M partly works. Now it works only -summary-only mode. - -* Changes in zebra - -** IPv6 network address delete bug is fixed. - -* Changes in ospfd - -** DR election bug fixed. - -** Now Database Description can be send or received. - -** Neighbor State Machine goes to Full state. - -* Changes in ospf6d - -** router zebra related bug is fixed. - -* Changes in zebra-0.67 - -* Changes in lib - -** `service password-encryption' is added for encrypted password. - -* Changes in bgpd - -** `set as-path prepend ASPATH' is added to route-map command. - -** `set weight WEIGHT' is added to route-map command. - -** `no set ipv6 nexthop global' and `no set ipv6 nexthop local' -command is added to route-map. - -** `neighbor IP_ADDR version BGP_VERSION' command's BGP_VERSION -argument changed. - -Old New -===================== -bgp4 4 -bgp4+ 4+ -bgp4+-draft-00 4- -===================== - -If you want to peer with old draft version of BGP-4+, please configure -like below: - -router bgp ASN - neighbor PEER version 4- - -** Some AS path isn't correctly compared during route selection. Now -it is fixed. - -* Changes in ospfd - -** `router zebra' is default behavior. - -* Changes in ospf6d - -** `router zebra' is default behavior. - -* Changes in zebra-0.66 - -* Changes in zebra - -** When other daemon such as gated install routes into the kernel then -zebra blocks. This is only occur with netlink socket. Now socket is -set as NONBLOCKING and problem is fixed. Reported and fixed by -Patrick Koppen <koppen@rhrk.uni-kl.de> - -* Changes in bgpd - -** Now `router zebra' is not needed to insert BGP routes into the -kernel. It is default behavior. If you don't want to install the BGP -routes to the kernel, please configure like below: - -! -router zebra - no redistribute bgp -! - -** redistribute connected works. - -** redistribute static now filter local loopback routes and link local -network. - -* Changes in ripd - -** Some network check is added. Patch is done by Carlos Alberto -Barcenilla <barce@frlp.utn.edu.ar> - -* Changes in ripngd - -** Sometimes ripngd install wrong nexthop into the kernel. This bug -is fixed now. - -** Now `router zebra' is not needed to insert RIPng routes into the -kernel. It is default behavior. If you don't want to install the BGP -routes to the kernel, please configure like below: - -! -router zebra - no redistribute ripng -! - -* Changes in zebra-0.65 - -* Changes in lib - -** `C-c' changes current node to ENABLE_NODE. Previously it doesn't. - -** In ENABLE_NODE, `exit' command close vty connection. - -** `service advanced-vty' enable advanced vty function. If this -service is specified one can directly connect to ENABLE_NODE when -enable password is not set. - -** `lines LINES' command is added by Stephen R. van den Berg -<srb@cuci.nl>. - -* Changes in zebra - -** Basic Linux policy based routing table support is added by Stephen -R. van den Berg <srb@cuci.nl>. - -* Changes in bgpd - -** route-map command is improved: - `match ip next-hop': New command. - `match metric': New command. - `set metric': Doc fixed. - `set local-preference': DEFUN added. - -* Changes in ripd - -** Check of announced network is added. Now multicast address is -filtered. Reported by Carlos Alberto Barcenilla -<barce@frlp.utn.edu.ar> - -** Check of network 127 is added. Reported by Carlos Alberto -Barcenilla <barce@frlp.utn.edu.ar> - -* Changes in ripngd - -** Aging route bug is fixed. - -** `router zebra' semantics changed. ripngd automatically connect to -zebra. - -* Changes in ospfd - -** `no router ospf' works. - -* Changes in ospf6d - -** Bug fix about network vertex. - -* Changes in zebra-0.64.1. - -This is bug fix release. - -* Changes in lib - -** Add check of sin6_scope_id in struct sockaddr_in6. For compilation -on implementation which doesn't have sin6_scope_id. Reported by Wim -Biemolt <Wim.Biemolt@ipv6.surfnet.nl>. - -* Changes in zebra - -** Fix bug of display BGP routes as "O" instead of "B". Reported by -"William F. Maton" <wmaton@enterprise.ic.gc.ca> and Dave Hartzell -<hartzell@greatplains.net>. - -* Changes in bgpd - -** `no network IPV6_NETWORK' statement and `no neighbor IP_ADDR timers -holdtime [TIMER]' statement doesn't work. Reported by Georg Hitsch -<georg@atnet.at>. Now both statement work. - -* Changes in ospfd - -** Last interface is not updated by ospf_if_update(). Reported by -Dave Hartzell <hartzell@greatplains.net>. - -* Changes in ospf6d - -** Byte order of ifid is changed. Due to this change, this code will -not work with previous version, sorry. - -** Fix `show ip route' route type mismatch. - -** Fix bug of no network IPV6_NETWORK. - -** Important bug fix about intra-area-prefix-lsa. - -* Changes in zebra-0.64. - -* Changes in lib - -** prefix-list based filtering routine is added. Currently used in -bgpd but it will be in other daemons. - -* Changes in bgpd - -** `no router bgp' works. But network statement is not cleared. This -should be fixed in next beta. - -** Route reflector related statement is added. - - router bgp ASN - bgp cluster-id a.b.c.d - neighbor a.b.c.d route-reflector-client - - is added. - -** Prefix list based filtering is added. - - router bgp ASN - neighbor a.b.c.d prefix-list PREFIX_LIST_NAME - -** Prefix list based routing display works. - - show ip bgp prefix-list PREFIX_LIST_NAME - -* Changes in ripd - -** Fix route metric check bug. Reported from Mr. Carlos Alberto -Barcenilla. - -* Changes in ospf6d - -** There are many changes. If you have interested in ospf6d please -visit ospf6d/README file. - -* Changes in zebra-0.63 first beta package. - -* Changes in lib - -** `copy running-config stgartup-config' command is added. - -** prefix length check bug is fixed. Thanks Marlos Barcenilla -<barce@frip.utn.edu.ar>. - -* Changes in ospfd - -** DR and BDR election works. - -** OSPF Hello simple authentication works. - -* Changes in ospf6d - -** Now ospf6d can be compiled on both Linux and *BSD system. - -* Changes in zebra-19990420 snapshot - -** `make dist' at top directory works now. - -* Changes in lib - -** VTY has now access-class to restrict remote connection. -Implemented by Alex Bligh <amb@gxn.net>. - -! -line vty - access-class ACCESS-LIST-NAME -! - -** `show version' command added. Implemented by Carlos Alberto -Barcenilla <barce@frlp.utn.edu.ar> - -* Changes in zebra - -** `ip address' command on *BSD bug is fixed. - -** `no ip address' works now for IPv4 address. - -** Now `write terminal' display `ip address' configuration. - -* Changes in bgpd - -** Redistribute static works now. Please run both zebra and bgpd. -bgpd.conf should be like this: - -! -router zebra -! -router bgp ASN - redisitribute static -! - -* Changes in guile - -** configure --enable-guile turns on zebra-guile build. - -** (router-bgp ASN) allocates real bgp structre. - -* Changes in zebra-19990416 snapshot - -** Set version to 0.60 for preparation of beta release. - -** New directory guile is added for linking with guile interpreter. - -* Changes in zebra - -** On GNU/Linux Kernel 2.2.x (with netlink support), zebra detects -asynchronous routing updates. *BSD support is not yet finished. - -* Changes in bgpd - -** `show ip bgp regexp ASPATH_REGEX' uses CISCO like regular expression -instead of RPSL like regular expression. I'm planing to provide RPSL -like regular expression with `show ip bgp rpsl' or something. - -* Changes in lib - -** Press '?' at variable mandatory argument, vty prints nothing. Now -vty outputs description about the argument. Fixed by Alex Bligh -<amb@gxn.net> - -** buffer.c has some ugly bugs. Due to the bug, vty interface hangs -when large output date exists. This bug is fixed. Reported by Alex -Bligh <amb@gxn.net>. - -* Changes in ospfd - -** DR and BDR information is shown by `show ip ospf interface' command. - -* Changes in zebra-19990408 snapshot - -* Changes in bgpd - -** Old BGP-4+ specification (described in old draft) treatment bug is -fixed. It seems that mrtd uses this format as default. So if you -have problem peering with mrtd and want to use old draft format please -use version statement like this. - -neighbor PEER_ADDRESS remote-as ASN -neighbor PEER_ADDRESS version bgp4+-draft-00 - -** When AS path is epmty (routes generated by bgpd), SEGV is occur -when announce the routes to eBGP peer. Reported by -kad@gibson.skif.net. - -** ip as-path access-list command is added. - -** neighbor PEER_ADDRESS filter-list AS_LIST [in|out] command is added. - -** neighbor PEER_ADDRESS timers holdtimer TIMER command is added. - -* Changes in all daemons - -** With KAME stack, terminal interface is now bind AF_INET socket -instead of AF_INET6 one. - -* Changes in zebra-19990403 snapshot - -* Changes in bgpd - -** When bgpd has 'router zebra', bgpd automatically select it's router -ID as most highest interface's IP Address. - -** When AS path is empty (in case of iBGP), it doesn't include any AS -segment. This change is for announcement to gated under iBGP. - -* Changes in ospfd - -** OSPF hello packet send/receive works. - -* Changes in ospf6d - -** Yasuhiro Ohara's ospf6d codes is imported. It is under development -and can't be compiled on any platform. - -* Changes in zebra-19990327 snapshot - -* Changes in bgpd - -** When BGP-4+ connection is done by IPv6 link-local address. One -have to specify interface index for the connection. So I've added -interface statement to the neighbor commmand. Please specify -interface name for getting interface index like below. This statement -only works on GNU/Linux. I'll support BSD ASAP. - -router bgp 7675 - neighbor fe80::200:f8ff:fe01:5fd3 remote-as 2500 - neighbor fe80::200:f8ff:fe01:5fd3 interface sit3 - -** For disable BGP peering `shutdown' command is added. - -router bgp 7675 - neighbor 10.0.0.1 shutdown - -** `description' command is added to neighbor statement. - -router bgp 7675 - neighbor 10.0.0.1 description peering with Norway. - -** `show ip bgp regexp AS-REGEXP' works again. - -show ip bgp regexp AS7675 - -will show routes which include AS7675. - -** When a route which is made from `network' statement is send to -neighbor. Set it's nexthop to self. So 10.0.0.0/8 is announced to -the peer A with source address 192.168.1.1. The routes nexthop is set -to 192.168.1.1. - -* Changes in zebra - -** In zebra/rtread_sysctl.c, function rtm_read() may overrun allocated -buffer when the address family is not supported and the length is big -(i.e link address). Reported Achim Patzner <ap@bnc.net>. - -* Changes in ospfd - -** Now ospfd receive OSPF packet. - -* Changes in zebra-19990319 snapshot - -* Changes in configuration and libraries - -** User can disable IPv6 feature and/or pthread feature by configure - option. - - To disable IPv6: configure --disable-ipv6 - To disable pthread: configure --disable-pthread - -** User can disable specified daemon by configure option. - - Don't make zebra: configure --disable-zebra - Don't make bgpd: configure --disable-bgpd - Don't make ripd: configure --disable-ripd - Don't make ripngd: configure --disable-ripngd - Don't make ospfd: configure --disable-ospfd - Don't make ospf6d: configure --disable-ospf6d - -** Sample configuration files are installed as 600 file flag. - Suggested by Jeroen Ruigrok/Asmodai <asmodai@wxs.nl>. - -** syslog logging feature is added by Peter Galbavy - <Peter.Galbavy@knowledge.com> - -** Inclusion of standard header files is reworked by Peter Galbavy - <Peter.Galbavy@knowledge.com> - -** Change description from GNU/Linux 2.1.X to GNU/Linux 2.2.X - -** If daemon function exists in standard C library use it. - -** To generate configure script we upgrade autoconf to 2.13. To -generate Makefile.in we upgrade automake to 1.4. - -** doc/texinfo.tex is added to distribution. - -** Update ports/pkg/DESCR description. - -** Update doc/zebra.texi. - -** logfile FILENAME statement deleted. Instead of that please use log -file FILENAME. - -* Changes in zebra - -* Changes in bgpd - -** Communication between zebra and bgpd works now. So if there is - `router zebra' line in bgpd.conf, selected route is installed - into kernel routing table. - -** Delete all routes which inserted by bgpd when bgpd dies. If you -want to retain routes even bgpd dies please specify [-r|--retain] -option to bgpd. - -** BGP announcement code is reworked. Now bgpd announce selected - routes to other peer. - -** All output bgp packet is buffered. It's written to the socket when - it gets ready. - -** Output route-map works now. You can specify output route-map by: - - neighbor IP_ADDR route-map ROUTE_MAP_NAME out - -** New route-map command added. - - set ip nexthop IP_ADDR - set ipv6 nexthop global IP_ADDR - -** Fix bug about unlock of the route_node structure. - -** BGP-4+ support is added. bgpd can listen and speak BGP-4+ packet -specified in RFC2283. You can view IPv6 bgp table by: `show ipv6 bgp'. - -** Meny packet overflow check is added. - -* Changes in ripd - -* Changes in ripngd - -* Changes in ospfd - -** ospfd work is started by Toshiaki Takada <takada@zebra.org>. Now -several files are included in ospfd directory. - -** ospf6d codes are merged from Yasuhiro Ohara <yasu@sfc.wide.ad.jp>'s -ospfd work. Now codes are located in ospf6d directory. - - -Local variables: -mode: outline -paragraph-separate: "[ ]*$" -end: diff --git a/README b/README deleted file mode 100644 index 7600ec54c..000000000 --- a/README +++ /dev/null @@ -1,16 +0,0 @@ -FRRouting is free software that implements and manages various IPv4 and IPv6 -routing protocols. - -Currently FRRouting supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1, RIPv2, RIPng, -IS-IS, PIM-SM/MSDP, LDP and Babel as well as very early support for EIGRP and -NHRP. - -See doc/user/bugs.rst for information on how to report bugs. - -See doc/developer/workflow.rst for information on contributing. - -See the file COPYING for copying conditions. - -Public email discussion can be found at https://lists.frrouting.org/listinfo - -Our public slack channel is at https://frrouting.slack.com diff --git a/README.md b/README.md new file mode 100644 index 000000000..48142f21b --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +FRRouting +========= + +FRR is free software that implements and manages various IPv4 and IPv6 routing +protocols. It runs on nearly all distributions of Linux and BSD as well as +Solaris and supports all modern CPU architectures. + +FRR currently supports the following protocols: + +* BGP +* OSPFv2 +* OSPFv3 +* RIPv1 +* RIPv2 +* RIPng +* IS-IS +* PIM-SM/MSDP +* LDP +* BFD +* Babel +* EIGRP (alpha) +* NHRP (alpha) + +Installation & Use +------------------ + +Packages are available for various distributions on our +[releases page](https://github.com/FRRouting/frr/releases). + +Snaps are also available [here](https://snapcraft.io/frr). + +Instructions on building and installing from source for supported platforms may +be found +[here](http://docs.frrouting.org/projects/dev-guide/en/latest/building.html). + +Once installed, please refer to the [user guide](http://docs.frrouting.org/) +for instructions on use. + +Community +--------- + +The FRRouting email list server is located +[here](https://lists.frrouting.org/listinfo) and offers the following public +lists: + +| Topic | List | +|-------------------|------------------------------| +| Development | dev@lists.frrouting.org | +| Users & Operators | frog@lists.frrouting.org | +| Announcements | announce@lists.frrouting.org | + +For chat, we currently use [Slack](https://frrouting.slack.com). Please email +the mailing list to request an invite as we do not issue automatic invites. + + +Contributing +------------ + +FRR maintains [developer's documentation](http://docs.frrouting.org/projects/dev-guide/en/latest/index.html) +which contains the [project workflow](http://docs.frrouting.org/projects/dev-guide/en/latest/workflow.html) +and expectations for contributors. Some technical documentation on project +internals is also available. + +We welcome and appreciate all contributions, no matter how small! + + +Security +-------- + +To report security issues, please use our security mailing list: + +``` +security [at] lists.frrouting.org +``` diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c index ff5cca42a..31778901a 100644 --- a/babeld/babel_filter.c +++ b/babeld/babel_filter.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "babel_filter.h" #include "vty.h" #include "filter.h" diff --git a/babeld/kernel.c b/babeld/kernel.c index ba2b58131..d4c962af3 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -21,6 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <sys/time.h> #include <sys/param.h> #include <time.h> diff --git a/babeld/neighbour.c b/babeld/neighbour.c index c1592fb18..512b60e29 100644 --- a/babeld/neighbour.c +++ b/babeld/neighbour.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <string.h> #include <stdio.h> diff --git a/babeld/net.c b/babeld/net.c index ad9a6bad9..d1f6a4414 100644 --- a/babeld/net.c +++ b/babeld/net.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <unistd.h> #include <fcntl.h> #include <string.h> diff --git a/babeld/resend.c b/babeld/resend.c index 1f2197744..8949075f6 100644 --- a/babeld/resend.c +++ b/babeld/resend.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <sys/time.h> #include <time.h> #include <string.h> diff --git a/babeld/source.c b/babeld/source.c index d6dd84895..75bca0620 100644 --- a/babeld/source.c +++ b/babeld/source.c @@ -20,6 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <stdio.h> #include <string.h> diff --git a/babeld/subdir.am b/babeld/subdir.am index 6f91f7393..e1f2cb0a0 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -6,6 +6,11 @@ if BABELD noinst_LIBRARIES += babeld/libbabel.a sbin_PROGRAMS += babeld/babeld dist_examples_DATA += babeld/babeld.conf.sample +vtysh_scan += \ + $(top_srcdir)/babeld/babel_interface.c \ + $(top_srcdir)/babeld/babel_zebra.c \ + $(top_srcdir)/babeld/babeld.c \ + # end endif babeld_libbabel_a_SOURCES = \ diff --git a/babeld/util.c b/babeld/util.c index 4a3ecace0..880cda2fc 100644 --- a/babeld/util.c +++ b/babeld/util.c @@ -21,6 +21,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <stdarg.h> #include <string.h> diff --git a/bfdd/.gitignore b/bfdd/.gitignore index e554d1b33..2b020911f 100644 --- a/bfdd/.gitignore +++ b/bfdd/.gitignore @@ -1,3 +1,2 @@ # ignore binary files -*.a bfdd diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 4bdfb314e..8acb9438c 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -248,6 +248,8 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, struct iovec iov[1]; uint8_t cmsgbuf[255]; + port[0] = '\0'; + /* Prepare the recvmsg params. */ iov[0].iov_base = msgbuf; iov[0].iov_len = msgbuflen; diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 428789162..a5fae3383 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -289,7 +289,7 @@ static int _ptm_msg_read(struct stream *msg, int command, { uint32_t pid; uint8_t ttl __attribute__((unused)); - uint8_t ifnamelen; + size_t ifnamelen; /* * Register/Deregister/Update Message format: diff --git a/bfdd/subdir.am b/bfdd/subdir.am index 86923f5ce..334e974b0 100644 --- a/bfdd/subdir.am +++ b/bfdd/subdir.am @@ -6,6 +6,8 @@ if BFDD noinst_LIBRARIES += bfdd/libbfd.a sbin_PROGRAMS += bfdd/bfdd dist_examples_DATA += bfdd/bfdd.conf.sample +vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c +man8 += $(MANBUILD)/bfdd.8 endif bfdd_libbfd_a_SOURCES = \ diff --git a/bgpd/.gitignore b/bgpd/.gitignore index 105be2299..2e77195b9 100644 --- a/bgpd/.gitignore +++ b/bgpd/.gitignore @@ -1,18 +1,3 @@ -Makefile -Makefile.in -*.o bgpd bgp_btoa bgpd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/bgpd/Makefile b/bgpd/Makefile new file mode 100644 index 000000000..b8664a8e2 --- /dev/null +++ b/bgpd/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C .. bgpd/bgpd +%: ALWAYS + @$(MAKE) -s -C .. bgpd/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am deleted file mode 100644 index b6b125f75..000000000 --- a/bgpd/Makefile.am +++ /dev/null @@ -1,140 +0,0 @@ -## Process this file with automake to produce Makefile.in. -AUTOMAKE_OPTIONS = subdir-objects - -include ../common.am - -if ENABLE_BGP_VNC -#o file to keep linker happy -BGP_VNC_RFP_LIB=rfapi/rfapi_descriptor_rfp_utils.o @top_builddir@/$(LIBRFP)/librfp.a -BGP_VNC_RFP_INC=-I@top_srcdir@/$(RFPINC) -BGP_VNC_RFP_HD=\ - @top_srcdir@/$(RFPINC)/rfp.h -BGP_VNC_RFP_LD_FLAGS_FILE=@top_srcdir@/$(LIBRFP)/rfp_ld_flags -BGP_VNC_RFP_LD_FLAGS=`if [ -e "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ] ; then cat "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ; fi ` - -#BGP_VNC_RFAPI_SRCDIR=rfapi -BGP_VNC_RFAPI_SRCDIR= -BGP_VNC_RFAPI_INC=-Irfapi -BGP_VNC_RFAPI_SRC=rfapi/bgp_rfapi_cfg.c \ - rfapi/rfapi_import.c \ - rfapi/rfapi.c \ - rfapi/rfapi_ap.c \ - rfapi/rfapi_descriptor_rfp_utils.c \ - rfapi/rfapi_encap_tlv.c \ - rfapi/rfapi_nve_addr.c \ - rfapi/rfapi_monitor.c \ - rfapi/rfapi_rib.c \ - rfapi/rfapi_vty.c \ - rfapi/vnc_debug.c \ - rfapi/vnc_export_bgp.c \ - rfapi/vnc_export_table.c \ - rfapi/vnc_import_bgp.c \ - rfapi/vnc_zebra.c -BGP_VNC_RFAPI_HD=rfapi/bgp_rfapi_cfg.h \ - rfapi/rfapi_import.h \ - rfapi/rfapi.h \ - rfapi/rfapi_ap.h \ - rfapi/rfapi_backend.h \ - rfapi/rfapi_descriptor_rfp_utils.h \ - rfapi/rfapi_encap_tlv.h \ - rfapi/rfapi_nve_addr.h \ - rfapi/rfapi_monitor.h \ - rfapi/rfapi_private.h \ - rfapi/rfapi_rib.h \ - rfapi/rfapi_vty.h \ - rfapi/vnc_debug.h \ - rfapi/vnc_export_bgp.h \ - rfapi/vnc_export_table.h \ - rfapi/vnc_import_bgp.h \ - rfapi/vnc_zebra.h \ - rfapi/vnc_export_bgp_p.h \ - rfapi/vnc_import_bgp_p.h \ - bgp_vnc_types.h $(BGP_VNC_RFP_HD) - -else -BGP_VNC_RFAPI_INC= -BGP_VNC_RFAPI_SRC= -BGP_VNC_RFAPI_HD= -BGP_VNC_RFP_LIB= -BGP_VNC_RFP_INC= -BGP_VNC_RFP_HD= -BGP_VNC_RFP_LD_FLAGS= -endif - -AM_CPPFLAGS += -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC) -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -INSTALL_SDATA=@INSTALL@ -m 600 - -noinst_LIBRARIES = libbgp.a -module_LTLIBRARIES = -sbin_PROGRAMS = bgpd -bin_PROGRAMS = bgp_btoa - -BUILT_SOURCES = - -libbgp_a_SOURCES = \ - bgp_memory.c \ - bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \ - bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \ - bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \ - bgp_dump.c bgp_ecommunity.c bgp_lcommunity.c \ - bgp_mplsvpn.c bgp_nexthop.c \ - bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \ - bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \ - bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \ - bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c bgp_rd.c \ - bgp_keepalives.c bgp_io.c bgp_flowspec.c bgp_flowspec_util.c \ - bgp_flowspec_vty.c bgp_labelpool.c bgp_pbr.c bgp_errors.c - -noinst_HEADERS = \ - bgp_memory.h \ - bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \ - bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \ - bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \ - bgp_ecommunity.h bgp_lcommunity.h \ - bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \ - bgp_advertise.h bgp_vty.h bgp_mpath.h bgp_nht.h \ - bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h \ - $(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \ - bgp_vpn.h bgp_label.h bgp_rd.h bgp_evpn_private.h bgp_keepalives.h \ - bgp_io.h bgp_flowspec.h bgp_flowspec_private.h bgp_flowspec_util.h \ - bgp_labelpool.h bgp_pbr.h bgp_errors.h - -bgpd_SOURCES = bgp_main.c -bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@ -bgpd_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS) - -bgp_btoa_SOURCES = bgp_btoa.c -bgp_btoa_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@ -bgp_btoa_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS) - -if SNMP -module_LTLIBRARIES += bgpd_snmp.la -endif - -bgpd_snmp_la_SOURCES = bgp_snmp.c -bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 -bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -bgpd_snmp_la_LIBADD = ../lib/libfrrsnmp.la - -if RPKI -module_LTLIBRARIES += bgpd_rpki.la -BUILT_SOURCES += bgp_rpki_clippy.c -endif - -bgpd_rpki_la_SOURCES = bgp_rpki.c -bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS) -bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS) - -examplesdir = $(exampledir) -dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \ - bgpd.conf.vnc.sample - -bgp_vty.o: bgp_vty_clippy.c -bgp_route.o: bgp_route_clippy.c -bgp_debug.o: bgp_debug_clippy.c - -EXTRA_DIST = BGP4-MIB.txt - diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index e29508bf3..c604135bf 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "math.h" - #include <zebra.h> +#include <math.h> + #include "prefix.h" #include "lib_errors.h" diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 32506623c..2107d1f9f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -5456,7 +5456,8 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate) XFREE(MTYPE_BGP_AGGREGATE, aggregate); } -static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath, +static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin, + struct aspath *aspath, struct community *comm) { static struct aspath *ae = NULL; @@ -5467,6 +5468,9 @@ static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath, if (!ri) return 0; + if (origin != ri->attr->origin) + return 0; + if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae)) return 0; @@ -5501,7 +5505,8 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi, * If the aggregate information has not changed * no need to re-install it again. */ - if (bgp_aggregate_info_same(rn->info, aspath, community)) { + if (bgp_aggregate_info_same(rn->info, origin, aspath, + community)) { bgp_unlock_node(rn); if (aspath) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 82b268c31..2e0bb1ae6 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -49,6 +49,7 @@ #include "bgpd/bgp_route.h" #include "lib/network.h" #include "lib/thread.h" +#ifndef VTYSH_EXTRACT_PL #include "rtrlib/rtrlib.h" #include "rtrlib/rtr_mgr.h" #include "rtrlib/lib/ip.h" @@ -56,6 +57,7 @@ #if defined(FOUND_SSH) #include "rtrlib/transport/ssh/ssh_transport.h" #endif +#endif #include "hook.h" #include "libfrr.h" #include "version.h" diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index a427608f6..51504bb0a 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c index 691e1e4ec..c5fda15d3 100644 --- a/bgpd/rfapi/rfapi_ap.c +++ b/bgpd/rfapi/rfapi_ap.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c index 3217d34e7..ce5acf002 100644 --- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c +++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/table.h" diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 4c506da68..4601718f1 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -23,8 +23,6 @@ * Purpose: Handle import of routes from BGP to RFAPI */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c index 59387240f..f18c6bfe1 100644 --- a/bgpd/rfapi/rfapi_monitor.c +++ b/bgpd/rfapi/rfapi_monitor.c @@ -24,8 +24,6 @@ /* TBD remove unneeded includes */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 3ac217ff8..008da3011 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -23,8 +23,6 @@ * Purpose: maintain per-nve ribs and generate change lists */ -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index b2767da8b..cd751319e 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -18,9 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include <errno.h> - #include "lib/zebra.h" #include "lib/prefix.h" #include "lib/agg_table.h" diff --git a/bgpd/rfp-example/librfp/Makefile b/bgpd/rfp-example/librfp/Makefile new file mode 100644 index 000000000..8deb93d74 --- /dev/null +++ b/bgpd/rfp-example/librfp/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/librfp/librfp.a +%: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/librfp/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/bgpd/rfp-example/librfp/Makefile.am b/bgpd/rfp-example/librfp/Makefile.am deleted file mode 100644 index fc66a40f0..000000000 --- a/bgpd/rfp-example/librfp/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -# -# This file has been modified by LabN Consulting, L.L.C. -# -# -## Process this file with automake to produce Makefile.in. - -if ENABLE_BGP_VNC -BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi -BGP_VNC_RFP_LIBDIR=. -BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR) -BGP_VNC_RFP_LIB=librfp.a -BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR) - -librfp_a_SOURCES = \ - rfp_example.c - -librfp_a_INCLUDES = \ - rfp.h \ - rfp_internal.h - -else -BGP_VNC_RFAPI_INC= -BGP_VNC_RFAPI_SRC= -BGP_VNC_RFP_LIB= -BGP_VNC_RFP_INC= -endif - -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \ - -I$(top_builddir) -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC) -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -INSTALL_SDATA=@INSTALL@ -m 600 - -AM_CFLAGS = $(PICFLAGS) -AM_LDFLAGS = $(PILDFLAGS) - -noinst_LIBRARIES = $(BGP_VNC_RFP_LIB) - -noinst_HEADERS = \ - $(librfp_a_INCLUDES) diff --git a/bgpd/rfp-example/librfp/rfp_example.c b/bgpd/rfp-example/librfp/rfp_example.c index 75e57a029..af3092232 100644 --- a/bgpd/rfp-example/librfp/rfp_example.c +++ b/bgpd/rfp-example/librfp/rfp_example.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + /* stub rfp */ #include "rfp_internal.h" #include "bgpd/rfapi/rfapi.h" diff --git a/bgpd/rfp-example/librfp/subdir.am b/bgpd/rfp-example/librfp/subdir.am new file mode 100644 index 000000000..254ab716d --- /dev/null +++ b/bgpd/rfp-example/librfp/subdir.am @@ -0,0 +1,17 @@ +# +# librfp +# + +if ENABLE_BGP_VNC +noinst_LIBRARIES += bgpd/rfp-example/librfp/librfp.a +RFPLDADD = bgpd/rfp-example/librfp/librfp.a +endif + +bgpd_rfp_example_librfp_librfp_a_SOURCES = \ + bgpd/rfp-example/librfp/rfp_example.c \ + # end + +noinst_HEADERS += \ + bgpd/rfp-example/librfp/rfp.h \ + bgpd/rfp-example/librfp/rfp_internal.h \ + # end diff --git a/bgpd/rfp-example/rfptest/Makefile b/bgpd/rfp-example/rfptest/Makefile new file mode 100644 index 000000000..659a9ceb1 --- /dev/null +++ b/bgpd/rfp-example/rfptest/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/rfptest/rfptest +%: ALWAYS + @$(MAKE) -s -C ../../.. bgpd/rfp-example/rfptest/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/bgpd/rfp-example/rfptest/Makefile.am b/bgpd/rfp-example/rfptest/Makefile.am deleted file mode 100644 index f5db852db..000000000 --- a/bgpd/rfp-example/rfptest/Makefile.am +++ /dev/null @@ -1,52 +0,0 @@ -# -# This file has been modified by LabN Consulting, L.L.C. -# -# -## Process this file with automake to produce Makefile.in. - -if ENABLE_BGP_VNC -BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi -BGP_VNC_RFP_LIBDIR=../librfp -BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR) -BGP_VNC_RFP_LIB=$(BGP_VNC_RFP_LIBDIR)/librfp.a -BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR) - -rfptest_SOURCES = \ - rfptest.c - -rfptest_INCLUDES = \ - rfptest.h - - -RFPTEST_BIN = rfptest - -else -BGP_VNC_RFAPI_INC= -BGP_VNC_RFAPI_SRC= -BGP_VNC_RFP_LIB= -BGP_VNC_RFP_INC= -RFPTEST_BIN= -endif - -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \ - -I$(top_builddir) -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC) - -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -INSTALL_SDATA=@INSTALL@ -m 600 - - -AM_CFLAGS = $(PICFLAGS) -AM_LDFLAGS = $(PILDFLAGS) - - -noinst_HEADERS = \ - $(rfptest_INCLUDES) - -noinst_LIBRARIES = -sbin_PROGRAMS = $(RFPTEST_BIN) - -examplesdir = $(exampledir) - -rfptest_LDADD = $(top_builddir)/lib/libfrr.la $(BGP_VNC_RFP_LIB) -dist_examples_DATA = diff --git a/bgpd/rfp-example/rfptest/rfptest.c b/bgpd/rfp-example/rfptest/rfptest.c index 53e1c33cf..48df6c0cc 100644 --- a/bgpd/rfp-example/rfptest/rfptest.c +++ b/bgpd/rfp-example/rfptest/rfptest.c @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* dummy test program */ #include <stdio.h> diff --git a/bgpd/rfp-example/rfptest/subdir.am b/bgpd/rfp-example/rfptest/subdir.am new file mode 100644 index 000000000..fa7c66011 --- /dev/null +++ b/bgpd/rfp-example/rfptest/subdir.am @@ -0,0 +1,20 @@ +# +# libtest +# + +if ENABLE_BGP_VNC +sbin_PROGRAMS += bgpd/rfp-example/rfptest/rfptest +endif + +bgpd_rfp_example_rfptest_rfptest_CFLAGS = -I$(top_srcdir)/bgpd/rfapi +bgpd_rfp_example_rfptest_rfptest_SOURCES = \ + bgpd/rfp-example/rfptest/rfptest.c \ + # end +noinst_HEADERS += \ + bgpd/rfp-example/rfptest/rfptest.h \ + # end + +bgpd_rfp_example_rfptest_rfptest_LDADD = \ + lib/libfrr.la \ + $(RFPLDADD) \ + # end diff --git a/bgpd/subdir.am b/bgpd/subdir.am new file mode 100644 index 000000000..429138856 --- /dev/null +++ b/bgpd/subdir.am @@ -0,0 +1,221 @@ +# +# bgpd +# + +if BGPD +noinst_LIBRARIES += bgpd/libbgp.a +sbin_PROGRAMS += bgpd/bgpd +noinst_PROGRAMS += bgpd/bgp_btoa +dist_examples_DATA += \ + bgpd/bgpd.conf.sample \ + bgpd/bgpd.conf.sample2 \ + bgpd/bgpd.conf.vnc.sample \ + # end +vtysh_scan += \ + $(top_srcdir)/bgpd/bgp_bfd.c \ + $(top_srcdir)/bgpd/bgp_debug.c \ + $(top_srcdir)/bgpd/bgp_dump.c \ + $(top_srcdir)/bgpd/bgp_evpn_vty.c \ + $(top_srcdir)/bgpd/bgp_filter.c \ + $(top_srcdir)/bgpd/bgp_mplsvpn.c \ + $(top_srcdir)/bgpd/bgp_nexthop.c \ + $(top_srcdir)/bgpd/bgp_route.c \ + $(top_srcdir)/bgpd/bgp_routemap.c \ + $(top_srcdir)/bgpd/bgp_vty.c \ + $(top_srcdir)/bgpd/bgp_flowspec_vty.c \ + # end + +# can be loaded as DSO - always include for vtysh +vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c + +if ENABLE_BGP_VNC +vtysh_scan += \ + $(top_srcdir)/bgpd/rfapi/bgp_rfapi_cfg.c \ + $(top_srcdir)/bgpd/rfapi/rfapi.c \ + $(top_srcdir)/bgpd/rfapi/rfapi_vty.c \ + $(top_srcdir)/bgpd/rfapi/vnc_debug.c \ + # end +endif +if SNMP +module_LTLIBRARIES += bgpd/bgpd_snmp.la +endif +if RPKI +module_LTLIBRARIES += bgpd/bgpd_rpki.la +endif +man8 += $(MANBUILD)/bgpd.8 +endif + +bgpd_libbgp_a_SOURCES = \ + bgpd/bgp_advertise.c \ + bgpd/bgp_aspath.c \ + bgpd/bgp_attr.c \ + bgpd/bgp_attr_evpn.c \ + bgpd/bgp_bfd.c \ + bgpd/bgp_clist.c \ + bgpd/bgp_community.c \ + bgpd/bgp_damp.c \ + bgpd/bgp_debug.c \ + bgpd/bgp_dump.c \ + bgpd/bgp_ecommunity.c \ + bgpd/bgp_encap_tlv.c \ + bgpd/bgp_errors.c \ + bgpd/bgp_evpn.c \ + bgpd/bgp_evpn_vty.c \ + bgpd/bgp_filter.c \ + bgpd/bgp_flowspec.c \ + bgpd/bgp_flowspec_util.c \ + bgpd/bgp_flowspec_vty.c \ + bgpd/bgp_fsm.c \ + bgpd/bgp_io.c \ + bgpd/bgp_keepalives.c \ + bgpd/bgp_label.c \ + bgpd/bgp_labelpool.c \ + bgpd/bgp_lcommunity.c \ + bgpd/bgp_memory.c \ + bgpd/bgp_mpath.c \ + bgpd/bgp_mplsvpn.c \ + bgpd/bgp_network.c \ + bgpd/bgp_nexthop.c \ + bgpd/bgp_nht.c \ + bgpd/bgp_open.c \ + bgpd/bgp_packet.c \ + bgpd/bgp_pbr.c \ + bgpd/bgp_rd.c \ + bgpd/bgp_regex.c \ + bgpd/bgp_route.c \ + bgpd/bgp_routemap.c \ + bgpd/bgp_table.c \ + bgpd/bgp_updgrp.c \ + bgpd/bgp_updgrp_adv.c \ + bgpd/bgp_updgrp_packet.c \ + bgpd/bgp_vpn.c \ + bgpd/bgp_vty.c \ + bgpd/bgp_zebra.c \ + bgpd/bgpd.c \ + # end + +if ENABLE_BGP_VNC +bgpd_libbgp_a_SOURCES += \ + bgpd/rfapi/bgp_rfapi_cfg.c \ + bgpd/rfapi/rfapi_import.c \ + bgpd/rfapi/rfapi.c \ + bgpd/rfapi/rfapi_ap.c \ + bgpd/rfapi/rfapi_descriptor_rfp_utils.c \ + bgpd/rfapi/rfapi_encap_tlv.c \ + bgpd/rfapi/rfapi_nve_addr.c \ + bgpd/rfapi/rfapi_monitor.c \ + bgpd/rfapi/rfapi_rib.c \ + bgpd/rfapi/rfapi_vty.c \ + bgpd/rfapi/vnc_debug.c \ + bgpd/rfapi/vnc_export_bgp.c \ + bgpd/rfapi/vnc_export_table.c \ + bgpd/rfapi/vnc_import_bgp.c \ + bgpd/rfapi/vnc_zebra.c \ + # end +endif + +noinst_HEADERS += \ + bgpd/bgp_advertise.h \ + bgpd/bgp_aspath.h \ + bgpd/bgp_attr.h \ + bgpd/bgp_attr_evpn.h \ + bgpd/bgp_bfd.h \ + bgpd/bgp_clist.h \ + bgpd/bgp_community.h \ + bgpd/bgp_damp.h \ + bgpd/bgp_debug.h \ + bgpd/bgp_dump.h \ + bgpd/bgp_ecommunity.h \ + bgpd/bgp_encap_tlv.h \ + bgpd/bgp_encap_types.h \ + bgpd/bgp_errors.h \ + bgpd/bgp_evpn.h \ + bgpd/bgp_evpn_private.h \ + bgpd/bgp_evpn_vty.h \ + bgpd/bgp_filter.h \ + bgpd/bgp_flowspec.h \ + bgpd/bgp_flowspec_private.h \ + bgpd/bgp_flowspec_util.h \ + bgpd/bgp_fsm.h \ + bgpd/bgp_io.h \ + bgpd/bgp_keepalives.h \ + bgpd/bgp_label.h \ + bgpd/bgp_labelpool.h \ + bgpd/bgp_lcommunity.h \ + bgpd/bgp_memory.h \ + bgpd/bgp_mpath.h \ + bgpd/bgp_mplsvpn.h \ + bgpd/bgp_network.h \ + bgpd/bgp_nexthop.h \ + bgpd/bgp_nht.h \ + bgpd/bgp_open.h \ + bgpd/bgp_packet.h \ + bgpd/bgp_pbr.h \ + bgpd/bgp_rd.h \ + bgpd/bgp_regex.h \ + bgpd/bgp_route.h \ + bgpd/bgp_table.h \ + bgpd/bgp_updgrp.h \ + bgpd/bgp_vpn.h \ + bgpd/bgp_vty.h \ + bgpd/bgp_zebra.h \ + bgpd/bgpd.h \ + \ + bgpd/rfapi/bgp_rfapi_cfg.h \ + bgpd/rfapi/rfapi_import.h \ + bgpd/rfapi/rfapi.h \ + bgpd/rfapi/rfapi_ap.h \ + bgpd/rfapi/rfapi_backend.h \ + bgpd/rfapi/rfapi_descriptor_rfp_utils.h \ + bgpd/rfapi/rfapi_encap_tlv.h \ + bgpd/rfapi/rfapi_nve_addr.h \ + bgpd/rfapi/rfapi_monitor.h \ + bgpd/rfapi/rfapi_private.h \ + bgpd/rfapi/rfapi_rib.h \ + bgpd/rfapi/rfapi_vty.h \ + bgpd/rfapi/vnc_debug.h \ + bgpd/rfapi/vnc_export_bgp.h \ + bgpd/rfapi/vnc_export_table.h \ + bgpd/rfapi/vnc_import_bgp.h \ + bgpd/rfapi/vnc_zebra.h \ + bgpd/rfapi/vnc_export_bgp_p.h \ + bgpd/rfapi/vnc_import_bgp_p.h \ + bgpd/bgp_vnc_types.h \ + # end + +bgpd_bgpd_SOURCES = bgpd/bgp_main.c +bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c + +if ENABLE_BGP_VNC +bgpd_bgpd_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c +bgpd_bgpd_CFLAGS = -Irfapi -I@top_srcdir@/$(RFPINC) + +bgpd_bgp_btoa_SOURCES += bgpd/rfapi/rfapi_descriptor_rfp_utils.c +bgpd_bgp_btoa_CFLAGS = -Irfapi -I@top_srcdir@/$(RFPINC) +endif + +# RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am +bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la @LIBCAP@ @LIBM@ +bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la @LIBCAP@ @LIBM@ + +bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c +bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 +bgpd_bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic +bgpd_bgpd_snmp_la_LIBADD = lib/libfrrsnmp.la + +bgpd_bgpd_rpki_la_SOURCES = bgpd/bgp_rpki.c +bgpd_bgpd_rpki_la_CFLAGS = $(WERROR) $(RTRLIB_CFLAGS) +bgpd_bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic +bgpd_bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS) + +bgpd/bgp_vty_clippy.c: $(CLIPPY_DEPS) +bgpd/bgp_vty.$(OBJEXT): bgpd/bgp_vty_clippy.c +bgpd/bgp_route_clippy.c: $(CLIPPY_DEPS) +bgpd/bgp_route.$(OBJEXT): bgpd/bgp_route_clippy.c +bgpd/bgp_debug_clippy.c: $(CLIPPY_DEPS) +bgpd/bgp_debug.$(OBJEXT): bgpd/bgp_debug_clippy.c +bgpd/bgp_rpki_clippy.c: $(CLIPPY_DEPS) +$(AUTOMAKE_DUMMY)bgpd/bgpd_bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c +$(AUTOMAKE_DUMMY)bgpd/bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c + +EXTRA_DIST += bgpd/BGP4-MIB.txt diff --git a/common.am b/common.am deleted file mode 100644 index 9c0c54781..000000000 --- a/common.am +++ /dev/null @@ -1,61 +0,0 @@ -# -# Automake fragment intended to be shared by Makefile.am files in the -# tree. When used, should be included at the very top of the file. -# -AM_CPPFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ -AM_CFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ $(WERROR) - -AM_V_CLIPPY = $(am__v_CLIPPY_$(V)) -am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY)) -am__v_CLIPPY_0 = @echo " CLIPPY " $@; -am__v_CLIPPY_1 = - -CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py - -SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h -.c_clippy.c: - @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } - $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $< - -## automake's "ylwrap" is a great piece of GNU software... not. -.l.c: - $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $< -.y.c: - $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $< - - -if HAVE_PROTOBUF - -# Uncomment to use an non-system version of libprotobuf-c. -# -# Q_PROTOBUF_C_CLIENT_INCLUDES = -I$(top_srcdir)/third-party/protobuf-c/src -# Q_PROTOBUF_C_CLIENT_LDOPTS = $(top_builddir)/third-party/protobuf-c/src/libprotobuf-c.la - -Q_PROTOBUF_C_CLIENT_INCLUDES= -Q_PROTOBUF_C_CLIENT_LDOPTS=-lprotobuf-c - -Q_PROTOC=protoc -Q_PROTOC_C=protoc-c - -# Rules -.proto.pb.h: - $(Q_PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^ - -AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V)) -am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY)) -am__v_PROTOC_C_0 = @echo " PROTOC_C" $@; -am__v_PROTOC_C_1 = - -.proto.pb-c.c: - $(AM_V_PROTOC_C)$(Q_PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^ -.pb-c.c.pb-c.h: - @/bin/true - -# -# Information about how to link to various libraries. -# -Q_FRR_PB_CLIENT_LDOPTS = $(top_srcdir)/qpb/libfrr_pb.la $(Q_PROTOBUF_C_CLIENT_LDOPTS) - -Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfrrfpm_pb.la $(Q_FRR_PB_CLIENT_LDOPTS) - -endif # HAVE_PROTOBUF diff --git a/configure.ac b/configure.ac index 09a6f364f..08f1c117e 100755 --- a/configure.ac +++ b/configure.ac @@ -57,7 +57,7 @@ AM_CONDITIONAL([BUILD_CLIPPY], [$build_clippy]) # Disable portability warnings -- our automake code (in particular # common.am) uses some constructs specific to gmake. -AM_INIT_AUTOMAKE([1.12 -Wno-portability]) +AM_INIT_AUTOMAKE([1.12 -Wno-portability foreign]) m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])]) AM_SILENT_RULES([yes]) AC_CONFIG_HEADERS(config.h) @@ -189,46 +189,6 @@ CC="${CC% -std=c99}" AC_C_FLAG([-std=gnu11], [CC="$ac_cc"], [CC="$CC -std=gnu11"]) -dnl AddressSanitizer support -AC_ARG_ENABLE([address-sanitizer], AS_HELP_STRING([--enable-address-sanitizer], \ - [enabled AddressSanitizer support for detecting a wide variety of \ - memory allocation and deallocation errors]), \ - [AC_DEFINE(HAVE_ADDRESS_SANITIZER, 1, [enable AddressSanitizer]) - ASAN_FLAGS="-fsanitize=address" - SAN_CLIPPY_FLAGS="-fno-sanitize=all" - AC_SUBST([ASAN_FLAGS]) - AC_SUBST([SAN_CLIPPY_FLAGS]) - LIBS="-ldl $LIBS" - AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Address Sanitizer Enabled])], - [AC_MSG_ERROR([Address Sanitizer not available])]) - ]) - -dnl ThreadSanitizer support -AC_ARG_ENABLE([thread-sanitizer], AS_HELP_STRING([--enable-thread-sanitizer], \ - [enabled ThreadSanitizer support for detecting data races]), \ - [AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable ThreadSanitizer]) - TSAN_FLAGS="-fsanitize=thread" - SAN_CLIPPY_FLAGS="-fno-sanitize=all" - AC_SUBST([TSAN_FLAGS]) - AC_SUBST([SAN_CLIPPY_FLAGS]) - LIBS="-ldl $LIBS" - AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Thread Sanitizer Enabled])], - [AC_MSG_ERROR([Thread Sanitizer not available])]) - ]) - -dnl MemorySanitizer support -AC_ARG_ENABLE([memory-sanitizer], AS_HELP_STRING([--enable-memory-sanitizer], \ - [enabled MemorySanitizer support for detecting uninitialized memory reads]), \ - [AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable MemorySanitizer]) - MSAN_FLAGS="-fsanitize=memory -fPIE -pie" - SAN_CLIPPY_FLAGS="-fno-sanitize=all" - AC_SUBST([MSAN_FLAGS]) - AC_SUBST([SAN_CLIPPY_FLAGS]) - LIBS="-ldl $LIBS" - AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Memory Sanitizer Enabled])], - [AC_MSG_ERROR([Memory Sanitizer not available])]) - ]) - dnl if the user has specified any CFLAGS, override our settings if test "x${enable_gcov}" = "xyes"; then if test "z$orig_cflags" = "z"; then @@ -287,19 +247,29 @@ if test x"${enable_werror}" = x"yes" ; then fi AC_SUBST(WERROR) -dnl need link on this one, not compile -AC_LANG_PUSH(C) -ac_ld_flag_save="$LDFLAGS" -LDFLAGS="$LDFLAGS -rdynamic" -AC_MSG_CHECKING([[whether linker supports -rdynamic]]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[]])], - [AC_MSG_RESULT([yes])], - [ - LDFLAGS="$ac_ld_flag_save" - AC_MSG_RESULT([no]) - ]) -AC_LANG_POP(C) +SAN_FLAGS="" +if test "$enable_address_sanitizer" = "yes"; then + AC_C_FLAG([-fsanitize=address], [ + AC_MSG_ERROR([$CC does not support Address Sanitizer.]) + ], [ + SAN_FLAGS="$SAN_FLAGS -fsanitize=address" + ]) +fi +if test "$enable_thread_sanitizer" = "yes"; then + AC_C_FLAG([-fsanitize=thread], [ + AC_MSG_ERROR([$CC does not support Thread Sanitizer.]) + ], [ + SAN_FLAGS="$SAN_FLAGS -fsanitize=thread" + ]) +fi +if test "$enable_memory_sanitizer" = "yes"; then + AC_C_FLAG([-fsanitize=thread -fPIE -pie], [ + AC_MSG_ERROR([$CC does not support Thread Sanitizer.]) + ], [ + SAN_FLAGS="-fsanitize=memory -fPIE -pie" + ]) +fi +AC_SUBST([SAN_FLAGS]) dnl ---------- dnl Essentials @@ -313,6 +283,13 @@ AX_PTHREAD([ AC_MSG_FAILURE([This FRR version needs pthreads]) ]) +AC_SEARCH_LIBS([pthread_condattr_setclock], [], + [frr_cv_pthread_condattr_setclock=yes], + [frr_cv_pthread_condattr_setclock=no]) +if test "$frr_cv_pthread_condattr_setclock" = yes; then + AC_DEFINE(HAVE_PTHREAD_CONDATTR_SETCLOCK, 1, [Have pthread.h pthread_condattr_setclock]) +fi + dnl -------------- dnl Check programs dnl -------------- @@ -321,11 +298,6 @@ AC_PROG_LN_S AC_PROG_MAKE_SET AC_CHECK_TOOL(AR, ar) -dnl ----------------- -dnl System extensions -dnl ----------------- -AC_GNU_SOURCE - dnl ------- dnl libtool dnl ------- @@ -381,12 +353,12 @@ AC_ARG_ENABLE(sharpd, AS_HELP_STRING([--enable-sharpd], [build sharpd])) AC_ARG_ENABLE(staticd, AS_HELP_STRING([--disable-staticd], [do not build staticd])) +AC_ARG_ENABLE(fabricd, + AS_HELP_STRING([--disable-fabricd], [do not build fabricd])) AC_ARG_ENABLE(bgp-announce, AS_HELP_STRING([--disable-bgp-announce,], [turn off BGP route announcement])) AC_ARG_ENABLE(bgp-vnc, AS_HELP_STRING([--disable-bgp-vnc],[turn off BGP VNC support])) -AC_ARG_WITH(rfp-path, - AS_HELP_STRING([--with-rfp-path[=DIR]],[path to replaced stub RFP used with BGP VNC])) AC_ARG_ENABLE(snmp, AS_HELP_STRING([--enable-snmp], [enable SNMP support for agentx])) AC_ARG_ENABLE(zeromq, @@ -460,6 +432,12 @@ AC_ARG_ENABLE([gcov], AS_HELP_STRING([--enable-gcov], [Add code coverage information])) AC_ARG_ENABLE(bfdd, AS_HELP_STRING([--disable-bfdd], [do not build bfdd])) +AC_ARG_ENABLE([address-sanitizer], + AS_HELP_STRING([--enable-address-sanitizer], [enable AddressSanitizer support for detecting a wide variety of memory allocation and deallocation errors])) +AC_ARG_ENABLE([thread-sanitizer], + AS_HELP_STRING([--enable-thread-sanitizer], [enable ThreadSanitizer support for detecting data races])) +AC_ARG_ENABLE([memory-sanitizer], + AS_HELP_STRING([--enable-memory-sanitizer], [enable MemorySanitizer support for detecting uninitialized memory reads])) AS_IF([test "${enable_clippy_only}" != "yes"], [ AC_CHECK_HEADERS(json-c/json.h) @@ -623,27 +601,26 @@ AC_SUBST(PYTHON_LIBS) # Logic for protobuf support. # if test "$enable_protobuf" = "yes"; then - have_protobuf=yes - - # Check for protoc-c - AC_CHECK_PROG([PROTOC_C], [protoc-c], [protoc-c], [/bin/false]) - if test "x$PROTOC_C" = "x/bin/false"; then - have_protobuf=no - else - found_protobuf_c=no - PKG_CHECK_MODULES([PROTOBUF_C], libprotobuf-c >= 0.14, - [found_protobuf_c=yes], - [AC_MSG_RESULT([pkg-config did not find libprotobuf-c])]) - - if test "x$found_protobuf_c" = "xyes"; then - LDFLAGS="$LDFLAGS $PROTOBUF_C_LIBS" - CFLAGS="$CFLAGS $PROTOBUF_C_CFLAGS" - else - AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [], - [have_protobuf=no; AC_MSG_RESULT([Couldn't find google/protobuf-c.h])]) - fi - fi + # Check for protoc & protoc-c + + # protoc is not required, it's only for a "be nice" helper target + AC_CHECK_PROGS([PROTOC], [protoc], [/bin/false]) + + AC_CHECK_PROGS([PROTOC_C], [protoc-c], [/bin/false]) + if test "$PROTOC_C" = "/bin/false"; then + AC_MSG_FAILURE([protobuf requested but protoc-c not found. Install protobuf-c.]) + fi + + PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c >= 0.14],, [ + AC_MSG_FAILURE([protobuf requested but libprotobuf-c not found. Install protobuf-c.]) + ]) + AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [], [ + AC_MSG_FAILURE([protobuf requested but protobuf-c.h not found. Install protobuf-c.]) + ]) + + AC_DEFINE(HAVE_PROTOBUF,, protobuf) fi +AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$enable_protobuf" = "xyes"]) # # Logic for old vpn commans support. @@ -652,18 +629,6 @@ if test "$enable_oldvpn_commands" = "yes"; then AC_DEFINE(KEEP_OLD_VPN_COMMANDS,, [Define for compiling with old vpn commands]) fi -# Fail if the user explicity enabled protobuf support and we couldn't -# find the compiler or libraries. -if test "x$have_protobuf" = "xno" && test "x$enable_protobuf" = "xyes"; then - AC_MSG_ERROR([Protobuf enabled explicitly but can't find libraries/tools]) -fi - -if test "x$have_protobuf" = "xyes"; then - AC_DEFINE(HAVE_PROTOBUF,, protobuf) -fi - -AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$have_protobuf" = "xyes"]) - # # End of logic for protobuf support. # @@ -850,10 +815,15 @@ int main(int argc, char **argv) { ]) ]) +AC_CHECK_HEADERS([pthread_np.h],,, [ +#include <pthread.h> +]) +AC_CHECK_FUNCS([pthread_setname_np pthread_set_name_np]) + dnl Utility macro to avoid retyping includes all the time m4_define([FRR_INCLUDES], [#ifdef SUNOS_5 -#define _XPG4_2 +#define _POSIX_C_SOURCE 200809L #define __EXTENSIONS__ #endif #include <stdio.h> @@ -946,6 +916,7 @@ case "$host_os" in AC_DEFINE(SUNOS_5, 1, [SunOS 5]) AC_DEFINE(SOLARIS_IPV6, 1, Solaris IPv6) + AC_DEFINE(_POSIX_C_SOURCE, 200809L, [enable POSIX.1-2008 and XPG7/SUSv4]) AC_CHECK_LIB(socket, main) AC_CHECK_LIB(nsl, main) @@ -1049,6 +1020,10 @@ dnl [TODO] on Linux, and in [TODO] on Solaris. if test $ac_cv_lib_readline_rl_completion_matches = no; then AC_DEFINE(rl_completion_matches,completion_matches,Old readline) fi + AC_SEARCH_LIBS([append_history], [readline], [frr_cv_append_history=yes], [frr_cv_append_history=no]) + if test "$frr_cv_append_history" = yes; then + AC_DEFINE(HAVE_APPEND_HISTORY, 1, [Have history.h append_history]) + fi ;; esac AC_SUBST(LIBREADLINE) @@ -1197,11 +1172,12 @@ case "$host_os" in if test $ac_cv_header_net_bpf_h = no; then if test $ac_cv_header_sys_dlpi_h = no; then AC_MSG_RESULT(none) - if test "${enable_isisd}" = yes; then + if test "${enable_isisd}" = yes -o "${enable_fabricd}" = yes; then AC_MSG_FAILURE([IS-IS support requested but no packet backend found]) fi AC_MSG_WARN([*** IS-IS support will not be built ***]) enable_isisd="no" + enable_fabricd="no" else AC_MSG_RESULT(DLPI) fi @@ -1339,8 +1315,13 @@ FRR_INCLUDES ])dnl dnl disable doc check -AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [no]) -AM_CONDITIONAL(DOC, test "${enable_doc}" != "no") +AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [/bin/false]) +if test "$SPHINXBUILD" = "/bin/false"; then + if test "${enable_doc}" = "yes"; then + AC_MSG_ERROR([Documentation was explicitly requested with --enable-doc but sphinx-build is not available. Please disable docs or install sphinx.]) + fi +fi +AM_CONDITIONAL(DOC, test "${enable_doc}" != "no" -a "$SPHINXBUILD" != "/bin/false") AM_CONDITIONAL(DOC_HTML, test "${enable_doc_html}" = "yes") dnl -------------------- @@ -1429,6 +1410,7 @@ AM_CONDITIONAL(PIMD, test "${enable_pimd}" != "no") AM_CONDITIONAL(PBRD, test "${enable_pbrd}" != "no") AM_CONDITIONAL(SHARPD, test "${enable_sharpd}" = "yes") AM_CONDITIONAL(STATICD, test "${enable_staticd}" != "no") +AM_CONDITIONAL(FABRICD, test "${enable_fabricd}" != "no") if test "${enable_bgp_announce}" = "no";then AC_DEFINE(DISABLE_BGP_ANNOUNCE,1,Disable BGP installation to zebra) @@ -1436,33 +1418,12 @@ else AC_DEFINE(DISABLE_BGP_ANNOUNCE,0,Disable BGP installation to zebra) fi -if test "${with_rfp_path}" = "yes" || test x"${with_rfp_path}" = x""; then - with_rfp_path="bgpd/rfp-example" -fi -if test "${with_rfp_path}" != "no"; then - VNC_RFP_PATH="${with_rfp_path}" - AC_SUBST(VNC_RFP_PATH) -fi - if test "${enable_bgp_vnc}" != "no";then AC_DEFINE(ENABLE_BGP_VNC,1,Enable BGP VNC support) - RFPTEST="${with_rfp_path}/rfptest" - LIBRFP="${with_rfp_path}/librfp" - RFPINC="${with_rfp_path}/librfp" -else - RFPTEST= - LIBRFP= - RFPINC="bgpd/rfp-example/librfp" fi -# set AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno]) -AC_SUBST(RFPTEST) -AC_SUBST(LIBRFP) -AC_SUBST(RFPINC) -AC_SUBST(BGPD) AC_SUBST(SOLARIS) -AC_SUBST(VTYSH) AC_SUBST(CURSES) AC_CHECK_LIB(crypt, crypt, [], [AC_CHECK_LIB(crypto, DES_crypt)]) @@ -1833,13 +1794,16 @@ dnl order to check no alternative allocator dnl has been specified, which might not provide dnl mallinfo, e.g. such as Umem on Solaris. dnl ----------------------------------------- -AC_CHECK_HEADERS([malloc.h malloc/malloc.h],,, [FRR_INCLUDES]) +AC_CHECK_HEADERS([malloc.h malloc_np.h malloc/malloc.h],,, [FRR_INCLUDES]) AC_CACHE_CHECK([whether mallinfo is available], [frr_cv_mallinfo], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [ #ifdef HAVE_MALLOC_H #include <malloc.h> #endif +#ifdef HAVE_MALLOC_NP_H +#include <malloc_np.h> +#endif #ifdef HAVE_MALLOC_MALLOC_H #include <malloc/malloc.h> #endif @@ -1983,8 +1947,7 @@ dnl Enable RPKI and add librtr to libs dnl ------------------------------------ if test "${enable_rpki}" = "yes"; then PKG_CHECK_MODULES(RTRLIB,[rtrlib >= 0.5.0], - [AC_DEFINE(HAVE_RPKI,1,Enable RPKI prefix validation for BGP) - RPKI=true], + [RPKI=true], [RPKI=false AC_MSG_ERROR([rtrlib was not found on your system or is too old.])] ) @@ -2016,11 +1979,6 @@ AC_MSG_RESULT($ac_cv_htonl_works) AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile]) AC_CONFIG_FILES([ - bgpd/Makefile - vtysh/Makefile - tests/Makefile - bgpd/rfp-example/rfptest/Makefile - bgpd/rfp-example/librfp/Makefile redhat/frr.spec solaris/Makefile debianpkg/changelog @@ -2032,12 +1990,6 @@ AC_CONFIG_FILES([ pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh pkgsrc/eigrpd.sh]) -if test "${enable_bgp_vnc}" != "no"; then - if test "${with_rfp_path}" != "bgpd/rfp-example" ; then - AC_CONFIG_FILES([${with_rfp_path}/rfptest/Makefile ${with_rfp_path}/librfp/Makefile]) - fi -fi - AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl]) AC_CONFIG_COMMANDS([lib/route_types.h], [ @@ -2079,9 +2031,9 @@ FRR version : ${PACKAGE_VERSION} host operating system : ${host_os} source code location : ${srcdir} compiler : ${CC} -compiler flags : ${CFLAGS} +compiler flags : ${CFLAGS} ${SAN_FLAGS} make : ${MAKE-make} -linker flags : ${LDFLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM} +linker flags : ${LDFLAGS} ${SAN_FLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM} state file directory : ${frr_statedir} config file directory : `eval echo \`echo ${sysconfdir}\`` example directory : `eval echo \`echo ${exampledir}\`` @@ -2091,12 +2043,12 @@ group to run as : ${enable_group} group for vty sockets : ${enable_vty_group} config file mask : ${enable_configfile_mask} log file mask : ${enable_logfile_mask} -zebra protobuf enabled : ${have_protobuf:-no} +zebra protobuf enabled : ${enable_protobuf:-no} The above user and group must have read/write access to the state file directory and to the config files in the config file directory." if test "${enable_doc}" != "no";then - AS_IF([test "x$SPHINXBUILD" = xno], + AS_IF([test "$SPHINXBUILD" = /bin/false], AC_MSG_WARN(sphinx-build is missing but required to build documentation)) fi diff --git a/debianpkg/frr-doc.docs b/debianpkg/frr-doc.docs index d2218d00f..605353289 100644 --- a/debianpkg/frr-doc.docs +++ b/debianpkg/frr-doc.docs @@ -1,5 +1,3 @@ -AUTHORS -NEWS -README +README.md doc/user/*.rst doc/figures/*.png diff --git a/doc/.gitignore b/doc/.gitignore index d99a6a5b2..fa2b50832 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,4 +1,3 @@ -!Makefile mdate-sh draft-zebra-00.txt *.pdf @@ -6,7 +5,6 @@ draft-zebra-00.txt frr.ps frr.dvi stamp-vti -.nfs* *.aux *.cp *.cps @@ -20,8 +18,4 @@ stamp-vti *.toc *.tp *.vr -.arch-inventory -.arch-ids -*~ -*.loT refix diff --git a/doc/developer/building-frr-for-centos6.rst b/doc/developer/building-frr-for-centos6.rst index d4c2c3bfd..5f10f3715 100644 --- a/doc/developer/building-frr-for-centos6.rst +++ b/doc/developer/building-frr-for-centos6.rst @@ -128,8 +128,8 @@ Add frr groups and user .. code-block:: shell sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + sudo groupadd -r -g 85 frrvty + sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr Download Source, configure and compile it @@ -158,7 +158,7 @@ an example.) --enable-ospfapi=yes \ --enable-user=frr \ --enable-group=frr \ - --enable-vty-group=frrvt \ + --enable-vty-group=frrvty \ --enable-rtadv \ --disable-exampledir \ --enable-watchfrr \ @@ -168,10 +168,11 @@ an example.) --enable-eigrpd \ --enable-babeld \ --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make SPHINXBUILD=sphinx-build2.7 - make check PYTHON=/usr/bin/python2.7 SPHINXBUILD=sphinx-build2.7 - sudo make SPHINXBUILD=sphinx-build2.7 install + --with-pkg-extra-version=-MyOwnFRRVersion \ + SPHINXBUILD=sphinx-build2.7 + make + make check PYTHON=/usr/bin/python2.7 + sudo make install Create empty FRR configuration files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst index 31cd4dcc4..b157f540a 100644 --- a/doc/developer/building-frr-for-centos7.rst +++ b/doc/developer/building-frr-for-centos7.rst @@ -36,8 +36,8 @@ Add frr groups and user :: sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + sudo groupadd -r -g 85 frrvty + sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr Download Source, configure and compile it @@ -66,7 +66,7 @@ an example.) --enable-ospfapi=yes \ --enable-user=frr \ --enable-group=frr \ - --enable-vty-group=frrvt \ + --enable-vty-group=frrvty \ --enable-rtadv \ --enable-systemd=yes \ --disable-exampledir \ @@ -102,7 +102,7 @@ Create empty FRR configuration files sudo touch /etc/frr/babeld.conf sudo chown -R frr:frr /etc/frr/ sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf + sudo chown frr:frrvty /etc/frr/vtysh.conf sudo chmod 640 /etc/frr/*.conf Install daemon config file diff --git a/doc/developer/building-frr-for-fedora24.rst b/doc/developer/building-frr-for-fedora24.rst index 208c580b6..669cc4ae2 100644 --- a/doc/developer/building-frr-for-fedora24.rst +++ b/doc/developer/building-frr-for-fedora24.rst @@ -29,8 +29,8 @@ Add frr groups and user :: sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + sudo groupadd -r -g 85 frrvty + sudo useradd -u 92 -g 92 -M -r -G frrvty -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr Download Source, configure and compile it @@ -59,7 +59,7 @@ an example.) --enable-ospfapi=yes \ --enable-user=frr \ --enable-group=frr \ - --enable-vty-group=frrvt \ + --enable-vty-group=frrvty \ --enable-rtadv \ --disable-exampledir \ --enable-watchfrr \ @@ -95,7 +95,7 @@ Create empty FRR configuration files sudo touch /etc/frr/babeld.conf sudo chown -R frr:frr /etc/frr/ sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf + sudo chown frr:frrvty /etc/frr/vtysh.conf sudo chmod 640 /etc/frr/*.conf Install daemon config file diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst index 20391c47b..c0716a5c9 100644 --- a/doc/developer/cli.rst +++ b/doc/developer/cli.rst @@ -450,8 +450,6 @@ is no ordering requirement) .. code-block:: make - include ../common.am - # ... # if linked into a LTLIBRARY (.la/.so): diff --git a/doc/manpages/common-options.rst b/doc/manpages/common-options.rst index 5fff6fca6..74d3eb7bb 100644 --- a/doc/manpages/common-options.rst +++ b/doc/manpages/common-options.rst @@ -125,6 +125,7 @@ These following options control the daemon's VTY (interactive command line) inte pbrd 2615 staticd 2616 bfdd 2617 + fabricd 2618 Port 2607 is used for ospfd's Opaque LSA API. diff --git a/doc/manpages/conf.py b/doc/manpages/conf.py index e540d236e..f57bc1d27 100644 --- a/doc/manpages/conf.py +++ b/doc/manpages/conf.py @@ -333,6 +333,7 @@ man_pages = [ ('vtysh', 'vtysh', 'an integrated shell for FRRouting.', [], 1), ('frr', 'frr', 'a systemd interaction script', [], 1), ('bfdd', 'bfdd', fwfrr.format("a bfd"), [], 8), + ('fabricd', 'fabricd', fwfrr.format("an OpenFabric "), [], 8), ] # -- Options for Texinfo output ------------------------------------------- diff --git a/doc/manpages/fabricd.rst b/doc/manpages/fabricd.rst new file mode 100644 index 000000000..c14c07661 --- /dev/null +++ b/doc/manpages/fabricd.rst @@ -0,0 +1,38 @@ +******* +FABRICD +******* + +.. include:: defines.rst +.. |DAEMON| replace:: fabricd + +SYNOPSIS +======== +|DAEMON| |synopsis-options-hv| + +|DAEMON| |synopsis-options| + +DESCRIPTION +=========== +|DAEMON| is a routing component that works with the FRRouting routing engine. + +OPTIONS +======= +OPTIONS available for the |DAEMON| command: + +.. include:: common-options.rst + +FILES +===== + +|INSTALL_PREFIX_SBIN|/|DAEMON| + The default location of the |DAEMON| binary. + +|INSTALL_PREFIX_ETC|/|DAEMON|.conf + The default location of the |DAEMON| config file. + +$(PWD)/|DAEMON|.log + If the |DAEMON| process is configured to output logs to a file, then you + will find this file in the directory where you started |DAEMON|. + +.. include:: epilogue.rst + diff --git a/doc/manpages/index.rst b/doc/manpages/index.rst index c62835c77..053555c4e 100644 --- a/doc/manpages/index.rst +++ b/doc/manpages/index.rst @@ -10,6 +10,7 @@ bgpd eigrpd isisd + fabricd ldpd nhrpd ospf6d diff --git a/doc/manpages/subdir.am b/doc/manpages/subdir.am index 24f47fc7a..4a9aa4de4 100644 --- a/doc/manpages/subdir.am +++ b/doc/manpages/subdir.am @@ -9,6 +9,7 @@ man_RSTFILES = \ doc/manpages/defines.rst \ doc/manpages/eigrpd.rst \ doc/manpages/epilogue.rst \ + doc/manpages/fabricd.rst \ doc/manpages/frr.rst \ doc/manpages/index.rst \ doc/manpages/isisd.rst \ @@ -46,83 +47,16 @@ rstman8dir = $(mandir)/man8 rstman1_DATA = rstman8_DATA = -rstman1_DATA += $(MANBUILD)/frr.1 +if DOC +rstman1_DATA += $(man1) +rstman8_DATA += $(man8) +endif # DOC -if PIMD -rstman8_DATA += $(MANBUILD)/pimd.8 -rstman8_DATA += $(MANBUILD)/mtracebis.8 -endif - -if PBRD -rstman8_DATA += $(MANBUILD)/pbrd.8 -endif - -if BGPD -rstman8_DATA += $(MANBUILD)/bgpd.8 -endif - -if ISISD -rstman8_DATA += $(MANBUILD)/isisd.8 -endif - -if OSPF6D -rstman8_DATA += $(MANBUILD)/ospf6d.8 -endif - -if OSPFCLIENT -rstman8_DATA += $(MANBUILD)/ospfclient.8 -endif - -if OSPFD -rstman8_DATA += $(MANBUILD)/ospfd.8 -endif - -if LDPD -rstman8_DATA += $(MANBUILD)/ldpd.8 -endif - -if RIPD -rstman8_DATA += $(MANBUILD)/ripd.8 -endif - -if RIPNGD -rstman8_DATA += $(MANBUILD)/ripngd.8 -endif - -if NHRPD -rstman8_DATA += $(MANBUILD)/nhrpd.8 -endif - -if VTYSH -rstman1_DATA += $(MANBUILD)/vtysh.1 -endif - -if WATCHFRR -rstman8_DATA += $(MANBUILD)/watchfrr.8 -endif - -if ZEBRA -rstman8_DATA += $(MANBUILD)/zebra.8 -endif - -if EIGRPD -rstman8_DATA += $(MANBUILD)/eigrpd.8 -endif - -if SHARPD -rstman8_DATA += $(MANBUILD)/sharpd.8 -endif - -if STATICD -rstman8_DATA += $(MANBUILD)/staticd.8 -endif - -if BFDD -rstman8_DATA += $(MANBUILD)/bfdd.8 -endif +man1 = $(MANBUILD)/frr.1 +man8 = # dependency -$(rstman8_DATA) $(rstman1_DATA): $(MANBUILD)/man.stamp +$(man8) $(man1): $(MANBUILD)/man.stamp # # hook-ins for clean / doc diff --git a/doc/mpls/.gitignore b/doc/mpls/.gitignore deleted file mode 100644 index b0a4a4619..000000000 --- a/doc/mpls/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.arch-ids -.arch-inventory -*~ -*.loT - diff --git a/doc/user/fabricd.rst b/doc/user/fabricd.rst new file mode 100644 index 000000000..cf0f937c1 --- /dev/null +++ b/doc/user/fabricd.rst @@ -0,0 +1,404 @@ +.. _fabricd: + +********** +OpenFabric +********** + +OpenFabric, specified in :t:`draft-white-openfabric-06.txt`, is a routing +protocol derived from IS-IS, providing link-state routing with efficient +flooding for topologies like spine-leaf networks. + +FRR implements OpenFabric in a daemon called *fabricd* + +.. _configuring-fabricd: + +Configuring fabricd +=================== + +There are no *fabricd* specific options. Common options can be specified +(:ref:`common-invocation-options`) to *fabricd*. *fabricd* needs to acquire +interface information from *zebra* in order to function. Therefore *zebra* must +be running before invoking *fabricd*. Also, if *zebra* is restarted then *fabricd* +must be too. + +Like other daemons, *fabricd* configuration is done in an OpenFabric specific +configuration file :file:`fabricd.conf`. + +.. _openfabric-router: + +OpenFabric router +================= + +To enable the OpenFabric routing protocol, an OpenFabric router needs to be created +in the configuration: + +.. index:: router openfabric WORD +.. clicmd:: router openfabric WORD + +.. index:: no router openfabric WORD +.. clicmd:: no router openfabric WORD + + Enable or disable the OpenFabric process by specifying the OpenFabric domain with + 'WORD'. + +.. index:: net XX.XXXX. ... .XXX.XX +.. clicmd:: net XX.XXXX. ... .XXX.XX + +.. index:: no net XX.XXXX. ... .XXX.XX +.. clicmd:: no net XX.XXXX. ... .XXX.XX + + Set/Unset network entity title (NET) provided in ISO format. + +.. index:: domain-password [clear | md5] <password> +.. clicmd:: domain-password [clear | md5] <password> + +.. index:: no domain-password +.. clicmd:: no domain-password + + Configure the authentication password for a domain, as clear text or md5 one. + +.. index:: log-adjacency-changes +.. clicmd:: log-adjacency-changes + +.. index:: no log-adjacency-changes +.. clicmd:: no log-adjacency-changes + + Log changes in adjacency state. + +.. index:: set-overload-bit +.. clicmd:: set-overload-bit + +.. index:: no set-overload-bit +.. clicmd:: no set-overload-bit + + Set overload bit to avoid any transit traffic. + +.. index:: purge-originator +.. clicmd:: purge-originator + +.. index:: no purge-originator +.. clicmd:: no purge-originator + + Enable or disable :rfc:`6232` purge originator identification. + +.. index:: fabric-tier (0-14) +.. clicmd:: fabric-tier (0-14) + +.. index:: no fabric-tier +.. clicmd:: no fabric-tier + + Configure a static tier number to advertise as location in the fabric + +.. _openfabric-timer: + +OpenFabric Timer +================ + +.. index:: lsp-gen-interval (1-120) +.. clicmd:: lsp-gen-interval (1-120) + +.. index:: no lsp-gen-interval +.. clicmd:: no lsp-gen-interval + + Set minimum interval in seconds between regenerating same LSP. + +.. index:: lsp-refresh-interval (1-65235) +.. clicmd:: lsp-refresh-interval (1-65235) + +.. index:: no lsp-refresh-interval +.. clicmd:: no lsp-refresh-interval + + Set LSP refresh interval in seconds. + +.. index:: max-lsp-lifetime (360-65535) +.. clicmd:: max-lsp-lifetime (360-65535) + +.. index:: no max-lsp-lifetime +.. clicmd:: no max-lsp-lifetime + + Set LSP maximum LSP lifetime in seconds. + +.. index:: spf-interval (1-120) +.. clicmd:: spf-interval (1-120) + +.. index:: no spf-interval +.. clicmd:: no spf-interval + + Set minimum interval between consecutive SPF calculations in seconds. + +.. _openfabric-interface: + +OpenFabric interface +==================== + +.. index:: ip router openfabric WORD +.. clicmd:: ip router openfabric WORD + +.. index:: no ip router openfabric WORD +.. clicmd:: no ip router openfabric WORD + +.. _ip-router-openfabric-word: + + Activate OpenFabric on this interface. Note that the name + of OpenFabric instance must be the same as the one used to configure the + routing process (see command :clicmd:`router openfabric WORD`). + +.. index:: openfabric csnp-interval (1-600) +.. clicmd:: openfabric csnp-interval (1-600) + +.. index:: no openfabric csnp-interval +.. clicmd:: no openfabric csnp-interval + + Set CSNP interval in seconds. + +.. index:: openfabric hello-interval (1-600) +.. clicmd:: openfabric hello-interval (1-600) + +.. index:: no openfabric hello-interval +.. clicmd:: no openfabric hello-interval + + Set Hello interval in seconds. + +.. index:: openfabric hello-multiplier (2-100) +.. clicmd:: openfabric hello-multiplier (2-100) + +.. index:: no openfabric hello-multiplier +.. clicmd:: no openfabric hello-multiplier + + Set multiplier for Hello holding time. + +.. index:: openfabric metric (0-16777215) +.. clicmd:: openfabric metric (0-16777215) + +.. index:: no openfabric metric +.. clicmd:: no openfabric metric + + Set interface metric value. + +.. index:: openfabric passive +.. clicmd:: openfabric passive + +.. index:: no openfabric passive +.. clicmd:: no openfabric passive + + Configure the passive mode for this interface. + +.. index:: openfabric password [clear | md5] <password> +.. clicmd:: openfabric password [clear | md5] <password> + +.. index:: no openfabric password +.. clicmd:: no openfabric password + + Configure the authentication password (clear or encoded text) for the + interface. + +.. index:: openfabric psnp-interval (1-120) +.. clicmd:: openfabric psnp-interval (1-120) + +.. index:: no openfabric psnp-interval +.. clicmd:: no openfabric psnp-interval + + Set PSNP interval in seconds. + +.. _showing-openfabric-information: + +Showing OpenFabric information +============================== + +.. index:: show openfabric summary +.. clicmd:: show openfabric summary + + Show summary information about OpenFabric. + +.. index:: show openfabric hostname +.. clicmd:: show openfabric hostname + + Show which hostnames are associated with which OpenFabric system ids. + +.. index:: show openfabric interface +.. clicmd:: show openfabric interface + +.. index:: show openfabric interface detail +.. clicmd:: show openfabric interface detail + +.. index:: show openfabric interface <interface name> +.. clicmd:: show openfabric interface <interface name> + + Show state and configuration of specified OpenFabric interface, or all interfaces + if no interface is given with or without details. + +.. index:: show openfabric neighbor +.. clicmd:: show openfabric neighbor + +.. index:: show openfabric neighbor <System Id> +.. clicmd:: show openfabric neighbor <System Id> + +.. index:: show openfabric neighbor detail +.. clicmd:: show openfabric neighbor detail + + Show state and information of specified OpenFabric neighbor, or all neighbors if + no system id is given with or without details. + +.. index:: show openfabric database +.. clicmd:: show openfabric database + +.. index:: show openfabric database [detail] +.. clicmd:: show openfabric database [detail] + +.. index:: show openfabric database <LSP id> [detail] +.. clicmd:: show openfabric database <LSP id> [detail] + +.. index:: show openfabric database detail <LSP id> +.. clicmd:: show openfabric database detail <LSP id> + + Show the OpenFabric database globally, for a specific LSP id without or with + details. + +.. index:: show openfabric topology +.. clicmd:: show openfabric topology + + Show calculated OpenFabric paths and associated topology information. + +.. _debugging-openfabric: + +Debugging OpenFabric +==================== + +.. index:: debug openfabric adj-packets +.. clicmd:: debug openfabric adj-packets + +.. index:: no debug openfabric adj-packets +.. clicmd:: no debug openfabric adj-packets + +OpenFabric Adjacency related packets. + +.. index:: debug openfabric checksum-errors +.. clicmd:: debug openfabric checksum-errors + +.. index:: no debug openfabric checksum-errors +.. clicmd:: no debug openfabric checksum-errors + +OpenFabric LSP checksum errors. + +.. index:: debug openfabric events +.. clicmd:: debug openfabric events + +.. index:: no debug openfabric events +.. clicmd:: no debug openfabric events + +OpenFabric Events. + +.. index:: debug openfabric local-updates +.. clicmd:: debug openfabric local-updates + +.. index:: no debug openfabric local-updates +.. clicmd:: no debug openfabric local-updates + +OpenFabric local update packets. + +.. index:: debug openfabric lsp-gen +.. clicmd:: debug openfabric lsp-gen + +.. index:: no debug openfabric lsp-gen +.. clicmd:: no debug openfabric lsp-gen + +Generation of own LSPs. + +.. index:: debug openfabric lsp-sched +.. clicmd:: debug openfabric lsp-sched + +.. index:: no debug openfabric lsp-sched +.. clicmd:: no debug openfabric lsp-sched + +Debug scheduling of generation of own LSPs. + +.. index:: debug openfabric packet-dump +.. clicmd:: debug openfabric packet-dump + +.. index:: no debug openfabric packet-dump +.. clicmd:: no debug openfabric packet-dump + +OpenFabric packet dump. + +.. index:: debug openfabric protocol-errors +.. clicmd:: debug openfabric protocol-errors + +.. index:: no debug openfabric protocol-errors +.. clicmd:: no debug openfabric protocol-errors + +OpenFabric LSP protocol errors. + +.. index:: debug openfabric route-events +.. clicmd:: debug openfabric route-events + +.. index:: no debug openfabric route-events +.. clicmd:: no debug openfabric route-events + +OpenFabric Route related events. + +.. index:: debug openfabric snp-packets +.. clicmd:: debug openfabric snp-packets + +.. index:: no debug openfabric snp-packets +.. clicmd:: no debug openfabric snp-packets + +OpenFabric CSNP/PSNP packets. + +.. index:: debug openfabric spf-events +.. clicmd:: debug openfabric spf-events + +.. index:: debug openfabric spf-statistics +.. clicmd:: debug openfabric spf-statistics + +.. index:: debug openfabric spf-triggers +.. clicmd:: debug openfabric spf-triggers + +.. index:: no debug openfabric spf-events +.. clicmd:: no debug openfabric spf-events + +.. index:: no debug openfabric spf-statistics +.. clicmd:: no debug openfabric spf-statistics + +.. index:: no debug openfabric spf-triggers +.. clicmd:: no debug openfabric spf-triggers + +OpenFabric Shortest Path First Events, Timing and Statistic Data and triggering +events. + +.. index:: debug openfabric update-packets +.. clicmd:: debug openfabric update-packets + +.. index:: no debug openfabric update-packets +.. clicmd:: no debug openfabric update-packets + +Update related packets. + +.. index:: show debugging openfabric +.. clicmd:: show debugging openfabric + + Print which OpenFabric debug levels are active. + +OpenFabric configuration example +================================ + +A simple example: + +.. code-block:: frr + + ! + interface lo + ip address 192.0.2.1/32 + ip router openfabric 1 + ipv6 address 2001:db8::1/128 + ipv6 router openfabric 1 + ! + interface eth0 + ip router openfabric 1 + ipv6 router openfabric 1 + ! + interface eth1 + ip router openfabric 1 + ipv6 router openfabric 1 + ! + router openfabric 1 + net 49.0000.0000.0001.00 diff --git a/doc/user/index.rst b/doc/user/index.rst index 581855134..8190415bf 100644 --- a/doc/user/index.rst +++ b/doc/user/index.rst @@ -42,6 +42,7 @@ Protocols bfd bgp babeld + fabricd ldpd eigrpd isisd diff --git a/doc/user/installation.rst b/doc/user/installation.rst index 3da5a6cd3..da431916a 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -139,6 +139,10 @@ options from the list below. Do not build isisd. +.. option:: --disable-fabricd + + Do not build fabricd. + .. option:: --enable-isis-topology Enable IS-IS topology generator. diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 54f82f683..ee681858d 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -106,6 +106,14 @@ writing, *isisd* does not support multiple ISIS processes. Set overload bit to avoid any transit traffic. +.. index:: purge-originator +.. clicmd:: purge-originator + +.. index:: no purge-originator +.. clicmd:: no purge-originator + + Enable or disable :rfc:`6232` purge originator identification. + .. _isis-timer: ISIS Timer diff --git a/doc/user/setup.rst b/doc/user/setup.rst index 68ce14982..8a76a61e7 100644 --- a/doc/user/setup.rst +++ b/doc/user/setup.rst @@ -32,6 +32,7 @@ systemd. The file initially looks like this: staticd=no pbrd=no bfdd=no + fabricd=no To enable a particular daemon, simply change the corresponding 'no' to 'yes'. Subsequent service restarts should start the daemon. @@ -68,6 +69,7 @@ This file has several parts. Here is an example: staticd_options=" --daemon -A 127.0.0.1" pbrd_options=" --daemon -A 127.0.0.1" bfdd_options=" --daemon -A 127.0.0.1" + fabricd_options=" --daemon -A 127.0.0.1" # The list of daemons to watch is automatically generated by the init script. watchfrr_enable=yes @@ -139,6 +141,7 @@ add the following entries to :file:`/etc/services`. ldpd 2612/tcp # LDPd vty eigprd 2613/tcp # EIGRPd vty bfdd 2617/tcp # bfdd vty + fabricd 2618/tcp # fabricd vty If you use a FreeBSD newer than 2.2.8, the above entries are already added to diff --git a/doc/user/subdir.am b/doc/user/subdir.am index 6e51eed9d..53d36052a 100644 --- a/doc/user/subdir.am +++ b/doc/user/subdir.am @@ -10,6 +10,7 @@ user_RSTFILES = \ doc/user/bugs.rst \ doc/user/conf.py \ doc/user/eigrpd.rst \ + doc/user/fabricd.rst \ doc/user/filter.rst \ doc/user/glossary.rst \ doc/user/index.rst \ diff --git a/eigrpd/.gitignore b/eigrpd/.gitignore index 5b72399e7..0303c6f0d 100644 --- a/eigrpd/.gitignore +++ b/eigrpd/.gitignore @@ -1,18 +1,2 @@ -!Makefile -Makefile.in -*.o -*.a eigrpd eigrpd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index eeefc5196..d291cab4c 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -67,8 +67,8 @@ * 7- state not changed, usually by receiving not last reply */ -#include <thread.h> #include <zebra.h> +#include <thread.h> #include "prefix.h" #include "table.h" diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 2635d555d..bc48173bb 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -6,6 +6,12 @@ if EIGRPD noinst_LIBRARIES += eigrpd/libeigrp.a sbin_PROGRAMS += eigrpd/eigrpd dist_examples_DATA += eigrpd/eigrpd.conf.sample +vtysh_scan += \ + $(top_srcdir)/eigrpd/eigrp_dump.c \ + $(top_srcdir)/eigrpd/eigrp_vty.c \ + # end +# $(top_srcdir)/eigrpd/eigrp_routemap.c +man8 += $(MANBUILD)/eigrpd.8 endif eigrpd_libeigrp_a_SOURCES = \ diff --git a/fpm/.gitignore b/fpm/.gitignore deleted file mode 100644 index 17e90443e..000000000 --- a/fpm/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -!Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/fpm/subdir.am b/fpm/subdir.am index 795535596..05cec5a52 100644 --- a/fpm/subdir.am +++ b/fpm/subdir.am @@ -3,8 +3,7 @@ lib_LTLIBRARIES += fpm/libfrrfpm_pb.la endif fpm_libfrrfpm_pb_la_LDFLAGS = -version-info 0:0:0 -fpm_libfrrfpm_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \ - $(Q_PROTOBUF_C_CLIENT_INCLUDES) +fpm_libfrrfpm_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS) fpm_libfrrfpm_pb_la_SOURCES = \ fpm/fpm.h \ fpm/fpm_pb.h \ @@ -12,11 +11,14 @@ fpm_libfrrfpm_pb_la_SOURCES = \ # end if HAVE_PROTOBUF -nodist_fpm_libfrrfpm_pb_la_SOURCES = fpm/fpm.pb-c.c +nodist_fpm_libfrrfpm_pb_la_SOURCES = \ + fpm/fpm.pb-c.c \ + # end +endif + CLEANFILES += \ fpm/fpm.pb-c.c \ fpm/fpm.pb-c.h \ # end -endif EXTRA_DIST += fpm/fpm.proto diff --git a/init/.gitignore b/init/.gitignore deleted file mode 100644 index 30b4bc99e..000000000 --- a/init/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile -Makefile.in -.nfs* -*~ -*.loT - diff --git a/isisd/.gitignore b/isisd/.gitignore index a882bbf67..b6184ca0f 100644 --- a/isisd/.gitignore +++ b/isisd/.gitignore @@ -1,15 +1,3 @@ -!Makefile -Makefile.in -*.o isisd -.deps +fabricd isisd.conf -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/isisd/fabricd.c b/isisd/fabricd.c new file mode 100644 index 000000000..7951efe5a --- /dev/null +++ b/isisd/fabricd.c @@ -0,0 +1,717 @@ +/* + * IS-IS Rout(e)ing protocol - OpenFabric extensions + * + * Copyright (C) 2018 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> +#include "isisd/fabricd.h" +#include "isisd/isisd.h" +#include "isisd/isis_memory.h" +#include "isisd/isis_circuit.h" +#include "isisd/isis_misc.h" +#include "isisd/isis_adjacency.h" +#include "isisd/isis_spf.h" +#include "isisd/isis_tlvs.h" +#include "isisd/isis_lsp.h" +#include "isisd/isis_spf_private.h" +#include "isisd/isis_tx_queue.h" + +DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric") +DEFINE_MTYPE_STATIC(ISISD, FABRICD_NEIGHBOR, "ISIS OpenFabric Neighbor Entry") + +/* Tracks initial synchronization as per section 2.4 + * + * We declare the sync complete once we have seen at least one + * CSNP and there are no more LSPs with SSN or SRM set. + */ +enum fabricd_sync_state { + FABRICD_SYNC_PENDING, + FABRICD_SYNC_STARTED, + FABRICD_SYNC_COMPLETE +}; + +struct fabricd { + struct isis_area *area; + + enum fabricd_sync_state initial_sync_state; + time_t initial_sync_start; + struct isis_circuit *initial_sync_circuit; + struct thread *initial_sync_timeout; + + struct isis_spftree *spftree; + struct skiplist *neighbors; + struct hash *neighbors_neighbors; + + uint8_t tier; + uint8_t tier_config; + uint8_t tier_pending; + struct thread *tier_calculation_timer; + struct thread *tier_set_timer; +}; + +/* Code related to maintaining the neighbor lists */ + +struct neighbor_entry { + struct isis_vertex *vertex; + bool present; +}; + +static struct neighbor_entry *neighbor_entry_new(struct isis_vertex *vertex) +{ + struct neighbor_entry *rv = XMALLOC(MTYPE_FABRICD_NEIGHBOR, sizeof(*rv)); + + rv->vertex = vertex; + return rv; +} + +static void neighbor_entry_del(struct neighbor_entry *neighbor) +{ + XFREE(MTYPE_FABRICD_NEIGHBOR, neighbor); +} + +static void neighbor_entry_del_void(void *arg) +{ + neighbor_entry_del((struct neighbor_entry *)arg); +} + +static void neighbor_lists_clear(struct fabricd *f) +{ + while (!skiplist_empty(f->neighbors)) + skiplist_delete_first(f->neighbors); + + hash_clean(f->neighbors_neighbors, neighbor_entry_del_void); +} + +static unsigned neighbor_entry_hash_key(void *np) +{ + struct neighbor_entry *n = np; + + return jhash(n->vertex->N.id, ISIS_SYS_ID_LEN, 0x55aa5a5a); +} + +static int neighbor_entry_hash_cmp(const void *a, const void *b) +{ + const struct neighbor_entry *na = a, *nb = b; + + return memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN) == 0; +} + +static int neighbor_entry_list_cmp(void *a, void *b) +{ + struct neighbor_entry *na = a, *nb = b; + + return -memcmp(na->vertex->N.id, nb->vertex->N.id, ISIS_SYS_ID_LEN); +} + +static struct neighbor_entry *neighbor_entry_lookup_list(struct skiplist *list, + const uint8_t *id) +{ + struct isis_vertex querier; + isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS); + + struct neighbor_entry n = { + .vertex = &querier + }; + + struct neighbor_entry *rv; + + if (skiplist_search(list, &n, (void**)&rv)) + return NULL; + + if (!rv->present) + return NULL; + + return rv; +} + +static struct neighbor_entry *neighbor_entry_lookup_hash(struct hash *hash, + const uint8_t *id) +{ + struct isis_vertex querier; + isis_vertex_id_init(&querier, id, VTYPE_NONPSEUDO_TE_IS); + + struct neighbor_entry n = { + .vertex = &querier + }; + + struct neighbor_entry *rv = hash_lookup(hash, &n); + + if (!rv || !rv->present) + return NULL; + + return rv; +} + +static void neighbor_lists_update(struct fabricd *f) +{ + neighbor_lists_clear(f); + + struct listnode *node; + struct isis_vertex *v; + + for (ALL_QUEUE_ELEMENTS_RO(&f->spftree->paths, node, v)) { + if (!v->d_N || !VTYPE_IS(v->type)) + continue; + + if (v->d_N > 2) + break; + + struct neighbor_entry *n = neighbor_entry_new(v); + if (v->d_N == 1) { + skiplist_insert(f->neighbors, n, n); + } else { + struct neighbor_entry *inserted; + inserted = hash_get(f->neighbors_neighbors, n, hash_alloc_intern); + assert(inserted == n); + } + } +} + +struct fabricd *fabricd_new(struct isis_area *area) +{ + struct fabricd *rv = XCALLOC(MTYPE_FABRICD_STATE, sizeof(*rv)); + + rv->area = area; + rv->initial_sync_state = FABRICD_SYNC_PENDING; + + rv->spftree = isis_spftree_new(area); + rv->neighbors = skiplist_new(0, neighbor_entry_list_cmp, + neighbor_entry_del_void); + rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key, + neighbor_entry_hash_cmp, + "Fabricd Neighbors"); + + rv->tier = rv->tier_config = ISIS_TIER_UNDEFINED; + return rv; +}; + +void fabricd_finish(struct fabricd *f) +{ + if (f->initial_sync_timeout) + thread_cancel(f->initial_sync_timeout); + + if (f->tier_calculation_timer) + thread_cancel(f->tier_calculation_timer); + + if (f->tier_set_timer) + thread_cancel(f->tier_set_timer); + + isis_spftree_del(f->spftree); + neighbor_lists_clear(f); + skiplist_free(f->neighbors); + hash_free(f->neighbors_neighbors); +} + +static int fabricd_initial_sync_timeout(struct thread *thread) +{ + struct fabricd *f = THREAD_ARG(thread); + + zlog_info("OpenFabric: Initial synchronization on %s timed out!", + f->initial_sync_circuit->interface->name); + f->initial_sync_state = FABRICD_SYNC_PENDING; + f->initial_sync_circuit = NULL; + f->initial_sync_timeout = NULL; + return 0; +} + +void fabricd_initial_sync_hello(struct isis_circuit *circuit) +{ + struct fabricd *f = circuit->area->fabricd; + + if (!f) + return; + + if (f->initial_sync_state > FABRICD_SYNC_PENDING) + return; + + f->initial_sync_state = FABRICD_SYNC_STARTED; + + long timeout = 2 * circuit->hello_interval[1] * circuit->hello_multiplier[1]; + + f->initial_sync_circuit = circuit; + if (f->initial_sync_timeout) + return; + + thread_add_timer(master, fabricd_initial_sync_timeout, f, + timeout, &f->initial_sync_timeout); + f->initial_sync_start = monotime(NULL); + + zlog_info("OpenFabric: Started initial synchronization with %s on %s", + sysid_print(circuit->u.p2p.neighbor->sysid), + circuit->interface->name); +} + +bool fabricd_initial_sync_is_in_progress(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return false; + + if (f->initial_sync_state > FABRICD_SYNC_PENDING + && f->initial_sync_state < FABRICD_SYNC_COMPLETE) + return true; + + return false; +} + +bool fabricd_initial_sync_is_complete(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return false; + + return f->initial_sync_state == FABRICD_SYNC_COMPLETE; +} + +struct isis_circuit *fabricd_initial_sync_circuit(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + if (!f) + return NULL; + + return f->initial_sync_circuit; +} + +void fabricd_initial_sync_finish(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return; + + if (monotime(NULL) - f->initial_sync_start < 5) + return; + + zlog_info("OpenFabric: Initial synchronization on %s complete.", + f->initial_sync_circuit->interface->name); + f->initial_sync_state = FABRICD_SYNC_COMPLETE; + f->initial_sync_circuit = NULL; + thread_cancel(f->initial_sync_timeout); + f->initial_sync_timeout = NULL; +} + +static void fabricd_bump_tier_calculation_timer(struct fabricd *f); +static void fabricd_set_tier(struct fabricd *f, uint8_t tier); + +static uint8_t fabricd_calculate_fabric_tier(struct isis_area *area) +{ + struct isis_spftree *local_tree = fabricd_spftree(area); + struct listnode *node; + + struct isis_vertex *furthest_t0 = NULL, + *second_furthest_t0 = NULL; + + struct isis_vertex *v; + + for (ALL_QUEUE_ELEMENTS_RO(&local_tree->paths, node, v)) { + struct isis_lsp *lsp = lsp_for_vertex(local_tree, v); + + if (!lsp || !lsp->tlvs + || !lsp->tlvs->spine_leaf + || !lsp->tlvs->spine_leaf->has_tier + || lsp->tlvs->spine_leaf->tier != 0) + continue; + + second_furthest_t0 = furthest_t0; + furthest_t0 = v; + } + + if (!second_furthest_t0) { + zlog_info("OpenFabric: Could not find two T0 routers"); + return ISIS_TIER_UNDEFINED; + } + + zlog_info("OpenFabric: Found %s as furthest t0 from local system, dist == %" + PRIu32, rawlspid_print(furthest_t0->N.id), furthest_t0->d_N); + + struct isis_spftree *remote_tree = + isis_run_hopcount_spf(area, furthest_t0->N.id, NULL); + + struct isis_vertex *furthest_from_remote = + isis_vertex_queue_last(&remote_tree->paths); + + if (!furthest_from_remote) { + zlog_info("OpenFabric: Found no furthest node in remote spf"); + isis_spftree_del(remote_tree); + return ISIS_TIER_UNDEFINED; + } else { + zlog_info("OpenFabric: Found %s as furthest from remote dist == %" + PRIu32, rawlspid_print(furthest_from_remote->N.id), + furthest_from_remote->d_N); + } + + int64_t tier = furthest_from_remote->d_N - furthest_t0->d_N; + isis_spftree_del(remote_tree); + + if (tier < 0 || tier >= ISIS_TIER_UNDEFINED) { + zlog_info("OpenFabric: Calculated tier %" PRId64 " seems implausible", + tier); + return ISIS_TIER_UNDEFINED; + } + + zlog_info("OpenFabric: Calculated %" PRId64 " as tier", tier); + return tier; +} + +static int fabricd_tier_set_timer(struct thread *thread) +{ + struct fabricd *f = THREAD_ARG(thread); + f->tier_set_timer = NULL; + + fabricd_set_tier(f, f->tier_pending); + return 0; +} + +static int fabricd_tier_calculation_cb(struct thread *thread) +{ + struct fabricd *f = THREAD_ARG(thread); + uint8_t tier = ISIS_TIER_UNDEFINED; + f->tier_calculation_timer = NULL; + + tier = fabricd_calculate_fabric_tier(f->area); + if (tier == ISIS_TIER_UNDEFINED) + return 0; + + zlog_info("OpenFabric: Got tier %" PRIu8 " from algorithm. Arming timer.", + tier); + f->tier_pending = tier; + thread_add_timer(master, fabricd_tier_set_timer, f, + f->area->lsp_gen_interval[ISIS_LEVEL2 - 1], + &f->tier_set_timer); + + return 0; +} + +static void fabricd_bump_tier_calculation_timer(struct fabricd *f) +{ + /* Cancel timer if we already know our tier */ + if (f->tier != ISIS_TIER_UNDEFINED + || f->tier_set_timer) { + if (f->tier_calculation_timer) { + thread_cancel(f->tier_calculation_timer); + f->tier_calculation_timer = NULL; + } + return; + } + + /* If we need to calculate the tier, wait some + * time for the topology to settle before running + * the calculation */ + if (f->tier_calculation_timer) { + thread_cancel(f->tier_calculation_timer); + f->tier_calculation_timer = NULL; + } + + thread_add_timer(master, fabricd_tier_calculation_cb, f, + 2 * f->area->lsp_gen_interval[ISIS_LEVEL2 - 1], + &f->tier_calculation_timer); +} + +static void fabricd_set_tier(struct fabricd *f, uint8_t tier) +{ + if (f->tier == tier) + return; + + zlog_info("OpenFabric: Set own tier to %" PRIu8, tier); + f->tier = tier; + + fabricd_bump_tier_calculation_timer(f); + lsp_regenerate_schedule(f->area, ISIS_LEVEL2, 0); +} + +void fabricd_run_spf(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return; + + isis_run_hopcount_spf(area, isis->sysid, f->spftree); + neighbor_lists_update(f); + fabricd_bump_tier_calculation_timer(f); +} + +struct isis_spftree *fabricd_spftree(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return NULL; + + return f->spftree; +} + +void fabricd_configure_tier(struct isis_area *area, uint8_t tier) +{ + struct fabricd *f = area->fabricd; + + if (!f || f->tier_config == tier) + return; + + f->tier_config = tier; + fabricd_set_tier(f, tier); +} + +uint8_t fabricd_tier(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return ISIS_TIER_UNDEFINED; + + return f->tier; +} + +int fabricd_write_settings(struct isis_area *area, struct vty *vty) +{ + struct fabricd *f = area->fabricd; + int written = 0; + + if (!f) + return written; + + if (f->tier_config != ISIS_TIER_UNDEFINED) { + vty_out(vty, " fabric-tier %" PRIu8 "\n", f->tier_config); + written++; + } + + return written; +} + +static void move_to_dnr(struct isis_lsp *lsp, struct neighbor_entry *n) +{ + struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N); + + n->present = false; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("OpenFabric: Adding %s to DNR", + vid2string(n->vertex, buff, sizeof(buff))); + } + + if (adj) { + isis_tx_queue_add(adj->circuit->tx_queue, lsp, + TX_LSP_CIRCUIT_SCOPED); + } +} + +static void move_to_rf(struct isis_lsp *lsp, struct neighbor_entry *n) +{ + struct isis_adjacency *adj = listnode_head(n->vertex->Adj_N); + + n->present = false; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("OpenFabric: Adding %s to RF", + vid2string(n->vertex, buff, sizeof(buff))); + } + + if (adj) { + isis_tx_queue_add(adj->circuit->tx_queue, lsp, + TX_LSP_NORMAL); + } +} + +static void mark_neighbor_as_present(struct hash_backet *backet, void *arg) +{ + struct neighbor_entry *n = backet->data; + + n->present = true; +} + +static void handle_firsthops(struct hash_backet *backet, void *arg) +{ + struct isis_lsp *lsp = arg; + struct fabricd *f = lsp->area->fabricd; + struct isis_vertex *vertex = backet->data; + + struct neighbor_entry *n; + + n = neighbor_entry_lookup_list(f->neighbors, vertex->N.id); + if (n) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Removing %s from NL as its in the reverse path", + vid2string(vertex, buff, sizeof(buff))); + } + n->present = false; + } + + n = neighbor_entry_lookup_hash(f->neighbors_neighbors, vertex->N.id); + if (n) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Removing %s from NN as its in the reverse path", + vid2string(vertex, buff, sizeof(buff))); + } + n->present = false; + } +} + +void fabricd_lsp_flood(struct isis_lsp *lsp) +{ + struct fabricd *f = lsp->area->fabricd; + assert(f); + + void *cursor = NULL; + struct neighbor_entry *n; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + zlog_debug("OpenFabric: Flooding LSP %s", + rawlspid_print(lsp->hdr.lsp_id)); + } + + /* Mark all elements in NL as present and move T0s into DNR */ + while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) { + n->present = true; + + struct isis_lsp *lsp = lsp_for_vertex(f->spftree, n->vertex); + if (!lsp || !lsp->tlvs || !lsp->tlvs->spine_leaf) + continue; + + if (!lsp->tlvs->spine_leaf->has_tier + || lsp->tlvs->spine_leaf->tier != 0) + continue; + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + zlog_debug("Moving %s to DNR because it's T0", + rawlspid_print(lsp->hdr.lsp_id)); + } + + move_to_dnr(lsp, n); + } + + /* Mark all elements in NN as present */ + hash_iterate(f->neighbors_neighbors, mark_neighbor_as_present, NULL); + + struct isis_vertex *originator = isis_find_vertex(&f->spftree->paths, + lsp->hdr.lsp_id, + VTYPE_NONPSEUDO_TE_IS); + + /* Remove all IS from NL and NN in the shortest path + * to the IS that originated the LSP */ + if (originator) + hash_iterate(originator->firsthops, handle_firsthops, lsp); + + /* Iterate over all remaining IS in NL */ + cursor = NULL; + while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) { + if (!n->present) + continue; + + struct isis_lsp *nlsp = lsp_for_vertex(f->spftree, n->vertex); + if (!nlsp || !nlsp->tlvs) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Moving %s to DNR as it has no LSP", + vid2string(n->vertex, buff, sizeof(buff))); + } + + move_to_dnr(lsp, n); + continue; + } + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Considering %s from NL...", + vid2string(n->vertex, buff, sizeof(buff))); + } + + /* For all neighbors of the NL IS check whether they are present + * in NN. If yes, remove from NN and set need_reflood. */ + bool need_reflood = false; + struct isis_extended_reach *er; + for (er = (struct isis_extended_reach *)nlsp->tlvs->extended_reach.head; + er; er = er->next) { + struct neighbor_entry *nn; + + nn = neighbor_entry_lookup_hash(f->neighbors_neighbors, + er->id); + + if (nn) { + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + char buff[PREFIX2STR_BUFFER]; + zlog_debug("Found neighbor %s in NN, removing it from NN and setting reflood.", + vid2string(nn->vertex, buff, sizeof(buff))); + } + + nn->present = false; + need_reflood = true; + } + } + + if (need_reflood) + move_to_rf(lsp, n); + else + move_to_dnr(lsp, n); + } + + if (isis->debugs & DEBUG_FABRICD_FLOODING) { + zlog_debug("OpenFabric: Flooding algorithm complete."); + } +} + +void fabricd_trigger_csnp(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return; + + struct listnode *node; + struct isis_circuit *circuit; + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if (!circuit->t_send_csnp[1]) + continue; + + thread_cancel(circuit->t_send_csnp[ISIS_LEVEL2 - 1]); + thread_add_timer_msec(master, send_l2_csnp, circuit, + isis_jitter(500, CSNP_JITTER), + &circuit->t_send_csnp[ISIS_LEVEL2 - 1]); + } +} + +struct list *fabricd_ip_addrs(struct isis_circuit *circuit) +{ + if (circuit->ip_addrs && listcount(circuit->ip_addrs)) + return circuit->ip_addrs; + + if (!fabricd || !circuit->area || !circuit->area->circuit_list) + return NULL; + + struct listnode *node; + struct isis_circuit *c; + + for (ALL_LIST_ELEMENTS_RO(circuit->area->circuit_list, node, c)) { + if (c->circ_type != CIRCUIT_T_LOOPBACK) + continue; + + if (!c->ip_addrs || !listcount(c->ip_addrs)) + return NULL; + + return c->ip_addrs; + } + + return NULL; +} diff --git a/isisd/fabricd.conf.sample b/isisd/fabricd.conf.sample new file mode 100644 index 000000000..be9e33ba6 --- /dev/null +++ b/isisd/fabricd.conf.sample @@ -0,0 +1,27 @@ +! -*- openfabric -*- +! +! fabricd sample configuration file +! +hostname fabricd +password foo +enable password foo +log stdout +!log file /tmp/fabricd.log +! +! +router openfabric DEAD + net 47.0023.0000.0003.0300.0100.0102.0304.0506.00 +! lsp-lifetime 65535 + +! hostname isisd-router +! domain-password foobar + +interface eth0 + ip router openfabric DEAD +! openfabric hello-interval 5 +! openfabric lsp-interval 1000 + +! -- optional +! openfabric retransmit-interval 10 +! openfabric retransmit-throttle-interval +! diff --git a/isisd/fabricd.h b/isisd/fabricd.h new file mode 100644 index 000000000..76c182f2d --- /dev/null +++ b/isisd/fabricd.h @@ -0,0 +1,49 @@ +/* + * IS-IS Rout(e)ing protocol - OpenFabric extensions + * + * Copyright (C) 2018 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef FABRICD_H +#define FABRICD_H + +struct fabricd; + +struct isis_circuit; +struct isis_area; +struct isis_spftree; +struct isis_lsp; +struct vty; + +struct fabricd *fabricd_new(struct isis_area *area); +void fabricd_finish(struct fabricd *f); +void fabricd_initial_sync_hello(struct isis_circuit *circuit); +bool fabricd_initial_sync_is_complete(struct isis_area *area); +bool fabricd_initial_sync_is_in_progress(struct isis_area *area); +struct isis_circuit *fabricd_initial_sync_circuit(struct isis_area *area); +void fabricd_initial_sync_finish(struct isis_area *area); +void fabricd_run_spf(struct isis_area *area); +struct isis_spftree *fabricd_spftree(struct isis_area *area); +void fabricd_configure_tier(struct isis_area *area, uint8_t tier); +uint8_t fabricd_tier(struct isis_area *area); +int fabricd_write_settings(struct isis_area *area, struct vty *vty); +void fabricd_lsp_flood(struct isis_lsp *lsp); +void fabricd_trigger_csnp(struct isis_area *area); +struct list *fabricd_ip_addrs(struct isis_circuit *circuit); + +#endif diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 4b3d78421..a41d6ff81 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -48,6 +48,7 @@ #include "isisd/isis_events.h" #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" +#include "isisd/fabricd.h" extern struct isis *isis; @@ -193,6 +194,9 @@ void isis_adj_process_threeway(struct isis_adjacency *adj, } } + if (next_tw_state != ISIS_THREEWAY_DOWN) + fabricd_initial_sync_hello(adj->circuit); + if (next_tw_state == ISIS_THREEWAY_DOWN) { isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Neighbor restarted"); return; @@ -264,7 +268,7 @@ void isis_adj_state_change(struct isis_adjacency *adj, circuit->upadjcount[level - 1]--; if (circuit->upadjcount[level - 1] == 0) - isis_circuit_lsp_queue_clean(circuit); + isis_tx_queue_clean(circuit->tx_queue); isis_event_adjacency_state_change(adj, new_state); @@ -306,16 +310,21 @@ void isis_adj_state_change(struct isis_adjacency *adj, adj->last_flap = time(NULL); adj->flaps++; - /* 7.3.17 - going up on P2P -> send CSNP */ - /* FIXME: yup, I know its wrong... but i will do - * it! (for now) */ - send_csnp(circuit, level); + if (level == IS_LEVEL_1) { + thread_add_timer(master, send_l1_csnp, + circuit, 0, + &circuit->t_send_csnp[0]); + } else { + thread_add_timer(master, send_l2_csnp, + circuit, 0, + &circuit->t_send_csnp[1]); + } } else if (new_state == ISIS_ADJ_DOWN) { if (adj->circuit->u.p2p.neighbor == adj) adj->circuit->u.p2p.neighbor = NULL; circuit->upadjcount[level - 1]--; if (circuit->upadjcount[level - 1] == 0) - isis_circuit_lsp_queue_clean(circuit); + isis_tx_queue_clean(circuit->tx_queue); isis_event_adjacency_state_change(adj, new_state); diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c index 7e8a4a4ed..28750278b 100644 --- a/isisd/isis_bpf.c +++ b/isisd/isis_bpf.c @@ -213,7 +213,7 @@ int isis_sock_init(struct isis_circuit *circuit) int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa) { - int bytesread = 0, bytestoread, offset, one = 1, err = ISIS_OK; + int bytesread = 0, bytestoread, offset, one = 1; uint8_t *buff_ptr; struct bpf_hdr *bpf_hdr; @@ -249,7 +249,7 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, uint8_t *ssnpa) memcpy(ssnpa, buff_ptr + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN, ETHER_ADDR_LEN); - err = isis_handle_pdu(circuit, ssnpa); + isis_handle_pdu(circuit, ssnpa); stream_reset(circuit->rcv_stream); buff_ptr += BPF_WORDALIGN(bpf_hdr->bh_hdrlen + bpf_hdr->bh_datalen); diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index cd4b76139..817a44baf 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -45,7 +45,6 @@ #include "isisd/isis_flags.h" #include "isisd/isis_circuit.h" #include "isisd/isis_lsp.h" -#include "isisd/isis_lsp_hash.h" #include "isisd/isis_pdu.h" #include "isisd/isis_network.h" #include "isisd/isis_misc.h" @@ -58,6 +57,7 @@ #include "isisd/isis_te.h" #include "isisd/isis_mt.h" #include "isisd/isis_errors.h" +#include "isisd/isis_tx_queue.h" DEFINE_QOBJ_TYPE(isis_circuit) @@ -412,7 +412,7 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp) isis_circuit_if_bind(circuit, ifp); if (if_is_broadcast(ifp)) { - if (circuit->circ_type_config == CIRCUIT_T_P2P) + if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P) circuit->circ_type = CIRCUIT_T_P2P; else circuit->circ_type = CIRCUIT_T_BROADCAST; @@ -495,29 +495,29 @@ static void isis_circuit_update_all_srmflags(struct isis_circuit *circuit, { struct isis_area *area; struct isis_lsp *lsp; - dnode_t *dnode, *dnode_next; + dnode_t *dnode; int level; assert(circuit); area = circuit->area; assert(area); for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) { - if (level & circuit->is_type) { - if (area->lspdb[level - 1] - && dict_count(area->lspdb[level - 1]) > 0) { - for (dnode = dict_first(area->lspdb[level - 1]); - dnode != NULL; dnode = dnode_next) { - dnode_next = dict_next( - area->lspdb[level - 1], dnode); - lsp = dnode_get(dnode); - if (is_set) { - ISIS_SET_FLAG(lsp->SRMflags, - circuit); - } else { - ISIS_CLEAR_FLAG(lsp->SRMflags, - circuit); - } - } + if (!(level & circuit->is_type)) + continue; + + if (!area->lspdb[level - 1] + || !dict_count(area->lspdb[level - 1])) + continue; + + for (dnode = dict_first(area->lspdb[level - 1]); + dnode != NULL; + dnode = dict_next(area->lspdb[level - 1], dnode)) { + lsp = dnode_get(dnode); + if (is_set) { + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); + } else { + isis_tx_queue_del(circuit->tx_queue, lsp); } } } @@ -672,10 +672,7 @@ int isis_circuit_up(struct isis_circuit *circuit) isis_circuit_prepare(circuit); - circuit->lsp_queue = list_new(); - circuit->lsp_hash = isis_lsp_hash_new(); - circuit->lsp_queue_last_push[0] = circuit->lsp_queue_last_push[1] = - monotime(NULL); + circuit->tx_queue = isis_tx_queue_new(circuit, send_lsp); return ISIS_OK; } @@ -743,13 +740,9 @@ void isis_circuit_down(struct isis_circuit *circuit) THREAD_OFF(circuit->t_send_lsp); THREAD_OFF(circuit->t_read); - if (circuit->lsp_queue) { - list_delete_and_null(&circuit->lsp_queue); - } - - if (circuit->lsp_hash) { - isis_lsp_hash_free(circuit->lsp_hash); - circuit->lsp_hash = NULL; + if (circuit->tx_queue) { + isis_tx_queue_free(circuit->tx_queue); + circuit->tx_queue = NULL; } /* send one gratuitous hello to spead up convergence */ @@ -957,33 +950,35 @@ int isis_interface_config_write(struct vty *vty) if (circuit == NULL) continue; if (circuit->ip_router) { - vty_out(vty, " ip router isis %s\n", + vty_out(vty, " ip router " PROTO_NAME " %s\n", area->area_tag); write++; } if (circuit->is_passive) { - vty_out(vty, " isis passive\n"); + vty_out(vty, " " PROTO_NAME " passive\n"); write++; } if (circuit->circ_type_config == CIRCUIT_T_P2P) { - vty_out(vty, " isis network point-to-point\n"); + vty_out(vty, " " PROTO_NAME " network point-to-point\n"); write++; } if (circuit->ipv6_router) { - vty_out(vty, " ipv6 router isis %s\n", + vty_out(vty, " ipv6 router " PROTO_NAME " %s\n", area->area_tag); write++; } /* ISIS - circuit type */ - if (circuit->is_type == IS_LEVEL_1) { - vty_out(vty, " isis circuit-type level-1\n"); - write++; - } else { - if (circuit->is_type == IS_LEVEL_2) { - vty_out(vty, - " isis circuit-type level-2-only\n"); + if (!fabricd) { + if (circuit->is_type == IS_LEVEL_1) { + vty_out(vty, " " PROTO_NAME " circuit-type level-1\n"); write++; + } else { + if (circuit->is_type == IS_LEVEL_2) { + vty_out(vty, + " " PROTO_NAME " circuit-type level-2-only\n"); + write++; + } } } @@ -992,7 +987,7 @@ int isis_interface_config_write(struct vty *vty) == circuit->csnp_interval[1]) { if (circuit->csnp_interval[0] != DEFAULT_CSNP_INTERVAL) { - vty_out(vty, " isis csnp-interval %d\n", + vty_out(vty, " " PROTO_NAME " csnp-interval %d\n", circuit->csnp_interval[0]); write++; } @@ -1001,7 +996,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->csnp_interval[i] != DEFAULT_CSNP_INTERVAL) { vty_out(vty, - " isis csnp-interval %d level-%d\n", + " " PROTO_NAME " csnp-interval %d level-%d\n", circuit->csnp_interval [i], i + 1); @@ -1015,7 +1010,7 @@ int isis_interface_config_write(struct vty *vty) == circuit->psnp_interval[1]) { if (circuit->psnp_interval[0] != DEFAULT_PSNP_INTERVAL) { - vty_out(vty, " isis psnp-interval %d\n", + vty_out(vty, " " PROTO_NAME " psnp-interval %d\n", circuit->psnp_interval[0]); write++; } @@ -1024,7 +1019,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->psnp_interval[i] != DEFAULT_PSNP_INTERVAL) { vty_out(vty, - " isis psnp-interval %d level-%d\n", + " " PROTO_NAME " psnp-interval %d level-%d\n", circuit->psnp_interval [i], i + 1); @@ -1036,7 +1031,7 @@ int isis_interface_config_write(struct vty *vty) /* ISIS - Hello padding - Defaults to true so only * display if false */ if (circuit->pad_hellos == 0) { - vty_out(vty, " no isis hello padding\n"); + vty_out(vty, " no " PROTO_NAME " hello padding\n"); write++; } @@ -1051,7 +1046,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_interval[0] != DEFAULT_HELLO_INTERVAL) { vty_out(vty, - " isis hello-interval %d\n", + " " PROTO_NAME " hello-interval %d\n", circuit->hello_interval[0]); write++; } @@ -1060,7 +1055,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_interval[i] != DEFAULT_HELLO_INTERVAL) { vty_out(vty, - " isis hello-interval %d level-%d\n", + " " PROTO_NAME " hello-interval %d level-%d\n", circuit->hello_interval [i], i + 1); @@ -1075,7 +1070,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_multiplier[0] != DEFAULT_HELLO_MULTIPLIER) { vty_out(vty, - " isis hello-multiplier %d\n", + " " PROTO_NAME " hello-multiplier %d\n", circuit->hello_multiplier[0]); write++; } @@ -1084,7 +1079,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->hello_multiplier[i] != DEFAULT_HELLO_MULTIPLIER) { vty_out(vty, - " isis hello-multiplier %d level-%d\n", + " " PROTO_NAME " hello-multiplier %d level-%d\n", circuit->hello_multiplier [i], i + 1); @@ -1096,7 +1091,7 @@ int isis_interface_config_write(struct vty *vty) /* ISIS - Priority */ if (circuit->priority[0] == circuit->priority[1]) { if (circuit->priority[0] != DEFAULT_PRIORITY) { - vty_out(vty, " isis priority %d\n", + vty_out(vty, " " PROTO_NAME " priority %d\n", circuit->priority[0]); write++; } @@ -1105,7 +1100,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->priority[i] != DEFAULT_PRIORITY) { vty_out(vty, - " isis priority %d level-%d\n", + " " PROTO_NAME " priority %d level-%d\n", circuit->priority[i], i + 1); write++; @@ -1117,7 +1112,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->te_metric[0] == circuit->te_metric[1]) { if (circuit->te_metric[0] != DEFAULT_CIRCUIT_METRIC) { - vty_out(vty, " isis metric %d\n", + vty_out(vty, " " PROTO_NAME " metric %d\n", circuit->te_metric[0]); write++; } @@ -1126,7 +1121,7 @@ int isis_interface_config_write(struct vty *vty) if (circuit->te_metric[i] != DEFAULT_CIRCUIT_METRIC) { vty_out(vty, - " isis metric %d level-%d\n", + " " PROTO_NAME " metric %d level-%d\n", circuit->te_metric[i], i + 1); write++; @@ -1134,12 +1129,12 @@ int isis_interface_config_write(struct vty *vty) } } if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) { - vty_out(vty, " isis password md5 %s\n", + vty_out(vty, " " PROTO_NAME " password md5 %s\n", circuit->passwd.passwd); write++; } else if (circuit->passwd.type == ISIS_PASSWD_TYPE_CLEARTXT) { - vty_out(vty, " isis password clear %s\n", + vty_out(vty, " " PROTO_NAME " password clear %s\n", circuit->passwd.passwd); write++; } @@ -1343,60 +1338,4 @@ void isis_circuit_init() /* Install interface node */ install_node(&interface_node, isis_interface_config_write); if_cmd_init(); - - isis_vty_init(); -} - -void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit) -{ - if (circuit->t_send_lsp) - return; - circuit->t_send_lsp = - thread_add_event(master, send_lsp, circuit, 0, NULL); -} - -void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp) -{ - if (isis_lsp_hash_lookup(circuit->lsp_hash, lsp)) - return; - - listnode_add(circuit->lsp_queue, lsp); - isis_lsp_hash_add(circuit->lsp_hash, lsp); - isis_circuit_schedule_lsp_send(circuit); -} - -void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit) -{ - if (!circuit->lsp_queue) - return; - - list_delete_all_node(circuit->lsp_queue); - isis_lsp_hash_clean(circuit->lsp_hash); -} - -void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit, - struct isis_lsp *lsp) -{ - if (!circuit->lsp_queue) - return; - - listnode_delete(circuit->lsp_queue, lsp); - isis_lsp_hash_release(circuit->lsp_hash, lsp); -} - -struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit) -{ - if (!circuit->lsp_queue) - return NULL; - - struct listnode *node = listhead(circuit->lsp_queue); - if (!node) - return NULL; - - struct isis_lsp *rv = listgetdata(node); - - list_delete_node(circuit->lsp_queue, node); - isis_lsp_hash_release(circuit->lsp_hash, rv); - - return rv; } diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index 8dbd7ac49..ea68767fe 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -80,14 +80,8 @@ struct isis_circuit { struct thread *t_send_csnp[2]; struct thread *t_send_psnp[2]; struct thread *t_send_lsp; - struct list *lsp_queue; /* LSPs to be txed (both levels) */ - struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */ - time_t lsp_queue_last_push[2]; /* timestamp used to enforce transmit - * interval; - * for scalability, use one timestamp per - * circuit, instead of one per lsp per - * circuit - */ + struct isis_tx_queue *tx_queue; + /* there is no real point in two streams, just for programming kicker */ int (*rx)(struct isis_circuit *circuit, uint8_t *ssnpa); struct stream *rcv_stream; /* Stream for receiving */ @@ -114,10 +108,10 @@ struct isis_circuit { struct isis_passwd passwd; /* Circuit rx/tx password */ int is_type; /* circuit is type == level of circuit * differentiated from circuit type (media) */ - uint32_t hello_interval[2]; /* l1HelloInterval in msecs */ - uint16_t hello_multiplier[2]; /* l1HelloMultiplier */ - uint16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */ - uint16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */ + uint32_t hello_interval[2]; /* hello-interval in seconds */ + uint16_t hello_multiplier[2]; /* hello-multiplier */ + uint16_t csnp_interval[2]; /* csnp-interval in seconds */ + uint16_t psnp_interval[2]; /* psnp-interval in seconds */ uint8_t metric[2]; uint32_t te_metric[2]; struct mpls_te_circuit @@ -196,10 +190,4 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit, int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, bool enabled); -void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit); -void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp); -void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit); -void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit, - struct isis_lsp *lsp); -struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit); #endif /* _ZEBRA_ISIS_CIRCUIT_H */ diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 66c97ae89..e8777e9b5 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -56,6 +56,8 @@ #include "isisd/isis_te.h" #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" +#include "isisd/fabricd.h" +#include "isisd/isis_tx_queue.h" static int lsp_l1_refresh(struct thread *thread); static int lsp_l2_refresh(struct thread *thread); @@ -117,10 +119,9 @@ static void lsp_destroy(struct isis_lsp *lsp) return; for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, circuit)) - isis_circuit_cancel_queued_lsp(circuit, lsp); + isis_tx_queue_del(circuit->tx_queue, lsp); ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags); - ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); lsp_clear_data(lsp); @@ -352,7 +353,21 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno) isis_spf_schedule(lsp->area, lsp->level); } -static void lsp_purge(struct isis_lsp *lsp, int level) +static void lsp_purge_add_poi(struct isis_lsp *lsp, + const uint8_t *sender) +{ + if (!lsp->area->purge_originator) + return; + + /* add purge originator identification */ + if (!lsp->tlvs) + lsp->tlvs = isis_alloc_tlvs(); + isis_tlvs_set_purge_originator(lsp->tlvs, isis->sysid, sender); + isis_tlvs_set_dynamic_hostname(lsp->tlvs, cmd_hostname_get()); +} + +static void lsp_purge(struct isis_lsp *lsp, int level, + const uint8_t *sender) { /* reset stream */ lsp_clear_data(lsp); @@ -364,8 +379,10 @@ static void lsp_purge(struct isis_lsp *lsp, int level) lsp->level = level; lsp->age_out = lsp->area->max_lsp_lifetime[level - 1]; + lsp_purge_add_poi(lsp, sender); + lsp_pack_pdu(lsp); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); } /* @@ -385,7 +402,7 @@ static void lsp_seqno_update(struct isis_lsp *lsp0) if (lsp->tlvs) lsp_inc_seqno(lsp, 0); else - lsp_purge(lsp, lsp0->level); + lsp_purge(lsp, lsp0->level, NULL); } return; @@ -425,7 +442,8 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, lsp->tlvs = tlvs; - if (area->dynhostname && lsp->tlvs->hostname) { + if (area->dynhostname && lsp->tlvs->hostname + && lsp->hdr.rem_lifetime) { isis_dynhn_insert(lsp->hdr.lsp_id, lsp->tlvs->hostname, (lsp->hdr.lsp_bits & LSPBIT_IST) == IS_LEVEL_1_AND_2 @@ -462,10 +480,10 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, lsp->own_lsp = 0; } - lsp_update_data(lsp, hdr, tlvs, stream, area, level); if (confusion) { - lsp->hdr.rem_lifetime = hdr->rem_lifetime = 0; - put_lsp_hdr(lsp, NULL, true); + lsp_purge(lsp, level, NULL); + } else { + lsp_update_data(lsp, hdr, tlvs, stream, area, level); } if (LSP_FRAGMENT(lsp->hdr.lsp_id) && !lsp->lspu.zero_lsp) { @@ -928,6 +946,14 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) lsp_debug("ISIS (%s): Adding circuit specific information.", area->area_tag); + if (fabricd) { + lsp_debug( + "ISIS (%s): Adding tier %" PRIu8 " spine-leaf-extension tlv.", + area->area_tag, fabricd_tier(area)); + isis_tlvs_add_spine_leaf(lsp->tlvs, fabricd_tier(area), true, + false, false, false); + } + struct isis_circuit *circuit; for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { if (!circuit->interface) @@ -1091,9 +1117,16 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) */ subtlv_len = 0; + uint32_t neighbor_metric; + if (fabricd_tier(area) == 0) { + neighbor_metric = 0xffe; + } else { + neighbor_metric = metric; + } + tlvs_add_mt_p2p(lsp->tlvs, circuit, - ne_id, metric, subtlvs, - subtlv_len); + ne_id, neighbor_metric, + subtlvs, subtlv_len); } } else { lsp_debug( @@ -1192,7 +1225,7 @@ int lsp_generate(struct isis_area *area, int level) /* time to calculate our checksum */ lsp_seqno_update(newlsp); newlsp->last_generated = time(NULL); - lsp_set_all_srmflags(newlsp); + lsp_flood(newlsp, NULL); refresh_time = lsp_refresh_time(newlsp, rem_lifetime); @@ -1223,7 +1256,7 @@ int lsp_generate(struct isis_area *area, int level) } /* - * Search own LSPs, update holding time and set SRM + * Search own LSPs, update holding time and flood */ static int lsp_regenerate(struct isis_area *area, int level) { @@ -1255,7 +1288,7 @@ static int lsp_regenerate(struct isis_area *area, int level) rem_lifetime = lsp_rem_lifetime(area, level); lsp->hdr.rem_lifetime = rem_lifetime; lsp->last_generated = time(NULL); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { frag->hdr.lsp_bits = lsp_bits_generate( level, area->overload_bit, area->attached_bit); @@ -1265,7 +1298,7 @@ static int lsp_regenerate(struct isis_area *area, int level) */ frag->hdr.rem_lifetime = rem_lifetime; frag->age_out = ZERO_AGE_LIFETIME; - lsp_set_all_srmflags(frag); + lsp_flood(frag, NULL); } lsp_seqno_update(lsp); @@ -1565,7 +1598,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level) lsp_pack_pdu(lsp); lsp->own_lsp = 1; lsp_insert(lsp, lspdb); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); refresh_time = lsp_refresh_time(lsp, rem_lifetime); THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); @@ -1624,7 +1657,7 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level) lsp_build_pseudo(lsp, circuit, level); lsp_inc_seqno(lsp, 0); lsp->last_generated = time(NULL); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); refresh_time = lsp_refresh_time(lsp, rem_lifetime); if (level == IS_LEVEL_1) @@ -1800,30 +1833,25 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level) /* * Walk through LSPs for an area * - set remaining lifetime - * - set LSPs with SRMflag set for sending */ int lsp_tick(struct thread *thread) { struct isis_area *area; - struct isis_circuit *circuit; struct isis_lsp *lsp; - struct list *lsp_list; - struct listnode *lspnode, *cnode; dnode_t *dnode, *dnode_next; int level; uint16_t rem_lifetime; - time_t now = monotime(NULL); - - lsp_list = list_new(); + bool fabricd_sync_incomplete = false; area = THREAD_ARG(thread); assert(area); area->t_tick = NULL; thread_add_timer(master, lsp_tick, area, 1, &area->t_tick); + struct isis_circuit *fabricd_init_c = fabricd_initial_sync_circuit(area); + /* - * Build a list of LSPs with (any) SRMflag set - * and removed the ones that have aged out + * Remove LSPs which have aged out */ for (level = 0; level < ISIS_LEVELS; level++) { if (area->lspdb[level] && dict_count(area->lspdb[level]) > 0) { @@ -1854,17 +1882,14 @@ int lsp_tick(struct thread *thread) */ if (rem_lifetime == 1 && lsp->hdr.seqno != 0) { /* 7.3.16.4 a) set SRM flags on all */ - lsp_set_all_srmflags(lsp); - /* 7.3.16.4 b) retain only the header - * FIXME */ + /* 7.3.16.4 b) retain only the header */ + if (lsp->area->purge_originator) + lsp_purge(lsp, lsp->level, NULL); + else + lsp_flood(lsp, NULL); /* 7.3.16.4 c) record the time to purge * FIXME */ - /* run/schedule spf */ - /* isis_spf_schedule is called inside - * lsp_destroy() below; - * so it is not needed here. */ - /* isis_spf_schedule (lsp->area, - * lsp->level); */ + isis_spf_schedule(lsp->area, lsp->level); } if (lsp->age_out == 0) { @@ -1878,44 +1903,22 @@ int lsp_tick(struct thread *thread) lsp = NULL; dict_delete_free(area->lspdb[level], dnode); - } else if (flags_any_set(lsp->SRMflags)) - listnode_add(lsp_list, lsp); - } - - /* - * Send LSPs on circuits indicated by the SRMflags - */ - if (listcount(lsp_list) > 0) { - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, - cnode, circuit)) { - if (!circuit->lsp_queue) - continue; - - if (now - circuit->lsp_queue_last_push[level] - < MIN_LSP_RETRANS_INTERVAL) { - continue; - } + } - circuit->lsp_queue_last_push[level] = now; - - for (ALL_LIST_ELEMENTS_RO( - lsp_list, lspnode, lsp)) { - if (circuit->upadjcount - [lsp->level - 1] - && ISIS_CHECK_FLAG( - lsp->SRMflags, - circuit)) { - isis_circuit_queue_lsp( - circuit, lsp); - } - } + if (fabricd_init_c) { + fabricd_sync_incomplete |= + ISIS_CHECK_FLAG(lsp->SSNflags, + fabricd_init_c); } - list_delete_all_node(lsp_list); } } } - list_delete_and_null(&lsp_list); + if (fabricd_init_c + && !fabricd_sync_incomplete + && !isis_tx_queue_len(fabricd_init_c->tx_queue)) { + fabricd_initial_sync_finish(area); + } return ISIS_OK; } @@ -1928,7 +1931,7 @@ void lsp_purge_pseudo(uint8_t *id, struct isis_circuit *circuit, int level) if (!lsp) return; - lsp_purge(lsp, level); + lsp_purge(lsp, level, NULL); } /* @@ -1952,27 +1955,44 @@ void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr, memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr)); lsp->hdr.rem_lifetime = 0; + lsp_purge_add_poi(lsp, NULL); + lsp_pack_pdu(lsp); lsp_insert(lsp, area->lspdb[lsp->level - 1]); - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); return; } -void lsp_set_all_srmflags(struct isis_lsp *lsp) +void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set) { struct listnode *node; struct isis_circuit *circuit; assert(lsp); - ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); + if (!lsp->area) + return; - if (lsp->area) { - struct list *circuit_list = lsp->area->circuit_list; - for (ALL_LIST_ELEMENTS_RO(circuit_list, node, circuit)) { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + struct list *circuit_list = lsp->area->circuit_list; + for (ALL_LIST_ELEMENTS_RO(circuit_list, node, circuit)) { + if (set) { + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); + } else { + isis_tx_queue_del(circuit->tx_queue, lsp); } } } + +void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit) +{ + if (!fabricd) { + lsp_set_all_srmflags(lsp, true); + if (circuit) + isis_tx_queue_del(circuit->tx_queue, lsp); + } else { + fabricd_lsp_flood(lsp); + } +} diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index d531cb157..4e6379447 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -37,7 +37,6 @@ struct isis_lsp { struct list *frags; struct isis_lsp *zero_lsp; } lspu; - uint32_t SRMflags[ISIS_MAX_CIRCUITS]; uint32_t SSNflags[ISIS_MAX_CIRCUITS]; int level; /* L1 or L2? */ int scheduled; /* scheduled for sending */ @@ -100,6 +99,7 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost); void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost); int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost); /* sets SRMflags for all active circuits of an lsp */ -void lsp_set_all_srmflags(struct isis_lsp *lsp); +void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set); +void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit); #endif /* ISIS_LSP */ diff --git a/isisd/isis_lsp_hash.c b/isisd/isis_lsp_hash.c deleted file mode 100644 index c521f42b3..000000000 --- a/isisd/isis_lsp_hash.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * IS-IS Rout(e)ing protocol - LSP Hash - * - * Copyright (C) 2017 Christian Franke - * - * This file is part of FreeRangeRouting (FRR) - * - * FRR is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * FRR is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include <zebra.h> - -#include "hash.h" -#include "jhash.h" - -#include "isisd/isis_memory.h" -#include "isisd/isis_flags.h" -#include "dict.h" -#include "isisd/isis_circuit.h" -#include "isisd/isis_lsp.h" -#include "isisd/isis_lsp_hash.h" - -DEFINE_MTYPE_STATIC(ISISD, LSP_HASH, "ISIS LSP Hash") - -struct isis_lsp_hash { - struct hash *h; -}; - -static unsigned lsp_hash_key(void *lp) -{ - struct isis_lsp *lsp = lp; - - return jhash(lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 2, 0x55aa5a5a); -} - -static int lsp_hash_cmp(const void *a, const void *b) -{ - const struct isis_lsp *la = a, *lb = b; - - return 0 == memcmp(la->hdr.lsp_id, lb->hdr.lsp_id, ISIS_SYS_ID_LEN + 2); -} - -struct isis_lsp_hash *isis_lsp_hash_new(void) -{ - struct isis_lsp_hash *rv = XCALLOC(MTYPE_LSP_HASH, sizeof(*rv)); - - rv->h = hash_create(lsp_hash_key, lsp_hash_cmp, NULL); - return rv; -} - -void isis_lsp_hash_clean(struct isis_lsp_hash *ih) -{ - hash_clean(ih->h, NULL); -} - -void isis_lsp_hash_free(struct isis_lsp_hash *ih) -{ - isis_lsp_hash_clean(ih); - hash_free(ih->h); -} - -struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih, - struct isis_lsp *lsp) -{ - return hash_lookup(ih->h, lsp); -} - -void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp) -{ - struct isis_lsp *inserted; - inserted = hash_get(ih->h, lsp, hash_alloc_intern); - assert(inserted == lsp); -} - -void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp) -{ - hash_release(ih->h, lsp); -} diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 3b4168adb..4d6a6da5d 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -54,11 +54,13 @@ #include "isisd/isis_zebra.h" #include "isisd/isis_te.h" #include "isisd/isis_errors.h" +#include "isisd/isis_vty_common.h" /* Default configuration file name */ #define ISISD_DEFAULT_CONFIG "isisd.conf" /* Default vty port */ #define ISISD_VTY_PORT 2608 +#define FABRICD_VTY_PORT 2618 /* isisd privileges */ zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND}; @@ -145,9 +147,15 @@ struct quagga_signal_t isisd_signals[] = { }, }; +#ifdef FABRICD +FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT, + + .proghelp = "Implementation of the OpenFabric routing protocol.", +#else FRR_DAEMON_INFO(isisd, ISIS, .vty_port = ISISD_VTY_PORT, .proghelp = "Implementation of the IS-IS routing protocol.", +#endif .copyright = "Copyright (c) 2001-2002 Sampo Saaristo," " Ofer Wald and Hannes Gredler", @@ -164,7 +172,11 @@ int main(int argc, char **argv, char **envp) { int opt; +#ifdef FABRICD + frr_preinit(&fabricd_di, argc, argv); +#else frr_preinit(&isisd_di, argc, argv); +#endif frr_opt_add("", longopts, ""); /* Command line argument treatment. */ @@ -196,6 +208,7 @@ int main(int argc, char **argv, char **envp) prefix_list_init(); isis_init(); isis_circuit_init(); + isis_vty_init(); isis_spf_cmds_init(); isis_redist_init(); isis_route_map_init(); diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index 2155bf584..2dfccf983 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -311,7 +311,7 @@ int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty) for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, setting)) { const char *name = isis_mtid2str(setting->mtid); if (name && !setting->enabled) { - vty_out(vty, " no isis topology %s\n", name); + vty_out(vty, " no " PROTO_NAME " topology %s\n", name); written++; } } diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 5c4e3a35b..88575f531 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -56,6 +56,8 @@ #include "isisd/isis_mt.h" #include "isisd/isis_tlvs.h" #include "isisd/isis_errors.h" +#include "isisd/fabricd.h" +#include "isisd/isis_tx_queue.h" static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit, int level) @@ -207,6 +209,12 @@ static int process_p2p_hello(struct iih_info *iih) thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, &adj->t_expire); + /* While fabricds initial sync is in progress, ignore hellos from other + * interfaces than the one we are performing the initial sync on. */ + if (fabricd_initial_sync_is_in_progress(iih->circuit->area) + && fabricd_initial_sync_circuit(iih->circuit->area) != iih->circuit) + return ISIS_OK; + /* 8.2.5.2 a) a match was detected */ if (isis_tlvs_area_addresses_match(iih->tlvs, iih->circuit->area->area_addrs)) { @@ -671,7 +679,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, goto out; } - iih.v4_usable = (circuit->ip_addrs && listcount(circuit->ip_addrs) + iih.v4_usable = (fabricd_ip_addrs(circuit) && iih.tlvs->ipv4_address.count); iih.v6_usable = (circuit->ipv6_link && listcount(circuit->ipv6_link) @@ -700,14 +708,37 @@ out: * Section 7.3.15.1 - Action on receipt of a link state PDU */ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit, - const uint8_t *ssnpa) + const uint8_t *ssnpa, uint8_t max_area_addrs) { - int level = (pdu_type == L1_LINK_STATE) ? ISIS_LEVEL1 : ISIS_LEVEL2; + int level; + bool circuit_scoped; + + if (pdu_type == FS_LINK_STATE) { + if (!fabricd) + return ISIS_ERROR; + if (max_area_addrs != L2_CIRCUIT_FLOODING_SCOPE) + return ISIS_ERROR; + level = ISIS_LEVEL2; + circuit_scoped = true; + + /* The stream is used verbatim for sending out new LSPDUs. + * So make sure we store it as an L2 LSPDU internally. + * (compare for the reverse in `send_lsp`) */ + stream_putc_at(circuit->rcv_stream, 4, L2_LINK_STATE); + stream_putc_at(circuit->rcv_stream, 7, 0); + } else { + if (pdu_type == L1_LINK_STATE) + level = ISIS_LEVEL1; + else + level = ISIS_LEVEL2; + circuit_scoped = false; + } if (isis->debugs & DEBUG_UPDATE_PACKETS) { zlog_debug( - "ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u", - circuit->area->area_tag, level, + "ISIS-Upd (%s): Rcvd %sL%d LSP on %s, cirType %s, cirID %u", + circuit->area->area_tag, + circuit_scoped ? "Circuit scoped " : "", level, circuit->interface->name, circuit_t2string(circuit->is_type), circuit->circuit_id); @@ -869,7 +900,8 @@ dontcheckadj: * but * wrong checksum, initiate a purge. */ if (lsp && (lsp->hdr.seqno == hdr.seqno) - && (lsp->hdr.checksum != hdr.checksum)) { + && (lsp->hdr.checksum != hdr.checksum) + && hdr.rem_lifetime) { zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08" PRIx32 " with confused checksum received.", circuit->area->area_tag, rawlspid_print(hdr.lsp_id), @@ -899,7 +931,8 @@ dontcheckadj: lsp_confusion); tlvs = NULL; /* ii */ - lsp_set_all_srmflags(lsp); + if (!circuit_scoped) + lsp_flood(lsp, NULL); /* v */ ISIS_FLAGS_CLEAR_ALL( lsp->SSNflags); /* FIXME: @@ -913,9 +946,10 @@ dontcheckadj: * Otherwise, don't reflood * through incoming circuit as usual */ if (!lsp_confusion) { - /* iii */ - ISIS_CLEAR_FLAG(lsp->SRMflags, - circuit); + isis_tx_queue_del( + circuit->tx_queue, + lsp); + /* iv */ if (circuit->circ_type != CIRCUIT_T_BROADCAST) @@ -926,7 +960,8 @@ dontcheckadj: } /* 7.3.16.4 b) 2) */ else if (comp == LSP_EQUAL) { /* i */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, + lsp); /* ii */ if (circuit->circ_type != CIRCUIT_T_BROADCAST) @@ -934,16 +969,19 @@ dontcheckadj: circuit); } /* 7.3.16.4 b) 3) */ else { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, + lsp, TX_LSP_NORMAL); ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); } } else if (lsp->hdr.rem_lifetime != 0) { /* our own LSP -> 7.3.16.4 c) */ if (comp == LSP_NEWER) { lsp_inc_seqno(lsp, hdr.seqno); - lsp_set_all_srmflags(lsp); + if (!circuit_scoped) + lsp_flood(lsp, NULL); } else { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, + lsp, TX_LSP_NORMAL); ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); } if (isis->debugs & DEBUG_UPDATE_PACKETS) @@ -985,7 +1023,7 @@ dontcheckadj: } /* If the received LSP is older or equal, * resend the LSP which will act as ACK */ - lsp_set_all_srmflags(lsp); + lsp_flood(lsp, NULL); } else { /* 7.3.15.1 e) - This lsp originated on another system */ @@ -1006,7 +1044,7 @@ dontcheckadj: if (!lsp0) { zlog_debug( "Got lsp frag, while zero lsp not in database"); - return ISIS_OK; + goto out; } } /* i */ @@ -1023,10 +1061,8 @@ dontcheckadj: circuit->area, level, false); tlvs = NULL; } - /* ii */ - lsp_set_all_srmflags(lsp); - /* iii */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + if (!circuit_scoped) + lsp_flood(lsp, circuit); /* iv */ if (circuit->circ_type != CIRCUIT_T_BROADCAST) @@ -1035,7 +1071,7 @@ dontcheckadj: } /* 7.3.15.1 e) 2) LSP equal to the one in db */ else if (comp == LSP_EQUAL) { - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream, circuit->area, level, false); tlvs = NULL; @@ -1044,7 +1080,8 @@ dontcheckadj: } /* 7.3.15.1 e) 3) LSP older than the one in db */ else { - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); } } @@ -1052,6 +1089,10 @@ dontcheckadj: retval = ISIS_OK; out: + if (circuit_scoped) { + fabricd_trigger_csnp(circuit->area); + } + isis_free_tlvs(tlvs); return retval; } @@ -1157,7 +1198,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, circuit->u.bc.adjdb[level - 1])) return ISIS_OK; /* Silently discard */ } else { - if (!circuit->u.p2p.neighbor) { + if (!fabricd && !circuit->u.p2p.neighbor) { zlog_warn("no p2p neighbor on circuit %s", circuit->interface->name); return ISIS_OK; /* Silently discard */ @@ -1206,6 +1247,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, } } + bool resync_needed = false; + /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */ for (struct isis_lsp_entry *entry = entry_head; entry; entry = entry->next) { @@ -1221,25 +1264,28 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, if (cmp == LSP_EQUAL) { /* if (circuit->circ_type != * CIRCUIT_T_BROADCAST) */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); } /* 7.3.15.2 b) 3) if it is older, clear SSN and set SRM */ else if (cmp == LSP_OLDER) { ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); } /* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM on p2p */ else { if (own_lsp) { lsp_inc_seqno(lsp, entry->seqno); - ISIS_SET_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_add(circuit->tx_queue, lsp, + TX_LSP_NORMAL); } else { ISIS_SET_FLAG(lsp->SSNflags, circuit); /* if (circuit->circ_type != * CIRCUIT_T_BROADCAST) */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); + resync_needed = true; } } } else { @@ -1271,8 +1317,10 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, entry->checksum, lsp0, level); lsp_insert(lsp, circuit->area->lspdb[level - 1]); - ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags); + + lsp_set_all_srmflags(lsp, false); ISIS_SET_FLAG(lsp->SSNflags, circuit); + resync_needed = true; } } } @@ -1303,12 +1351,18 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, } /* on remaining LSPs we set SRM (neighbor knew not of) */ - for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) - ISIS_SET_FLAG(lsp->SRMflags, circuit); + for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) { + isis_tx_queue_add(circuit->tx_queue, lsp, TX_LSP_NORMAL); + resync_needed = true; + } + /* lets free it */ list_delete_and_null(&lsp_list); } + if (fabricd_initial_sync_is_complete(circuit->area) && resync_needed) + zlog_warn("OpenFabric: Needed to resync LSPDB using CSNP!\n"); + retval = ISIS_OK; out: isis_free_tlvs(tlvs); @@ -1327,6 +1381,7 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size) break; case L1_LINK_STATE: case L2_LINK_STATE: + case FS_LINK_STATE: *size = ISIS_LSP_HDR_LEN; break; case L1_COMPLETE_SEQ_NUM: @@ -1427,7 +1482,9 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) } /* either 3 or 0 */ - if (max_area_addrs != 0 && max_area_addrs != isis->max_area_addrs) { + if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr field */ + && max_area_addrs != 0 + && max_area_addrs != isis->max_area_addrs) { flog_err( ISIS_ERR_PACKET, "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8 @@ -1440,11 +1497,18 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) case L1_LAN_HELLO: case L2_LAN_HELLO: case P2P_HELLO: + if (fabricd && pdu_type != P2P_HELLO) + return ISIS_ERROR; retval = process_hello(pdu_type, circuit, ssnpa); break; case L1_LINK_STATE: case L2_LINK_STATE: - retval = process_lsp(pdu_type, circuit, ssnpa); + case FS_LINK_STATE: + if (fabricd + && pdu_type != L2_LINK_STATE + && pdu_type != FS_LINK_STATE) + return ISIS_ERROR; + retval = process_lsp(pdu_type, circuit, ssnpa, max_area_addrs); break; case L1_COMPLETE_SEQ_NUM: case L2_COMPLETE_SEQ_NUM: @@ -1582,8 +1646,15 @@ int send_hello(struct isis_circuit *circuit, int level) && !circuit->disable_threeway_adj) { uint32_t ext_circuit_id = circuit->idx; if (circuit->u.p2p.neighbor) { + uint8_t threeway_state; + + if (fabricd_initial_sync_is_in_progress(circuit->area) + && fabricd_initial_sync_circuit(circuit->area) != circuit) + threeway_state = ISIS_THREEWAY_DOWN; + else + threeway_state = circuit->u.p2p.neighbor->threeway_state; isis_tlvs_add_threeway_adj(tlvs, - circuit->u.p2p.neighbor->threeway_state, + threeway_state, ext_circuit_id, circuit->u.p2p.neighbor->sysid, circuit->u.p2p.neighbor->ext_circuit_id); @@ -1618,8 +1689,12 @@ int send_hello(struct isis_circuit *circuit, int level) false, false); } - if (circuit->ip_router && circuit->ip_addrs) - isis_tlvs_add_ipv4_addresses(tlvs, circuit->ip_addrs); + if (circuit->ip_router) { + struct list *circuit_ip_addrs = fabricd_ip_addrs(circuit); + + if (circuit_ip_addrs) + isis_tlvs_add_ipv4_addresses(tlvs, circuit_ip_addrs); + } if (circuit->ipv6_router && circuit->ipv6_link) isis_tlvs_add_ipv6_addresses(tlvs, circuit->ipv6_link); @@ -1889,8 +1964,9 @@ int send_l1_csnp(struct thread *thread) circuit->t_send_csnp[0] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST - && circuit->u.bc.is_dr[0]) { + if ((circuit->circ_type == CIRCUIT_T_BROADCAST + && circuit->u.bc.is_dr[0]) + || circuit->circ_type == CIRCUIT_T_P2P) { send_csnp(circuit, 1); } /* set next timer thread */ @@ -1911,8 +1987,9 @@ int send_l2_csnp(struct thread *thread) circuit->t_send_csnp[1] = NULL; - if (circuit->circ_type == CIRCUIT_T_BROADCAST - && circuit->u.bc.is_dr[1]) { + if ((circuit->circ_type == CIRCUIT_T_BROADCAST + && circuit->u.bc.is_dr[1]) + || circuit->circ_type == CIRCUIT_T_P2P) { send_csnp(circuit, 2); } /* set next timer thread */ @@ -2086,25 +2163,12 @@ int send_l2_psnp(struct thread *thread) /* * ISO 10589 - 7.3.14.3 */ -int send_lsp(struct thread *thread) +void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type) { - struct isis_circuit *circuit; - struct isis_lsp *lsp; + struct isis_circuit *circuit = arg; int clear_srm = 1; int retval = ISIS_OK; - circuit = THREAD_ARG(thread); - assert(circuit); - circuit->t_send_lsp = NULL; - - lsp = isis_circuit_lsp_queue_pop(circuit); - if (!lsp) - return ISIS_OK; - - if (!list_isempty(circuit->lsp_queue)) { - isis_circuit_schedule_lsp_send(circuit); - } - if (circuit->state != C_STATE_UP || circuit->is_passive == 1) goto out; @@ -2144,6 +2208,11 @@ int send_lsp(struct thread *thread) /* copy our lsp to the send buffer */ stream_copy(circuit->snd_stream, lsp->pdu); + if (tx_type == TX_LSP_CIRCUIT_SCOPED) { + stream_putc_at(circuit->snd_stream, 4, FS_LINK_STATE); + stream_putc_at(circuit->snd_stream, 7, L2_CIRCUIT_FLOODING_SCOPE); + } + if (isis->debugs & DEBUG_UPDATE_PACKETS) { zlog_debug("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 @@ -2181,8 +2250,6 @@ out: * to clear * the fag. */ - ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); + isis_tx_queue_del(circuit->tx_queue, lsp); } - - return retval; } diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h index c69bfedea..3d2420eb0 100644 --- a/isisd/isis_pdu.h +++ b/isisd/isis_pdu.h @@ -24,6 +24,8 @@ #ifndef _ZEBRA_ISIS_PDU_H #define _ZEBRA_ISIS_PDU_H +#include "isisd/isis_tx_queue.h" + #ifdef __SUNPRO_C #pragma pack(1) #endif @@ -125,6 +127,8 @@ struct isis_p2p_hello_hdr { #define L1_LINK_STATE 18 #define L2_LINK_STATE 20 +#define FS_LINK_STATE 10 +#define L2_CIRCUIT_FLOODING_SCOPE 2 struct isis_lsp_hdr { uint16_t pdu_len; uint16_t rem_lifetime; @@ -212,7 +216,7 @@ int send_l1_csnp(struct thread *thread); int send_l2_csnp(struct thread *thread); int send_l1_psnp(struct thread *thread); int send_l2_psnp(struct thread *thread); -int send_lsp(struct thread *thread); +void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type); void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream); int send_hello(struct isis_circuit *circuit, int level); int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa); diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index cd3ca4437..ab7584ed3 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -377,7 +377,7 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis) * routes to Zebra and has nothing to do with * redistribution, * so skip it. */ - if (type == ZEBRA_ROUTE_ISIS) + if (type == PROTO_TYPE) continue; afi_t afi = afi_for_redist_protocol(protocol); @@ -515,13 +515,19 @@ void isis_redist_area_finish(struct isis_area *area) DEFUN (isis_redistribute, isis_redistribute_cmd, - "redistribute <ipv4|ipv6> " FRR_REDIST_STR_ISISD " <level-1|level-2> [<metric (0-16777215)|route-map WORD>]", + "redistribute <ipv4|ipv6> " PROTO_REDIST_STR +#ifndef FABRICD + " <level-1|level-2>" +#endif + " [<metric (0-16777215)|route-map WORD>]", REDIST_STR "Redistribute IPv4 routes\n" "Redistribute IPv6 routes\n" - FRR_REDIST_HELP_STR_ISISD + PROTO_REDIST_HELP +#ifndef FABRICD "Redistribute into level-1\n" "Redistribute into level-2\n" +#endif "Metric for redistributed routes\n" "ISIS default metric\n" "Route map reference\n" @@ -530,7 +536,7 @@ DEFUN (isis_redistribute, int idx_afi = 1; int idx_protocol = 2; int idx_level = 3; - int idx_metric_rmap = 4; + int idx_metric_rmap = fabricd ? 3 : 4; VTY_DECLVAR_CONTEXT(isis_area, area); int family; int afi; @@ -551,7 +557,9 @@ DEFUN (isis_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - if (!strcmp("level-1", argv[idx_level]->arg)) + if (fabricd) + level = 2; + else if (!strcmp("level-1", argv[idx_level]->arg)) level = 1; else if (!strcmp("level-2", argv[idx_level]->arg)) level = 2; @@ -585,14 +593,20 @@ DEFUN (isis_redistribute, DEFUN (no_isis_redistribute, no_isis_redistribute_cmd, - "no redistribute <ipv4|ipv6> " FRR_REDIST_STR_ISISD " <level-1|level-2>", - NO_STR + "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR +#ifndef FABRICD + " <level-1|level-2>" +#endif + , NO_STR REDIST_STR "Redistribute IPv4 routes\n" "Redistribute IPv6 routes\n" - FRR_REDIST_HELP_STR_ISISD + PROTO_REDIST_HELP +#ifndef FABRICD "Redistribute into level-1\n" - "Redistribute into level-2\n") + "Redistribute into level-2\n" +#endif + ) { int idx_afi = 2; int idx_protocol = 3; @@ -615,7 +629,10 @@ DEFUN (no_isis_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + if (fabricd) + level = 2; + else + level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; isis_redist_unset(area, level, family, type); return 0; @@ -623,13 +640,19 @@ DEFUN (no_isis_redistribute, DEFUN (isis_default_originate, isis_default_originate_cmd, - "default-information originate <ipv4|ipv6> <level-1|level-2> [always] [<metric (0-16777215)|route-map WORD>]", + "default-information originate <ipv4|ipv6>" +#ifndef FABRICD + " <level-1|level-2>" +#endif + " [always] [<metric (0-16777215)|route-map WORD>]", "Control distribution of default information\n" "Distribute a default route\n" "Distribute default route for IPv4\n" "Distribute default route for IPv6\n" +#ifndef FABRICD "Distribute default route into level-1\n" "Distribute default route into level-2\n" +#endif "Always advertise default route\n" "Metric for default route\n" "ISIS default metric\n" @@ -638,8 +661,8 @@ DEFUN (isis_default_originate, { int idx_afi = 2; int idx_level = 3; - int idx_always = 4; - int idx_metric_rmap = 4; + int idx_always = fabricd ? 3 : 4; + int idx_metric_rmap = fabricd ? 3 : 4; VTY_DECLVAR_CONTEXT(isis_area, area); int family; int originate_type = DEFAULT_ORIGINATE; @@ -651,7 +674,10 @@ DEFUN (isis_default_originate, if (family < 0) return CMD_WARNING_CONFIG_FAILED; - level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; + if (fabricd) + level = 2; + else + level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2; if ((area->is_type & level) != level) { vty_out(vty, "Node is not a level-%d IS\n", level); @@ -685,14 +711,20 @@ DEFUN (isis_default_originate, DEFUN (no_isis_default_originate, no_isis_default_originate_cmd, - "no default-information originate <ipv4|ipv6> <level-1|level-2>", - NO_STR + "no default-information originate <ipv4|ipv6>" +#ifndef FABRICD + " <level-1|level-2>" +#endif + , NO_STR "Control distribution of default information\n" "Distribute a default route\n" "Distribute default route for IPv4\n" "Distribute default route for IPv6\n" +#ifndef FABRICD "Distribute default route into level-1\n" - "Distribute default route into level-2\n") + "Distribute default route into level-2\n" +#endif + ) { int idx_afi = 3; int idx_level = 4; @@ -704,7 +736,9 @@ DEFUN (no_isis_default_originate, if (family < 0) return CMD_WARNING_CONFIG_FAILED; - if (strmatch("level-1", argv[idx_level]->text)) + if (fabricd) + level = 2; + else if (strmatch("level-1", argv[idx_level]->text)) level = 1; else if (strmatch("level-2", argv[idx_level]->text)) level = 2; @@ -732,15 +766,17 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, return 0; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if (type == ZEBRA_ROUTE_ISIS) + if (type == PROTO_TYPE) continue; for (level = 1; level <= ISIS_LEVELS; level++) { redist = get_redist_settings(area, family, type, level); if (!redist->redist) continue; - vty_out(vty, " redistribute %s %s level-%d", family_str, - zebra_route_string(type), level); + vty_out(vty, " redistribute %s %s", family_str, + zebra_route_string(type)); + if (!fabricd) + vty_out(vty, " level-%d", level); if (redist->metric) vty_out(vty, " metric %u", redist->metric); if (redist->map_name) @@ -755,8 +791,10 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, get_redist_settings(area, family, DEFAULT_ROUTE, level); if (!redist->redist) continue; - vty_out(vty, " default-information originate %s level-%d", - family_str, level); + vty_out(vty, " default-information originate %s", + family_str); + if (!fabricd) + vty_out(vty, " level-%d", level); if (redist->redist == DEFAULT_ORIGINATE_ALWAYS) vty_out(vty, " always"); if (redist->metric) @@ -772,8 +810,8 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area, void isis_redist_init(void) { - install_element(ISIS_NODE, &isis_redistribute_cmd); - install_element(ISIS_NODE, &no_isis_redistribute_cmd); - install_element(ISIS_NODE, &isis_default_originate_cmd); - install_element(ISIS_NODE, &no_isis_default_originate_cmd); + install_element(ROUTER_NODE, &isis_redistribute_cmd); + install_element(ROUTER_NODE, &no_isis_redistribute_cmd); + install_element(ROUTER_NODE, &isis_default_originate_cmd); + install_element(ROUTER_NODE, &no_isis_default_originate_cmd); } diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 341921146..6a7528623 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -31,14 +31,10 @@ #include "command.h" #include "memory.h" #include "prefix.h" -#include "hash.h" #include "if.h" #include "table.h" #include "spf_backoff.h" -#include "jhash.h" -#include "skiplist.h" #include "srcdest_table.h" -#include "lib_errors.h" #include "isis_constants.h" #include "isis_common.h" @@ -56,256 +52,11 @@ #include "isis_csm.h" #include "isis_mt.h" #include "isis_tlvs.h" +#include "fabricd.h" +#include "isis_spf_private.h" DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info"); -enum vertextype { - VTYPE_PSEUDO_IS = 1, - VTYPE_PSEUDO_TE_IS, - VTYPE_NONPSEUDO_IS, - VTYPE_NONPSEUDO_TE_IS, - VTYPE_ES, - VTYPE_IPREACH_INTERNAL, - VTYPE_IPREACH_EXTERNAL, - VTYPE_IPREACH_TE, - VTYPE_IP6REACH_INTERNAL, - VTYPE_IP6REACH_EXTERNAL -}; - -#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS) -#define VTYPE_ES(t) ((t) == VTYPE_ES) -#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL) - -struct prefix_pair { - struct prefix dest; - struct prefix_ipv6 src; -}; - -/* - * Triple <N, d(N), {Adj(N)}> - */ -union isis_N { - uint8_t id[ISIS_SYS_ID_LEN + 1]; - struct prefix_pair ip; -}; -struct isis_vertex { - enum vertextype type; - union isis_N N; - uint32_t d_N; /* d(N) Distance from this IS */ - uint16_t depth; /* The depth in the imaginary tree */ - struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */ - struct list *parents; /* list of parents for ECMP */ - uint64_t insert_counter; -}; - -/* Vertex Queue and associated functions */ - -struct isis_vertex_queue { - union { - struct skiplist *slist; - struct list *list; - } l; - struct hash *hash; - uint64_t insert_counter; -}; - -static unsigned isis_vertex_queue_hash_key(void *vp) -{ - struct isis_vertex *vertex = vp; - - if (VTYPE_IP(vertex->type)) { - uint32_t key; - - key = prefix_hash_key(&vertex->N.ip.dest); - key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key); - return key; - } - - return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a); -} - -static int isis_vertex_queue_hash_cmp(const void *a, const void *b) -{ - const struct isis_vertex *va = a, *vb = b; - - if (va->type != vb->type) - return 0; - - if (VTYPE_IP(va->type)) { - if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest)) - return 0; - - return prefix_cmp((struct prefix *)&va->N.ip.src, - (struct prefix *)&vb->N.ip.src) == 0; - } - - return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0; -} - -/* - * Compares vertizes for sorting in the TENT list. Returns true - * if candidate should be considered before current, false otherwise. - */ -static int isis_vertex_queue_tent_cmp(void *a, void *b) -{ - struct isis_vertex *va = a; - struct isis_vertex *vb = b; - - if (va->d_N < vb->d_N) - return -1; - - if (va->d_N > vb->d_N) - return 1; - - if (va->type < vb->type) - return -1; - - if (va->type > vb->type) - return 1; - - if (va->insert_counter < vb->insert_counter) - return -1; - - if (va->insert_counter > vb->insert_counter) - return 1; - - return 0; -} - -static struct skiplist *isis_vertex_queue_skiplist(void) -{ - return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL); -} - -static void isis_vertex_queue_init(struct isis_vertex_queue *queue, - const char *name, bool ordered) -{ - if (ordered) { - queue->insert_counter = 1; - queue->l.slist = isis_vertex_queue_skiplist(); - } else { - queue->insert_counter = 0; - queue->l.list = list_new(); - } - queue->hash = hash_create(isis_vertex_queue_hash_key, - isis_vertex_queue_hash_cmp, name); -} - -static void isis_vertex_del(struct isis_vertex *vertex); - -static void isis_vertex_queue_clear(struct isis_vertex_queue *queue) -{ - hash_clean(queue->hash, NULL); - - if (queue->insert_counter) { - struct isis_vertex *vertex; - while (0 == skiplist_first(queue->l.slist, NULL, - (void **)&vertex)) { - isis_vertex_del(vertex); - skiplist_delete_first(queue->l.slist); - } - queue->insert_counter = 1; - } else { - queue->l.list->del = (void (*)(void *))isis_vertex_del; - list_delete_all_node(queue->l.list); - queue->l.list->del = NULL; - } -} - -static void isis_vertex_queue_free(struct isis_vertex_queue *queue) -{ - isis_vertex_queue_clear(queue); - - hash_free(queue->hash); - queue->hash = NULL; - - if (queue->insert_counter) { - skiplist_free(queue->l.slist); - queue->l.slist = NULL; - } else - list_delete_and_null(&queue->l.list); -} - -static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue) -{ - return hashcount(queue->hash); -} - -static void isis_vertex_queue_append(struct isis_vertex_queue *queue, - struct isis_vertex *vertex) -{ - assert(!queue->insert_counter); - - listnode_add(queue->l.list, vertex); - - struct isis_vertex *inserted; - - inserted = hash_get(queue->hash, vertex, hash_alloc_intern); - assert(inserted == vertex); -} - -static void isis_vertex_queue_insert(struct isis_vertex_queue *queue, - struct isis_vertex *vertex) -{ - assert(queue->insert_counter); - vertex->insert_counter = queue->insert_counter++; - assert(queue->insert_counter != (uint64_t)-1); - - skiplist_insert(queue->l.slist, vertex, vertex); - - struct isis_vertex *inserted; - inserted = hash_get(queue->hash, vertex, hash_alloc_intern); - assert(inserted == vertex); -} - -static struct isis_vertex * -isis_vertex_queue_pop(struct isis_vertex_queue *queue) -{ - assert(queue->insert_counter); - - struct isis_vertex *rv; - - if (skiplist_first(queue->l.slist, NULL, (void **)&rv)) - return NULL; - - skiplist_delete_first(queue->l.slist); - hash_release(queue->hash, rv); - - return rv; -} - -static void isis_vertex_queue_delete(struct isis_vertex_queue *queue, - struct isis_vertex *vertex) -{ - assert(queue->insert_counter); - - skiplist_delete(queue->l.slist, vertex, vertex); - hash_release(queue->hash, vertex); -} - -#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \ - ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data) - - -/* End of vertex queue definitions */ - -struct isis_spftree { - struct isis_vertex_queue paths; /* the SPT */ - struct isis_vertex_queue tents; /* TENT */ - struct route_table *route_table; - struct isis_area *area; /* back pointer to area */ - unsigned int runcount; /* number of runs since uptime */ - time_t last_run_timestamp; /* last run timestamp as wall time for display */ - time_t last_run_monotime; /* last run as monotime for scheduling */ - time_t last_run_duration; /* last run duration in msec */ - - uint16_t mtid; - int family; - int level; - enum spf_tree_id tree_id; -}; - - /* * supports the given af ? */ @@ -411,8 +162,7 @@ static const char *vtype2string(enum vertextype vtype) return NULL; /* Not reached */ } -#define VID2STR_BUFFER SRCDEST2STR_BUFFER -static const char *vid2string(struct isis_vertex *vertex, char *buff, int size) +const char *vid2string(struct isis_vertex *vertex, char *buff, int size) { if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) { return print_sys_hostname(vertex->N.id); @@ -428,44 +178,26 @@ static const char *vid2string(struct isis_vertex *vertex, char *buff, int size) return "UNKNOWN"; } -static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n, - enum vertextype vtype) -{ - vertex->type = vtype; - - if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) { - memcpy(vertex->N.id, n->id, ISIS_SYS_ID_LEN + 1); - } else if (VTYPE_IP(vtype)) { - memcpy(&vertex->N.ip, &n->ip, sizeof(n->ip)); - } else { - flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type"); - } -} - -static struct isis_vertex *isis_vertex_new(union isis_N *n, +static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree, + void *id, enum vertextype vtype) { struct isis_vertex *vertex; vertex = XCALLOC(MTYPE_ISIS_VERTEX, sizeof(struct isis_vertex)); - isis_vertex_id_init(vertex, n, vtype); + isis_vertex_id_init(vertex, id, vtype); vertex->Adj_N = list_new(); vertex->parents = list_new(); - return vertex; -} - -static void isis_vertex_del(struct isis_vertex *vertex) -{ - list_delete_and_null(&vertex->Adj_N); - list_delete_and_null(&vertex->parents); - - memset(vertex, 0, sizeof(struct isis_vertex)); - XFREE(MTYPE_ISIS_VERTEX, vertex); + if (spftree->hopcount_metric) { + vertex->firsthops = hash_create(isis_vertex_queue_hash_key, + isis_vertex_queue_hash_cmp, + NULL); + } - return; + return vertex; } static void isis_vertex_adj_del(struct isis_vertex *vertex, @@ -563,6 +295,9 @@ void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj) adj); } } + + if (fabricd_spftree(area) != NULL) + isis_spftree_adj_del(fabricd_spftree(area), adj); } /* @@ -595,17 +330,13 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree, #ifdef EXTREME_DEBUG char buff[VID2STR_BUFFER]; #endif /* EXTREME_DEBUG */ - union isis_N n; - - memcpy(n.id, sysid, ISIS_SYS_ID_LEN); - LSP_PSEUDO_ID(n.id) = 0; lsp = isis_root_system_lsp(spftree->area, spftree->level, sysid); if (lsp == NULL) zlog_warn("ISIS-Spf: could not find own l%d LSP!", spftree->level); - vertex = isis_vertex_new(&n, + vertex = isis_vertex_new(spftree, sysid, spftree->area->oldmetric ? VTYPE_NONPSEUDO_IS : VTYPE_NONPSEUDO_TE_IS); @@ -621,14 +352,24 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree, return vertex; } -static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue, - union isis_N *n, - enum vertextype vtype) +static void vertex_add_parent_firsthop(struct hash_backet *backet, void *arg) { - struct isis_vertex querier; + struct isis_vertex *vertex = arg; + struct isis_vertex *hop = backet->data; - isis_vertex_id_init(&querier, n, vtype); - return hash_lookup(queue->hash, &querier); + hash_get(vertex->firsthops, hop, hash_alloc_intern); +} + +static void vertex_update_firsthops(struct isis_vertex *vertex, + struct isis_vertex *parent) +{ + if (vertex->d_N <= 2) + hash_get(vertex->firsthops, vertex, hash_alloc_intern); + + if (vertex->d_N < 2 || !parent) + return; + + hash_iterate(parent->firsthops, vertex_add_parent_firsthop, vertex); } /* @@ -649,7 +390,7 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, assert(isis_find_vertex(&spftree->paths, id, vtype) == NULL); assert(isis_find_vertex(&spftree->tents, id, vtype) == NULL); - vertex = isis_vertex_new(id, vtype); + vertex = isis_vertex_new(spftree, id, vtype); vertex->d_N = cost; vertex->depth = depth; @@ -657,6 +398,9 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, listnode_add(vertex->parents, parent); } + if (spftree->hopcount_metric) + vertex_update_firsthops(vertex, parent); + if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) { for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_adj)) listnode_add(vertex->Adj_N, parent_adj); @@ -722,6 +466,10 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, assert(spftree && parent); + if (spftree->hopcount_metric + && !VTYPE_IS(vtype)) + return; + struct prefix_pair p; if (vtype >= VTYPE_IPREACH_INTERNAL) { memcpy(&p, id, sizeof(p)); @@ -774,6 +522,8 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, if (listnode_lookup(vertex->Adj_N, parent_adj) == NULL) listnode_add(vertex->Adj_N, parent_adj); + if (spftree->hopcount_metric) + vertex_update_firsthops(vertex, parent); /* 2) */ if (listcount(vertex->Adj_N) > ISIS_MAX_PATH_SPLITS) remove_excess_adjs(vertex->Adj_N); @@ -853,6 +603,9 @@ lspfragloop: for (r = (struct isis_oldstyle_reach *) lsp->tlvs->oldstyle_reach.head; r; r = r->next) { + if (fabricd) + continue; + /* C.2.6 a) */ /* Two way connectivity */ if (!memcmp(r->id, root_sysid, ISIS_SYS_ID_LEN)) @@ -889,7 +642,7 @@ lspfragloop: if (!pseudo_lsp && !memcmp(er->id, null_sysid, ISIS_SYS_ID_LEN)) continue; - dist = cost + er->metric; + dist = cost + (spftree->hopcount_metric ? 1 : er->metric); process_N(spftree, LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS : VTYPE_NONPSEUDO_TE_IS, @@ -897,7 +650,7 @@ lspfragloop: } } - if (!pseudo_lsp && spftree->family == AF_INET + if (!fabricd && !pseudo_lsp && spftree->family == AF_INET && spftree->mtid == ISIS_MT_IPV4_UNICAST) { struct isis_item_list *reachs[] = { &lsp->tlvs->oldstyle_ip_reach, @@ -1037,7 +790,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, /* * Add IP(v6) addresses of this circuit */ - if (spftree->family == AF_INET) { + if (spftree->family == AF_INET && !spftree->hopcount_metric) { memset(&ip_info, 0, sizeof(ip_info)); ip_info.dest.family = AF_INET; for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, ipnode, @@ -1050,7 +803,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, &ip_info, NULL, 0, parent); } } - if (spftree->family == AF_INET6) { + if (spftree->family == AF_INET6 && !spftree->hopcount_metric) { memset(&ip_info, 0, sizeof(ip_info)); ip_info.dest.family = AF_INET6; for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, @@ -1094,6 +847,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, LSP_PSEUDO_ID(lsp_id) = 0; isis_spf_add_local( spftree, VTYPE_ES, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric [spftree->level - 1], parent); @@ -1111,6 +865,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, ? VTYPE_NONPSEUDO_IS : VTYPE_NONPSEUDO_TE_IS, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric [spftree->level - 1], parent); @@ -1180,10 +935,10 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, circuit->circuit_id); continue; } - isis_spf_process_lsp( - spftree, lsp, - circuit->te_metric[spftree->level - 1], 0, - root_sysid, parent); + isis_spf_process_lsp(spftree, lsp, + spftree->hopcount_metric ? + 1 : circuit->te_metric[spftree->level - 1], + 0, root_sysid, parent); } else if (circuit->circ_type == CIRCUIT_T_P2P) { adj = circuit->u.p2p.neighbor; if (!adj || adj->adj_state != ISIS_ADJ_UP) @@ -1196,6 +951,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, LSP_PSEUDO_ID(lsp_id) = 0; isis_spf_add_local( spftree, VTYPE_ES, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric[spftree->level - 1], parent); break; @@ -1215,6 +971,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree, ? VTYPE_NONPSEUDO_IS : VTYPE_NONPSEUDO_TE_IS, lsp_id, adj, + spftree->hopcount_metric ? 1 : circuit->te_metric [spftree->level - 1], parent); @@ -1275,7 +1032,8 @@ static void add_to_paths(struct isis_spftree *spftree, } static void init_spt(struct isis_spftree *spftree, int mtid, int level, - int family, enum spf_tree_id tree_id) + int family, enum spf_tree_id tree_id, + bool hopcount_metric) { isis_vertex_queue_clear(&spftree->tents); isis_vertex_queue_clear(&spftree->paths); @@ -1284,7 +1042,63 @@ static void init_spt(struct isis_spftree *spftree, int mtid, int level, spftree->level = level; spftree->family = family; spftree->tree_id = tree_id; - return; + spftree->hopcount_metric = hopcount_metric; +} + +static void isis_spf_loop(struct isis_spftree *spftree, + uint8_t *root_sysid) +{ + struct isis_vertex *vertex; + struct isis_lsp *lsp; + + while (isis_vertex_queue_count(&spftree->tents)) { + vertex = isis_vertex_queue_pop(&spftree->tents); + +#ifdef EXTREME_DEBUG + zlog_debug( + "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS", + print_sys_hostname(vertex->N.id), + vtype2string(vertex->type), vertex->depth, vertex->d_N); +#endif /* EXTREME_DEBUG */ + + add_to_paths(spftree, vertex); + if (!VTYPE_IS(vertex->type)) + continue; + + lsp = lsp_for_vertex(spftree, vertex); + if (!lsp) { + zlog_warn("ISIS-Spf: No LSP found for %s", + rawlspid_print(vertex->N.id)); /* FIXME */ + continue; + } + + isis_spf_process_lsp(spftree, lsp, vertex->d_N, vertex->depth, + root_sysid, vertex); + } +} + +struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area, + uint8_t *sysid, + struct isis_spftree *spftree) +{ + if (!spftree) + spftree = isis_spftree_new(area); + + init_spt(spftree, ISIS_MT_IPV4_UNICAST, ISIS_LEVEL2, + AF_INET, SPFTREE_IPV4, true); + if (!memcmp(sysid, isis->sysid, ISIS_SYS_ID_LEN)) { + /* If we are running locally, initialize with information from adjacencies */ + struct isis_vertex *root = isis_spf_add_root(spftree, sysid); + isis_spf_preload_tent(spftree, sysid, root); + } else { + isis_vertex_queue_insert(&spftree->tents, isis_vertex_new( + spftree, sysid, + VTYPE_NONPSEUDO_TE_IS)); + } + + isis_spf_loop(spftree, sysid); + + return spftree; } static int isis_run_spf(struct isis_area *area, int level, @@ -1292,11 +1106,8 @@ static int isis_run_spf(struct isis_area *area, int level, uint8_t *sysid, struct timeval *nowtv) { int retval = ISIS_OK; - struct isis_vertex *vertex; struct isis_vertex *root_vertex; struct isis_spftree *spftree = area->spftree[tree_id][level - 1]; - uint8_t lsp_id[ISIS_SYS_ID_LEN + 2]; - struct isis_lsp *lsp; struct timeval time_now; unsigned long long start_time, end_time; uint16_t mtid = 0; @@ -1330,7 +1141,7 @@ static int isis_run_spf(struct isis_area *area, int level, /* * C.2.5 Step 0 */ - init_spt(spftree, mtid, level, family, tree_id); + init_spt(spftree, mtid, level, family, tree_id, false); /* a) */ root_vertex = isis_spf_add_root(spftree, sysid); /* b) */ @@ -1350,32 +1161,7 @@ static int isis_run_spf(struct isis_area *area, int level, print_sys_hostname(sysid)); } - while (isis_vertex_queue_count(&spftree->tents)) { - vertex = isis_vertex_queue_pop(&spftree->tents); - -#ifdef EXTREME_DEBUG - zlog_debug( - "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS", - print_sys_hostname(vertex->N.id), - vtype2string(vertex->type), vertex->depth, vertex->d_N); -#endif /* EXTREME_DEBUG */ - - add_to_paths(spftree, vertex); - if (VTYPE_IS(vertex->type)) { - memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1); - LSP_FRAGMENT(lsp_id) = 0; - lsp = lsp_search(lsp_id, area->lspdb[level - 1]); - if (lsp && lsp->hdr.rem_lifetime != 0) { - isis_spf_process_lsp(spftree, lsp, vertex->d_N, - vertex->depth, sysid, - vertex); - } else { - zlog_warn("ISIS-Spf: No LSP found for %s", - rawlspid_print(lsp_id)); - } - } - } - + isis_spf_loop(spftree, sysid); out: spftree->runcount++; spftree->last_run_timestamp = time(NULL); @@ -1446,6 +1232,8 @@ static int isis_run_spf_cb(struct thread *thread) for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF); + fabricd_run_spf(area); + return retval; } @@ -1617,12 +1405,18 @@ static void isis_print_spftree(struct vty *vty, int level, DEFUN (show_isis_topology, show_isis_topology_cmd, - "show isis topology [<level-1|level-2>]", - SHOW_STR - "IS-IS information\n" + "show " PROTO_NAME " topology" +#ifndef FABRICD + " [<level-1|level-2>]" +#endif + , SHOW_STR + PROTO_HELP "IS-IS paths to Intermediate Systems\n" +#ifndef FABRICD "Paths to all level-1 routers in the area\n" - "Paths to all level-2 routers in the domain\n") + "Paths to all level-2 routers in the domain\n" +#endif + ) { int levels; struct listnode *node; @@ -1660,6 +1454,13 @@ DEFUN (show_isis_topology, } } + if (fabricd_spftree(area)) { + vty_out(vty, + "IS-IS paths to level-2 routers with hop-by-hop metric\n"); + isis_print_paths(vty, &fabricd_spftree(area)->paths, isis->sysid); + vty_out(vty, "\n"); + } + vty_out(vty, "\n"); } diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h index 9a73ca878..f4db98cfe 100644 --- a/isisd/isis_spf.h +++ b/isisd/isis_spf.h @@ -37,4 +37,7 @@ void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj); int isis_spf_schedule(struct isis_area *area, int level); void isis_spf_cmds_init(void); void isis_spf_print(struct isis_spftree *spftree, struct vty *vty); +struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area, + uint8_t *sysid, + struct isis_spftree *spftree); #endif /* _ZEBRA_ISIS_SPF_H */ diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h new file mode 100644 index 000000000..af552e0ed --- /dev/null +++ b/isisd/isis_spf_private.h @@ -0,0 +1,362 @@ +/* + * IS-IS Rout(e)ing protocol - isis_spf_private.h + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2017 Christian Franke <chris@opensourcerouting.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef ISIS_SPF_PRIVATE_H +#define ISIS_SPF_PRIVATE_H + +#include "hash.h" +#include "jhash.h" +#include "skiplist.h" +#include "lib_errors.h" + +enum vertextype { + VTYPE_PSEUDO_IS = 1, + VTYPE_PSEUDO_TE_IS, + VTYPE_NONPSEUDO_IS, + VTYPE_NONPSEUDO_TE_IS, + VTYPE_ES, + VTYPE_IPREACH_INTERNAL, + VTYPE_IPREACH_EXTERNAL, + VTYPE_IPREACH_TE, + VTYPE_IP6REACH_INTERNAL, + VTYPE_IP6REACH_EXTERNAL +}; + +#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS) +#define VTYPE_ES(t) ((t) == VTYPE_ES) +#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL) + +struct prefix_pair { + struct prefix dest; + struct prefix_ipv6 src; +}; + +/* + * Triple <N, d(N), {Adj(N)}> + */ +struct isis_vertex { + enum vertextype type; + union { + uint8_t id[ISIS_SYS_ID_LEN + 1]; + struct prefix_pair ip; + } N; + uint32_t d_N; /* d(N) Distance from this IS */ + uint16_t depth; /* The depth in the imaginary tree */ + struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */ + struct list *parents; /* list of parents for ECMP */ + struct hash *firsthops; /* first two hops to neighbor */ + uint64_t insert_counter; +}; + +/* Vertex Queue and associated functions */ + +struct isis_vertex_queue { + union { + struct skiplist *slist; + struct list *list; + } l; + struct hash *hash; + uint64_t insert_counter; +}; + +__attribute__((__unused__)) +static unsigned isis_vertex_queue_hash_key(void *vp) +{ + struct isis_vertex *vertex = vp; + + if (VTYPE_IP(vertex->type)) { + uint32_t key; + + key = prefix_hash_key(&vertex->N.ip.dest); + key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key); + return key; + } + + return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a); +} + +__attribute__((__unused__)) +static int isis_vertex_queue_hash_cmp(const void *a, const void *b) +{ + const struct isis_vertex *va = a, *vb = b; + + if (va->type != vb->type) + return 0; + + if (VTYPE_IP(va->type)) { + if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest)) + return 0; + + return prefix_cmp((struct prefix *)&va->N.ip.src, + (struct prefix *)&vb->N.ip.src) == 0; + } + + return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0; +} + +/* + * Compares vertizes for sorting in the TENT list. Returns true + * if candidate should be considered before current, false otherwise. + */ +__attribute__((__unused__)) +static int isis_vertex_queue_tent_cmp(void *a, void *b) +{ + struct isis_vertex *va = a; + struct isis_vertex *vb = b; + + if (va->d_N < vb->d_N) + return -1; + + if (va->d_N > vb->d_N) + return 1; + + if (va->type < vb->type) + return -1; + + if (va->type > vb->type) + return 1; + + if (va->insert_counter < vb->insert_counter) + return -1; + + if (va->insert_counter > vb->insert_counter) + return 1; + + return 0; +} + +__attribute__((__unused__)) +static struct skiplist *isis_vertex_queue_skiplist(void) +{ + return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL); +} + +__attribute__((__unused__)) +static void isis_vertex_queue_init(struct isis_vertex_queue *queue, + const char *name, bool ordered) +{ + if (ordered) { + queue->insert_counter = 1; + queue->l.slist = isis_vertex_queue_skiplist(); + } else { + queue->insert_counter = 0; + queue->l.list = list_new(); + } + queue->hash = hash_create(isis_vertex_queue_hash_key, + isis_vertex_queue_hash_cmp, name); +} + +__attribute__((__unused__)) +static void isis_vertex_del(struct isis_vertex *vertex) +{ + list_delete_and_null(&vertex->Adj_N); + list_delete_and_null(&vertex->parents); + if (vertex->firsthops) { + hash_clean(vertex->firsthops, NULL); + hash_free(vertex->firsthops); + vertex->firsthops = NULL; + } + + memset(vertex, 0, sizeof(struct isis_vertex)); + XFREE(MTYPE_ISIS_VERTEX, vertex); +} + +__attribute__((__unused__)) +static void isis_vertex_queue_clear(struct isis_vertex_queue *queue) +{ + hash_clean(queue->hash, NULL); + + if (queue->insert_counter) { + struct isis_vertex *vertex; + while (0 == skiplist_first(queue->l.slist, NULL, + (void **)&vertex)) { + isis_vertex_del(vertex); + skiplist_delete_first(queue->l.slist); + } + queue->insert_counter = 1; + } else { + queue->l.list->del = (void (*)(void *))isis_vertex_del; + list_delete_all_node(queue->l.list); + queue->l.list->del = NULL; + } +} + +__attribute__((__unused__)) +static void isis_vertex_queue_free(struct isis_vertex_queue *queue) +{ + isis_vertex_queue_clear(queue); + + hash_free(queue->hash); + queue->hash = NULL; + + if (queue->insert_counter) { + skiplist_free(queue->l.slist); + queue->l.slist = NULL; + } else + list_delete_and_null(&queue->l.list); +} + +__attribute__((__unused__)) +static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue) +{ + return hashcount(queue->hash); +} + +__attribute__((__unused__)) +static void isis_vertex_queue_append(struct isis_vertex_queue *queue, + struct isis_vertex *vertex) +{ + assert(!queue->insert_counter); + + listnode_add(queue->l.list, vertex); + + struct isis_vertex *inserted; + + inserted = hash_get(queue->hash, vertex, hash_alloc_intern); + assert(inserted == vertex); +} + +__attribute__((__unused__)) +static struct isis_vertex *isis_vertex_queue_last(struct isis_vertex_queue *queue) +{ + struct listnode *tail; + + assert(!queue->insert_counter); + tail = listtail(queue->l.list); + assert(tail); + return listgetdata(tail); +} + +__attribute__((__unused__)) +static void isis_vertex_queue_insert(struct isis_vertex_queue *queue, + struct isis_vertex *vertex) +{ + assert(queue->insert_counter); + vertex->insert_counter = queue->insert_counter++; + assert(queue->insert_counter != (uint64_t)-1); + + skiplist_insert(queue->l.slist, vertex, vertex); + + struct isis_vertex *inserted; + inserted = hash_get(queue->hash, vertex, hash_alloc_intern); + assert(inserted == vertex); +} + +__attribute__((__unused__)) +static struct isis_vertex * +isis_vertex_queue_pop(struct isis_vertex_queue *queue) +{ + assert(queue->insert_counter); + + struct isis_vertex *rv; + + if (skiplist_first(queue->l.slist, NULL, (void **)&rv)) + return NULL; + + skiplist_delete_first(queue->l.slist); + hash_release(queue->hash, rv); + + return rv; +} + +__attribute__((__unused__)) +static void isis_vertex_queue_delete(struct isis_vertex_queue *queue, + struct isis_vertex *vertex) +{ + assert(queue->insert_counter); + + skiplist_delete(queue->l.slist, vertex, vertex); + hash_release(queue->hash, vertex); +} + +#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \ + ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data) + +/* End of vertex queue definitions */ + +struct isis_spftree { + struct isis_vertex_queue paths; /* the SPT */ + struct isis_vertex_queue tents; /* TENT */ + struct route_table *route_table; + struct isis_area *area; /* back pointer to area */ + unsigned int runcount; /* number of runs since uptime */ + time_t last_run_timestamp; /* last run timestamp as wall time for display */ + time_t last_run_monotime; /* last run as monotime for scheduling */ + time_t last_run_duration; /* last run duration in msec */ + + uint16_t mtid; + int family; + int level; + enum spf_tree_id tree_id; + bool hopcount_metric; +}; + +__attribute__((__unused__)) +static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id, + enum vertextype vtype) +{ + vertex->type = vtype; + + if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) { + memcpy(vertex->N.id, id, ISIS_SYS_ID_LEN + 1); + } else if (VTYPE_IP(vtype)) { + memcpy(&vertex->N.ip, id, sizeof(vertex->N.ip)); + } else { + flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type"); + } +} + +__attribute__((__unused__)) +static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue, + const void *id, + enum vertextype vtype) +{ + struct isis_vertex querier; + + isis_vertex_id_init(&querier, id, vtype); + return hash_lookup(queue->hash, &querier); +} + +__attribute__((__unused__)) +static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree, + struct isis_vertex *vertex) +{ + uint8_t lsp_id[ISIS_SYS_ID_LEN + 2]; + + assert(VTYPE_IS(vertex->type)); + + memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1); + LSP_FRAGMENT(lsp_id) = 0; + + dict_t *lspdb = spftree->area->lspdb[spftree->level - 1]; + struct isis_lsp *lsp = lsp_search(lsp_id, lspdb); + + if (lsp && lsp->hdr.rem_lifetime != 0) + return lsp; + + return NULL; +} + +#define VID2STR_BUFFER SRCDEST2STR_BUFFER +const char *vid2string(struct isis_vertex *vertex, char *buff, int size); + +#endif diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 44ba64ce2..08b905c65 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -67,17 +67,6 @@ const char *mode2text[] = {"Disable", "Area", "AS", "Emulate"}; * Followings are control functions for MPLS-TE parameters management. *------------------------------------------------------------------------*/ -/* Search MPLS TE Circuit context from Interface */ -static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp) -{ - struct isis_circuit *circuit; - - if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) - return NULL; - - return circuit->mtc; -} - /* Create new MPLS TE Circuit context */ struct mpls_te_circuit *mpls_te_circuit_new() { @@ -1085,6 +1074,18 @@ void isis_mpls_te_config_write_router(struct vty *vty) /*------------------------------------------------------------------------* * Followings are vty command functions. *------------------------------------------------------------------------*/ +#ifndef FABRICD + +/* Search MPLS TE Circuit context from Interface */ +static struct mpls_te_circuit *lookup_mpls_params_by_ifp(struct interface *ifp) +{ + struct isis_circuit *circuit; + + if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) + return NULL; + + return circuit->mtc; +} DEFUN (isis_mpls_te_on, isis_mpls_te_on_cmd, @@ -1223,9 +1224,9 @@ DEFUN (no_isis_mpls_te_inter_as, DEFUN (show_isis_mpls_te_router, show_isis_mpls_te_router_cmd, - "show isis mpls-te router", + "show " PROTO_NAME " mpls-te router", SHOW_STR - ISIS_STR + PROTO_HELP MPLS_TE_STR "Router information\n") { @@ -1314,9 +1315,9 @@ static void show_mpls_te_sub(struct vty *vty, struct interface *ifp) DEFUN (show_isis_mpls_te_interface, show_isis_mpls_te_interface_cmd, - "show isis mpls-te interface [INTERFACE]", + "show " PROTO_NAME " mpls-te interface [INTERFACE]", SHOW_STR - ISIS_STR + PROTO_HELP MPLS_TE_STR "Interface information\n" "Interface name\n") @@ -1342,6 +1343,7 @@ DEFUN (show_isis_mpls_te_interface, return CMD_SUCCESS; } +#endif /* Initialize MPLS_TE */ void isis_mpls_te_init(void) @@ -1357,15 +1359,17 @@ void isis_mpls_te_init(void) isisMplsTE.cir_list = list_new(); isisMplsTE.router_id.s_addr = 0; +#ifndef FABRICD /* Register new VTY commands */ install_element(VIEW_NODE, &show_isis_mpls_te_router_cmd); install_element(VIEW_NODE, &show_isis_mpls_te_interface_cmd); - install_element(ISIS_NODE, &isis_mpls_te_on_cmd); - install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd); - install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd); - install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd); - install_element(ISIS_NODE, &no_isis_mpls_te_inter_as_cmd); + install_element(ROUTER_NODE, &isis_mpls_te_on_cmd); + install_element(ROUTER_NODE, &no_isis_mpls_te_on_cmd); + install_element(ROUTER_NODE, &isis_mpls_te_router_addr_cmd); + install_element(ROUTER_NODE, &isis_mpls_te_inter_as_cmd); + install_element(ROUTER_NODE, &no_isis_mpls_te_inter_as_cmd); +#endif return; } diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index a433fcdb4..b22460a0b 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -107,6 +107,111 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX]; /* Prototypes */ static void append_item(struct isis_item_list *dest, struct isis_item *item); +/* Functions for Sub-TLV 3 SR Prefix-SID */ + +static struct isis_item *copy_item_prefix_sid(struct isis_item *i) +{ + struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i; + struct isis_prefix_sid *rv = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*rv)); + + rv->flags = sid->flags; + rv->algorithm = sid->algorithm; + rv->value = sid->value; + return (struct isis_item *)rv; +} + +static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i, + struct sbuf *buf, int indent) +{ + struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i; + + sbuf_push(buf, indent, "SR Prefix-SID:\n"); + sbuf_push(buf, indent, " Flags:%s%s%s%s%s%s\n", + sid->flags & ISIS_PREFIX_SID_READVERTISED ? " READVERTISED" : "", + sid->flags & ISIS_PREFIX_SID_NODE ? " NODE" : "", + sid->flags & ISIS_PREFIX_SID_NO_PHP ? " NO_PHP" : "", + sid->flags & ISIS_PREFIX_SID_EXPLICIT_NULL ? " EXPLICIT-NULL" : "", + sid->flags & ISIS_PREFIX_SID_VALUE ? " VALUE" : "", + sid->flags & ISIS_PREFIX_SID_LOCAL ? " LOCAL" : ""); + sbuf_push(buf, indent, " Algorithm: %" PRIu8 "\n", sid->algorithm); + if (sid->flags & ISIS_PREFIX_SID_VALUE) { + sbuf_push(buf, indent, "Label: %" PRIu32 "\n", sid->value); + } else { + sbuf_push(buf, indent, "Index: %" PRIu32 "\n", sid->value); + } +} + +static void free_item_prefix_sid(struct isis_item *i) +{ + XFREE(MTYPE_ISIS_SUBTLV, i); +} + +static int pack_item_prefix_sid(struct isis_item *i, struct stream *s) +{ + struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i; + + uint8_t size = (sid->flags & ISIS_PREFIX_SID_VALUE) ? 5 : 6; + + if (STREAM_WRITEABLE(s) < size) + return 1; + + stream_putc(s, sid->flags); + stream_putc(s, sid->algorithm); + + if (sid->flags & ISIS_PREFIX_SID_VALUE) { + stream_put3(s, sid->value); + } else { + stream_putl(s, sid->value); + } + + return 0; +} + +static int unpack_item_prefix_sid(uint16_t mtid, uint8_t len, struct stream *s, + struct sbuf *log, void *dest, int indent) +{ + struct isis_subtlvs *subtlvs = dest; + struct isis_prefix_sid sid = { + }; + + sbuf_push(log, indent, "Unpacking SR Prefix-SID...\n"); + + if (len < 5) { + sbuf_push(log, indent, + "Not enough data left. (expected 5 or more bytes, got %" PRIu8 ")\n", + len); + return 1; + } + + sid.flags = stream_getc(s); + if ((sid.flags & ISIS_PREFIX_SID_VALUE) + != (sid.flags & ISIS_PREFIX_SID_LOCAL)) { + sbuf_push(log, indent, "Flags inplausible: Local Flag needs to match Value Flag\n"); + return 0; + } + + sid.algorithm = stream_getc(s); + + uint8_t expected_size = (sid.flags & ISIS_PREFIX_SID_VALUE) ? 5 : 6; + if (len != expected_size) { + sbuf_push(log, indent, + "TLV size differs from expected size. " + "(expected %u but got %" PRIu8 ")\n", + expected_size, len); + return 1; + } + + if (sid.flags & ISIS_PREFIX_SID_VALUE) { + sid.value = stream_get3(s); + } else { + sid.value = stream_getl(s); + } + + format_item_prefix_sid(mtid, (struct isis_item *)&sid, log, indent + 2); + append_item(&subtlvs->prefix_sids, copy_item_prefix_sid((struct isis_item *)&sid)); + return 0; +} + /* Functions for Sub-TVL ??? IPv6 Source Prefix */ static struct prefix_ipv6 *copy_subtlv_ipv6_source_prefix(struct prefix_ipv6 *p) @@ -198,14 +303,36 @@ static int unpack_subtlv_ipv6_source_prefix(enum isis_tlv_context context, memcpy(subtlvs->source_prefix, &p, sizeof(p)); return 0; } +static void init_item_list(struct isis_item_list *items); +static struct isis_item *copy_item(enum isis_tlv_context context, + enum isis_tlv_type type, + struct isis_item *item); +static void copy_items(enum isis_tlv_context context, enum isis_tlv_type type, + struct isis_item_list *src, struct isis_item_list *dest); +static void format_items_(uint16_t mtid, enum isis_tlv_context context, + enum isis_tlv_type type, struct isis_item_list *items, + struct sbuf *buf, int indent); +#define format_items(...) format_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__) +static void free_items(enum isis_tlv_context context, enum isis_tlv_type type, + struct isis_item_list *items); +static int pack_items_(uint16_t mtid, enum isis_tlv_context context, + enum isis_tlv_type type, struct isis_item_list *items, + struct stream *s, struct isis_tlvs **fragment_tlvs, + struct pack_order_entry *pe, + struct isis_tlvs *(*new_fragment)(struct list *l), + struct list *new_fragment_arg); +#define pack_items(...) pack_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__) /* Functions related to subtlvs */ -static struct isis_subtlvs *isis_alloc_subtlvs(void) +static struct isis_subtlvs *isis_alloc_subtlvs(enum isis_tlv_context context) { struct isis_subtlvs *result; result = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*result)); + result->context = context; + + init_item_list(&result->prefix_sids); return result; } @@ -217,6 +344,11 @@ static struct isis_subtlvs *copy_subtlvs(struct isis_subtlvs *subtlvs) struct isis_subtlvs *rv = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*rv)); + rv->context = subtlvs->context; + + copy_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids, &rv->prefix_sids); + rv->source_prefix = copy_subtlv_ipv6_source_prefix(subtlvs->source_prefix); return rv; @@ -225,6 +357,9 @@ static struct isis_subtlvs *copy_subtlvs(struct isis_subtlvs *subtlvs) static void format_subtlvs(struct isis_subtlvs *subtlvs, struct sbuf *buf, int indent) { + format_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids, buf, indent); + format_subtlv_ipv6_source_prefix(subtlvs->source_prefix, buf, indent); } @@ -233,6 +368,9 @@ static void isis_free_subtlvs(struct isis_subtlvs *subtlvs) if (!subtlvs) return; + free_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids); + XFREE(MTYPE_ISIS_SUBTLV, subtlvs->source_prefix); XFREE(MTYPE_ISIS_SUBTLV, subtlvs); @@ -248,6 +386,11 @@ static int pack_subtlvs(struct isis_subtlvs *subtlvs, struct stream *s) stream_putc(s, 0); /* Put 0 as subtlvs length, filled in later */ + rv = pack_items(subtlvs->context, ISIS_SUBTLV_PREFIX_SID, + &subtlvs->prefix_sids, s, NULL, NULL, NULL, NULL); + if (rv) + return rv; + rv = pack_subtlv_ipv6_source_prefix(subtlvs->source_prefix, s); if (rv) return rv; @@ -1135,6 +1278,7 @@ static void free_item_extended_ip_reach(struct isis_item *i) { struct isis_extended_ip_reach *item = (struct isis_extended_ip_reach *)i; + isis_free_subtlvs(item->subtlvs); XFREE(MTYPE_ISIS_TLV, item); } @@ -1149,11 +1293,16 @@ static int pack_item_extended_ip_reach(struct isis_item *i, struct stream *s) control = r->down ? ISIS_EXTENDED_IP_REACH_DOWN : 0; control |= r->prefix.prefixlen; + control |= r->subtlvs ? ISIS_EXTENDED_IP_REACH_SUBTLV : 0; + stream_putc(s, control); if (STREAM_WRITEABLE(s) < (unsigned)PSIZE(r->prefix.prefixlen)) return 1; stream_put(s, &r->prefix.prefix.s_addr, PSIZE(r->prefix.prefixlen)); + + if (r->subtlvs) + return pack_subtlvs(r->subtlvs, s); return 0; } @@ -1235,9 +1384,12 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len, len - 6 - PSIZE(rv->prefix.prefixlen)); goto out; } - sbuf_push(log, indent, "Skipping %" PRIu8 " bytes of subvls", - subtlv_len); - stream_forward_getp(s, subtlv_len); + + rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH); + if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IP_REACH, subtlv_len, s, + log, rv->subtlvs, indent + 4)) { + goto out; + } } append_item(items, (struct isis_item *)rv); @@ -1329,6 +1481,126 @@ static int unpack_tlv_dynamic_hostname(enum isis_tlv_context context, return 0; } +/* Functions related to TLV 150 Spine-Leaf-Extension */ + +static struct isis_spine_leaf *copy_tlv_spine_leaf( + const struct isis_spine_leaf *spine_leaf) +{ + if (!spine_leaf) + return NULL; + + struct isis_spine_leaf *rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + memcpy(rv, spine_leaf, sizeof(*rv)); + + return rv; +} + +static void format_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf, + struct sbuf *buf, int indent) +{ + if (!spine_leaf) + return; + + sbuf_push(buf, indent, "Spine-Leaf-Extension:\n"); + if (spine_leaf->has_tier) { + if (spine_leaf->tier == ISIS_TIER_UNDEFINED) { + sbuf_push(buf, indent, " Tier: undefined\n"); + } else { + sbuf_push(buf, indent, " Tier: %" PRIu8 "\n", + spine_leaf->tier); + } + } + + sbuf_push(buf, indent, " Flags:%s%s%s\n", + spine_leaf->is_leaf ? " LEAF" : "", + spine_leaf->is_spine ? " SPINE" : "", + spine_leaf->is_backup ? " BACKUP" : ""); + +} + +static void free_tlv_spine_leaf(struct isis_spine_leaf *spine_leaf) +{ + XFREE(MTYPE_ISIS_TLV, spine_leaf); +} + +#define ISIS_SPINE_LEAF_FLAG_TIER 0x08 +#define ISIS_SPINE_LEAF_FLAG_BACKUP 0x04 +#define ISIS_SPINE_LEAF_FLAG_SPINE 0x02 +#define ISIS_SPINE_LEAF_FLAG_LEAF 0x01 + +static int pack_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf, + struct stream *s) +{ + if (!spine_leaf) + return 0; + + uint8_t tlv_len = 2; + + if (STREAM_WRITEABLE(s) < (unsigned)(2 + tlv_len)) + return 1; + + stream_putc(s, ISIS_TLV_SPINE_LEAF_EXT); + stream_putc(s, tlv_len); + + uint16_t spine_leaf_flags = 0; + + if (spine_leaf->has_tier) { + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_TIER; + spine_leaf_flags |= spine_leaf->tier << 12; + } + + if (spine_leaf->is_leaf) + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_LEAF; + + if (spine_leaf->is_spine) + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_SPINE; + + if (spine_leaf->is_backup) + spine_leaf_flags |= ISIS_SPINE_LEAF_FLAG_BACKUP; + + stream_putw(s, spine_leaf_flags); + + return 0; +} + +static int unpack_tlv_spine_leaf(enum isis_tlv_context context, + uint8_t tlv_type, uint8_t tlv_len, + struct stream *s, struct sbuf *log, + void *dest, int indent) +{ + struct isis_tlvs *tlvs = dest; + + sbuf_push(log, indent, "Unpacking Spine Leaf Extension TLV...\n"); + if (tlv_len < 2) { + sbuf_push(log, indent, "WARNING: Unexepected TLV size\n"); + stream_forward_getp(s, tlv_len); + return 0; + } + + if (tlvs->spine_leaf) { + sbuf_push(log, indent, + "WARNING: Spine Leaf Extension TLV present multiple times.\n"); + stream_forward_getp(s, tlv_len); + return 0; + } + + tlvs->spine_leaf = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->spine_leaf)); + + uint16_t spine_leaf_flags = stream_getw(s); + + if (spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_TIER) { + tlvs->spine_leaf->has_tier = true; + tlvs->spine_leaf->tier = spine_leaf_flags >> 12; + } + + tlvs->spine_leaf->is_leaf = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_LEAF; + tlvs->spine_leaf->is_spine = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_SPINE; + tlvs->spine_leaf->is_backup = spine_leaf_flags & ISIS_SPINE_LEAF_FLAG_BACKUP; + + stream_forward_getp(s, tlv_len - 2); + return 0; +} + /* Functions related to TLV 240 P2P Three-Way Adjacency */ const char *isis_threeway_state_name(enum isis_threeway_state state) @@ -1592,7 +1864,7 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s, goto out; } - rv->subtlvs = isis_alloc_subtlvs(); + rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH); if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH, subtlv_len, s, log, rv->subtlvs, indent + 4)) { goto out; @@ -1713,6 +1985,114 @@ static int unpack_item_auth(uint16_t mtid, uint8_t len, struct stream *s, return 0; } +/* Functions related to TLV 13 Purge Originator */ + +static struct isis_purge_originator *copy_tlv_purge_originator( + struct isis_purge_originator *poi) +{ + if (!poi) + return NULL; + + struct isis_purge_originator *rv; + + rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + rv->sender_set = poi->sender_set; + memcpy(rv->generator, poi->generator, sizeof(rv->generator)); + if (poi->sender_set) + memcpy(rv->sender, poi->sender, sizeof(rv->sender)); + return rv; +} + +static void format_tlv_purge_originator(struct isis_purge_originator *poi, + struct sbuf *buf, int indent) +{ + if (!poi) + return; + + sbuf_push(buf, indent, "Purge Originator Identification:\n"); + sbuf_push(buf, indent, " Generator: %s\n", + isis_format_id(poi->generator, sizeof(poi->generator))); + if (poi->sender_set) { + sbuf_push(buf, indent, " Received-From: %s\n", + isis_format_id(poi->sender, sizeof(poi->sender))); + } +} + +static void free_tlv_purge_originator(struct isis_purge_originator *poi) +{ + XFREE(MTYPE_ISIS_TLV, poi); +} + +static int pack_tlv_purge_originator(struct isis_purge_originator *poi, + struct stream *s) +{ + if (!poi) + return 0; + + uint8_t data_len = 1 + sizeof(poi->generator); + + if (poi->sender_set) + data_len += sizeof(poi->sender); + + if (STREAM_WRITEABLE(s) < (unsigned)(2 + data_len)) + return 1; + + stream_putc(s, ISIS_TLV_PURGE_ORIGINATOR); + stream_putc(s, data_len); + stream_putc(s, poi->sender_set ? 2 : 1); + stream_put(s, poi->generator, sizeof(poi->generator)); + if (poi->sender_set) + stream_put(s, poi->sender, sizeof(poi->sender)); + return 0; +} + +static int unpack_tlv_purge_originator(enum isis_tlv_context context, + uint8_t tlv_type, uint8_t tlv_len, + struct stream *s, struct sbuf *log, + void *dest, int indent) +{ + struct isis_tlvs *tlvs = dest; + struct isis_purge_originator poi = {}; + + sbuf_push(log, indent, "Unpacking Purge Originator Identification TLV...\n"); + if (tlv_len < 7) { + sbuf_push(log, indent, "Not enough data left. (Expected at least 7 bytes, got %" + PRIu8 ")\n", tlv_len); + return 1; + } + + uint8_t number_of_ids = stream_getc(s); + + if (number_of_ids == 1) { + poi.sender_set = false; + } else if (number_of_ids == 2) { + poi.sender_set = true; + } else { + sbuf_push(log, indent, "Got invalid value for number of system IDs: %" + PRIu8 ")\n", number_of_ids); + return 1; + } + + if (tlv_len != 1 + 6 * number_of_ids) { + sbuf_push(log, indent, "Incorrect tlv len for number of IDs.\n"); + return 1; + } + + stream_get(poi.generator, s, sizeof(poi.generator)); + if (poi.sender_set) + stream_get(poi.sender, s, sizeof(poi.sender)); + + if (tlvs->purge_originator) { + sbuf_push(log, indent, + "WARNING: Purge originator present multiple times, ignoring.\n"); + return 0; + } + + tlvs->purge_originator = copy_tlv_purge_originator(&poi); + return 0; +} + + /* Functions relating to item TLVs */ static void init_item_list(struct isis_item_list *items) @@ -1770,7 +2150,6 @@ static void format_items_(uint16_t mtid, enum isis_tlv_context context, for (i = items->head; i; i = i->next) format_item(mtid, context, type, i, buf, indent); } -#define format_items(...) format_items_(ISIS_MT_IPV4_UNICAST, __VA_ARGS__) static void free_item(enum isis_tlv_context tlv_context, enum isis_tlv_type tlv_type, struct isis_item *item) @@ -1876,6 +2255,14 @@ top: break; } + /* Multiple prefix-sids don't go into one TLV, so always break */ + if (type == ISIS_SUBTLV_PREFIX_SID + && (context == ISIS_CONTEXT_SUBTLV_IP_REACH + || context == ISIS_CONTEXT_SUBTLV_IPV6_REACH)) { + item = item->next; + break; + } + if (len > 255) { if (!last_len) /* strange, not a single item fit */ return 1; @@ -2131,6 +2518,9 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs) copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth, &rv->isis_auth); + rv->purge_originator = + copy_tlv_purge_originator(tlvs->purge_originator); + copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES, &tlvs->area_addresses, &rv->area_addresses); @@ -2187,6 +2577,8 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs) rv->threeway_adj = copy_tlv_threeway_adj(tlvs->threeway_adj); + rv->spine_leaf = copy_tlv_spine_leaf(tlvs->spine_leaf); + return rv; } @@ -2197,6 +2589,8 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent) format_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth, buf, indent); + format_tlv_purge_originator(tlvs->purge_originator, buf, indent); + format_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES, &tlvs->area_addresses, buf, indent); @@ -2250,6 +2644,8 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent) &tlvs->mt_ipv6_reach, buf, indent); format_tlv_threeway_adj(tlvs->threeway_adj, buf, indent); + + format_tlv_spine_leaf(tlvs->spine_leaf, buf, indent); } const char *isis_format_tlvs(struct isis_tlvs *tlvs) @@ -2270,6 +2666,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs) return; free_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth); + free_tlv_purge_originator(tlvs->purge_originator); free_items(ISIS_CONTEXT_LSP, ISIS_TLV_AREA_ADDRESSES, &tlvs->area_addresses); free_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_ROUTER_INFO, @@ -2301,6 +2698,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs) free_mt_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_IPV6_REACH, &tlvs->mt_ipv6_reach); free_tlv_threeway_adj(tlvs->threeway_adj); + free_tlv_spine_leaf(tlvs->spine_leaf); XFREE(MTYPE_ISIS_TLV, tlvs); } @@ -2417,6 +2815,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream, return rv; } + rv = pack_tlv_purge_originator(tlvs->purge_originator, stream); + if (rv) + return rv; + if (fragment_tlvs) { + fragment_tlvs->purge_originator = + copy_tlv_purge_originator(tlvs->purge_originator); + } + rv = pack_tlv_protocols_supported(&tlvs->protocols_supported, stream); if (rv) return rv; @@ -2480,6 +2886,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream, copy_tlv_threeway_adj(tlvs->threeway_adj); } + rv = pack_tlv_spine_leaf(tlvs->spine_leaf, stream); + if (rv) + return rv; + if (fragment_tlvs) { + fragment_tlvs->spine_leaf = + copy_tlv_spine_leaf(tlvs->spine_leaf); + } + for (size_t pack_idx = 0; pack_idx < array_size(pack_order); pack_idx++) { rv = handle_pack_entry(&pack_order[pack_idx], tlvs, stream, @@ -2667,11 +3081,15 @@ int isis_unpack_tlvs(size_t avail_len, struct stream *stream, .name = _desc_, .unpack = unpack_subtlv_##_name_, \ } +#define ITEM_SUBTLV_OPS(_name_, _desc_) \ + ITEM_TLV_OPS(_name_, _desc_) + ITEM_TLV_OPS(area_address, "TLV 1 Area Addresses"); ITEM_TLV_OPS(oldstyle_reach, "TLV 2 IS Reachability"); ITEM_TLV_OPS(lan_neighbor, "TLV 6 LAN Neighbors"); ITEM_TLV_OPS(lsp_entry, "TLV 9 LSP Entries"); ITEM_TLV_OPS(auth, "TLV 10 IS-IS Auth"); +TLV_OPS(purge_originator, "TLV 13 Purge Originator Identification"); ITEM_TLV_OPS(extended_reach, "TLV 22 Extended Reachability"); ITEM_TLV_OPS(oldstyle_ip_reach, "TLV 128/130 IP Reachability"); TLV_OPS(protocols_supported, "TLV 129 Protocols Supported"); @@ -2679,11 +3097,13 @@ ITEM_TLV_OPS(ipv4_address, "TLV 132 IPv4 Interface Address"); TLV_OPS(te_router_id, "TLV 134 TE Router ID"); ITEM_TLV_OPS(extended_ip_reach, "TLV 135 Extended IP Reachability"); TLV_OPS(dynamic_hostname, "TLV 137 Dynamic Hostname"); +TLV_OPS(spine_leaf, "TLV 150 Spine Leaf Extensions"); ITEM_TLV_OPS(mt_router_info, "TLV 229 MT Router Information"); TLV_OPS(threeway_adj, "TLV 240 P2P Three-Way Adjacency"); ITEM_TLV_OPS(ipv6_address, "TLV 232 IPv6 Interface Address"); ITEM_TLV_OPS(ipv6_reach, "TLV 236 IPv6 Reachability"); +ITEM_SUBTLV_OPS(prefix_sid, "Sub-TLV 3 SR Prefix-SID"); SUBTLV_OPS(ipv6_source_prefix, "Sub-TLV 22 IPv6 Source Prefix"); static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { @@ -2693,6 +3113,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { [ISIS_TLV_LAN_NEIGHBORS] = &tlv_lan_neighbor_ops, [ISIS_TLV_LSP_ENTRY] = &tlv_lsp_entry_ops, [ISIS_TLV_AUTH] = &tlv_auth_ops, + [ISIS_TLV_PURGE_ORIGINATOR] = &tlv_purge_originator_ops, [ISIS_TLV_EXTENDED_REACH] = &tlv_extended_reach_ops, [ISIS_TLV_MT_REACH] = &tlv_extended_reach_ops, [ISIS_TLV_OLDSTYLE_IP_REACH] = &tlv_oldstyle_ip_reach_ops, @@ -2703,6 +3124,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { [ISIS_TLV_EXTENDED_IP_REACH] = &tlv_extended_ip_reach_ops, [ISIS_TLV_MT_IP_REACH] = &tlv_extended_ip_reach_ops, [ISIS_TLV_DYNAMIC_HOSTNAME] = &tlv_dynamic_hostname_ops, + [ISIS_TLV_SPINE_LEAF_EXT] = &tlv_spine_leaf_ops, [ISIS_TLV_MT_ROUTER_INFO] = &tlv_mt_router_info_ops, [ISIS_TLV_THREE_WAY_ADJ] = &tlv_threeway_adj_ops, [ISIS_TLV_IPV6_ADDRESS] = &tlv_ipv6_address_ops, @@ -2710,8 +3132,11 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { [ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops, }, [ISIS_CONTEXT_SUBTLV_NE_REACH] = {}, - [ISIS_CONTEXT_SUBTLV_IP_REACH] = {}, + [ISIS_CONTEXT_SUBTLV_IP_REACH] = { + [ISIS_SUBTLV_PREFIX_SID] = &tlv_prefix_sid_ops, + }, [ISIS_CONTEXT_SUBTLV_IPV6_REACH] = { + [ISIS_SUBTLV_PREFIX_SID] = &tlv_prefix_sid_ops, [ISIS_SUBTLV_IPV6_SOURCE_PREFIX] = &subtlv_ipv6_source_prefix_ops, } }; @@ -3183,7 +3608,7 @@ void isis_tlvs_add_ipv6_dstsrc_reach(struct isis_tlvs *tlvs, uint16_t mtid, mtid); struct isis_ipv6_reach *r = (struct isis_ipv6_reach*)last_item(l); - r->subtlvs = isis_alloc_subtlvs(); + r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH); r->subtlvs->source_prefix = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*src)); memcpy(r->subtlvs->source_prefix, src, sizeof(*src)); } @@ -3239,6 +3664,24 @@ void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs, } } +void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier, + bool has_tier, bool is_leaf, bool is_spine, + bool is_backup) +{ + assert(!tlvs->spine_leaf); + + tlvs->spine_leaf = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->spine_leaf)); + + if (has_tier) { + tlvs->spine_leaf->tier = tier; + } + + tlvs->spine_leaf->has_tier = has_tier; + tlvs->spine_leaf->is_leaf = is_leaf; + tlvs->spine_leaf->is_spine = is_spine; + tlvs->spine_leaf->is_backup = is_backup; +} + struct isis_mt_router_info * isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid) { @@ -3254,3 +3697,20 @@ isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid) return NULL; } + +void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs, + const uint8_t *generator, + const uint8_t *sender) +{ + assert(!tlvs->purge_originator); + + tlvs->purge_originator = XCALLOC(MTYPE_ISIS_TLV, + sizeof(*tlvs->purge_originator)); + memcpy(tlvs->purge_originator->generator, generator, + sizeof(tlvs->purge_originator->generator)); + if (sender) { + tlvs->purge_originator->sender_set = true; + memcpy(tlvs->purge_originator->sender, sender, + sizeof(tlvs->purge_originator->sender)); + } +} diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index bd1fa3e67..4144809fa 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -83,6 +83,8 @@ struct isis_extended_ip_reach { uint32_t metric; bool down; struct prefix_ipv4 prefix; + + struct isis_subtlvs *subtlvs; }; struct isis_ipv6_reach; @@ -103,6 +105,17 @@ struct isis_protocols_supported { uint8_t *protocols; }; +#define ISIS_TIER_UNDEFINED 15 + +struct isis_spine_leaf { + uint8_t tier; + + bool has_tier; + bool is_leaf; + bool is_spine; + bool is_backup; +}; + enum isis_threeway_state { ISIS_THREEWAY_DOWN = 2, ISIS_THREEWAY_INITIALIZING = 1, @@ -176,6 +189,13 @@ struct isis_item_list { unsigned int count; }; +struct isis_purge_originator { + bool sender_set; + + uint8_t generator[6]; + uint8_t sender[6]; +}; + RB_HEAD(isis_mt_item_list, isis_item_list); struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m, @@ -185,6 +205,7 @@ struct isis_item_list *isis_lookup_mt_items(struct isis_mt_item_list *m, struct isis_tlvs { struct isis_item_list isis_auth; + struct isis_purge_originator *purge_originator; struct isis_item_list area_addresses; struct isis_item_list oldstyle_reach; struct isis_item_list lan_neighbor; @@ -205,11 +226,24 @@ struct isis_tlvs { struct isis_item_list ipv6_reach; struct isis_mt_item_list mt_ipv6_reach; struct isis_threeway_adj *threeway_adj; + struct isis_spine_leaf *spine_leaf; }; -struct isis_subtlvs { - /* draft-baker-ipv6-isis-dst-src-routing-06 */ - struct prefix_ipv6 *source_prefix; +#define ISIS_PREFIX_SID_READVERTISED 0x80 +#define ISIS_PREFIX_SID_NODE 0x40 +#define ISIS_PREFIX_SID_NO_PHP 0x20 +#define ISIS_PREFIX_SID_EXPLICIT_NULL 0x10 +#define ISIS_PREFIX_SID_VALUE 0x08 +#define ISIS_PREFIX_SID_LOCAL 0x04 + +struct isis_prefix_sid; +struct isis_prefix_sid { + struct isis_prefix_sid *next; + + uint8_t flags; + uint8_t algorithm; + + uint32_t value; }; enum isis_tlv_context { @@ -220,6 +254,15 @@ enum isis_tlv_context { ISIS_CONTEXT_MAX }; +struct isis_subtlvs { + enum isis_tlv_context context; + + /* draft-baker-ipv6-isis-dst-src-routing-06 */ + struct prefix_ipv6 *source_prefix; + /* draft-ietf-isis-segment-routing-extensions-16 */ + struct isis_item_list prefix_sids; +}; + enum isis_tlv_type { ISIS_TLV_AREA_ADDRESSES = 1, ISIS_TLV_OLDSTYLE_REACH = 2, @@ -227,6 +270,7 @@ enum isis_tlv_type { ISIS_TLV_PADDING = 8, ISIS_TLV_LSP_ENTRY = 9, ISIS_TLV_AUTH = 10, + ISIS_TLV_PURGE_ORIGINATOR = 13, ISIS_TLV_EXTENDED_REACH = 22, ISIS_TLV_OLDSTYLE_IP_REACH = 128, @@ -236,6 +280,7 @@ enum isis_tlv_type { ISIS_TLV_TE_ROUTER_ID = 134, ISIS_TLV_EXTENDED_IP_REACH = 135, ISIS_TLV_DYNAMIC_HOSTNAME = 137, + ISIS_TLV_SPINE_LEAF_EXT = 150, ISIS_TLV_MT_REACH = 222, ISIS_TLV_MT_ROUTER_INFO = 229, ISIS_TLV_IPV6_ADDRESS = 232, @@ -245,6 +290,7 @@ enum isis_tlv_type { ISIS_TLV_THREE_WAY_ADJ = 240, ISIS_TLV_MAX = 256, + ISIS_SUBTLV_PREFIX_SID = 3, ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22 }; @@ -331,6 +377,14 @@ void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs, const uint8_t *neighbor_id, uint32_t neighbor_circuit_id); +void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier, + bool has_tier, bool is_leaf, bool is_spine, + bool is_backup); + struct isis_mt_router_info * isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid); + +void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs, + const uint8_t *generator, + const uint8_t *sender); #endif diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c new file mode 100644 index 000000000..32427628a --- /dev/null +++ b/isisd/isis_tx_queue.c @@ -0,0 +1,182 @@ +/* + * IS-IS Rout(e)ing protocol - LSP TX Queuing logic + * + * Copyright (C) 2018 Christian Franke + * + * This file is part of FreeRangeRouting (FRR) + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> + +#include "hash.h" +#include "jhash.h" + +#include "isisd/isisd.h" +#include "isisd/isis_memory.h" +#include "isisd/isis_flags.h" +#include "dict.h" +#include "isisd/isis_circuit.h" +#include "isisd/isis_lsp.h" +#include "isisd/isis_tx_queue.h" + +DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE, "ISIS TX Queue") +DEFINE_MTYPE_STATIC(ISISD, TX_QUEUE_ENTRY, "ISIS TX Queue Entry") + +struct isis_tx_queue { + void *arg; + void (*send_event)(void *arg, struct isis_lsp *, enum isis_tx_type); + struct hash *hash; +}; + +struct isis_tx_queue_entry { + struct isis_lsp *lsp; + enum isis_tx_type type; + struct thread *retry; + struct isis_tx_queue *queue; +}; + +static unsigned tx_queue_hash_key(void *p) +{ + struct isis_tx_queue_entry *e = p; + + uint32_t id_key = jhash(e->lsp->hdr.lsp_id, + ISIS_SYS_ID_LEN + 2, 0x55aa5a5a); + + return jhash_1word(e->lsp->level, id_key); +} + +static int tx_queue_hash_cmp(const void *a, const void *b) +{ + const struct isis_tx_queue_entry *ea = a, *eb = b; + + if (ea->lsp->level != eb->lsp->level) + return 0; + + if (memcmp(ea->lsp->hdr.lsp_id, eb->lsp->hdr.lsp_id, + ISIS_SYS_ID_LEN + 2)) + return 0; + + return 1; +} + +struct isis_tx_queue *isis_tx_queue_new(void *arg, + void(*send_event)(void *arg, + struct isis_lsp *, + enum isis_tx_type)) +{ + struct isis_tx_queue *rv = XCALLOC(MTYPE_TX_QUEUE, sizeof(*rv)); + + rv->arg = arg; + rv->send_event = send_event; + + rv->hash = hash_create(tx_queue_hash_key, tx_queue_hash_cmp, NULL); + return rv; +} + +static void tx_queue_element_free(void *element) +{ + struct isis_tx_queue_entry *e = element; + + if (e->retry) + thread_cancel(e->retry); + + XFREE(MTYPE_TX_QUEUE_ENTRY, e); +} + +void isis_tx_queue_free(struct isis_tx_queue *queue) +{ + hash_clean(queue->hash, tx_queue_element_free); + hash_free(queue->hash); + XFREE(MTYPE_TX_QUEUE, queue); +} + +static struct isis_tx_queue_entry *tx_queue_find(struct isis_tx_queue *queue, + struct isis_lsp *lsp) +{ + struct isis_tx_queue_entry e = { + .lsp = lsp + }; + + return hash_lookup(queue->hash, &e); +} + +static int tx_queue_send_event(struct thread *thread) +{ + struct isis_tx_queue_entry *e = THREAD_ARG(thread); + struct isis_tx_queue *queue = e->queue; + + e->retry = NULL; + thread_add_timer(master, tx_queue_send_event, e, 5, &e->retry); + + queue->send_event(queue->arg, e->lsp, e->type); + /* Don't access e here anymore, send_event might have destroyed it */ + + return 0; +} + +void isis_tx_queue_add(struct isis_tx_queue *queue, + struct isis_lsp *lsp, + enum isis_tx_type type) +{ + if (!queue) + return; + + struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp); + if (!e) { + e = XCALLOC(MTYPE_TX_QUEUE_ENTRY, sizeof(*e)); + e->lsp = lsp; + e->queue = queue; + + struct isis_tx_queue_entry *inserted; + inserted = hash_get(queue->hash, e, hash_alloc_intern); + assert(inserted == e); + } + + e->type = type; + + if (e->retry) + thread_cancel(e->retry); + thread_add_event(master, tx_queue_send_event, e, 0, &e->retry); +} + +void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp) +{ + if (!queue) + return; + + struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp); + if (!e) + return; + + if (e->retry) + thread_cancel(e->retry); + + hash_release(queue->hash, e); + XFREE(MTYPE_TX_QUEUE_ENTRY, e); +} + +unsigned long isis_tx_queue_len(struct isis_tx_queue *queue) +{ + if (!queue) + return 0; + + return hashcount(queue->hash); +} + +void isis_tx_queue_clean(struct isis_tx_queue *queue) +{ + hash_clean(queue->hash, tx_queue_element_free); +} diff --git a/isisd/isis_lsp_hash.h b/isisd/isis_tx_queue.h index b50aa09dc..ddecdf1e4 100644 --- a/isisd/isis_lsp_hash.h +++ b/isisd/isis_tx_queue.h @@ -1,7 +1,7 @@ /* - * IS-IS Rout(e)ing protocol - LSP Hash + * IS-IS Rout(e)ing protocol - LSP TX Queuing logic * - * Copyright (C) 2017 Christian Franke + * Copyright (C) 2018 Christian Franke * * This file is part of FreeRangeRouting (FRR) * @@ -19,16 +19,31 @@ * with this program; see the file COPYING; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef ISIS_LSP_HASH_H -#define ISIS_LSP_HASH_H - -struct isis_lsp_hash; - -struct isis_lsp_hash *isis_lsp_hash_new(void); -void isis_lsp_hash_clean(struct isis_lsp_hash *ih); -void isis_lsp_hash_free(struct isis_lsp_hash *ih); -struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih, - struct isis_lsp *lsp); -void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp); -void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp); +#ifndef ISIS_TX_QUEUE_H +#define ISIS_TX_QUEUE_H + +enum isis_tx_type { + TX_LSP_NORMAL = 0, + TX_LSP_CIRCUIT_SCOPED +}; + +struct isis_tx_queue; + +struct isis_tx_queue *isis_tx_queue_new(void *arg, + void(*send_event)(void *arg, + struct isis_lsp *, + enum isis_tx_type)); + +void isis_tx_queue_free(struct isis_tx_queue *queue); + +void isis_tx_queue_add(struct isis_tx_queue *queue, + struct isis_lsp *lsp, + enum isis_tx_type type); + +void isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp); + +unsigned long isis_tx_queue_len(struct isis_tx_queue *queue); + +void isis_tx_queue_clean(struct isis_tx_queue *queue); + #endif diff --git a/isisd/isis_vty.c b/isisd/isis_vty.c deleted file mode 100644 index ce2952c13..000000000 --- a/isisd/isis_vty.c +++ /dev/null @@ -1,2165 +0,0 @@ -/* - * IS-IS Rout(e)ing protocol - isis_circuit.h - * - * Copyright (C) 2001,2002 Sampo Saaristo - * Tampere University of Technology - * Institute of Communications Engineering - * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public Licenseas published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include "command.h" -#include "spf_backoff.h" - -#include "isis_circuit.h" -#include "isis_csm.h" -#include "isis_misc.h" -#include "isis_mt.h" -#include "isisd.h" - -static struct isis_circuit *isis_circuit_lookup(struct vty *vty) -{ - struct interface *ifp = VTY_GET_CONTEXT(interface); - struct isis_circuit *circuit; - - if (!ifp) { - vty_out(vty, "Invalid interface \n"); - return NULL; - } - - circuit = circuit_scan_by_ifp(ifp); - if (!circuit) { - vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); - return NULL; - } - - return circuit; -} - -DEFUN (ip_router_isis, - ip_router_isis_cmd, - "ip router isis WORD", - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - "IS-IS Routing for IP\n" - "Routing process tag\n") -{ - int idx_afi = 0; - int idx_word = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct isis_circuit *circuit; - struct isis_area *area; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - /* Prevent more than one area per circuit */ - circuit = circuit_scan_by_ifp(ifp); - if (circuit && circuit->area) { - if (strcmp(circuit->area->area_tag, area_tag)) { - vty_out(vty, "ISIS circuit is already defined on %s\n", - circuit->area->area_tag); - return CMD_ERR_NOTHING_TODO; - } - } - - area = isis_area_lookup(area_tag); - if (!area) - area = isis_area_create(area_tag); - - if (!circuit || !circuit->area) { - circuit = isis_circuit_create(area, ifp); - - if (circuit->state != C_STATE_CONF - && circuit->state != C_STATE_UP) { - vty_out(vty, - "Couldn't bring up interface, please check log.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = true; - else - ip = true; - - isis_circuit_af_set(circuit, ip, ipv6); - return CMD_SUCCESS; -} - -DEFUN (ip6_router_isis, - ip6_router_isis_cmd, - "ipv6 router isis WORD", - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - "IS-IS Routing for IP\n" - "Routing process tag\n") -{ - return ip_router_isis(self, vty, argc, argv); -} - -DEFUN (no_ip_router_isis, - no_ip_router_isis_cmd, - "no <ip|ipv6> router isis WORD", - NO_STR - "Interface Internet Protocol config commands\n" - "IP router interface commands\n" - "IP router interface commands\n" - "IS-IS Routing for IP\n" - "Routing process tag\n") -{ - int idx_afi = 1; - int idx_word = 4; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct isis_area *area; - struct isis_circuit *circuit; - const char *af = argv[idx_afi]->arg; - const char *area_tag = argv[idx_word]->arg; - - area = isis_area_lookup(area_tag); - if (!area) { - vty_out(vty, "Can't find ISIS instance %s\n", - argv[idx_afi]->arg); - return CMD_ERR_NO_MATCH; - } - - circuit = circuit_lookup_by_ifp(ifp, area->circuit_list); - if (!circuit) { - vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); - return CMD_ERR_NO_MATCH; - } - - bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; - if (af[2] != '\0') - ipv6 = false; - else - ip = false; - - isis_circuit_af_set(circuit, ip, ipv6); - return CMD_SUCCESS; -} - -DEFUN (isis_passive, - isis_passive_cmd, - "isis passive", - "IS-IS commands\n" - "Configure the passive mode for interface\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1), - "Cannot set passive: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_passive, - no_isis_passive_cmd, - "no isis passive", - NO_STR - "IS-IS commands\n" - "Configure the passive mode for interface\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0), - "Cannot set no passive: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (isis_circuit_type, - isis_circuit_type_cmd, - "isis circuit-type <level-1|level-1-2|level-2-only>", - "IS-IS commands\n" - "Configure circuit type for interface\n" - "Level-1 only adjacencies are formed\n" - "Level-1-2 adjacencies are formed\n" - "Level-2 only adjacencies are formed\n") -{ - int idx_level = 2; - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - is_type = string2circuit_t(argv[idx_level]->arg); - if (!is_type) { - vty_out(vty, "Unknown circuit-type \n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (circuit->state == C_STATE_UP - && circuit->area->is_type != IS_LEVEL_1_AND_2 - && circuit->area->is_type != is_type) { - vty_out(vty, "Invalid circuit level for area %s.\n", - circuit->area->area_tag); - return CMD_WARNING_CONFIG_FAILED; - } - isis_circuit_is_type_set(circuit, is_type); - - return CMD_SUCCESS; -} - -DEFUN (no_isis_circuit_type, - no_isis_circuit_type_cmd, - "no isis circuit-type <level-1|level-1-2|level-2-only>", - NO_STR - "IS-IS commands\n" - "Configure circuit type for interface\n" - "Level-1 only adjacencies are formed\n" - "Level-1-2 adjacencies are formed\n" - "Level-2 only adjacencies are formed\n") -{ - int is_type; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - /* - * Set the circuits level to its default value - */ - if (circuit->state == C_STATE_UP) - is_type = circuit->area->is_type; - else - is_type = IS_LEVEL_1_AND_2; - isis_circuit_is_type_set(circuit, is_type); - - return CMD_SUCCESS; -} - -DEFUN (isis_network, - isis_network_cmd, - "isis network point-to-point", - "IS-IS commands\n" - "Set network type\n" - "point-to-point network type\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) { - vty_out(vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (no_isis_network, - no_isis_network_cmd, - "no isis network point-to-point", - NO_STR - "IS-IS commands\n" - "Set network type for circuit\n" - "point-to-point network type\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) { - vty_out(vty, - "isis network point-to-point is valid only on broadcast interfaces\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (isis_passwd, - isis_passwd_cmd, - "isis password <md5|clear> WORD", - "IS-IS commands\n" - "Configure the authentication password for a circuit\n" - "HMAC-MD5 authentication\n" - "Cleartext password\n" - "Circuit password\n") -{ - int idx_encryption = 2; - int idx_word = 3; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - ferr_r rv; - - if (!circuit) - return CMD_ERR_NO_MATCH; - - if (argv[idx_encryption]->arg[0] == 'm') - rv = isis_circuit_passwd_hmac_md5_set(circuit, - argv[idx_word]->arg); - else - rv = isis_circuit_passwd_cleartext_set(circuit, - argv[idx_word]->arg); - - CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR"); - return CMD_SUCCESS; -} - -DEFUN (no_isis_passwd, - no_isis_passwd_cmd, - "no isis password [<md5|clear> WORD]", - NO_STR - "IS-IS commands\n" - "Configure the authentication password for a circuit\n" - "HMAC-MD5 authentication\n" - "Cleartext password\n" - "Circuit password\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit), - "Failed to unset circuit password: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (isis_priority, - isis_priority_cmd, - "isis priority (0-127)", - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n") -{ - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - prio = atoi(argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { - vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->priority[0] = prio; - circuit->priority[1] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority, - no_isis_priority_cmd, - "no isis priority [(0-127)]", - NO_STR - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[0] = DEFAULT_PRIORITY; - circuit->priority[1] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - - -DEFUN (isis_priority_l1, - isis_priority_l1_cmd, - "isis priority (0-127) level-1", - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-1 routing\n") -{ - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - prio = atoi(argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { - vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->priority[0] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority_l1, - no_isis_priority_l1_cmd, - "no isis priority [(0-127)] level-1", - NO_STR - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-1 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[0] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - - -DEFUN (isis_priority_l2, - isis_priority_l2_cmd, - "isis priority (0-127) level-2", - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-2 routing\n") -{ - int idx_number = 2; - int prio; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - prio = atoi(argv[idx_number]->arg); - if (prio < MIN_PRIORITY || prio > MAX_PRIORITY) { - vty_out(vty, "Invalid priority %d - should be <0-127>\n", prio); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->priority[1] = prio; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_priority_l2, - no_isis_priority_l2_cmd, - "no isis priority [(0-127)] level-2", - NO_STR - "IS-IS commands\n" - "Set priority for Designated Router election\n" - "Priority value\n" - "Specify priority for level-2 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->priority[1] = DEFAULT_PRIORITY; - - return CMD_SUCCESS; -} - - -/* Metric command */ -DEFUN (isis_metric, - isis_metric_cmd, - "isis metric (0-16777215)", - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n") -{ - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - met = atoi(argv[idx_number]->arg); - - /* RFC3787 section 5.1 */ - if (circuit->area && circuit->area->oldmetric == 1 - && met > MAX_NARROW_LINK_METRIC) { - vty_out(vty, - "Invalid metric %d - should be <0-63> " - "when narrow metric type enabled\n", - met); - return CMD_WARNING_CONFIG_FAILED; - } - - /* RFC4444 */ - if (circuit->area && circuit->area->newmetric == 1 - && met > MAX_WIDE_LINK_METRIC) { - vty_out(vty, - "Invalid metric %d - should be <0-16777215> " - "when wide metric type enabled\n", - met); - return CMD_WARNING_CONFIG_FAILED; - } - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met), - "Failed to set L1 metric: $ERR"); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (no_isis_metric, - no_isis_metric_cmd, - "no isis metric [(0-16777215)]", - NO_STR - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L1 metric: $ERR"); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (isis_metric_l1, - isis_metric_l1_cmd, - "isis metric (0-16777215) level-1", - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-1 routing\n") -{ - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - met = atoi(argv[idx_number]->arg); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met), - "Failed to set L1 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (no_isis_metric_l1, - no_isis_metric_l1_cmd, - "no isis metric [(0-16777215)] level-1", - NO_STR - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-1 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L1 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (isis_metric_l2, - isis_metric_l2_cmd, - "isis metric (0-16777215) level-2", - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-2 routing\n") -{ - int idx_number = 2; - int met; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - met = atoi(argv[idx_number]->arg); - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - - -DEFUN (no_isis_metric_l2, - no_isis_metric_l2_cmd, - "no isis metric [(0-16777215)] level-2", - NO_STR - "IS-IS commands\n" - "Set default metric for circuit\n" - "Default metric value\n" - "Specify metric for level-2 routing\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, - DEFAULT_CIRCUIT_METRIC), - "Failed to set L2 metric: $ERR"); - return CMD_SUCCESS; -} - -/* end of metrics */ - -DEFUN (isis_hello_interval, - isis_hello_interval_cmd, - "isis hello-interval (1-600)", - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 seconds, interval depends on multiplier\n") -{ - int idx_number = 2; - int interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atoi(argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { - vty_out(vty, "Invalid hello-interval %d - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_interval[0] = (uint16_t)interval; - circuit->hello_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_interval, - no_isis_hello_interval_cmd, - "no isis hello-interval [(1-600)]", - NO_STR - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; - circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_interval_l1, - isis_hello_interval_l1_cmd, - "isis hello-interval (1-600) level-1", - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-1 IIHs\n") -{ - int idx_number = 2; - long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atoi(argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { - vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_interval[0] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_interval_l1, - no_isis_hello_interval_l1_cmd, - "no isis hello-interval [(1-600)] level-1", - NO_STR - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-1 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_interval_l2, - isis_hello_interval_l2_cmd, - "isis hello-interval (1-600) level-2", - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-2 IIHs\n") -{ - int idx_number = 2; - long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atoi(argv[idx_number]->arg); - if (interval < MIN_HELLO_INTERVAL || interval > MAX_HELLO_INTERVAL) { - vty_out(vty, "Invalid hello-interval %ld - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_interval_l2, - no_isis_hello_interval_l2_cmd, - "no isis hello-interval [(1-600)] level-2", - NO_STR - "IS-IS commands\n" - "Set Hello interval\n" - "Holdtime 1 second, interval depends on multiplier\n" - "Specify hello-interval for level-2 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_multiplier, - isis_hello_multiplier_cmd, - "isis hello-multiplier (2-100)", - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n") -{ - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - mult = atoi(argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { - vty_out(vty, - "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_multiplier[0] = (uint16_t)mult; - circuit->hello_multiplier[1] = (uint16_t)mult; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_multiplier, - no_isis_hello_multiplier_cmd, - "no isis hello-multiplier [(2-100)]", - NO_STR - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; - circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_multiplier_l1, - isis_hello_multiplier_l1_cmd, - "isis hello-multiplier (2-100) level-1", - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-1 IIHs\n") -{ - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - mult = atoi(argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { - vty_out(vty, - "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_multiplier[0] = (uint16_t)mult; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_multiplier_l1, - no_isis_hello_multiplier_l1_cmd, - "no isis hello-multiplier [(2-100)] level-1", - NO_STR - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-1 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_multiplier_l2, - isis_hello_multiplier_l2_cmd, - "isis hello-multiplier (2-100) level-2", - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-2 IIHs\n") -{ - int idx_number = 2; - int mult; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - mult = atoi(argv[idx_number]->arg); - if (mult < MIN_HELLO_MULTIPLIER || mult > MAX_HELLO_MULTIPLIER) { - vty_out(vty, - "Invalid hello-multiplier %d - should be <2-100>\n", - mult); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->hello_multiplier[1] = (uint16_t)mult; - - return CMD_SUCCESS; -} - - -DEFUN (no_isis_hello_multiplier_l2, - no_isis_hello_multiplier_l2_cmd, - "no isis hello-multiplier [(2-100)] level-2", - NO_STR - "IS-IS commands\n" - "Set multiplier for Hello holding time\n" - "Hello multiplier value\n" - "Specify hello multiplier for level-2 IIHs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; - - return CMD_SUCCESS; -} - - -DEFUN (isis_hello_padding, - isis_hello_padding_cmd, - "isis hello padding", - "IS-IS commands\n" - "Add padding to IS-IS hello packets\n" - "Pad hello packets\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->pad_hellos = 1; - - return CMD_SUCCESS; -} - -DEFUN (no_isis_hello_padding, - no_isis_hello_padding_cmd, - "no isis hello padding", - NO_STR - "IS-IS commands\n" - "Add padding to IS-IS hello packets\n" - "Pad hello packets\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->pad_hellos = 0; - - return CMD_SUCCESS; -} - -DEFUN (isis_threeway_adj, - isis_threeway_adj_cmd, - "[no] isis three-way-handshake", - NO_STR - "IS-IS commands\n" - "Enable/Disable three-way handshake\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->disable_threeway_adj = !strcmp(argv[0]->text, "no"); - return CMD_SUCCESS; -} - -DEFUN (csnp_interval, - csnp_interval_cmd, - "isis csnp-interval (1-600)", - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { - vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->csnp_interval[0] = (uint16_t)interval; - circuit->csnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_csnp_interval, - no_csnp_interval_cmd, - "no isis csnp-interval [(1-600)]", - NO_STR - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; - circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (csnp_interval_l1, - csnp_interval_l1_cmd, - "isis csnp-interval (1-600) level-1", - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-1 CSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { - vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->csnp_interval[0] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_csnp_interval_l1, - no_csnp_interval_l1_cmd, - "no isis csnp-interval [(1-600)] level-1", - NO_STR - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-1 CSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (csnp_interval_l2, - csnp_interval_l2_cmd, - "isis csnp-interval (1-600) level-2", - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-2 CSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_CSNP_INTERVAL || interval > MAX_CSNP_INTERVAL) { - vty_out(vty, "Invalid csnp-interval %lu - should be <1-600>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->csnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_csnp_interval_l2, - no_csnp_interval_l2_cmd, - "no isis csnp-interval [(1-600)] level-2", - NO_STR - "IS-IS commands\n" - "Set CSNP interval in seconds\n" - "CSNP interval value\n" - "Specify interval for level-2 CSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (psnp_interval, - psnp_interval_cmd, - "isis psnp-interval (1-120)", - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { - vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->psnp_interval[0] = (uint16_t)interval; - circuit->psnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_psnp_interval, - no_psnp_interval_cmd, - "no isis psnp-interval [(1-120)]", - NO_STR - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; - circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (psnp_interval_l1, - psnp_interval_l1_cmd, - "isis psnp-interval (1-120) level-1", - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-1 PSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { - vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->psnp_interval[0] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_psnp_interval_l1, - no_psnp_interval_l1_cmd, - "no isis psnp-interval [(1-120)] level-1", - NO_STR - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-1 PSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (psnp_interval_l2, - psnp_interval_l2_cmd, - "isis psnp-interval (1-120) level-2", - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-2 PSNPs\n") -{ - int idx_number = 2; - unsigned long interval; - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - interval = atol(argv[idx_number]->arg); - if (interval < MIN_PSNP_INTERVAL || interval > MAX_PSNP_INTERVAL) { - vty_out(vty, "Invalid psnp-interval %lu - should be <1-120>\n", - interval); - return CMD_WARNING_CONFIG_FAILED; - } - - circuit->psnp_interval[1] = (uint16_t)interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_psnp_interval_l2, - no_psnp_interval_l2_cmd, - "no isis psnp-interval [(1-120)] level-2", - NO_STR - "IS-IS commands\n" - "Set PSNP interval in seconds\n" - "PSNP interval value\n" - "Specify interval for level-2 PSNPs\n") -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - - circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (circuit_topology, - circuit_topology_cmd, - "isis topology " ISIS_MT_NAMES, - "IS-IS commands\n" - "Configure interface IS-IS topologies\n" - ISIS_MT_DESCRIPTIONS) -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[2]->arg; - uint16_t mtid = isis_str2mtid(arg); - - if (circuit->area && circuit->area->oldmetric) { - vty_out(vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (mtid == (uint16_t)-1) { - vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return isis_circuit_mt_enabled_set(circuit, mtid, true); -} - -DEFUN (no_circuit_topology, - no_circuit_topology_cmd, - "no isis topology " ISIS_MT_NAMES, - NO_STR - "IS-IS commands\n" - "Configure interface IS-IS topologies\n" - ISIS_MT_DESCRIPTIONS) -{ - struct isis_circuit *circuit = isis_circuit_lookup(vty); - if (!circuit) - return CMD_ERR_NO_MATCH; - const char *arg = argv[3]->arg; - uint16_t mtid = isis_str2mtid(arg); - - if (circuit->area && circuit->area->oldmetric) { - vty_out(vty, - "Multi topology IS-IS can only be used with wide metrics\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (mtid == (uint16_t)-1) { - vty_out(vty, "Don't know topology '%s'\n", arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return isis_circuit_mt_enabled_set(circuit, mtid, false); -} - -static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) -{ - struct isis_circuit *circuit; - struct listnode *node; - - if (!vty) - return CMD_WARNING_CONFIG_FAILED; - - if (!area) { - vty_out(vty, "ISIS area is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { - if ((area->is_type & IS_LEVEL_1) - && (circuit->is_type & IS_LEVEL_1) - && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) { - vty_out(vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_WARNING_CONFIG_FAILED; - } - if ((area->is_type & IS_LEVEL_2) - && (circuit->is_type & IS_LEVEL_2) - && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) { - vty_out(vty, "ISIS circuit %s metric is invalid\n", - circuit->interface->name); - return CMD_WARNING_CONFIG_FAILED; - } - } - - return CMD_SUCCESS; -} - -DEFUN (metric_style, - metric_style_cmd, - "metric-style <narrow|transition|wide>", - "Use old-style (ISO 10589) or new-style packet formats\n" - "Use old style of TLVs with narrow metric\n" - "Send and accept both styles of TLVs during transition\n" - "Use new style of TLVs to carry wider metric\n") -{ - int idx_metric_style = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - int ret; - - if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) { - isis_area_metricstyle_set(area, false, true); - return CMD_SUCCESS; - } - - if (area_is_mt(area)) { - vty_out(vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = validate_metric_style_narrow(vty, area); - if (ret != CMD_SUCCESS) - return ret; - - if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0) - isis_area_metricstyle_set(area, true, true); - else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0) - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; - - return CMD_SUCCESS; -} - -DEFUN (no_metric_style, - no_metric_style_cmd, - "no metric-style", - NO_STR - "Use old-style (ISO 10589) or new-style packet formats\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int ret; - - if (area_is_mt(area)) { - vty_out(vty, - "Narrow metrics cannot be used while multi topology IS-IS is active\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = validate_metric_style_narrow(vty, area); - if (ret != CMD_SUCCESS) - return ret; - - isis_area_metricstyle_set(area, true, false); - return CMD_SUCCESS; -} - -DEFUN (set_overload_bit, - set_overload_bit_cmd, - "set-overload-bit", - "Set overload bit to avoid any transit traffic\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_overload_bit_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_set_overload_bit, - no_set_overload_bit_cmd, - "no set-overload-bit", - "Reset overload bit to accept transit traffic\n" - "Reset overload bit\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_overload_bit_set(area, false); - return CMD_SUCCESS; -} - -DEFUN (set_attached_bit, - set_attached_bit_cmd, - "set-attached-bit", - "Set attached bit to identify as L1/L2 router for inter-area traffic\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_attached_bit_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_set_attached_bit, - no_set_attached_bit_cmd, - "no set-attached-bit", - NO_STR - "Reset attached bit\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_attached_bit_set(area, false); - return CMD_SUCCESS; -} - -DEFUN (dynamic_hostname, - dynamic_hostname_cmd, - "hostname dynamic", - "Dynamic hostname for IS-IS\n" - "Dynamic hostname\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_dynhostname_set(area, true); - return CMD_SUCCESS; -} - -DEFUN (no_dynamic_hostname, - no_dynamic_hostname_cmd, - "no hostname dynamic", - NO_STR - "Dynamic hostname for IS-IS\n" - "Dynamic hostname\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - isis_area_dynhostname_set(area, false); - return CMD_SUCCESS; -} - -static int area_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - struct listnode *node; - struct isis_circuit *circuit; - - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { - if (circuit->state != C_STATE_INIT - && circuit->state != C_STATE_UP) - continue; - if (lsp_mtu > isis_circuit_pdu_size(circuit)) { - vty_out(vty, - "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", - circuit->interface->name, - isis_circuit_pdu_size(circuit)); - return CMD_WARNING_CONFIG_FAILED; - } - } - - isis_area_lsp_mtu_set(area, lsp_mtu); - return CMD_SUCCESS; -} - -DEFUN (area_lsp_mtu, - area_lsp_mtu_cmd, - "lsp-mtu (128-4352)", - "Configure the maximum size of generated LSPs\n" - "Maximum size of generated LSPs\n") -{ - int idx_number = 1; - unsigned int lsp_mtu; - - lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10); - - return area_lsp_mtu_set(vty, lsp_mtu); -} - - -DEFUN (no_area_lsp_mtu, - no_area_lsp_mtu_cmd, - "no lsp-mtu [(128-4352)]", - NO_STR - "Configure the maximum size of generated LSPs\n" - "Maximum size of generated LSPs\n") -{ - return area_lsp_mtu_set(vty, DEFAULT_LSP_MTU); -} - - -DEFUN (is_type, - is_type_cmd, - "is-type <level-1|level-1-2|level-2-only>", - "IS Level for this routing process (OSI only)\n" - "Act as a station router only\n" - "Act as both a station router and an area router\n" - "Act as an area router only\n") -{ - int idx_level = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - int type; - - type = string2circuit_t(argv[idx_level]->arg); - if (!type) { - vty_out(vty, "Unknown IS level \n"); - return CMD_SUCCESS; - } - - isis_area_is_type_set(area, type); - - return CMD_SUCCESS; -} - -DEFUN (no_is_type, - no_is_type_cmd, - "no is-type <level-1|level-1-2|level-2-only>", - NO_STR - "IS Level for this routing process (OSI only)\n" - "Act as a station router only\n" - "Act as both a station router and an area router\n" - "Act as an area router only\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int type; - - /* - * Put the is-type back to defaults: - * - level-1-2 on first area - * - level-1 for the rest - */ - if (listgetdata(listhead(isis->area_list)) == area) - type = IS_LEVEL_1_AND_2; - else - type = IS_LEVEL_1; - - isis_area_is_type_set(area, type); - - return CMD_SUCCESS; -} - -static int set_lsp_gen_interval(struct vty *vty, struct isis_area *area, - uint16_t interval, int level) -{ - int lvl; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - - if (interval >= area->lsp_refresh[lvl - 1]) { - vty_out(vty, - "LSP gen interval %us must be less than " - "the LSP refresh interval %us\n", - interval, area->lsp_refresh[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - area->lsp_gen_interval[lvl - 1] = interval; - } - - return CMD_SUCCESS; -} - -DEFUN (lsp_gen_interval, - lsp_gen_interval_cmd, - "lsp-gen-interval [<level-1|level-2>] (1-120)", - "Minimum interval between regenerating same LSP\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval in seconds\n") -{ - int idx = 0; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - int level; - - level = 0; - level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; - level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; - if (!level) - level = IS_LEVEL_1 | IS_LEVEL_2; - - argv_find(argv, argc, "(1-120)", &idx); - - interval = atoi(argv[idx]->arg); - return set_lsp_gen_interval(vty, area, interval, level); -} - -DEFUN (no_lsp_gen_interval, - no_lsp_gen_interval_cmd, - "no lsp-gen-interval [<level-1|level-2>] [(1-120)]", - NO_STR - "Minimum interval between regenerating same LSP\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval in seconds\n") -{ - int idx = 0; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - int level; - - level = 0; - level |= argv_find(argv, argc, "level-1", &idx) ? IS_LEVEL_1 : 0; - level |= argv_find(argv, argc, "level-2", &idx) ? IS_LEVEL_2 : 0; - if (!level) - level = IS_LEVEL_1 | IS_LEVEL_2; - - interval = DEFAULT_MIN_LSP_GEN_INTERVAL; - return set_lsp_gen_interval(vty, area, interval, level); -} - -DEFUN (spf_interval, - spf_interval_cmd, - "spf-interval (1-120)", - "Minimum interval between SPF calculations\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - int idx_number = 1; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - - interval = atoi(argv[idx_number]->arg); - area->min_spf_interval[0] = interval; - area->min_spf_interval[1] = interval; - - return CMD_SUCCESS; -} - - -DEFUN (no_spf_interval, - no_spf_interval_cmd, - "no spf-interval [[<level-1|level-2>] (1-120)]", - NO_STR - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n" - "Set interval for level 2 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (spf_interval_l1, - spf_interval_l1_cmd, - "spf-interval level-1 (1-120)", - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - int idx_number = 2; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - - interval = atoi(argv[idx_number]->arg); - area->min_spf_interval[0] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_interval_l1, - no_spf_interval_l1_cmd, - "no spf-interval level-1", - NO_STR - "Minimum interval between SPF calculations\n" - "Set interval for level 1 only\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - - -DEFUN (spf_interval_l2, - spf_interval_l2_cmd, - "spf-interval level-2 (1-120)", - "Minimum interval between SPF calculations\n" - "Set interval for level 2 only\n" - "Minimum interval between consecutive SPFs in seconds\n") -{ - int idx_number = 2; - VTY_DECLVAR_CONTEXT(isis_area, area); - uint16_t interval; - - interval = atoi(argv[idx_number]->arg); - area->min_spf_interval[1] = interval; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_interval_l2, - no_spf_interval_l2_cmd, - "no spf-interval level-2", - NO_STR - "Minimum interval between SPF calculations\n" - "Set interval for level 2 only\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (no_spf_delay_ietf, - no_spf_delay_ietf_cmd, - "no spf-delay-ietf", - NO_STR - "IETF SPF delay algorithm\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - spf_backoff_free(area->spf_delay_ietf[0]); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[0] = NULL; - area->spf_delay_ietf[1] = NULL; - - return CMD_SUCCESS; -} - -DEFUN (spf_delay_ietf, - spf_delay_ietf_cmd, - "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", - "IETF SPF delay algorithm\n" - "Delay used while in QUIET state\n" - "Delay used while in QUIET state in milliseconds\n" - "Delay used while in SHORT_WAIT state\n" - "Delay used while in SHORT_WAIT state in milliseconds\n" - "Delay used while in LONG_WAIT\n" - "Delay used while in LONG_WAIT state in milliseconds\n" - "Time with no received IGP events before considering IGP stable\n" - "Time with no received IGP events before considering IGP stable (in milliseconds)\n" - "Maximum duration needed to learn all the events related to a single failure\n" - "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - long init_delay = atol(argv[2]->arg); - long short_delay = atol(argv[4]->arg); - long long_delay = atol(argv[6]->arg); - long holddown = atol(argv[8]->arg); - long timetolearn = atol(argv[10]->arg); - - size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); - char *buf = XCALLOC(MTYPE_TMP, bufsiz); - - snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[0]); - area->spf_delay_ietf[0] = - spf_backoff_new(master, buf, init_delay, short_delay, - long_delay, holddown, timetolearn); - - snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag); - spf_backoff_free(area->spf_delay_ietf[1]); - area->spf_delay_ietf[1] = - spf_backoff_new(master, buf, init_delay, short_delay, - long_delay, holddown, timetolearn); - - XFREE(MTYPE_TMP, buf); - return CMD_SUCCESS; -} - -static int area_max_lsp_lifetime_set(struct vty *vty, int level, - uint16_t interval) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int lvl; - uint16_t refresh_interval = interval - 300; - int set_refresh_interval[ISIS_LEVELS] = {0, 0}; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { - if (!(lvl & level)) - continue; - - if (refresh_interval < area->lsp_refresh[lvl - 1]) { - vty_out(vty, - "Level %d Max LSP lifetime %us must be 300s greater than " - "the configured LSP refresh interval %us\n", - lvl, interval, area->lsp_refresh[lvl - 1]); - vty_out(vty, - "Automatically reducing level %d LSP refresh interval " - "to %us\n", - lvl, refresh_interval); - set_refresh_interval[lvl - 1] = 1; - - if (refresh_interval - <= area->lsp_gen_interval[lvl - 1]) { - vty_out(vty, - "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - refresh_interval, - area->lsp_gen_interval[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { - if (!(lvl & level)) - continue; - isis_area_max_lsp_lifetime_set(area, lvl, interval); - if (set_refresh_interval[lvl - 1]) - isis_area_lsp_refresh_set(area, lvl, refresh_interval); - } - - return CMD_SUCCESS; -} - -DEFUN (max_lsp_lifetime, - max_lsp_lifetime_cmd, - "max-lsp-lifetime [<level-1|level-2>] (350-65535)", - "Maximum LSP lifetime\n" - "Maximum LSP lifetime for Level 1 only\n" - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - argv_find(argv, argc, "(350-65535)", &idx); - int lifetime = atoi(argv[idx]->arg); - - return area_max_lsp_lifetime_set(vty, level, lifetime); -} - - -DEFUN (no_max_lsp_lifetime, - no_max_lsp_lifetime_cmd, - "no max-lsp-lifetime [<level-1|level-2>] [(350-65535)]", - NO_STR - "Maximum LSP lifetime\n" - "Maximum LSP lifetime for Level 1 only\n" - "Maximum LSP lifetime for Level 2 only\n" - "LSP lifetime in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - return area_max_lsp_lifetime_set(vty, level, DEFAULT_LSP_LIFETIME); -} - -static int area_lsp_refresh_interval_set(struct vty *vty, int level, - uint16_t interval) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - int lvl; - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - if (interval <= area->lsp_gen_interval[lvl - 1]) { - vty_out(vty, - "LSP refresh interval %us must be greater than " - "the configured LSP gen interval %us\n", - interval, area->lsp_gen_interval[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) { - vty_out(vty, - "LSP refresh interval %us must be less than " - "the configured LSP lifetime %us less 300\n", - interval, area->max_lsp_lifetime[lvl - 1]); - return CMD_WARNING_CONFIG_FAILED; - } - } - - for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { - if (!(lvl & level)) - continue; - isis_area_lsp_refresh_set(area, lvl, interval); - } - - return CMD_SUCCESS; -} - -DEFUN (lsp_refresh_interval, - lsp_refresh_interval_cmd, - "lsp-refresh-interval [<level-1|level-2>] (1-65235)", - "LSP refresh interval\n" - "LSP refresh interval for Level 1 only\n" - "LSP refresh interval for Level 2 only\n" - "LSP refresh interval in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - unsigned int interval = 0; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - interval = atoi(argv[argc - 1]->arg); - return area_lsp_refresh_interval_set(vty, level, interval); -} - -DEFUN (no_lsp_refresh_interval, - no_lsp_refresh_interval_cmd, - "no lsp-refresh-interval [<level-1|level-2>] [(1-65235)]", - NO_STR - "LSP refresh interval\n" - "LSP refresh interval for Level 1 only\n" - "LSP refresh interval for Level 2 only\n" - "LSP refresh interval in seconds\n") -{ - int idx = 0; - unsigned int level = IS_LEVEL_1_AND_2; - - if (argv_find(argv, argc, "level-1", &idx)) - level = IS_LEVEL_1; - else if (argv_find(argv, argc, "level-2", &idx)) - level = IS_LEVEL_2; - - return area_lsp_refresh_interval_set(vty, level, - DEFAULT_MAX_LSP_GEN_INTERVAL); -} - -static int area_passwd_set(struct vty *vty, int level, - int (*type_set)(struct isis_area *area, int level, - const char *passwd, - uint8_t snp_auth), - const char *passwd, uint8_t snp_auth) -{ - VTY_DECLVAR_CONTEXT(isis_area, area); - - if (passwd && strlen(passwd) > 254) { - vty_out(vty, "Too long area password (>254)\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - type_set(area, level, passwd, snp_auth); - return CMD_SUCCESS; -} - - -DEFUN (area_passwd_md5, - area_passwd_md5_cmd, - "area-password md5 WORD [authenticate snp <send-only|validate>]", - "Configure the authentication password for an area\n" - "Authentication type\n" - "Level-wide password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - int idx_password = 0; - int idx_word = 2; - int idx_type = 5; - uint8_t snp_auth = 0; - int level = strmatch(argv[idx_password]->text, "domain-password") - ? IS_LEVEL_2 - : IS_LEVEL_1; - - if (argc > 3) { - snp_auth = SNP_AUTH_SEND; - if (strmatch(argv[idx_type]->text, "validate")) - snp_auth |= SNP_AUTH_RECV; - } - - return area_passwd_set(vty, level, isis_area_passwd_hmac_md5_set, - argv[idx_word]->arg, snp_auth); -} - -DEFUN (domain_passwd_md5, - domain_passwd_md5_cmd, - "domain-password md5 WORD [authenticate snp <send-only|validate>]", - "Set the authentication password for a routing domain\n" - "Authentication type\n" - "Level-wide password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - return area_passwd_md5(self, vty, argc, argv); -} - -DEFUN (area_passwd_clear, - area_passwd_clear_cmd, - "area-password clear WORD [authenticate snp <send-only|validate>]", - "Configure the authentication password for an area\n" - "Authentication type\n" - "Area password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - int idx_password = 0; - int idx_word = 2; - int idx_type = 5; - uint8_t snp_auth = 0; - int level = strmatch(argv[idx_password]->text, "domain-password") - ? IS_LEVEL_2 - : IS_LEVEL_1; - - if (argc > 3) { - snp_auth = SNP_AUTH_SEND; - if (strmatch(argv[idx_type]->text, "validate")) - snp_auth |= SNP_AUTH_RECV; - } - - return area_passwd_set(vty, level, isis_area_passwd_cleartext_set, - argv[idx_word]->arg, snp_auth); -} - -DEFUN (domain_passwd_clear, - domain_passwd_clear_cmd, - "domain-password clear WORD [authenticate snp <send-only|validate>]", - "Set the authentication password for a routing domain\n" - "Authentication type\n" - "Area password\n" - "Authentication\n" - "SNP PDUs\n" - "Send but do not check PDUs on receiving\n" - "Send and check PDUs on receiving\n") -{ - return area_passwd_clear(self, vty, argc, argv); -} - -DEFUN (no_area_passwd, - no_area_passwd_cmd, - "no <area-password|domain-password>", - NO_STR - "Configure the authentication password for an area\n" - "Set the authentication password for a routing domain\n") -{ - int idx_password = 1; - int level = strmatch(argv[idx_password]->text, "domain-password") - ? IS_LEVEL_2 - : IS_LEVEL_1; - VTY_DECLVAR_CONTEXT(isis_area, area); - - return isis_area_passwd_unset(area, level); -} - -void isis_vty_init(void) -{ - install_element(INTERFACE_NODE, &ip_router_isis_cmd); - install_element(INTERFACE_NODE, &ip6_router_isis_cmd); - install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); - - install_element(INTERFACE_NODE, &isis_passive_cmd); - install_element(INTERFACE_NODE, &no_isis_passive_cmd); - - install_element(INTERFACE_NODE, &isis_circuit_type_cmd); - install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); - - install_element(INTERFACE_NODE, &isis_network_cmd); - install_element(INTERFACE_NODE, &no_isis_network_cmd); - - install_element(INTERFACE_NODE, &isis_passwd_cmd); - install_element(INTERFACE_NODE, &no_isis_passwd_cmd); - - install_element(INTERFACE_NODE, &isis_priority_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_cmd); - install_element(INTERFACE_NODE, &isis_priority_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_l1_cmd); - install_element(INTERFACE_NODE, &isis_priority_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_priority_l2_cmd); - - install_element(INTERFACE_NODE, &isis_metric_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_cmd); - install_element(INTERFACE_NODE, &isis_metric_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_l1_cmd); - install_element(INTERFACE_NODE, &isis_metric_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_metric_l2_cmd); - - install_element(INTERFACE_NODE, &isis_hello_interval_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); - install_element(INTERFACE_NODE, &isis_hello_interval_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_l1_cmd); - install_element(INTERFACE_NODE, &isis_hello_interval_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_interval_l2_cmd); - - install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); - install_element(INTERFACE_NODE, &isis_hello_multiplier_l1_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l1_cmd); - install_element(INTERFACE_NODE, &isis_hello_multiplier_l2_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_multiplier_l2_cmd); - - install_element(INTERFACE_NODE, &isis_hello_padding_cmd); - install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd); - - install_element(INTERFACE_NODE, &isis_threeway_adj_cmd); - - install_element(INTERFACE_NODE, &csnp_interval_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_cmd); - install_element(INTERFACE_NODE, &csnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &csnp_interval_l2_cmd); - install_element(INTERFACE_NODE, &no_csnp_interval_l2_cmd); - - install_element(INTERFACE_NODE, &psnp_interval_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_cmd); - install_element(INTERFACE_NODE, &psnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_l1_cmd); - install_element(INTERFACE_NODE, &psnp_interval_l2_cmd); - install_element(INTERFACE_NODE, &no_psnp_interval_l2_cmd); - - install_element(INTERFACE_NODE, &circuit_topology_cmd); - install_element(INTERFACE_NODE, &no_circuit_topology_cmd); - - install_element(ISIS_NODE, &metric_style_cmd); - install_element(ISIS_NODE, &no_metric_style_cmd); - - install_element(ISIS_NODE, &set_overload_bit_cmd); - install_element(ISIS_NODE, &no_set_overload_bit_cmd); - - install_element(ISIS_NODE, &set_attached_bit_cmd); - install_element(ISIS_NODE, &no_set_attached_bit_cmd); - - install_element(ISIS_NODE, &dynamic_hostname_cmd); - install_element(ISIS_NODE, &no_dynamic_hostname_cmd); - - install_element(ISIS_NODE, &area_lsp_mtu_cmd); - install_element(ISIS_NODE, &no_area_lsp_mtu_cmd); - - install_element(ISIS_NODE, &is_type_cmd); - install_element(ISIS_NODE, &no_is_type_cmd); - - install_element(ISIS_NODE, &lsp_gen_interval_cmd); - install_element(ISIS_NODE, &no_lsp_gen_interval_cmd); - - install_element(ISIS_NODE, &spf_interval_cmd); - install_element(ISIS_NODE, &no_spf_interval_cmd); - install_element(ISIS_NODE, &spf_interval_l1_cmd); - install_element(ISIS_NODE, &no_spf_interval_l1_cmd); - install_element(ISIS_NODE, &spf_interval_l2_cmd); - install_element(ISIS_NODE, &no_spf_interval_l2_cmd); - - install_element(ISIS_NODE, &max_lsp_lifetime_cmd); - install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd); - - install_element(ISIS_NODE, &lsp_refresh_interval_cmd); - install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd); - - install_element(ISIS_NODE, &area_passwd_md5_cmd); - install_element(ISIS_NODE, &area_passwd_clear_cmd); - install_element(ISIS_NODE, &domain_passwd_md5_cmd); - install_element(ISIS_NODE, &domain_passwd_clear_cmd); - install_element(ISIS_NODE, &no_area_passwd_cmd); - - install_element(ISIS_NODE, &spf_delay_ietf_cmd); - install_element(ISIS_NODE, &no_spf_delay_ietf_cmd); -} diff --git a/isisd/isis_vty_common.c b/isisd/isis_vty_common.c new file mode 100644 index 000000000..2b98a88b3 --- /dev/null +++ b/isisd/isis_vty_common.c @@ -0,0 +1,960 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_common.c + * + * This file contains the CLI that is shared between OpenFabric and IS-IS + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. + * Copyright (C) 2018 Christian Franke, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "command.h" +#include "spf_backoff.h" + +#include "isis_circuit.h" +#include "isis_csm.h" +#include "isis_misc.h" +#include "isis_mt.h" +#include "isisd.h" +#include "isis_vty_common.h" + +struct isis_circuit *isis_circuit_lookup(struct vty *vty) +{ + struct interface *ifp = VTY_GET_CONTEXT(interface); + struct isis_circuit *circuit; + + if (!ifp) { + vty_out(vty, "Invalid interface \n"); + return NULL; + } + + circuit = circuit_scan_by_ifp(ifp); + if (!circuit) { + vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); + return NULL; + } + + return circuit; +} + +DEFUN (ip_router_isis, + ip_router_isis_cmd, + "ip router " PROTO_NAME " WORD", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + PROTO_HELP + "Routing process tag\n") +{ + int idx_afi = 0; + int idx_word = 3; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct isis_circuit *circuit; + struct isis_area *area; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; + + /* Prevent more than one area per circuit */ + circuit = circuit_scan_by_ifp(ifp); + if (circuit && circuit->area) { + if (strcmp(circuit->area->area_tag, area_tag)) { + vty_out(vty, "ISIS circuit is already defined on %s\n", + circuit->area->area_tag); + return CMD_ERR_NOTHING_TODO; + } + } + + area = isis_area_lookup(area_tag); + if (!area) + area = isis_area_create(area_tag); + + if (!circuit || !circuit->area) { + circuit = isis_circuit_create(area, ifp); + + if (circuit->state != C_STATE_CONF + && circuit->state != C_STATE_UP) { + vty_out(vty, + "Couldn't bring up interface, please check log.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; + if (af[2] != '\0') + ipv6 = true; + else + ip = true; + + isis_circuit_af_set(circuit, ip, ipv6); + return CMD_SUCCESS; +} + +DEFUN (ip6_router_isis, + ip6_router_isis_cmd, + "ipv6 router " PROTO_NAME " WORD", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + PROTO_HELP + "Routing process tag\n") +{ + return ip_router_isis(self, vty, argc, argv); +} + +DEFUN (no_ip_router_isis, + no_ip_router_isis_cmd, + "no <ip|ipv6> router " PROTO_NAME " WORD", + NO_STR + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + "IP router interface commands\n" + PROTO_HELP + "Routing process tag\n") +{ + int idx_afi = 1; + int idx_word = 4; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct isis_area *area; + struct isis_circuit *circuit; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; + + area = isis_area_lookup(area_tag); + if (!area) { + vty_out(vty, "Can't find ISIS instance %s\n", + area_tag); + return CMD_ERR_NO_MATCH; + } + + circuit = circuit_lookup_by_ifp(ifp, area->circuit_list); + if (!circuit) { + vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name); + return CMD_ERR_NO_MATCH; + } + + bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router; + if (af[2] != '\0') + ipv6 = false; + else + ip = false; + + isis_circuit_af_set(circuit, ip, ipv6); + return CMD_SUCCESS; +} + +DEFUN (isis_passive, + isis_passive_cmd, + PROTO_NAME " passive", + PROTO_HELP + "Configure the passive mode for interface\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 1), + "Cannot set passive: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_passive, + no_isis_passive_cmd, + "no " PROTO_NAME " passive", + NO_STR + PROTO_HELP + "Configure the passive mode for interface\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_passive_set(circuit, 0), + "Cannot set no passive: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_passwd, + isis_passwd_cmd, + PROTO_NAME " password <md5|clear> WORD", + PROTO_HELP + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + int idx_encryption = 2; + int idx_word = 3; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + ferr_r rv; + + if (!circuit) + return CMD_ERR_NO_MATCH; + + if (argv[idx_encryption]->arg[0] == 'm') + rv = isis_circuit_passwd_hmac_md5_set(circuit, + argv[idx_word]->arg); + else + rv = isis_circuit_passwd_cleartext_set(circuit, + argv[idx_word]->arg); + + CMD_FERR_RETURN(rv, "Failed to set circuit password: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_passwd, + no_isis_passwd_cmd, + "no " PROTO_NAME " password [<md5|clear> WORD]", + NO_STR + PROTO_HELP + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_passwd_unset(circuit), + "Failed to unset circuit password: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_metric, + isis_metric_cmd, + PROTO_NAME " metric (0-16777215)", + PROTO_HELP + "Set default metric for circuit\n" + "Default metric value\n") +{ + int idx_number = 2; + int met; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + met = atoi(argv[idx_number]->arg); + + /* RFC3787 section 5.1 */ + if (circuit->area && circuit->area->oldmetric == 1 + && met > MAX_NARROW_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-63> " + "when narrow metric type enabled\n", + met); + return CMD_WARNING_CONFIG_FAILED; + } + + /* RFC4444 */ + if (circuit->area && circuit->area->newmetric == 1 + && met > MAX_WIDE_LINK_METRIC) { + vty_out(vty, + "Invalid metric %d - should be <0-16777215> " + "when wide metric type enabled\n", + met); + return CMD_WARNING_CONFIG_FAILED; + } + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met), + "Failed to set L1 metric: $ERR"); + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met), + "Failed to set L2 metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_metric, + no_isis_metric_cmd, + "no " PROTO_NAME " metric [(0-16777215)]", + NO_STR + PROTO_HELP + "Set default metric for circuit\n" + "Default metric value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, + DEFAULT_CIRCUIT_METRIC), + "Failed to set L1 metric: $ERR"); + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, + DEFAULT_CIRCUIT_METRIC), + "Failed to set L2 metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_hello_interval, + isis_hello_interval_cmd, + PROTO_NAME " hello-interval (1-600)", + PROTO_HELP + "Set Hello interval\n" + "Holdtime 1 seconds, interval depends on multiplier\n") +{ + uint32_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[0] = interval; + circuit->hello_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_interval, + no_isis_hello_interval_cmd, + "no " PROTO_NAME " hello-interval [(1-600)]", + NO_STR + PROTO_HELP + "Set Hello interval\n" + "Holdtime 1 second, interval depends on multiplier\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL; + circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (isis_hello_multiplier, + isis_hello_multiplier_cmd, + PROTO_NAME " hello-multiplier (2-100)", + PROTO_HELP + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n") +{ + uint16_t mult = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[0] = mult; + circuit->hello_multiplier[1] = mult; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_multiplier, + no_isis_hello_multiplier_cmd, + "no " PROTO_NAME " hello-multiplier [(2-100)]", + NO_STR + PROTO_HELP + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER; + circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER; + + return CMD_SUCCESS; +} + +DEFUN (csnp_interval, + csnp_interval_cmd, + PROTO_NAME " csnp-interval (1-600)", + PROTO_HELP + "Set CSNP interval in seconds\n" + "CSNP interval value\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[0] = interval; + circuit->csnp_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_csnp_interval, + no_csnp_interval_cmd, + "no " PROTO_NAME " csnp-interval [(1-600)]", + NO_STR + PROTO_HELP + "Set CSNP interval in seconds\n" + "CSNP interval value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL; + circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (psnp_interval, + psnp_interval_cmd, + PROTO_NAME " psnp-interval (1-120)", + PROTO_HELP + "Set PSNP interval in seconds\n" + "PSNP interval value\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[0] = interval; + circuit->psnp_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_psnp_interval, + no_psnp_interval_cmd, + "no " PROTO_NAME " psnp-interval [(1-120)]", + NO_STR + PROTO_HELP + "Set PSNP interval in seconds\n" + "PSNP interval value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL; + circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (circuit_topology, + circuit_topology_cmd, + PROTO_NAME " topology " ISIS_MT_NAMES, + PROTO_HELP + "Configure interface IS-IS topologies\n" + ISIS_MT_DESCRIPTIONS) +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + const char *arg = argv[2]->arg; + uint16_t mtid = isis_str2mtid(arg); + + if (circuit->area && circuit->area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_WARNING_CONFIG_FAILED; + } + + return isis_circuit_mt_enabled_set(circuit, mtid, true); +} + +DEFUN (no_circuit_topology, + no_circuit_topology_cmd, + "no " PROTO_NAME " topology " ISIS_MT_NAMES, + NO_STR + PROTO_HELP + "Configure interface IS-IS topologies\n" + ISIS_MT_DESCRIPTIONS) +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + const char *arg = argv[3]->arg; + uint16_t mtid = isis_str2mtid(arg); + + if (circuit->area && circuit->area->oldmetric) { + vty_out(vty, + "Multi topology IS-IS can only be used with wide metrics\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (mtid == (uint16_t)-1) { + vty_out(vty, "Don't know topology '%s'\n", arg); + return CMD_WARNING_CONFIG_FAILED; + } + + return isis_circuit_mt_enabled_set(circuit, mtid, false); +} + +DEFUN (set_overload_bit, + set_overload_bit_cmd, + "set-overload-bit", + "Set overload bit to avoid any transit traffic\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_overload_bit_set(area, true); + return CMD_SUCCESS; +} + +DEFUN (no_set_overload_bit, + no_set_overload_bit_cmd, + "no set-overload-bit", + "Reset overload bit to accept transit traffic\n" + "Reset overload bit\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_overload_bit_set(area, false); + return CMD_SUCCESS; +} + +static int isis_vty_lsp_mtu_set(struct vty *vty, unsigned int lsp_mtu) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + struct listnode *node; + struct isis_circuit *circuit; + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if (circuit->state != C_STATE_INIT + && circuit->state != C_STATE_UP) + continue; + if (lsp_mtu > isis_circuit_pdu_size(circuit)) { + vty_out(vty, + "ISIS area contains circuit %s, which has a maximum PDU size of %zu.\n", + circuit->interface->name, + isis_circuit_pdu_size(circuit)); + return CMD_WARNING_CONFIG_FAILED; + } + } + + isis_area_lsp_mtu_set(area, lsp_mtu); + return CMD_SUCCESS; +} + +DEFUN (area_lsp_mtu, + area_lsp_mtu_cmd, + "lsp-mtu (128-4352)", + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + int idx_number = 1; + unsigned int lsp_mtu; + + lsp_mtu = strtoul(argv[idx_number]->arg, NULL, 10); + + return isis_vty_lsp_mtu_set(vty, lsp_mtu); +} + +DEFUN (no_area_lsp_mtu, + no_area_lsp_mtu_cmd, + "no lsp-mtu [(128-4352)]", + NO_STR + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU); +} + +DEFUN (area_purge_originator, + area_purge_originator_cmd, + "[no] purge-originator", + NO_STR + "Use the RFC 6232 purge-originator\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + area->purge_originator = !!strcmp(argv[0]->text, "no"); + return CMD_SUCCESS; +} + +int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + + if (interval >= area->lsp_refresh[lvl - 1]) { + vty_out(vty, + "LSP gen interval %us must be less than " + "the LSP refresh interval %us\n", + interval, area->lsp_refresh[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + area->lsp_gen_interval[lvl - 1] = interval; + } + + return CMD_SUCCESS; +} + +DEFUN (lsp_gen_interval, + lsp_gen_interval_cmd, + "lsp-gen-interval (1-120)", + "Minimum interval between regenerating same LSP\n" + "Minimum interval in seconds\n") +{ + uint16_t interval = atoi(argv[1]->arg); + + return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, interval); +} + +DEFUN (no_lsp_gen_interval, + no_lsp_gen_interval_cmd, + "no lsp-gen-interval [(1-120)]", + NO_STR + "Minimum interval between regenerating same LSP\n" + "Minimum interval in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_vty_lsp_gen_interval_set(vty, IS_LEVEL_1_AND_2, + DEFAULT_MIN_LSP_GEN_INTERVAL); +} + +DEFUN (spf_interval, + spf_interval_cmd, + "spf-interval (1-120)", + "Minimum interval between SPF calculations\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + uint16_t interval = atoi(argv[1]->arg); + + area->min_spf_interval[0] = interval; + area->min_spf_interval[1] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_spf_interval, + no_spf_interval_cmd, + "no spf-interval [(1-120)]", + NO_STR + "Minimum interval between SPF calculations\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; + area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (no_spf_delay_ietf, + no_spf_delay_ietf_cmd, + "no spf-delay-ietf", + NO_STR + "IETF SPF delay algorithm\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + spf_backoff_free(area->spf_delay_ietf[0]); + spf_backoff_free(area->spf_delay_ietf[1]); + area->spf_delay_ietf[0] = NULL; + area->spf_delay_ietf[1] = NULL; + + return CMD_SUCCESS; +} + +DEFUN (spf_delay_ietf, + spf_delay_ietf_cmd, + "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", + "IETF SPF delay algorithm\n" + "Delay used while in QUIET state\n" + "Delay used while in QUIET state in milliseconds\n" + "Delay used while in SHORT_WAIT state\n" + "Delay used while in SHORT_WAIT state in milliseconds\n" + "Delay used while in LONG_WAIT\n" + "Delay used while in LONG_WAIT state in milliseconds\n" + "Time with no received IGP events before considering IGP stable\n" + "Time with no received IGP events before considering IGP stable (in milliseconds)\n" + "Maximum duration needed to learn all the events related to a single failure\n" + "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + long init_delay = atol(argv[2]->arg); + long short_delay = atol(argv[4]->arg); + long long_delay = atol(argv[6]->arg); + long holddown = atol(argv[8]->arg); + long timetolearn = atol(argv[10]->arg); + + size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); + char *buf = XCALLOC(MTYPE_TMP, bufsiz); + + snprintf(buf, bufsiz, "IS-IS %s L1", area->area_tag); + spf_backoff_free(area->spf_delay_ietf[0]); + area->spf_delay_ietf[0] = + spf_backoff_new(master, buf, init_delay, short_delay, + long_delay, holddown, timetolearn); + + snprintf(buf, bufsiz, "IS-IS %s L2", area->area_tag); + spf_backoff_free(area->spf_delay_ietf[1]); + area->spf_delay_ietf[1] = + spf_backoff_new(master, buf, init_delay, short_delay, + long_delay, holddown, timetolearn); + + XFREE(MTYPE_TMP, buf); + return CMD_SUCCESS; +} + +int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + uint16_t refresh_interval = interval - 300; + int set_refresh_interval[ISIS_LEVELS] = {0, 0}; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + if (!(lvl & level)) + continue; + + if (refresh_interval < area->lsp_refresh[lvl - 1]) { + vty_out(vty, + "Level %d Max LSP lifetime %us must be 300s greater than " + "the configured LSP refresh interval %us\n", + lvl, interval, area->lsp_refresh[lvl - 1]); + vty_out(vty, + "Automatically reducing level %d LSP refresh interval " + "to %us\n", + lvl, refresh_interval); + set_refresh_interval[lvl - 1] = 1; + + if (refresh_interval + <= area->lsp_gen_interval[lvl - 1]) { + vty_out(vty, + "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us\n", + refresh_interval, + area->lsp_gen_interval[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; lvl++) { + if (!(lvl & level)) + continue; + isis_area_max_lsp_lifetime_set(area, lvl, interval); + if (set_refresh_interval[lvl - 1]) + isis_area_lsp_refresh_set(area, lvl, refresh_interval); + } + + return CMD_SUCCESS; +} + +DEFUN (max_lsp_lifetime, + max_lsp_lifetime_cmd, + "max-lsp-lifetime (350-65535)", + "Maximum LSP lifetime\n" + "LSP lifetime in seconds\n") +{ + int lifetime = atoi(argv[1]->arg); + + return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, lifetime); +} + + +DEFUN (no_max_lsp_lifetime, + no_max_lsp_lifetime_cmd, + "no max-lsp-lifetime [(350-65535)]", + NO_STR + "Maximum LSP lifetime\n" + "LSP lifetime in seconds\n") +{ + return isis_vty_max_lsp_lifetime_set(vty, IS_LEVEL_1_AND_2, + DEFAULT_LSP_LIFETIME); +} + +int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int lvl; + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + if (interval <= area->lsp_gen_interval[lvl - 1]) { + vty_out(vty, + "LSP refresh interval %us must be greater than " + "the configured LSP gen interval %us\n", + interval, area->lsp_gen_interval[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + if (interval > (area->max_lsp_lifetime[lvl - 1] - 300)) { + vty_out(vty, + "LSP refresh interval %us must be less than " + "the configured LSP lifetime %us less 300\n", + interval, area->max_lsp_lifetime[lvl - 1]); + return CMD_WARNING_CONFIG_FAILED; + } + } + + for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { + if (!(lvl & level)) + continue; + isis_area_lsp_refresh_set(area, lvl, interval); + } + + return CMD_SUCCESS; +} + +DEFUN (lsp_refresh_interval, + lsp_refresh_interval_cmd, + "lsp-refresh-interval (1-65235)", + "LSP refresh interval\n" + "LSP refresh interval in seconds\n") +{ + unsigned int interval = atoi(argv[1]->arg); + return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, interval); +} + +DEFUN (no_lsp_refresh_interval, + no_lsp_refresh_interval_cmd, + "no lsp-refresh-interval [(1-65235)]", + NO_STR + "LSP refresh interval\n" + "LSP refresh interval in seconds\n") +{ + return isis_vty_lsp_refresh_set(vty, IS_LEVEL_1_AND_2, + DEFAULT_MAX_LSP_GEN_INTERVAL); +} + +int isis_vty_password_set(struct vty *vty, int argc, + struct cmd_token *argv[], int level) +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + int idx_algo = 1; + int idx_password = 2; + int idx_snp_auth = 5; + uint8_t snp_auth = 0; + + const char *passwd = argv[idx_password]->arg; + if (strlen(passwd) > 254) { + vty_out(vty, "Too long area password (>254)\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc > idx_snp_auth) { + snp_auth = SNP_AUTH_SEND; + if (strmatch(argv[idx_snp_auth]->text, "validate")) + snp_auth |= SNP_AUTH_RECV; + } + + if (strmatch(argv[idx_algo]->text, "clear")) { + return isis_area_passwd_cleartext_set(area, level, + passwd, snp_auth); + } else if (strmatch(argv[idx_algo]->text, "md5")) { + return isis_area_passwd_hmac_md5_set(area, level, + passwd, snp_auth); + } + + return CMD_WARNING_CONFIG_FAILED; +} + +DEFUN (domain_passwd, + domain_passwd_cmd, + "domain-password <clear|md5> WORD [authenticate snp <send-only|validate>]", + "Set the authentication password for a routing domain\n" + "Authentication type\n" + "Authentication type\n" + "Level-wide password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + return isis_vty_password_set(vty, argc, argv, IS_LEVEL_2); +} + +DEFUN (no_domain_passwd, + no_domain_passwd_cmd, + "no domain-password", + NO_STR + "Set the authentication password for a routing domain\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_area_passwd_unset(area, IS_LEVEL_2); +} + +void isis_vty_init(void) +{ + install_element(INTERFACE_NODE, &ip_router_isis_cmd); + install_element(INTERFACE_NODE, &ip6_router_isis_cmd); + install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); + + install_element(INTERFACE_NODE, &isis_passive_cmd); + install_element(INTERFACE_NODE, &no_isis_passive_cmd); + + install_element(INTERFACE_NODE, &isis_passwd_cmd); + install_element(INTERFACE_NODE, &no_isis_passwd_cmd); + + install_element(INTERFACE_NODE, &isis_metric_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_cmd); + + install_element(INTERFACE_NODE, &isis_hello_interval_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd); + + install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd); + + install_element(INTERFACE_NODE, &csnp_interval_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_cmd); + + install_element(INTERFACE_NODE, &psnp_interval_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_cmd); + + install_element(INTERFACE_NODE, &circuit_topology_cmd); + install_element(INTERFACE_NODE, &no_circuit_topology_cmd); + + install_element(ROUTER_NODE, &set_overload_bit_cmd); + install_element(ROUTER_NODE, &no_set_overload_bit_cmd); + + install_element(ROUTER_NODE, &area_lsp_mtu_cmd); + install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd); + + install_element(ROUTER_NODE, &area_purge_originator_cmd); + + install_element(ROUTER_NODE, &lsp_gen_interval_cmd); + install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd); + + install_element(ROUTER_NODE, &spf_interval_cmd); + install_element(ROUTER_NODE, &no_spf_interval_cmd); + + install_element(ROUTER_NODE, &max_lsp_lifetime_cmd); + install_element(ROUTER_NODE, &no_max_lsp_lifetime_cmd); + + install_element(ROUTER_NODE, &lsp_refresh_interval_cmd); + install_element(ROUTER_NODE, &no_lsp_refresh_interval_cmd); + + install_element(ROUTER_NODE, &domain_passwd_cmd); + install_element(ROUTER_NODE, &no_domain_passwd_cmd); + + install_element(ROUTER_NODE, &spf_delay_ietf_cmd); + install_element(ROUTER_NODE, &no_spf_delay_ietf_cmd); + + isis_vty_daemon_init(); +} diff --git a/isisd/isis_vty_common.h b/isisd/isis_vty_common.h new file mode 100644 index 000000000..b726b4ee8 --- /dev/null +++ b/isisd/isis_vty_common.h @@ -0,0 +1,38 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_common.h + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISIS_VTY_COMMON_H +#define ISIS_VTY_COMMON_H + +struct isis_circuit *isis_circuit_lookup(struct vty *vty); + +int isis_vty_max_lsp_lifetime_set(struct vty *vty, int level, uint16_t interval); +int isis_vty_lsp_refresh_set(struct vty *vty, int level, uint16_t interval); +int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval); +int isis_vty_password_set(struct vty *vty, int argc, + struct cmd_token *argv[], int level); + +void isis_vty_daemon_init(void); +void isis_vty_init(void); + +#endif diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c new file mode 100644 index 000000000..95ebe0de8 --- /dev/null +++ b/isisd/isis_vty_fabricd.c @@ -0,0 +1,94 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_fabricd.c + * + * This file contains the CLI that is specific to OpenFabric + * + * Copyright (C) 2018 Christian Franke, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> + +#include "command.h" + +#include "isisd.h" +#include "isis_vty_common.h" +#include "fabricd.h" +#include "isis_tlvs.h" + +DEFUN (fabric_tier, + fabric_tier_cmd, + "fabric-tier (0-14)", + "Statically configure the tier to advertise\n" + "Tier to advertise\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + uint8_t tier = atoi(argv[1]->arg); + + fabricd_configure_tier(area, tier); + return CMD_SUCCESS; +} + +DEFUN (no_fabric_tier, + no_fabric_tier_cmd, + "no fabric-tier [(0-14)]", + NO_STR + "Statically configure the tier to advertise\n" + "Tier to advertise\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + fabricd_configure_tier(area, ISIS_TIER_UNDEFINED); + return CMD_SUCCESS; +} + +DEFUN (debug_fabric_flooding, + debug_fabric_flooding_cmd, + "debug openfabric flooding", + DEBUG_STR + PROTO_HELP + "Flooding optimization algorithm\n") +{ + isis->debugs |= DEBUG_FABRICD_FLOODING; + print_debug(vty, DEBUG_FABRICD_FLOODING, 1); + + return CMD_SUCCESS; +} + +DEFUN (no_debug_fabric_flooding, + no_debug_fabric_flooding_cmd, + "no debug openfabric flooding", + NO_STR + UNDEBUG_STR + PROTO_HELP + "Flooding optimization algorithm\n") +{ + isis->debugs &= ~DEBUG_FABRICD_FLOODING; + print_debug(vty, DEBUG_FABRICD_FLOODING, 0); + + return CMD_SUCCESS; +} + + +void isis_vty_daemon_init(void) +{ + install_element(ROUTER_NODE, &fabric_tier_cmd); + install_element(ROUTER_NODE, &no_fabric_tier_cmd); + install_element(ENABLE_NODE, &debug_fabric_flooding_cmd); + install_element(ENABLE_NODE, &no_debug_fabric_flooding_cmd); + install_element(CONFIG_NODE, &debug_fabric_flooding_cmd); + install_element(CONFIG_NODE, &no_debug_fabric_flooding_cmd); +} diff --git a/isisd/isis_vty_isisd.c b/isisd/isis_vty_isisd.c new file mode 100644 index 000000000..95aaeae81 --- /dev/null +++ b/isisd/isis_vty_isisd.c @@ -0,0 +1,858 @@ +/* + * IS-IS Rout(e)ing protocol - isis_vty_isisd.c + * + * This file contains the CLI that is specific to IS-IS + * + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2016 David Lamparter, for NetDEF, Inc. + * Copyright (C) 2018 Christian Franke, for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public Licenseas published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "command.h" + +#include "isis_circuit.h" +#include "isis_csm.h" +#include "isis_misc.h" +#include "isis_mt.h" +#include "isisd.h" +#include "isis_vty_common.h" + +static int level_for_arg(const char *arg) +{ + if (!strcmp(arg, "level-1")) + return IS_LEVEL_1; + else + return IS_LEVEL_2; +} + +DEFUN (isis_circuit_type, + isis_circuit_type_cmd, + "isis circuit-type <level-1|level-1-2|level-2-only>", + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + int idx_level = 2; + int is_type; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + is_type = string2circuit_t(argv[idx_level]->arg); + if (!is_type) { + vty_out(vty, "Unknown circuit-type \n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (circuit->state == C_STATE_UP + && circuit->area->is_type != IS_LEVEL_1_AND_2 + && circuit->area->is_type != is_type) { + vty_out(vty, "Invalid circuit level for area %s.\n", + circuit->area->area_tag); + return CMD_WARNING_CONFIG_FAILED; + } + isis_circuit_is_type_set(circuit, is_type); + + return CMD_SUCCESS; +} + +DEFUN (no_isis_circuit_type, + no_isis_circuit_type_cmd, + "no isis circuit-type <level-1|level-1-2|level-2-only>", + NO_STR + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + int is_type; + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + /* + * Set the circuits level to its default value + */ + if (circuit->state == C_STATE_UP) + is_type = circuit->area->is_type; + else + is_type = IS_LEVEL_1_AND_2; + isis_circuit_is_type_set(circuit, is_type); + + return CMD_SUCCESS; +} + +DEFUN (isis_network, + isis_network_cmd, + "isis network point-to-point", + "IS-IS routing protocol\n" + "Set network type\n" + "point-to-point network type\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_P2P)) { + vty_out(vty, + "isis network point-to-point is valid only on broadcast interfaces\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + return CMD_SUCCESS; +} + +DEFUN (no_isis_network, + no_isis_network_cmd, + "no isis network point-to-point", + NO_STR + "IS-IS routing protocol\n" + "Set network type for circuit\n" + "point-to-point network type\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + if (isis_circuit_circ_type_set(circuit, CIRCUIT_T_BROADCAST)) { + vty_out(vty, + "isis network point-to-point is valid only on broadcast interfaces\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + return CMD_SUCCESS; +} + +DEFUN (isis_priority, + isis_priority_cmd, + "isis priority (0-127)", + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n") +{ + uint8_t prio = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[0] = prio; + circuit->priority[1] = prio; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_priority, + no_isis_priority_cmd, + "no isis priority [(0-127)]", + NO_STR + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[0] = DEFAULT_PRIORITY; + circuit->priority[1] = DEFAULT_PRIORITY; + + return CMD_SUCCESS; +} + +DEFUN (isis_priority_level, + isis_priority_level_cmd, + "isis priority (0-127) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + uint8_t prio = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[level_for_arg(argv[3]->text)] = prio; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_priority_level, + no_isis_priority_level_cmd, + "no isis priority [(0-127)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->priority[level] = DEFAULT_PRIORITY; + + return CMD_SUCCESS; +} + +DEFUN (isis_metric_level, + isis_metric_level_cmd, + "isis metric (0-16777215) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Default metric value\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n") +{ + uint32_t met = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, + level_for_arg(argv[3]->text), + met), + "Failed to set metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (no_isis_metric_level, + no_isis_metric_level_cmd, + "no isis metric [(0-16777215)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Default metric value\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + CMD_FERR_RETURN(isis_circuit_metric_set(circuit, level, + DEFAULT_CIRCUIT_METRIC), + "Failed to set L1 metric: $ERR"); + return CMD_SUCCESS; +} + +DEFUN (isis_hello_interval_level, + isis_hello_interval_level_cmd, + "isis hello-interval (1-600) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Holdtime 1 second, interval depends on multiplier\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n") +{ + uint32_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[level_for_arg(argv[3]->text)] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_interval_level, + no_isis_hello_interval_level_cmd, + "no isis hello-interval [(1-600)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Holdtime 1 second, interval depends on multiplier\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_interval[level] = DEFAULT_HELLO_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (isis_hello_multiplier_level, + isis_hello_multiplier_level_cmd, + "isis hello-multiplier (2-100) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n") +{ + uint16_t mult = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[level_for_arg(argv[3]->text)] = mult; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_multiplier_level, + no_isis_hello_multiplier_level_cmd, + "no isis hello-multiplier [(2-100)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Hello multiplier value\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->hello_multiplier[level] = DEFAULT_HELLO_MULTIPLIER; + + return CMD_SUCCESS; +} + +DEFUN (isis_threeway_adj, + isis_threeway_adj_cmd, + "[no] isis three-way-handshake", + NO_STR + "IS-IS commands\n" + "Enable/Disable three-way handshake\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->disable_threeway_adj = !strcmp(argv[0]->text, "no"); + return CMD_SUCCESS; +} + +DEFUN (isis_hello_padding, + isis_hello_padding_cmd, + "isis hello padding", + "IS-IS routing protocol\n" + "Add padding to IS-IS hello packets\n" + "Pad hello packets\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->pad_hellos = 1; + + return CMD_SUCCESS; +} + +DEFUN (no_isis_hello_padding, + no_isis_hello_padding_cmd, + "no isis hello padding", + NO_STR + "IS-IS routing protocol\n" + "Add padding to IS-IS hello packets\n" + "Pad hello packets\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->pad_hellos = 0; + + return CMD_SUCCESS; +} + +DEFUN (csnp_interval_level, + csnp_interval_level_cmd, + "isis csnp-interval (1-600) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[level_for_arg(argv[3]->text)] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_csnp_interval_level, + no_csnp_interval_level_cmd, + "no isis csnp-interval [(1-600)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->csnp_interval[level] = DEFAULT_CSNP_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (psnp_interval_level, + psnp_interval_level_cmd, + "isis psnp-interval (1-120) <level-1|level-2>", + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + uint16_t interval = atoi(argv[2]->arg); + struct isis_circuit *circuit = isis_circuit_lookup(vty); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[level_for_arg(argv[3]->text)] = (uint16_t)interval; + + return CMD_SUCCESS; +} + +DEFUN (no_psnp_interval_level, + no_psnp_interval_level_cmd, + "no isis psnp-interval [(1-120)] <level-1|level-2>", + NO_STR + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + struct isis_circuit *circuit = isis_circuit_lookup(vty); + int level = level_for_arg(argv[argc - 1]->text); + if (!circuit) + return CMD_ERR_NO_MATCH; + + circuit->psnp_interval[level] = DEFAULT_PSNP_INTERVAL; + + return CMD_SUCCESS; +} + +static int validate_metric_style_narrow(struct vty *vty, struct isis_area *area) +{ + struct isis_circuit *circuit; + struct listnode *node; + + if (!vty) + return CMD_WARNING_CONFIG_FAILED; + + if (!area) { + vty_out(vty, "ISIS area is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + if ((area->is_type & IS_LEVEL_1) + && (circuit->is_type & IS_LEVEL_1) + && (circuit->te_metric[0] > MAX_NARROW_LINK_METRIC)) { + vty_out(vty, "ISIS circuit %s metric is invalid\n", + circuit->interface->name); + return CMD_WARNING_CONFIG_FAILED; + } + if ((area->is_type & IS_LEVEL_2) + && (circuit->is_type & IS_LEVEL_2) + && (circuit->te_metric[1] > MAX_NARROW_LINK_METRIC)) { + vty_out(vty, "ISIS circuit %s metric is invalid\n", + circuit->interface->name); + return CMD_WARNING_CONFIG_FAILED; + } + } + + return CMD_SUCCESS; +} + +DEFUN (metric_style, + metric_style_cmd, + "metric-style <narrow|transition|wide>", + "Use old-style (ISO 10589) or new-style packet formats\n" + "Use old style of TLVs with narrow metric\n" + "Send and accept both styles of TLVs during transition\n" + "Use new style of TLVs to carry wider metric\n") +{ + int idx_metric_style = 1; + VTY_DECLVAR_CONTEXT(isis_area, area); + int ret; + + if (strncmp(argv[idx_metric_style]->arg, "w", 1) == 0) { + isis_area_metricstyle_set(area, false, true); + return CMD_SUCCESS; + } + + if (area_is_mt(area)) { + vty_out(vty, + "Narrow metrics cannot be used while multi topology IS-IS is active\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = validate_metric_style_narrow(vty, area); + if (ret != CMD_SUCCESS) + return ret; + + if (strncmp(argv[idx_metric_style]->arg, "t", 1) == 0) + isis_area_metricstyle_set(area, true, true); + else if (strncmp(argv[idx_metric_style]->arg, "n", 1) == 0) + isis_area_metricstyle_set(area, true, false); + return CMD_SUCCESS; + + return CMD_SUCCESS; +} + +DEFUN (no_metric_style, + no_metric_style_cmd, + "no metric-style", + NO_STR + "Use old-style (ISO 10589) or new-style packet formats\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int ret; + + if (area_is_mt(area)) { + vty_out(vty, + "Narrow metrics cannot be used while multi topology IS-IS is active\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = validate_metric_style_narrow(vty, area); + if (ret != CMD_SUCCESS) + return ret; + + isis_area_metricstyle_set(area, true, false); + return CMD_SUCCESS; +} + +DEFUN (set_attached_bit, + set_attached_bit_cmd, + "set-attached-bit", + "Set attached bit to identify as L1/L2 router for inter-area traffic\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_attached_bit_set(area, true); + return CMD_SUCCESS; +} + +DEFUN (no_set_attached_bit, + no_set_attached_bit_cmd, + "no set-attached-bit", + NO_STR + "Reset attached bit\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_attached_bit_set(area, false); + return CMD_SUCCESS; +} + +DEFUN (dynamic_hostname, + dynamic_hostname_cmd, + "hostname dynamic", + "Dynamic hostname for IS-IS\n" + "Dynamic hostname\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_dynhostname_set(area, true); + return CMD_SUCCESS; +} + +DEFUN (no_dynamic_hostname, + no_dynamic_hostname_cmd, + "no hostname dynamic", + NO_STR + "Dynamic hostname for IS-IS\n" + "Dynamic hostname\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + isis_area_dynhostname_set(area, false); + return CMD_SUCCESS; +} + +DEFUN (is_type, + is_type_cmd, + "is-type <level-1|level-1-2|level-2-only>", + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + int idx_level = 1; + VTY_DECLVAR_CONTEXT(isis_area, area); + int type; + + type = string2circuit_t(argv[idx_level]->arg); + if (!type) { + vty_out(vty, "Unknown IS level \n"); + return CMD_SUCCESS; + } + + isis_area_is_type_set(area, type); + + return CMD_SUCCESS; +} + +DEFUN (no_is_type, + no_is_type_cmd, + "no is-type <level-1|level-1-2|level-2-only>", + NO_STR + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int type; + + /* + * Put the is-type back to defaults: + * - level-1-2 on first area + * - level-1 for the rest + */ + if (listgetdata(listhead(isis->area_list)) == area) + type = IS_LEVEL_1_AND_2; + else + type = IS_LEVEL_1; + + isis_area_is_type_set(area, type); + + return CMD_SUCCESS; +} + +DEFUN (lsp_gen_interval_level, + lsp_gen_interval_level_cmd, + "lsp-gen-interval <level-1|level-2> (1-120)", + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + uint16_t interval = atoi(argv[2]->arg); + + return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[1]->text), + interval); +} + +DEFUN (no_lsp_gen_interval_level, + no_lsp_gen_interval_level_cmd, + "no lsp-gen-interval <level-1|level-2> [(1-120)]", + NO_STR + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_vty_lsp_gen_interval_set(vty, level_for_arg(argv[2]->text), + DEFAULT_MIN_LSP_GEN_INTERVAL); +} + +DEFUN (max_lsp_lifetime_level, + max_lsp_lifetime_level_cmd, + "max-lsp-lifetime <level-1|level-2> (350-65535)", + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + uint16_t lifetime = atoi(argv[2]->arg); + + return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text), + lifetime); +} + +DEFUN (no_max_lsp_lifetime_level, + no_max_lsp_lifetime_level_cmd, + "no max-lsp-lifetime <level-1|level-2> [(350-65535)]", + NO_STR + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + return isis_vty_max_lsp_lifetime_set(vty, level_for_arg(argv[1]->text), + DEFAULT_LSP_LIFETIME); +} + +DEFUN (spf_interval_level, + spf_interval_level_cmd, + "spf-interval <level-1|level-2> (1-120)", + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + uint16_t interval = atoi(argv[2]->arg); + + area->min_spf_interval[level_for_arg(argv[1]->text)] = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_spf_interval_level, + no_spf_interval_level_cmd, + "no spf-interval <level-1|level-2> [(1-120)]", + NO_STR + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + int level = level_for_arg(argv[1]->text); + + area->min_spf_interval[level] = MINIMUM_SPF_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (lsp_refresh_interval_level, + lsp_refresh_interval_level_cmd, + "lsp-refresh-interval <level-1|level-2> (1-65235)", + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + uint16_t interval = atoi(argv[2]->arg); + return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[1]->text), + interval); +} + +DEFUN (no_lsp_refresh_interval_level, + no_lsp_refresh_interval_level_cmd, + "no lsp-refresh-interval <level-1|level-2> [(1-65235)]", + NO_STR + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + return isis_vty_lsp_refresh_set(vty, level_for_arg(argv[2]->text), + DEFAULT_MAX_LSP_GEN_INTERVAL); +} + +DEFUN (area_passwd, + area_passwd_cmd, + "area-password <clear|md5> WORD [authenticate snp <send-only|validate>]", + "Configure the authentication password for an area\n" + "Authentication type\n" + "Authentication type\n" + "Area password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + return isis_vty_password_set(vty, argc, argv, IS_LEVEL_1); +} + +DEFUN (no_area_passwd, + no_area_passwd_cmd, + "no area-password", + NO_STR + "Configure the authentication password for an area\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + return isis_area_passwd_unset(area, IS_LEVEL_1); +} + +void isis_vty_daemon_init(void) +{ + install_element(INTERFACE_NODE, &isis_circuit_type_cmd); + install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); + + install_element(INTERFACE_NODE, &isis_network_cmd); + install_element(INTERFACE_NODE, &no_isis_network_cmd); + + install_element(INTERFACE_NODE, &isis_priority_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_cmd); + install_element(INTERFACE_NODE, &isis_priority_level_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_level_cmd); + + install_element(INTERFACE_NODE, &isis_metric_level_cmd); + install_element(INTERFACE_NODE, &no_isis_metric_level_cmd); + + install_element(INTERFACE_NODE, &isis_hello_interval_level_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_interval_level_cmd); + + install_element(INTERFACE_NODE, &isis_hello_multiplier_level_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_multiplier_level_cmd); + + install_element(INTERFACE_NODE, &isis_threeway_adj_cmd); + + install_element(INTERFACE_NODE, &isis_hello_padding_cmd); + install_element(INTERFACE_NODE, &no_isis_hello_padding_cmd); + + install_element(INTERFACE_NODE, &csnp_interval_level_cmd); + install_element(INTERFACE_NODE, &no_csnp_interval_level_cmd); + + install_element(INTERFACE_NODE, &psnp_interval_level_cmd); + install_element(INTERFACE_NODE, &no_psnp_interval_level_cmd); + + install_element(ROUTER_NODE, &metric_style_cmd); + install_element(ROUTER_NODE, &no_metric_style_cmd); + + install_element(ROUTER_NODE, &set_attached_bit_cmd); + install_element(ROUTER_NODE, &no_set_attached_bit_cmd); + + install_element(ROUTER_NODE, &dynamic_hostname_cmd); + install_element(ROUTER_NODE, &no_dynamic_hostname_cmd); + + install_element(ROUTER_NODE, &is_type_cmd); + install_element(ROUTER_NODE, &no_is_type_cmd); + + install_element(ROUTER_NODE, &lsp_gen_interval_level_cmd); + install_element(ROUTER_NODE, &no_lsp_gen_interval_level_cmd); + + install_element(ROUTER_NODE, &max_lsp_lifetime_level_cmd); + install_element(ROUTER_NODE, &no_max_lsp_lifetime_level_cmd); + + install_element(ROUTER_NODE, &spf_interval_level_cmd); + install_element(ROUTER_NODE, &no_spf_interval_level_cmd); + + install_element(ROUTER_NODE, &lsp_refresh_interval_level_cmd); + install_element(ROUTER_NODE, &no_lsp_refresh_interval_level_cmd); + + install_element(ROUTER_NODE, &area_passwd_cmd); + install_element(ROUTER_NODE, &no_area_passwd_cmd); +} diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 9bc0f2ef3..33d8a0f77 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -261,8 +261,10 @@ static void isis_zebra_route_add_route(struct prefix *prefix, return; memset(&api, 0, sizeof(api)); + if (fabricd) + api.flags |= ZEBRA_FLAG_ONLINK; api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; + api.type = PROTO_TYPE; api.safi = SAFI_UNICAST; api.prefix = *prefix; if (src_p && src_p->prefixlen) { @@ -337,7 +339,7 @@ static void isis_zebra_route_del_route(struct prefix *prefix, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_ISIS; + api.type = PROTO_TYPE; api.safi = SAFI_UNICAST; api.prefix = *prefix; if (src_p && src_p->prefixlen) { @@ -378,7 +380,7 @@ static int isis_zebra_read(int command, struct zclient *zclient, */ if (api.prefix.prefixlen == 0 && api.src_prefix.prefixlen == 0 - && api.type == ZEBRA_ROUTE_ISIS) { + && api.type == PROTO_TYPE) { command = ZEBRA_REDISTRIBUTE_ROUTE_DEL; } @@ -424,7 +426,7 @@ static void isis_zebra_connected(struct zclient *zclient) void isis_zebra_init(struct thread_master *master) { zclient = zclient_new_notify(master, &zclient_options_default); - zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0, &isisd_privs); + zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs); zclient->zebra_connected = isis_zebra_connected; zclient->router_id_update = isis_router_id_update_zebra; zclient->interface_add = isis_zebra_if_add; diff --git a/isisd/isisd.c b/isisd/isisd.c index a19f28745..e3ff3b8d9 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -56,6 +56,7 @@ #include "isisd/isis_events.h" #include "isisd/isis_te.h" #include "isisd/isis_mt.h" +#include "isisd/fabricd.h" struct isis *isis = NULL; @@ -95,6 +96,7 @@ void isis_new(unsigned long process_id) */ /* isis->debugs = 0xFFFF; */ isisMplsTE.status = disable; /* Only support TE metric */ + QOBJ_REG(isis, isis); } @@ -105,10 +107,13 @@ struct isis_area *isis_area_create(const char *area_tag) area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area)); /* - * The first instance is level-1-2 rest are level-1, unless otherwise - * configured + * Fabricd runs only as level-2. + * For IS-IS, the first instance is level-1-2 rest are level-1, + * unless otherwise configured */ - if (listcount(isis->area_list) > 0) + if (fabricd) { + area->is_type = IS_LEVEL_2; + } else if (listcount(isis->area_list) > 0) area->is_type = IS_LEVEL_1; else area->is_type = IS_LEVEL_1_AND_2; @@ -153,6 +158,8 @@ struct isis_area *isis_area_create(const char *area_tag) listnode_add(isis->area_list, area); area->isis = isis; + if (fabricd) + area->fabricd = fabricd_new(area); QOBJ_REG(area, isis_area); return area; @@ -179,7 +186,7 @@ int isis_area_get(struct vty *vty, const char *area_tag) area = isis_area_lookup(area_tag); if (area) { - VTY_PUSH_CONTEXT(ISIS_NODE, area); + VTY_PUSH_CONTEXT(ROUTER_NODE, area); return CMD_SUCCESS; } @@ -188,7 +195,7 @@ int isis_area_get(struct vty *vty, const char *area_tag) if (isis->debugs & DEBUG_EVENTS) zlog_debug("New IS-IS area instance %s", area->area_tag); - VTY_PUSH_CONTEXT(ISIS_NODE, area); + VTY_PUSH_CONTEXT(ROUTER_NODE, area); return CMD_SUCCESS; } @@ -209,6 +216,9 @@ int isis_area_destroy(struct vty *vty, const char *area_tag) QOBJ_UNREG(area); + if (fabricd) + fabricd_finish(area->fabricd); + if (area->circuit_list) { for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode, circuit)) { @@ -463,9 +473,9 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail) DEFUN (show_isis_interface, show_isis_interface_cmd, - "show isis interface", + "show " PROTO_NAME " interface", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS interface\n") { return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF); @@ -473,9 +483,9 @@ DEFUN (show_isis_interface, DEFUN (show_isis_interface_detail, show_isis_interface_detail_cmd, - "show isis interface detail", + "show " PROTO_NAME " interface detail", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS interface\n" "show detailed information\n") { @@ -484,9 +494,9 @@ DEFUN (show_isis_interface_detail, DEFUN (show_isis_interface_arg, show_isis_interface_arg_cmd, - "show isis interface WORD", + "show " PROTO_NAME " interface WORD", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS interface\n" "ISIS interface name\n") { @@ -634,9 +644,9 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id) DEFUN (show_isis_neighbor, show_isis_neighbor_cmd, - "show isis neighbor", + "show " PROTO_NAME " neighbor", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n") { return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF); @@ -644,9 +654,9 @@ DEFUN (show_isis_neighbor, DEFUN (show_isis_neighbor_detail, show_isis_neighbor_detail_cmd, - "show isis neighbor detail", + "show " PROTO_NAME " neighbor detail", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n" "show detailed information\n") { @@ -655,9 +665,9 @@ DEFUN (show_isis_neighbor_detail, DEFUN (show_isis_neighbor_arg, show_isis_neighbor_arg_cmd, - "show isis neighbor WORD", + "show " PROTO_NAME " neighbor WORD", SHOW_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n" "System id\n") { @@ -668,19 +678,19 @@ DEFUN (show_isis_neighbor_arg, DEFUN (clear_isis_neighbor, clear_isis_neighbor_cmd, - "clear isis neighbor", + "clear " PROTO_NAME " neighbor", CLEAR_STR - "Reset ISIS network information\n" - "Reset ISIS neighbor adjacencies\n") + PROTO_HELP + "ISIS neighbor adjacencies\n") { return clear_isis_neighbor_common(vty, NULL); } DEFUN (clear_isis_neighbor_arg, clear_isis_neighbor_arg_cmd, - "clear isis neighbor WORD", + "clear " PROTO_NAME " neighbor WORD", CLEAR_STR - "ISIS network information\n" + PROTO_HELP "ISIS neighbor adjacencies\n" "System id\n") { @@ -734,16 +744,18 @@ void print_debug(struct vty *vty, int flags, int onoff) vty_out(vty, "IS-IS LSP generation debugging is %s\n", onoffs); if (flags & DEBUG_LSP_SCHED) vty_out(vty, "IS-IS LSP scheduling debugging is %s\n", onoffs); + if (flags & DEBUG_FABRICD_FLOODING) + vty_out(vty, "OpenFabric Flooding debugging is %s\n", onoffs); } DEFUN_NOSH (show_debugging, show_debugging_isis_cmd, - "show debugging [isis]", + "show debugging [" PROTO_NAME "]", SHOW_STR "State of each debugging option\n" - ISIS_STR) + PROTO_HELP) { - vty_out(vty, "IS-IS debugging status:\n"); + vty_out(vty, PROTO_NAME " debugging status:\n"); if (isis->debugs) print_debug(vty, isis->debugs, 1); @@ -760,59 +772,63 @@ static int config_write_debug(struct vty *vty) int flags = isis->debugs; if (flags & DEBUG_ADJ_PACKETS) { - vty_out(vty, "debug isis adj-packets\n"); + vty_out(vty, "debug " PROTO_NAME " adj-packets\n"); write++; } if (flags & DEBUG_CHECKSUM_ERRORS) { - vty_out(vty, "debug isis checksum-errors\n"); + vty_out(vty, "debug " PROTO_NAME " checksum-errors\n"); write++; } if (flags & DEBUG_LOCAL_UPDATES) { - vty_out(vty, "debug isis local-updates\n"); + vty_out(vty, "debug " PROTO_NAME " local-updates\n"); write++; } if (flags & DEBUG_PROTOCOL_ERRORS) { - vty_out(vty, "debug isis protocol-errors\n"); + vty_out(vty, "debug " PROTO_NAME " protocol-errors\n"); write++; } if (flags & DEBUG_SNP_PACKETS) { - vty_out(vty, "debug isis snp-packets\n"); + vty_out(vty, "debug " PROTO_NAME " snp-packets\n"); write++; } if (flags & DEBUG_SPF_EVENTS) { - vty_out(vty, "debug isis spf-events\n"); + vty_out(vty, "debug " PROTO_NAME " spf-events\n"); write++; } if (flags & DEBUG_SPF_STATS) { - vty_out(vty, "debug isis spf-statistics\n"); + vty_out(vty, "debug " PROTO_NAME " spf-statistics\n"); write++; } if (flags & DEBUG_SPF_TRIGGERS) { - vty_out(vty, "debug isis spf-triggers\n"); + vty_out(vty, "debug " PROTO_NAME " spf-triggers\n"); write++; } if (flags & DEBUG_UPDATE_PACKETS) { - vty_out(vty, "debug isis update-packets\n"); + vty_out(vty, "debug " PROTO_NAME " update-packets\n"); write++; } if (flags & DEBUG_RTE_EVENTS) { - vty_out(vty, "debug isis route-events\n"); + vty_out(vty, "debug " PROTO_NAME " route-events\n"); write++; } if (flags & DEBUG_EVENTS) { - vty_out(vty, "debug isis events\n"); + vty_out(vty, "debug " PROTO_NAME " events\n"); write++; } if (flags & DEBUG_PACKET_DUMP) { - vty_out(vty, "debug isis packet-dump\n"); + vty_out(vty, "debug " PROTO_NAME " packet-dump\n"); write++; } if (flags & DEBUG_LSP_GEN) { - vty_out(vty, "debug isis lsp-gen\n"); + vty_out(vty, "debug " PROTO_NAME " lsp-gen\n"); write++; } if (flags & DEBUG_LSP_SCHED) { - vty_out(vty, "debug isis lsp-sched\n"); + vty_out(vty, "debug " PROTO_NAME " lsp-sched\n"); + write++; + } + if (flags & DEBUG_FABRICD_FLOODING) { + vty_out(vty, "debug " PROTO_NAME " flooding\n"); write++; } write += spf_backoff_write_config(vty); @@ -822,9 +838,9 @@ static int config_write_debug(struct vty *vty) DEFUN (debug_isis_adj, debug_isis_adj_cmd, - "debug isis adj-packets", + "debug " PROTO_NAME " adj-packets", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Adjacency related packets\n") { isis->debugs |= DEBUG_ADJ_PACKETS; @@ -835,10 +851,10 @@ DEFUN (debug_isis_adj, DEFUN (no_debug_isis_adj, no_debug_isis_adj_cmd, - "no debug isis adj-packets", + "no debug " PROTO_NAME " adj-packets", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Adjacency related packets\n") { isis->debugs &= ~DEBUG_ADJ_PACKETS; @@ -849,9 +865,9 @@ DEFUN (no_debug_isis_adj, DEFUN (debug_isis_csum, debug_isis_csum_cmd, - "debug isis checksum-errors", + "debug " PROTO_NAME " checksum-errors", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP checksum errors\n") { isis->debugs |= DEBUG_CHECKSUM_ERRORS; @@ -862,10 +878,10 @@ DEFUN (debug_isis_csum, DEFUN (no_debug_isis_csum, no_debug_isis_csum_cmd, - "no debug isis checksum-errors", + "no debug " PROTO_NAME " checksum-errors", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP checksum errors\n") { isis->debugs &= ~DEBUG_CHECKSUM_ERRORS; @@ -876,9 +892,9 @@ DEFUN (no_debug_isis_csum, DEFUN (debug_isis_lupd, debug_isis_lupd_cmd, - "debug isis local-updates", + "debug " PROTO_NAME " local-updates", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS local update packets\n") { isis->debugs |= DEBUG_LOCAL_UPDATES; @@ -889,10 +905,10 @@ DEFUN (debug_isis_lupd, DEFUN (no_debug_isis_lupd, no_debug_isis_lupd_cmd, - "no debug isis local-updates", + "no debug " PROTO_NAME " local-updates", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS local update packets\n") { isis->debugs &= ~DEBUG_LOCAL_UPDATES; @@ -903,9 +919,9 @@ DEFUN (no_debug_isis_lupd, DEFUN (debug_isis_err, debug_isis_err_cmd, - "debug isis protocol-errors", + "debug " PROTO_NAME " protocol-errors", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP protocol errors\n") { isis->debugs |= DEBUG_PROTOCOL_ERRORS; @@ -916,10 +932,10 @@ DEFUN (debug_isis_err, DEFUN (no_debug_isis_err, no_debug_isis_err_cmd, - "no debug isis protocol-errors", + "no debug " PROTO_NAME " protocol-errors", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS LSP protocol errors\n") { isis->debugs &= ~DEBUG_PROTOCOL_ERRORS; @@ -930,9 +946,9 @@ DEFUN (no_debug_isis_err, DEFUN (debug_isis_snp, debug_isis_snp_cmd, - "debug isis snp-packets", + "debug " PROTO_NAME " snp-packets", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS CSNP/PSNP packets\n") { isis->debugs |= DEBUG_SNP_PACKETS; @@ -943,10 +959,10 @@ DEFUN (debug_isis_snp, DEFUN (no_debug_isis_snp, no_debug_isis_snp_cmd, - "no debug isis snp-packets", + "no debug " PROTO_NAME " snp-packets", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS CSNP/PSNP packets\n") { isis->debugs &= ~DEBUG_SNP_PACKETS; @@ -957,9 +973,9 @@ DEFUN (no_debug_isis_snp, DEFUN (debug_isis_upd, debug_isis_upd_cmd, - "debug isis update-packets", + "debug " PROTO_NAME " update-packets", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Update related packets\n") { isis->debugs |= DEBUG_UPDATE_PACKETS; @@ -970,10 +986,10 @@ DEFUN (debug_isis_upd, DEFUN (no_debug_isis_upd, no_debug_isis_upd_cmd, - "no debug isis update-packets", + "no debug " PROTO_NAME " update-packets", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Update related packets\n") { isis->debugs &= ~DEBUG_UPDATE_PACKETS; @@ -984,9 +1000,9 @@ DEFUN (no_debug_isis_upd, DEFUN (debug_isis_spfevents, debug_isis_spfevents_cmd, - "debug isis spf-events", + "debug " PROTO_NAME " spf-events", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Shortest Path First Events\n") { isis->debugs |= DEBUG_SPF_EVENTS; @@ -997,10 +1013,10 @@ DEFUN (debug_isis_spfevents, DEFUN (no_debug_isis_spfevents, no_debug_isis_spfevents_cmd, - "no debug isis spf-events", + "no debug " PROTO_NAME " spf-events", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Shortest Path First Events\n") { isis->debugs &= ~DEBUG_SPF_EVENTS; @@ -1011,9 +1027,9 @@ DEFUN (no_debug_isis_spfevents, DEFUN (debug_isis_spfstats, debug_isis_spfstats_cmd, - "debug isis spf-statistics ", + "debug " PROTO_NAME " spf-statistics ", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF Timing and Statistic Data\n") { isis->debugs |= DEBUG_SPF_STATS; @@ -1024,10 +1040,10 @@ DEFUN (debug_isis_spfstats, DEFUN (no_debug_isis_spfstats, no_debug_isis_spfstats_cmd, - "no debug isis spf-statistics", + "no debug " PROTO_NAME " spf-statistics", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF Timing and Statistic Data\n") { isis->debugs &= ~DEBUG_SPF_STATS; @@ -1038,9 +1054,9 @@ DEFUN (no_debug_isis_spfstats, DEFUN (debug_isis_spftrigg, debug_isis_spftrigg_cmd, - "debug isis spf-triggers", + "debug " PROTO_NAME " spf-triggers", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF triggering events\n") { isis->debugs |= DEBUG_SPF_TRIGGERS; @@ -1051,10 +1067,10 @@ DEFUN (debug_isis_spftrigg, DEFUN (no_debug_isis_spftrigg, no_debug_isis_spftrigg_cmd, - "no debug isis spf-triggers", + "no debug " PROTO_NAME " spf-triggers", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS SPF triggering events\n") { isis->debugs &= ~DEBUG_SPF_TRIGGERS; @@ -1065,9 +1081,9 @@ DEFUN (no_debug_isis_spftrigg, DEFUN (debug_isis_rtevents, debug_isis_rtevents_cmd, - "debug isis route-events", + "debug " PROTO_NAME " route-events", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Route related events\n") { isis->debugs |= DEBUG_RTE_EVENTS; @@ -1078,10 +1094,10 @@ DEFUN (debug_isis_rtevents, DEFUN (no_debug_isis_rtevents, no_debug_isis_rtevents_cmd, - "no debug isis route-events", + "no debug " PROTO_NAME " route-events", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Route related events\n") { isis->debugs &= ~DEBUG_RTE_EVENTS; @@ -1092,9 +1108,9 @@ DEFUN (no_debug_isis_rtevents, DEFUN (debug_isis_events, debug_isis_events_cmd, - "debug isis events", + "debug " PROTO_NAME " events", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Events\n") { isis->debugs |= DEBUG_EVENTS; @@ -1105,10 +1121,10 @@ DEFUN (debug_isis_events, DEFUN (no_debug_isis_events, no_debug_isis_events_cmd, - "no debug isis events", + "no debug " PROTO_NAME " events", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Events\n") { isis->debugs &= ~DEBUG_EVENTS; @@ -1119,9 +1135,9 @@ DEFUN (no_debug_isis_events, DEFUN (debug_isis_packet_dump, debug_isis_packet_dump_cmd, - "debug isis packet-dump", + "debug " PROTO_NAME " packet-dump", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS packet dump\n") { isis->debugs |= DEBUG_PACKET_DUMP; @@ -1132,10 +1148,10 @@ DEFUN (debug_isis_packet_dump, DEFUN (no_debug_isis_packet_dump, no_debug_isis_packet_dump_cmd, - "no debug isis packet-dump", + "no debug " PROTO_NAME " packet-dump", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS packet dump\n") { isis->debugs &= ~DEBUG_PACKET_DUMP; @@ -1146,9 +1162,9 @@ DEFUN (no_debug_isis_packet_dump, DEFUN (debug_isis_lsp_gen, debug_isis_lsp_gen_cmd, - "debug isis lsp-gen", + "debug " PROTO_NAME " lsp-gen", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS generation of own LSPs\n") { isis->debugs |= DEBUG_LSP_GEN; @@ -1159,10 +1175,10 @@ DEFUN (debug_isis_lsp_gen, DEFUN (no_debug_isis_lsp_gen, no_debug_isis_lsp_gen_cmd, - "no debug isis lsp-gen", + "no debug " PROTO_NAME " lsp-gen", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS generation of own LSPs\n") { isis->debugs &= ~DEBUG_LSP_GEN; @@ -1173,9 +1189,9 @@ DEFUN (no_debug_isis_lsp_gen, DEFUN (debug_isis_lsp_sched, debug_isis_lsp_sched_cmd, - "debug isis lsp-sched", + "debug " PROTO_NAME " lsp-sched", DEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS scheduling of LSP generation\n") { isis->debugs |= DEBUG_LSP_SCHED; @@ -1186,10 +1202,10 @@ DEFUN (debug_isis_lsp_sched, DEFUN (no_debug_isis_lsp_sched, no_debug_isis_lsp_sched_cmd, - "no debug isis lsp-sched", + "no debug " PROTO_NAME " lsp-sched", NO_STR UNDEBUG_STR - "IS-IS information\n" + PROTO_HELP "IS-IS scheduling of LSP generation\n") { isis->debugs &= ~DEBUG_LSP_SCHED; @@ -1200,9 +1216,9 @@ DEFUN (no_debug_isis_lsp_sched, DEFUN (show_hostname, show_hostname_cmd, - "show isis hostname", + "show " PROTO_NAME " hostname", SHOW_STR - "IS-IS information\n" + PROTO_HELP "IS-IS Dynamic hostname mapping\n") { dynhn_print_all(vty); @@ -1212,10 +1228,10 @@ DEFUN (show_hostname, DEFUN (show_isis_spf_ietf, show_isis_spf_ietf_cmd, - "show isis spf-delay-ietf", + "show " PROTO_NAME " spf-delay-ietf", SHOW_STR - "IS-IS information\n" - "IS-IS SPF delay IETF information\n") + PROTO_HELP + "SPF delay IETF information\n") { if (!isis) { vty_out(vty, "ISIS is not running\n"); @@ -1261,15 +1277,15 @@ DEFUN (show_isis_spf_ietf, DEFUN (show_isis_summary, show_isis_summary_cmd, - "show isis summary", - SHOW_STR "IS-IS information\n" "IS-IS summary\n") + "show " PROTO_NAME " summary", + SHOW_STR PROTO_HELP "summary\n") { struct listnode *node, *node2; struct isis_area *area; int level; if (isis == NULL) { - vty_out(vty, "ISIS is not running\n"); + vty_out(vty, PROTO_NAME " is not running\n"); return CMD_SUCCESS; } @@ -1289,6 +1305,14 @@ DEFUN (show_isis_summary, vty_out(vty, "Area %s:\n", area->area_tag ? area->area_tag : "null"); + if (fabricd) { + uint8_t tier = fabricd_tier(area); + if (tier == ISIS_TIER_UNDEFINED) + vty_out(vty, " Tier: undefined\n"); + else + vty_out(vty, " Tier: %" PRIu8 "\n", tier); + } + if (listcount(area->area_addrs) > 0) { struct area_addr *area_addr; for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2, @@ -1471,10 +1495,10 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level) DEFUN (show_database, show_database_cmd, - "show isis database [detail] [WORD]", + "show " PROTO_NAME " database [detail] [WORD]", SHOW_STR - "IS-IS information\n" - "IS-IS link state database\n" + PROTO_HELP + "Link state database\n" "Detailed information\n" "LSP ID\n") { @@ -1491,9 +1515,9 @@ DEFUN (show_database, */ DEFUN_NOSH (router_isis, router_isis_cmd, - "router isis WORD", + "router " PROTO_NAME " WORD", ROUTER_STR - "ISO IS-IS\n" + PROTO_HELP "ISO Routing area tag\n") { int idx_word = 2; @@ -1505,8 +1529,11 @@ DEFUN_NOSH (router_isis, */ DEFUN (no_router_isis, no_router_isis_cmd, - "no router isis WORD", - "no\n" ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag\n") + "no router " PROTO_NAME " WORD", + NO_STR + ROUTER_STR + PROTO_HELP + "ISO Routing area tag\n") { int idx_word = 3; return isis_area_destroy(vty, argv[idx_word]->arg); @@ -1869,7 +1896,7 @@ int isis_config_write(struct vty *vty) for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { /* ISIS - Area name */ - vty_out(vty, "router isis %s\n", area->area_tag); + vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag); write++; /* ISIS - Net */ if (listcount(area->area_addrs) > 0) { @@ -1893,16 +1920,18 @@ int isis_config_write(struct vty *vty) write++; } /* ISIS - Metric-Style - when true displays wide */ - if (area->newmetric) { - if (!area->oldmetric) - vty_out(vty, " metric-style wide\n"); - else - vty_out(vty, - " metric-style transition\n"); - write++; - } else { - vty_out(vty, " metric-style narrow\n"); - write++; + if (!fabricd) { + if (area->newmetric) { + if (!area->oldmetric) + vty_out(vty, " metric-style wide\n"); + else + vty_out(vty, + " metric-style transition\n"); + write++; + } else { + vty_out(vty, " metric-style narrow\n"); + write++; + } } /* ISIS - overload-bit */ if (area->overload_bit) { @@ -1910,12 +1939,14 @@ int isis_config_write(struct vty *vty) write++; } /* ISIS - Area is-type (level-1-2 is default) */ - if (area->is_type == IS_LEVEL_1) { - vty_out(vty, " is-type level-1\n"); - write++; - } else if (area->is_type == IS_LEVEL_2) { - vty_out(vty, " is-type level-2-only\n"); - write++; + if (!fabricd) { + if (area->is_type == IS_LEVEL_1) { + vty_out(vty, " is-type level-1\n"); + write++; + } else if (area->is_type == IS_LEVEL_2) { + vty_out(vty, " is-type level-2-only\n"); + write++; + } } write += isis_redist_config_write(vty, area, AF_INET); write += isis_redist_config_write(vty, area, AF_INET6); @@ -1998,6 +2029,10 @@ int isis_config_write(struct vty *vty) vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu); write++; } + if (area->purge_originator) { + vty_out(vty, " purge-originator\n"); + write++; + } /* Minimum SPF interval. */ if (area->min_spf_interval[0] @@ -2116,6 +2151,7 @@ int isis_config_write(struct vty *vty) } write += area_write_mt_settings(area, vty); + write += fabricd_write_settings(area, vty); } isis_mpls_te_config_write_router(vty); } @@ -2123,12 +2159,12 @@ int isis_config_write(struct vty *vty) return write; } -struct cmd_node isis_node = {ISIS_NODE, "%s(config-router)# ", 1}; +struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1}; void isis_init() { /* Install IS-IS top node */ - install_node(&isis_node, isis_config_write); + install_node(&router_node, isis_config_write); install_element(VIEW_NODE, &show_isis_summary_cmd); @@ -2212,16 +2248,16 @@ void isis_init() install_element(CONFIG_NODE, &router_isis_cmd); install_element(CONFIG_NODE, &no_router_isis_cmd); - install_default(ISIS_NODE); + install_default(ROUTER_NODE); - install_element(ISIS_NODE, &net_cmd); - install_element(ISIS_NODE, &no_net_cmd); + install_element(ROUTER_NODE, &net_cmd); + install_element(ROUTER_NODE, &no_net_cmd); - install_element(ISIS_NODE, &isis_topology_cmd); - install_element(ISIS_NODE, &no_isis_topology_cmd); + install_element(ROUTER_NODE, &isis_topology_cmd); + install_element(ROUTER_NODE, &no_isis_topology_cmd); - install_element(ISIS_NODE, &log_adj_changes_cmd); - install_element(ISIS_NODE, &no_log_adj_changes_cmd); + install_element(ROUTER_NODE, &log_adj_changes_cmd); + install_element(ROUTER_NODE, &no_log_adj_changes_cmd); spf_backoff_cmd_init(); } diff --git a/isisd/isisd.h b/isisd/isisd.h index ce602e440..864021428 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -33,12 +33,32 @@ #include "isis_memory.h" #include "qobj.h" +#ifdef FABRICD +static const bool fabricd = true; +#define PROTO_TYPE ZEBRA_ROUTE_OPENFABRIC +#define PROTO_NAME "openfabric" +#define PROTO_HELP "OpenFabric routing protocol\n" +#define PROTO_REDIST_STR FRR_REDIST_STR_FABRICD +#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_FABRICD +#define ROUTER_NODE OPENFABRIC_NODE +#else +static const bool fabricd = false; +#define PROTO_TYPE ZEBRA_ROUTE_ISIS +#define PROTO_NAME "isis" +#define PROTO_HELP "IS-IS routing protocol\n" +#define PROTO_REDIST_STR FRR_REDIST_STR_ISISD +#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_ISISD +#define ROUTER_NODE ISIS_NODE +#endif + extern struct zebra_privs_t isisd_privs; /* uncomment if you are a developer in bug hunt */ /* #define EXTREME_DEBUG */ /* #define EXTREME_DICT_DEBUG */ +struct fabricd; + struct isis { unsigned long process_id; int sysid_set; @@ -93,6 +113,8 @@ struct isis_area { */ int lsp_regenerate_pending[ISIS_LEVELS]; + struct fabricd *fabricd; + /* * Configurables */ @@ -126,6 +148,7 @@ struct isis_area { /* multi topology settings */ struct list *mt_settings; int ipv6_circuits; + bool purge_originator; /* Counters */ uint32_t circuit_state_changes; struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT] @@ -168,7 +191,6 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level, const char *passwd, uint8_t snp_auth); int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level, const char *passwd, uint8_t snp_auth); -void isis_vty_init(void); /* Master of threads. */ extern struct thread_master *master; @@ -188,6 +210,7 @@ extern struct thread_master *master; #define DEBUG_PACKET_DUMP (1<<12) #define DEBUG_LSP_GEN (1<<13) #define DEBUG_LSP_SCHED (1<<14) +#define DEBUG_FABRICD_FLOODING (1<<15) #define lsp_debug(...) \ do { \ diff --git a/isisd/subdir.am b/isisd/subdir.am index 7b8be4616..7571255e5 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -6,35 +6,23 @@ if ISISD noinst_LIBRARIES += isisd/libisis.a sbin_PROGRAMS += isisd/isisd dist_examples_DATA += isisd/isisd.conf.sample +vtysh_scan += \ + $(top_srcdir)/isisd/isis_redist.c \ + $(top_srcdir)/isisd/isis_spf.c \ + $(top_srcdir)/isisd/isis_te.c \ + $(top_srcdir)/isisd/isis_vty_common.c \ + $(top_srcdir)/isisd/isis_vty_fabricd.c \ + $(top_srcdir)/isisd/isis_vty_isisd.c \ + $(top_srcdir)/isisd/isisd.c \ + # end +man8 += $(MANBUILD)/isisd.8 endif -isisd_libisis_a_SOURCES = \ - isisd/dict.c \ - isisd/isis_adjacency.c \ - isisd/isis_circuit.c \ - isisd/isis_csm.c \ - isisd/isis_dr.c \ - isisd/isis_dynhn.c \ - isisd/isis_errors.c \ - isisd/isis_events.c \ - isisd/isis_flags.c \ - isisd/isis_lsp.c \ - isisd/isis_lsp_hash.c \ - isisd/isis_memory.c \ - isisd/isis_misc.c \ - isisd/isis_mt.c \ - isisd/isis_pdu.c \ - isisd/isis_redist.c \ - isisd/isis_route.c \ - isisd/isis_routemap.c \ - isisd/isis_spf.c \ - isisd/isis_te.c \ - isisd/isis_tlvs.c \ - isisd/isis_vty.c \ - isisd/isis_zebra.c \ - isisd/isisd.c \ - isisd/iso_checksum.c \ - # end +if FABRICD +noinst_LIBRARIES += isisd/libfabric.a +sbin_PROGRAMS += isisd/fabricd +dist_examples_DATA += isisd/fabricd.conf.sample +endif noinst_HEADERS += \ isisd/dict.h \ @@ -49,7 +37,6 @@ noinst_HEADERS += \ isisd/isis_events.h \ isisd/isis_flags.h \ isisd/isis_lsp.h \ - isisd/isis_lsp_hash.h \ isisd/isis_memory.h \ isisd/isis_misc.h \ isisd/isis_mt.h \ @@ -59,17 +46,73 @@ noinst_HEADERS += \ isisd/isis_route.h \ isisd/isis_routemap.h \ isisd/isis_spf.h \ + isisd/isis_spf_private.h \ isisd/isis_te.h \ isisd/isis_tlvs.h \ + isisd/isis_tx_queue.h \ + isisd/isis_vty_common.h \ isisd/isis_zebra.h \ isisd/isisd.h \ isisd/iso_checksum.h \ + isisd/fabricd.h \ # end -isisd_isisd_LDADD = isisd/libisis.a lib/libfrr.la @LIBCAP@ -isisd_isisd_SOURCES = \ +LIBISIS_SOURCES = \ + isisd/dict.c \ + isisd/isis_adjacency.c \ + isisd/isis_circuit.c \ + isisd/isis_csm.c \ + isisd/isis_dr.c \ + isisd/isis_dynhn.c \ + isisd/isis_errors.c \ + isisd/isis_events.c \ + isisd/isis_flags.c \ + isisd/isis_lsp.c \ + isisd/isis_memory.c \ + isisd/isis_misc.c \ + isisd/isis_mt.c \ + isisd/isis_pdu.c \ + isisd/isis_redist.c \ + isisd/isis_route.c \ + isisd/isis_routemap.c \ + isisd/isis_spf.c \ + isisd/isis_te.c \ + isisd/isis_tlvs.c \ + isisd/isis_tx_queue.c \ + isisd/isis_vty_common.c \ + isisd/isis_zebra.c \ + isisd/isisd.c \ + isisd/iso_checksum.c \ + isisd/fabricd.c \ + # end + +ISIS_SOURCES = \ isisd/isis_bpf.c \ isisd/isis_dlpi.c \ isisd/isis_main.c \ isisd/isis_pfpacket.c \ # end + +ISIS_LDADD_COMMON = lib/libfrr.la @LIBCAP@ + +# Building isisd + +isisd_libisis_a_SOURCES = \ + $(LIBISIS_SOURCES) \ + isisd/isis_vty_isisd.c \ + #end +isisd_isisd_LDADD = isisd/libisis.a $(ISIS_LDADD_COMMON) +isisd_isisd_SOURCES = $(ISIS_SOURCES) + +# Building fabricd + +FABRICD_CPPFLAGS = -DFABRICD=1 $(AM_CPPFLAGS) + +isisd_libfabric_a_SOURCES = \ + $(LIBISIS_SOURCES) \ + isisd/isis_vty_fabricd.c \ + #end +isisd_libfabric_a_CPPFLAGS = $(FABRICD_CPPFLAGS) +isisd_fabricd_LDADD = isisd/libfabric.a $(ISIS_LDADD_COMMON) +isisd_fabricd_SOURCES = $(ISIS_SOURCES) +isisd_fabricd_CPPFLAGS = $(FABRICD_CPPFLAGS) diff --git a/ldpd/.gitignore b/ldpd/.gitignore index a2f4b5169..ec8a5c408 100644 --- a/ldpd/.gitignore +++ b/ldpd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ldpd ldpd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/ldpd/lde.c b/ldpd/lde.c index 03b62b482..810439888 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -1620,10 +1620,8 @@ lde_address_list_free(struct lde_nbr *ln) { struct lde_addr *lde_addr; - while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) { - TAILQ_REMOVE(&ln->addr_list, lde_addr, entry); + while ((lde_addr = TAILQ_POP_FIRST(&ln->addr_list, entry)) != NULL) free(lde_addr); - } } static void zclient_sync_init(unsigned short instance) diff --git a/ldpd/pfkey.c b/ldpd/pfkey.c index 906737217..a719d0cbb 100644 --- a/ldpd/pfkey.c +++ b/ldpd/pfkey.c @@ -17,6 +17,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __OpenBSD__ #include <sys/types.h> #include <sys/socket.h> diff --git a/ldpd/subdir.am b/ldpd/subdir.am index 2d87be0cd..24e738d62 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -6,6 +6,8 @@ if LDPD noinst_LIBRARIES += ldpd/libldp.a sbin_PROGRAMS += ldpd/ldpd dist_examples_DATA += ldpd/ldpd.conf.sample +vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c +man8 += $(MANBUILD)/ldpd.8 endif ldpd_libldp_a_SOURCES = \ diff --git a/lib/.gitignore b/lib/.gitignore index 072146dbd..6176b30f8 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,26 +1,13 @@ -!Makefile -Makefile.in -*.o -*.lo -*.la -version.c -version.h -gitversion.h -gitversion.h.tmp -.deps -.nfs* -.libs -.arch-inventory -.arch-ids -*~ -*.loT -route_types.h -memtypes.h -command_lex.c -command_lex.h -command_parse.c -command_parse.h -refix -grammar_sandbox -clippy -defun_lex.c +/version.c +/version.h +/gitversion.h +/gitversion.h.tmp +/route_types.h +/memtypes.h +/command_lex.c +/command_lex.h +/command_parse.c +/command_parse.h +/grammar_sandbox +/clippy +/defun_lex.c diff --git a/lib/command.c b/lib/command.c index 1df644210..26afc762f 100644 --- a/lib/command.c +++ b/lib/command.c @@ -146,6 +146,7 @@ const char *node_names[] = { */ "bfd", /* BFD_NODE */ "bfd peer", /* BFD_PEER_NODE */ + "openfabric", // OPENFABRIC_NODE }; /* clang-format on */ @@ -1197,6 +1198,7 @@ static int handle_pipe_action(struct vty *vty, const char *cmd_in, /* retrieve action */ token = strsep(&working, " "); + assert(token); /* match result to known actions */ if (strmatch(token, "include")) { @@ -1435,6 +1437,7 @@ void cmd_exit(struct vty *vty) case LDP_NODE: case LDP_L2VPN_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case RMAP_NODE: case PBRMAP_NODE: @@ -1550,6 +1553,7 @@ DEFUN (config_end, case LDP_L2VPN_NODE: case LDP_PSEUDOWIRE_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case KEYCHAIN_KEY_NODE: case VTY_NODE: diff --git a/lib/command.h b/lib/command.h index 75b69507e..8e51641b8 100644 --- a/lib/command.h +++ b/lib/command.h @@ -141,6 +141,7 @@ enum node_type { BGP_FLOWSPECV6_NODE, /* BGP IPv6 FLOWSPEC Address-Family */ BFD_NODE, /* BFD protocol mode. */ BFD_PEER_NODE, /* BFD peer configuration mode. */ + OPENFABRIC_NODE, /* OpenFabric router configuration node */ NODE_TYPE_MAX, /* maximum */ }; @@ -364,7 +365,6 @@ struct cmd_node { #define PREFIX_LIST_STR "Build a prefix list\n" #define OSPF6_DUMP_TYPE_LIST \ "<neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr>" -#define ISIS_STR "IS-IS information\n" #define AREA_TAG_STR "[area tag]\n" #define COMMUNITY_AANN_STR "Community number where AA and NN are (0-65535)\n" #define COMMUNITY_VAL_STR "Community number in AA:NN format (where AA and NN are (0-65535)) or local-AS|no-advertise|no-export|internet or additive\n" diff --git a/lib/command_lex.l b/lib/command_lex.l index 0d6e6ee7e..3b18b58a2 100644 --- a/lib/command_lex.l +++ b/lib/command_lex.l @@ -22,6 +22,11 @@ * 02111-1307, USA. */ +%top{ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +} %{ /* ignore flex generated code in static analyzer */ #ifndef __clang_analyzer__ @@ -17,6 +17,11 @@ * with this program; see the file COPYING; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -563,6 +568,8 @@ void csv_decode(csv_t *csv, char *inbuf) csv_record_t *rec; buf = (inbuf) ? inbuf : csv->buf; + assert(buf); + pos = strpbrk(buf, "\n"); while (pos != NULL) { rec = calloc(1, sizeof(csv_record_t)); diff --git a/lib/defun_lex.l b/lib/defun_lex.l index d901c26a2..6c0805a4f 100644 --- a/lib/defun_lex.l +++ b/lib/defun_lex.l @@ -1,4 +1,3 @@ -%{ /* * clippy (CLI preparator in python) C pseudo-lexer * Copyright (C) 2016-2017 David Lamparter for NetDEF, Inc. @@ -34,6 +33,12 @@ * code documentation in it. */ +%top{ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +} +%{ /* ignore harmless bugs in old versions of flex */ #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wunused-value" diff --git a/lib/ferr.c b/lib/ferr.c index 35d0fe4ff..afef196ce 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -14,6 +14,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <stdarg.h> #include <string.h> @@ -148,7 +152,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json) snprintf(pbuf, sizeof(pbuf), "\nError %"PRIu32" - %s", ref->code, ref->title); memset(ubuf, '=', strlen(pbuf)); - ubuf[strlen(pbuf) - 1] = '\0'; + ubuf[strlen(pbuf)] = '\0'; vty_out(vty, "%s\n%s\n", pbuf, ubuf); vty_out(vty, "Description:\n%s\n\n", ref->description); diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index c0aae5e52..d48b23f38 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -19,6 +19,9 @@ #include <zebra.h> #include <pthread.h> +#ifdef HAVE_PTHREAD_NP_H +#include <pthread_np.h> +#endif #include <sched.h> #include "frr_pthread.h" @@ -163,10 +166,14 @@ int frr_pthread_set_name(struct frr_pthread *fpt, const char *name, pthread_mutex_lock(&fpt->mtx); snprintf(fpt->os_name, OS_THREAD_NAMELEN, "%s", os_name); pthread_mutex_unlock(&fpt->mtx); -#ifdef GNU_LINUX +#ifdef HAVE_PTHREAD_SETNAME_NP +# ifdef GNU_LINUX ret = pthread_setname_np(fpt->thread, fpt->os_name); -#elif defined(OPEN_BSD) - ret = pthread_set_name_np(fpt->thread, fpt->os_name); +# else /* NetBSD */ + ret = pthread_setname_np(fpt->thread, fpt->os_name, NULL); +# endif +#elif defined(HAVE_PTHREAD_SET_NAME_NP) + pthread_set_name_np(fpt->thread, fpt->os_name); #endif } diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h index cc4fc7433..732e2925f 100644 --- a/lib/frr_pthread.h +++ b/lib/frr_pthread.h @@ -234,4 +234,8 @@ void frr_pthread_yield(void); */ uint32_t frr_pthread_get_id(void); +#ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK +#define pthread_condattr_setclock(A, B) +#endif + #endif /* _FRR_PTHREAD_H */ diff --git a/lib/frrstr.c b/lib/frrstr.c index 715e67b86..85d968182 100644 --- a/lib/frrstr.c +++ b/lib/frrstr.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <ctype.h> #include <sys/types.h> diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 51e7a3987..ef03e8521 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -23,6 +23,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "command.h" #include "memory_vty.h" #include "graph.h" diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c index 264c7c48f..c9c942f9b 100644 --- a/lib/grammar_sandbox_main.c +++ b/lib/grammar_sandbox_main.c @@ -23,6 +23,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "command.h" #include "memory_vty.h" diff --git a/lib/hook.c b/lib/hook.c index 935064f4d..4fe305f28 100644 --- a/lib/hook.c +++ b/lib/hook.c @@ -20,6 +20,10 @@ * DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "memory.h" #include "hook.h" @@ -371,37 +371,47 @@ struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id) one. */ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty) { - struct interface *ifp; + struct interface *ifp = NULL; - ifp = if_lookup_by_name(name, vrf_id); - if (ifp) - return ifp; - /* Not Found on same VRF. If the interface command - * was entered in vty without a VRF (passed as VRF_DEFAULT), - * accept the ifp we found. If a vrf was entered and there is - * a mismatch, reject it if from vty. - */ - ifp = if_lookup_by_name_all_vrf(name); - if (!ifp) + if (vrf_is_mapped_on_netns(vrf_lookup_by_id(vrf_id))) { + ifp = if_lookup_by_name(name, vrf_id); + if (ifp) + return ifp; + if (vty) { + /* If the interface command was entered in vty without a + * VRF (passed as VRF_DEFAULT), search an interface with + * this name in all VRs + */ + if (vrf_id == VRF_DEFAULT) + return if_lookup_by_name_all_vrf(name); + return NULL; + } return if_create(name, vrf_id); - if (vty) { - if (vrf_id == VRF_DEFAULT) + } + /* vrf is based on vrf-lite */ + ifp = if_lookup_by_name_all_vrf(name); + if (ifp) { + if (ifp->vrf_id == vrf_id) return ifp; - return NULL; + /* Found a match on a different VRF. If the interface command + * was entered in vty without a VRF (passed as VRF_DEFAULT), + * accept the ifp we found. If a vrf was entered and there is a + * mismatch, reject it if from vty. If it came from the kernel + * or by way of zclient, believe it and update the ifp + * accordingly. + */ + if (vty) { + if (vrf_id == VRF_DEFAULT) + return ifp; + return NULL; + } + /* If it came from the kernel or by way of zclient, believe it + * and update the ifp accordingly. + */ + if_update_to_new_vrf(ifp, vrf_id); + return ifp; } - /* if vrf backend uses NETNS, then - * this should not be considered as an update - * then create the new interface - */ - if (ifp->vrf_id != vrf_id && vrf_is_mapped_on_netns( - vrf_lookup_by_id(vrf_id))) - return if_create(name, vrf_id); - /* If it came from the kernel - * or by way of zclient, believe it and update - * the ifp accordingly. - */ - if_update_to_new_vrf(ifp, vrf_id); - return ifp; + return if_create(name, vrf_id); } void if_set_index(struct interface *ifp, ifindex_t ifindex) @@ -619,7 +629,7 @@ DEFUN (no_interface_desc, * if not: * - no idea, just get the name in its entirety. */ -static struct interface *if_sunwzebra_get(char *name, vrf_id_t vrf_id) +static struct interface *if_sunwzebra_get(const char *name, vrf_id_t vrf_id) { struct interface *ifp; char *cp; diff --git a/lib/imsg-buffer.c b/lib/imsg-buffer.c index b83f1f76f..c2f4052b8 100644 --- a/lib/imsg-buffer.c +++ b/lib/imsg-buffer.c @@ -21,9 +21,9 @@ #include "queue.h" #include "imsg.h" -int ibuf_realloc(struct ibuf *, size_t); -void ibuf_enqueue(struct msgbuf *, struct ibuf *); -void ibuf_dequeue(struct msgbuf *, struct ibuf *); +static int ibuf_realloc(struct ibuf *, size_t); +static void ibuf_enqueue(struct msgbuf *, struct ibuf *); +static void ibuf_dequeue(struct msgbuf *, struct ibuf *); struct ibuf *ibuf_open(size_t len) { @@ -57,7 +57,7 @@ struct ibuf *ibuf_dynamic(size_t len, size_t max) return (buf); } -int ibuf_realloc(struct ibuf *buf, size_t len) +static int ibuf_realloc(struct ibuf *buf, size_t len) { uint8_t *b; @@ -183,6 +183,8 @@ void msgbuf_drain(struct msgbuf *msgbuf, size_t n) next = TAILQ_NEXT(buf, entry); if (buf->rpos + n >= buf->wpos) { n -= buf->wpos - buf->rpos; + + TAILQ_REMOVE(&msgbuf->bufs, buf, entry); ibuf_dequeue(msgbuf, buf); } else { buf->rpos += n; @@ -195,7 +197,7 @@ void msgbuf_clear(struct msgbuf *msgbuf) { struct ibuf *buf; - while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) + while ((buf = TAILQ_POP_FIRST(&msgbuf->bufs, entry)) != NULL) ibuf_dequeue(msgbuf, buf); } @@ -266,16 +268,15 @@ again: return (1); } -void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) +static void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) { TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); msgbuf->queued++; } -void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) +static void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) { - TAILQ_REMOVE(&msgbuf->bufs, buf, entry); - + /* TAILQ_REMOVE done by caller */ if (buf->fd != -1) close(buf->fd); diff --git a/lib/imsg.c b/lib/imsg.c index 542414072..935d13772 100644 --- a/lib/imsg.c +++ b/lib/imsg.c @@ -299,11 +299,10 @@ int imsg_get_fd(struct imsgbuf *ibuf) int fd; struct imsg_fd *ifd; - if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + if ((ifd = TAILQ_POP_FIRST(&ibuf->fds, entry)) == NULL) return (-1); fd = ifd->fd; - TAILQ_REMOVE(&ibuf->fds, ifd, entry); free(ifd); return (fd); diff --git a/lib/lib_errors.c b/lib/lib_errors.c index b27f9391a..a608aa9e6 100644 --- a/lib/lib_errors.c +++ b/lib/lib_errors.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "lib_errors.h" /* clang-format off */ diff --git a/lib/libfrr.c b/lib/libfrr.c index 18e263656..ecdc27757 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -262,6 +262,32 @@ bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, static struct frr_daemon_info *di = NULL; +static void frr_guard_daemon(void) +{ + int fd; + struct flock lock; + const char *path = di->pid_file; + + fd = open(path, O_RDWR); + if (fd != -1) { + memset(&lock, 0, sizeof(lock)); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + if (fcntl(fd, F_GETLK, &lock) < 0) { + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Could not do F_GETLK pid_file %s (%s), exiting", + path, safe_strerror(errno)); + exit(1); + } else if (lock.l_type == F_WRLCK) { + flog_err_sys(LIB_ERR_SYSTEM_CALL, + "Process %d has a write lock on file %s already! Error: (%s)", + lock.l_pid, path, safe_strerror(errno)); + exit(1); + } + close(fd); + } +} + void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv) { di = daemon; @@ -591,6 +617,9 @@ struct thread_master *frr_init(void) zprivs_init(di->privs); + /* Guard to prevent a second instance of this daemon */ + frr_guard_daemon(); + master = thread_master_create(NULL); signal_init(master, di->n_signals, di->signals); @@ -1074,6 +1074,8 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; + else if (strmatch(s, "openfabric")) + return ZEBRA_ROUTE_OPENFABRIC; } if (afi == AFI_IP6) { if (strmatch(s, "kernel")) @@ -1102,6 +1104,8 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; + else if (strmatch(s, "openfabric")) + return ZEBRA_ROUTE_OPENFABRIC; } return -1; } diff --git a/lib/memory.c b/lib/memory.c index 695bbfe11..fee23a75a 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -20,6 +20,9 @@ #ifdef HAVE_MALLOC_H #include <malloc.h> #endif +#ifdef HAVE_MALLOC_NP_H +#include <malloc_np.h> +#endif #ifdef HAVE_MALLOC_MALLOC_H #include <malloc/malloc.h> #endif diff --git a/lib/memory_vty.c b/lib/memory_vty.c index 73a18529a..5fd9c3b90 100644 --- a/lib/memory_vty.c +++ b/lib/memory_vty.c @@ -28,7 +28,9 @@ #include <malloc/malloc.h> #endif #include <dlfcn.h> +#ifdef HAVE_LINK_H #include <link.h> +#endif #include "log.h" #include "memory.h" diff --git a/lib/openbsd-tree.c b/lib/openbsd-tree.c index 35bfce3a8..e8d13339b 100644 --- a/lib/openbsd-tree.c +++ b/lib/openbsd-tree.c @@ -41,6 +41,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdlib.h> #include <lib/openbsd-tree.h> diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c index 69fd61e2a..7f868beda 100644 --- a/lib/ptm_lib.c +++ b/lib/ptm_lib.c @@ -17,6 +17,11 @@ * with this program; see the file COPYING; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <stdlib.h> #include <stdbool.h> diff --git a/lib/queue.h b/lib/queue.h index 04fbeee70..11e28b4c9 100644 --- a/lib/queue.h +++ b/lib/queue.h @@ -72,4 +72,17 @@ #include "freebsd-queue.h" #endif /* defined(__OpenBSD__) && !defined(STAILQ_HEAD) */ +#ifndef TAILQ_POP_FIRST +#define TAILQ_POP_FIRST(head, field) \ + ({ typeof((head)->tqh_first) _elm = TAILQ_FIRST(head); \ + if (_elm) { \ + if ((TAILQ_NEXT((_elm), field)) != NULL) \ + TAILQ_NEXT((_elm), field)->field.tqe_prev = \ + &TAILQ_FIRST(head); \ + else \ + (head)->tqh_last = &TAILQ_FIRST(head); \ + TAILQ_FIRST(head) = TAILQ_NEXT((_elm), field); \ + }; _elm; }) +#endif + #endif /* _FRR_QUEUE_H */ diff --git a/lib/route_types.txt b/lib/route_types.txt index 72f59a1b7..c5eff44ca 100644 --- a/lib/route_types.txt +++ b/lib/route_types.txt @@ -82,6 +82,7 @@ ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, 1, "Babel" ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, 1, "SHARP" ZEBRA_ROUTE_PBR, pbr, pbrd, 'F', 1, 1, 0, "PBR" ZEBRA_ROUTE_BFD, bfd, bfdd, '-', 0, 0, 0, "BFD" +ZEBRA_ROUTE_OPENFABRIC, openfabric, fabricd, 'f', 1, 1, 1, "OpenFabric" ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, 0, "-" @@ -109,3 +110,4 @@ ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)" ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)" ZEBRA_ROUTE_PBR, "Policy Based Routing (PBR)" ZEBRA_ROUTE_BFD, "Bidirectional Fowarding Detection (BFD)" +ZEBRA_ROUTE_OPENFABRIC, "OpenFabric Routing Protocol" diff --git a/lib/skiplist.c b/lib/skiplist.c index a36bf4713..585cf859e 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -202,6 +202,7 @@ int skiplist_insert(register struct skiplist *l, register void *key, } k = randomLevel(); + assert(k >= 0); if (k > l->level) { k = ++l->level; update[k] = l->header; diff --git a/lib/stream.c b/lib/stream.c index 2a34ec233..8424a941d 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -272,7 +272,7 @@ void stream_forward_endp(struct stream *s, size_t size) } /* Copy from stream to destination. */ -inline bool stream_get2(void *dst, struct stream *s, size_t size) +bool stream_get2(void *dst, struct stream *s, size_t size) { STREAM_VERIFY_SANE(s); @@ -301,7 +301,7 @@ void stream_get(void *dst, struct stream *s, size_t size) } /* Get next character from the stream. */ -inline bool stream_getc2(struct stream *s, uint8_t *byte) +bool stream_getc2(struct stream *s, uint8_t *byte) { STREAM_VERIFY_SANE(s); @@ -346,7 +346,7 @@ uint8_t stream_getc_from(struct stream *s, size_t from) return c; } -inline bool stream_getw2(struct stream *s, uint16_t *word) +bool stream_getw2(struct stream *s, uint16_t *word) { STREAM_VERIFY_SANE(s); @@ -467,7 +467,7 @@ void stream_get_from(void *dst, struct stream *s, size_t from, size_t size) memcpy(dst, s->data + from, size); } -inline bool stream_getl2(struct stream *s, uint32_t *l) +bool stream_getl2(struct stream *s, uint32_t *l) { STREAM_VERIFY_SANE(s); diff --git a/lib/strlcat.c b/lib/strlcat.c index be211f82a..39773d9ac 100644 --- a/lib/strlcat.c +++ b/lib/strlcat.c @@ -20,11 +20,13 @@ /* adapted for Quagga from glibc patch submission originally from * Florian Weimer <fweimer@redhat.com>, 2016-05-18 */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdint.h> #include <string.h> -#include "config.h" - #ifndef HAVE_STRLCAT #undef strlcat diff --git a/lib/strlcpy.c b/lib/strlcpy.c index b0c33ca7f..71ee9f1a5 100644 --- a/lib/strlcpy.c +++ b/lib/strlcpy.c @@ -20,9 +20,11 @@ /* adapted for Quagga from glibc patch submission originally from * Florian Weimer <fweimer@redhat.com>, 2016-05-18 */ -#include <string.h> - +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + +#include <string.h> #ifndef HAVE_STRLCPY #undef strlcpy diff --git a/lib/subdir.am b/lib/subdir.am index ef6c8f8e5..499bb9492 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -84,6 +84,22 @@ lib_libfrr_la_SOURCES = \ lib/logicalrouter.c \ # end +vtysh_scan += \ + $(top_srcdir)/lib/distribute.c \ + $(top_srcdir)/lib/filter.c \ + $(top_srcdir)/lib/if.c \ + $(top_srcdir)/lib/if_rmap.c \ + $(top_srcdir)/lib/keychain.c \ + $(top_srcdir)/lib/logicalrouter.c \ + $(top_srcdir)/lib/nexthop_group.c \ + $(top_srcdir)/lib/plist.c \ + $(top_srcdir)/lib/routemap.c \ + $(top_srcdir)/lib/vrf.c \ + $(top_srcdir)/lib/vty.c \ + # end +# can be loaded as DSO - always include for vtysh +vtysh_scan += $(top_srcdir)/lib/agentx.c + lib/plist_clippy.c: $(CLIPPY_DEPS) lib/plist.lo: lib/plist_clippy.c lib/nexthop_group_clippy.c: $(CLIPPY_DEPS) @@ -152,6 +168,7 @@ pkginclude_HEADERS += \ lib/sha256.h \ lib/sigevent.h \ lib/skiplist.h \ + lib/smux.h \ lib/sockopt.h \ lib/sockunion.h \ lib/spf_backoff.h \ @@ -237,9 +254,10 @@ lib_grammar_sandbox_SOURCES = \ lib_grammar_sandbox_LDADD = \ lib/libfrr.la -lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY @SAN_CLIPPY_FLAGS@ -lib_clippy_CFLAGS = $(PYTHON_CFLAGS) @SAN_CLIPPY_FLAGS@ +lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY +lib_clippy_CFLAGS = $(PYTHON_CFLAGS) lib_clippy_LDADD = $(PYTHON_LIBS) +lib_clippy_LDFLAGS = -export-dynamic lib_clippy_SOURCES = \ lib/clippy.c \ lib/command_graph.c \ @@ -252,6 +270,26 @@ lib_clippy_SOURCES = \ lib/vector.c \ # end +# (global) clippy rules for all directories + +AM_V_CLIPPY = $(am__v_CLIPPY_$(V)) +am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY)) +am__v_CLIPPY_0 = @echo " CLIPPY " $@; +am__v_CLIPPY_1 = + +CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py + +SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h +.c_clippy.c: + @{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || \ + $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } + $(AM_V_CLIPPY) $(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $< + +## automake's "ylwrap" is a great piece of GNU software... not. +.l.c: + $(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $< +.y.c: + $(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $< # # generated sources & extra foo @@ -493,9 +493,15 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *), "vrf_init: failed to create the default VRF!"); exit(1); } - if (vrf_is_backend_netns()) + if (vrf_is_backend_netns()) { + struct ns *ns; + strlcpy(default_vrf->data.l.netns_name, VRF_DEFAULT_NAME, NS_NAMSIZ); + ns = ns_lookup(ns_get_default_id()); + ns->vrf_ctxt = default_vrf; + default_vrf->ns_ctxt = ns; + } /* Enable the default VRF. */ if (!vrf_enable(default_vrf)) { @@ -712,8 +718,6 @@ int vrf_is_mapped_on_netns(struct vrf *vrf) { if (!vrf || vrf->data.l.netns_name[0] == '\0') return 0; - if (vrf->vrf_id == VRF_DEFAULT) - return 0; return 1; } @@ -813,6 +813,7 @@ static void vty_end_config(struct vty *vty) case LDP_L2VPN_NODE: case LDP_PSEUDOWIRE_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case KEYCHAIN_KEY_NODE: case VTY_NODE: @@ -1212,6 +1213,7 @@ static void vty_stop_input(struct vty *vty) case LDP_L2VPN_NODE: case LDP_PSEUDOWIRE_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case KEYCHAIN_NODE: case KEYCHAIN_KEY_NODE: case VTY_NODE: diff --git a/lib/zebra.h b/lib/zebra.h index b12f6616b..d80aa0693 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -28,7 +28,6 @@ #include "compiler.h" #ifdef SUNOS_5 -#define _XPG4_2 typedef unsigned int uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; @@ -414,6 +413,7 @@ extern const char *zserv_command_string(unsigned int command); #define ZEBRA_FLAG_FIB_OVERRIDE 0x200 #define ZEBRA_FLAG_EVPN_ROUTE 0x400 #define ZEBRA_FLAG_RR_USE_DISTANCE 0x800 +#define ZEBRA_FLAG_ONLINK 0x1000 /* ZEBRA_FLAG_BLACKHOLE was 0x04 */ /* ZEBRA_FLAG_REJECT was 0x80 */ diff --git a/m4/.gitignore b/m4/.gitignore index 798188b0b..357e65588 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -1,8 +1,8 @@ -Makefile -Makefile.in -.arch-inventory -.arch-ids -*~ -*.loT +*.m4 + +!ax_compare_version.m4 +!ax_prog_perl_modules.m4 !ax_pthread.m4 !ax_sys_weak_alias.m4 +!ax_sys_weak_alias.m4 +!pkg.m4 @@ -109,7 +109,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $1 ($2)]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) diff --git a/nhrpd/.gitignore b/nhrpd/.gitignore index 3f4738127..3d4d56d58 100644 --- a/nhrpd/.gitignore +++ b/nhrpd/.gitignore @@ -1,2 +1 @@ -!Makefile nhrpd diff --git a/nhrpd/linux.c b/nhrpd/linux.c index 46a327b59..85e941e7b 100644 --- a/nhrpd/linux.c +++ b/nhrpd/linux.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <fcntl.h> #include <stdio.h> #include <unistd.h> diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c index af78b3d9e..4c6827cb3 100644 --- a/nhrpd/netlink_arp.c +++ b/nhrpd/netlink_arp.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <fcntl.h> #include <net/if.h> #include <netinet/if_ether.h> diff --git a/nhrpd/netlink_gre.c b/nhrpd/netlink_gre.c index 75ecaa70c..3fdfa9c31 100644 --- a/nhrpd/netlink_gre.c +++ b/nhrpd/netlink_gre.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> diff --git a/nhrpd/nhrp_event.c b/nhrpd/nhrp_event.c index 7ca973176..9301c2d51 100644 --- a/nhrpd/nhrp_event.c +++ b/nhrpd/nhrp_event.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <sys/socket.h> #include <sys/un.h> diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index 3a4271274..ccca100db 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <net/if_arp.h> #include "zebra.h" #include "linklist.h" diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index 737e70103..f99e56639 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <unistd.h> #include "zebra.h" diff --git a/nhrpd/nhrp_packet.c b/nhrpd/nhrp_packet.c index e62ee1ef7..a983aa71b 100644 --- a/nhrpd/nhrp_packet.c +++ b/nhrpd/nhrp_packet.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <netinet/if_ether.h> #include "nhrpd.h" #include "zbuf.h" diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 44271d68a..e051830f8 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <netinet/if_ether.h> #include "zebra.h" diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 044529a5c..e7b187f3b 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "nhrpd.h" #include "table.h" #include "memory.h" diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 9ed251706..84053b4b5 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "nhrpd.h" #include "table.h" #include "memory.h" diff --git a/nhrpd/resolver.c b/nhrpd/resolver.c index dfa5dc3df..f017d974d 100644 --- a/nhrpd/resolver.c +++ b/nhrpd/resolver.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <ares.h> #include <ares_version.h> diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am index d66e96822..758c22e2b 100644 --- a/nhrpd/subdir.am +++ b/nhrpd/subdir.am @@ -4,6 +4,8 @@ if NHRPD sbin_PROGRAMS += nhrpd/nhrpd +vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c +man8 += $(MANBUILD)/nhrpd.8 endif nhrpd_nhrpd_LDADD = lib/libfrr.la @LIBCAP@ @CARES_LIBS@ diff --git a/nhrpd/vici.c b/nhrpd/vici.c index 7cd703414..c1a99685f 100644 --- a/nhrpd/vici.c +++ b/nhrpd/vici.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <sys/socket.h> #include <sys/un.h> diff --git a/nhrpd/zbuf.c b/nhrpd/zbuf.c index 6e7cad8ae..c66229508 100644 --- a/nhrpd/zbuf.c +++ b/nhrpd/zbuf.c @@ -7,7 +7,10 @@ * (at your option) any later version. */ -#define _GNU_SOURCE +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> #include <unistd.h> #include <errno.h> diff --git a/nhrpd/znl.c b/nhrpd/znl.c index 01b2f433a..6030987a1 100644 --- a/nhrpd/znl.c +++ b/nhrpd/znl.c @@ -7,6 +7,10 @@ * (at your option) any later version. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <fcntl.h> #include <errno.h> #include <string.h> diff --git a/ospf6d/.gitignore b/ospf6d/.gitignore index 744af2d5c..e398b1ca5 100644 --- a/ospf6d/.gitignore +++ b/ospf6d/.gitignore @@ -1,18 +1,2 @@ -!Makefile -Makefile.in -*.o -*.patch ospf6d ospf6d.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 5af88defe..dc7a3f6d4 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -732,7 +732,8 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, ? 1 : 2, buf, listcount(route->paths), - listcount(route->nh_list)); + route->nh_list ? + listcount(route->nh_list) : 0); } if (listcount(route->paths)) { diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 8b720b6d8..40b3522c3 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -130,7 +130,7 @@ uint8_t ospf6_lstype_debug(uint16_t type) { const struct ospf6_lsa_handler *handler; handler = ospf6_get_lsa_handler(type); - return handler->debug; + return handler->lh_debug; } /* RFC2328: Section 13.2 */ @@ -844,13 +844,13 @@ DEFUN (debug_ospf6_lsa_type, if (argc == 5) { if (strmatch(argv[idx_type]->text, "originate")) - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_ORIGINATE); else if (strmatch(argv[idx_type]->text, "examine")) - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN); else if (strmatch(argv[idx_type]->text, "flooding")) - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD); } else - SET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + SET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG); return CMD_SUCCESS; } @@ -896,13 +896,14 @@ DEFUN (no_debug_ospf6_lsa_type, if (argc == 6) { if (strmatch(argv[idx_type]->text, "originate")) - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); + UNSET_FLAG(handler->lh_debug, + OSPF6_LSA_DEBUG_ORIGINATE); if (strmatch(argv[idx_type]->text, "examine")) - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN); if (strmatch(argv[idx_type]->text, "flooding")) - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD); } else - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG); return CMD_SUCCESS; } @@ -924,16 +925,16 @@ int config_write_ospf6_debug_lsa(struct vty *vty) handler = vector_slot(ospf6_lsa_handler_vector, i); if (handler == NULL) continue; - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG)) vty_out(vty, "debug ospf6 lsa %s\n", ospf6_lsa_handler_name(handler)); - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_ORIGINATE)) vty_out(vty, "debug ospf6 lsa %s originate\n", ospf6_lsa_handler_name(handler)); - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_EXAMIN)) vty_out(vty, "debug ospf6 lsa %s examine\n", ospf6_lsa_handler_name(handler)); - if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD)) + if (CHECK_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG_FLOOD)) vty_out(vty, "debug ospf6 lsa %s flooding\n", ospf6_lsa_handler_name(handler)); } diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index e88d10ad7..d871a8842 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -137,21 +137,14 @@ struct ospf6_lsa { #define OSPF6_LSA_SEQWRAPPED 0x20 struct ospf6_lsa_handler { - const struct { - uint16_t type; /* host byte order */ - const char *name; - const char *short_name; - int (*show)(struct vty *, struct ospf6_lsa *); - char *(*get_prefix_str)(struct ospf6_lsa *, char *buf, - int buflen, int pos); - } s; -#define lh_type s.type -#define lh_name s.name -#define lh_short_name s.short_name -#define lh_show s.show -#define lh_get_prefix_str s.get_prefix_str - uint8_t debug; -#define lh_debug debug + uint16_t lh_type; /* host byte order */ + const char *lh_name; + const char *lh_short_name; + int (*lh_show)(struct vty *, struct ospf6_lsa *); + char *(*lh_get_prefix_str)(struct ospf6_lsa *, char *buf, + int buflen, int pos); + + uint8_t lh_debug; }; #define OSPF6_LSA_IS_KNOWN(t) \ diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 0cc7294d6..4c24f4713 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -921,7 +921,7 @@ DEFUN (no_debug_ospf6, handler = vector_slot(ospf6_lsa_handler_vector, i); if (handler != NULL) { - UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + UNSET_FLAG(handler->lh_debug, OSPF6_LSA_DEBUG); } } diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index a099eead4..021e825ae 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -732,7 +732,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, route->next = next; if (node->info == next) { - assert(next->rnode == node); + assert(next && next->rnode == node); node->info = route; UNSET_FLAG(next->flag, OSPF6_ROUTE_BEST); SET_FLAG(route->flag, OSPF6_ROUTE_BEST); diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index fde47c74f..ca1a65ff0 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -425,19 +425,6 @@ DEFUN(no_ospf6_router_id, return CMD_SUCCESS; } -#if CONFDATE > 20180828 -CPP_NOTICE("ospf6: `router-id A.B.C.D` deprecated 2017/08/28") -#endif -ALIAS_HIDDEN(ospf6_router_id, ospf6_router_id_hdn_cmd, "router-id A.B.C.D", - "Configure OSPF6 Router-ID\n" V4NOTATION_STR) - -#if CONFDATE > 20180828 -CPP_NOTICE("ospf6: `no router-id A.B.C.D` deprecated 2017/08/28") -#endif -ALIAS_HIDDEN(no_ospf6_router_id, no_ospf6_router_id_hdn_cmd, - "no router-id [A.B.C.D]", - NO_STR "Configure OSPF6 Router-ID\n" V4NOTATION_STR) - DEFUN (ospf6_log_adjacency_changes, ospf6_log_adjacency_changes_cmd, "log-adjacency-changes", @@ -1144,8 +1131,6 @@ void ospf6_top_init(void) install_default(OSPF6_NODE); install_element(OSPF6_NODE, &ospf6_router_id_cmd); install_element(OSPF6_NODE, &no_ospf6_router_id_cmd); - install_element(OSPF6_NODE, &ospf6_router_id_hdn_cmd); - install_element(OSPF6_NODE, &no_ospf6_router_id_hdn_cmd); install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd); install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd); install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd); diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index 8a6c4a5cc..d9c29f265 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -6,9 +6,27 @@ if OSPF6D noinst_LIBRARIES += ospf6d/libospf6.a sbin_PROGRAMS += ospf6d/ospf6d dist_examples_DATA += ospf6d/ospf6d.conf.sample +vtysh_scan += \ + $(top_srcdir)/ospf6d/ospf6_abr.c \ + $(top_srcdir)/ospf6d/ospf6_asbr.c \ + $(top_srcdir)/ospf6d/ospf6_area.c \ + $(top_srcdir)/ospf6d/ospf6_bfd.c \ + $(top_srcdir)/ospf6d/ospf6_flood.c \ + $(top_srcdir)/ospf6d/ospf6_interface.c \ + $(top_srcdir)/ospf6d/ospf6_intra.c \ + $(top_srcdir)/ospf6d/ospf6_lsa.c \ + $(top_srcdir)/ospf6d/ospf6_message.c \ + $(top_srcdir)/ospf6d/ospf6_neighbor.c \ + $(top_srcdir)/ospf6d/ospf6_route.c \ + $(top_srcdir)/ospf6d/ospf6_spf.c \ + $(top_srcdir)/ospf6d/ospf6_top.c \ + $(top_srcdir)/ospf6d/ospf6_zebra.c \ + $(top_srcdir)/ospf6d/ospf6d.c \ + # end if SNMP module_LTLIBRARIES += ospf6d/ospf6d_snmp.la endif +man8 += $(MANBUILD)/ospf6d.8 endif ospf6d_libospf6_a_SOURCES = \ diff --git a/ospfclient/.gitignore b/ospfclient/.gitignore index 1740b04fb..9be70451f 100644 --- a/ospfclient/.gitignore +++ b/ospfclient/.gitignore @@ -1,16 +1 @@ -!Makefile -Makefile.in -*.o ospfclient -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -refix diff --git a/ospfclient/subdir.am b/ospfclient/subdir.am index 834d4aaba..df7d85a1f 100644 --- a/ospfclient/subdir.am +++ b/ospfclient/subdir.am @@ -5,6 +5,7 @@ if OSPFCLIENT lib_LTLIBRARIES += ospfclient/libfrrospfapiclient.la sbin_PROGRAMS += ospfclient/ospfclient +man8 += $(MANBUILD)/ospfclient.8 endif ospfclient_libfrrospfapiclient_la_LDFLAGS = -version-info 0:0:0 diff --git a/ospfd/.gitignore b/ospfd/.gitignore index 752c875a6..fc65db33e 100644 --- a/ospfd/.gitignore +++ b/ospfd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ospfd ospfd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 19d2e6a95..755634a2f 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -995,7 +995,6 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, if (len <= 0) type_next = 1; else { - len = 1; type_next = 0; *type = *offset; } diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 2f8ff9909..17aa10ba0 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -24,6 +24,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <math.h> #include <stdio.h> #include <stdlib.h> diff --git a/ospfd/subdir.am b/ospfd/subdir.am index cd659a9bc..83074b5ac 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -6,9 +6,20 @@ if OSPFD noinst_LIBRARIES += ospfd/libfrrospf.a sbin_PROGRAMS += ospfd/ospfd dist_examples_DATA += ospfd/ospfd.conf.sample +vtysh_scan += \ + $(top_srcdir)/ospfd/ospf_bfd.c \ + $(top_srcdir)/ospfd/ospf_dump.c \ + $(top_srcdir)/ospfd/ospf_opaque.c \ + $(top_srcdir)/ospfd/ospf_ri.c \ + $(top_srcdir)/ospfd/ospf_routemap.c \ + $(top_srcdir)/ospfd/ospf_te.c \ + $(top_srcdir)/ospfd/ospf_sr.c \ + $(top_srcdir)/ospfd/ospf_vty.c \ + # end if SNMP module_LTLIBRARIES += ospfd/ospfd_snmp.la endif +man8 += $(MANBUILD)/ospfd.8 endif ospfd_libfrrospf_a_SOURCES = \ diff --git a/pbrd/.gitignore b/pbrd/.gitignore index ff95d8852..86622ea17 100644 --- a/pbrd/.gitignore +++ b/pbrd/.gitignore @@ -1,15 +1 @@ -!Makefile -Makefile.in -libpbr.a pbrd -tags -TAGS -.deps -*.o -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/pbrd/subdir.am b/pbrd/subdir.am index 42ab39321..794755903 100644 --- a/pbrd/subdir.am +++ b/pbrd/subdir.am @@ -6,6 +6,11 @@ if PBRD noinst_LIBRARIES += pbrd/libpbr.a sbin_PROGRAMS += pbrd/pbrd dist_examples_DATA += pbrd/pbrd.conf.sample +vtysh_scan += \ + $(top_srcdir)/pbrd/pbr_vty.c \ + $(top_srcdir)/pbrd/pbr_debug.c \ + # end +man8 += $(MANBUILD)/pbrd.8 endif pbrd_libpbr_a_SOURCES = \ diff --git a/pimd/.gitignore b/pimd/.gitignore index 1f56cfaec..b1780df75 100644 --- a/pimd/.gitignore +++ b/pimd/.gitignore @@ -1,17 +1,3 @@ -!Makefile -Makefile.in -libpim.a pimd mtracebis test_igmpv3_join -tags -TAGS -.deps -*.o -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/pimd/mtracebis.c b/pimd/mtracebis.c index c0d95aeed..65c495eff 100644 --- a/pimd/mtracebis.c +++ b/pimd/mtracebis.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __linux__ #include "pim_igmp_mtrace.h" diff --git a/pimd/mtracebis_netlink.c b/pimd/mtracebis_netlink.c index b4bf6bada..30ee8f24a 100644 --- a/pimd/mtracebis_netlink.c +++ b/pimd/mtracebis_netlink.c @@ -10,6 +10,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __linux__ #include <stdio.h> diff --git a/pimd/mtracebis_routeget.c b/pimd/mtracebis_routeget.c index 8c1cd8d96..8d974403a 100644 --- a/pimd/mtracebis_routeget.c +++ b/pimd/mtracebis_routeget.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __linux__ #include <asm/types.h> diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 5dc86417c..968fc378f 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -5640,27 +5640,6 @@ DEFUN (show_ip_pim_group_type, return CMD_SUCCESS; } -DEFUN_HIDDEN (ip_multicast_routing, - ip_multicast_routing_cmd, - "ip multicast-routing", - IP_STR - "Enable IP multicast forwarding\n") -{ - return CMD_SUCCESS; -} - -DEFUN_HIDDEN (no_ip_multicast_routing, - no_ip_multicast_routing_cmd, - "no ip multicast-routing", - NO_STR - IP_STR - "Enable IP multicast forwarding\n") -{ - vty_out(vty, - "Command is Disabled and will be removed in a future version\n"); - return CMD_SUCCESS; -} - DEFUN (ip_ssmpingd, ip_ssmpingd_cmd, "ip ssmpingd [A.B.C.D]", @@ -6431,16 +6410,12 @@ DEFUN_HIDDEN (interface_ip_pim_ssm, return CMD_SUCCESS; } -DEFUN (interface_ip_pim_sm, - interface_ip_pim_sm_cmd, - "ip pim sm", - IP_STR - PIM_STR - IFACE_PIM_SM_STR) +static int interface_ip_pim_helper(struct vty *vty) { struct pim_interface *pim_ifp; VTY_DECLVAR_CONTEXT(interface, ifp); + if (!pim_cmd_interface_add(ifp)) { vty_out(vty, "Could not enable PIM SM on interface\n"); return CMD_WARNING_CONFIG_FAILED; @@ -6453,6 +6428,25 @@ DEFUN (interface_ip_pim_sm, return CMD_SUCCESS; } +DEFUN_HIDDEN (interface_ip_pim_sm, + interface_ip_pim_sm_cmd, + "ip pim sm", + IP_STR + PIM_STR + IFACE_PIM_SM_STR) +{ + return interface_ip_pim_helper(vty); +} + +DEFUN (interface_ip_pim, + interface_ip_pim_cmd, + "ip pim", + IP_STR + PIM_STR) +{ + return interface_ip_pim_helper(vty); +} + static int pim_cmd_interface_delete(struct interface *ifp) { struct pim_interface *pim_ifp = ifp->info; @@ -6478,13 +6472,7 @@ static int pim_cmd_interface_delete(struct interface *ifp) return 1; } -DEFUN_HIDDEN (interface_no_ip_pim_ssm, - interface_no_ip_pim_ssm_cmd, - "no ip pim ssm", - NO_STR - IP_STR - PIM_STR - IFACE_PIM_STR) +static int interface_no_ip_pim_helper(struct vty *vty) { VTY_DECLVAR_CONTEXT(interface, ifp); if (!pim_cmd_interface_delete(ifp)) { @@ -6495,7 +6483,18 @@ DEFUN_HIDDEN (interface_no_ip_pim_ssm, return CMD_SUCCESS; } -DEFUN (interface_no_ip_pim_sm, +DEFUN_HIDDEN (interface_no_ip_pim_ssm, + interface_no_ip_pim_ssm_cmd, + "no ip pim ssm", + NO_STR + IP_STR + PIM_STR + IFACE_PIM_STR) +{ + return interface_no_ip_pim_helper(vty); +} + +DEFUN_HIDDEN (interface_no_ip_pim_sm, interface_no_ip_pim_sm_cmd, "no ip pim sm", NO_STR @@ -6503,13 +6502,17 @@ DEFUN (interface_no_ip_pim_sm, PIM_STR IFACE_PIM_SM_STR) { - VTY_DECLVAR_CONTEXT(interface, ifp); - if (!pim_cmd_interface_delete(ifp)) { - vty_out(vty, "Unable to delete interface information\n"); - return CMD_WARNING_CONFIG_FAILED; - } + return interface_no_ip_pim_helper(vty); +} - return CMD_SUCCESS; +DEFUN (interface_no_ip_pim, + interface_no_ip_pim_cmd, + "no ip pim", + NO_STR + IP_STR + PIM_STR) +{ + return interface_no_ip_pim_helper(vty); } /* boundaries */ @@ -7466,7 +7469,7 @@ DEFUN (interface_pim_use_source, interface_pim_use_source_cmd, "ip pim use-source A.B.C.D", IP_STR - "pim multicast routing\n" + PIM_STR "Configure primary IP address\n" "source ip address\n") { @@ -7478,7 +7481,7 @@ DEFUN (interface_no_pim_use_source, "no ip pim use-source [A.B.C.D]", NO_STR IP_STR - "pim multicast routing\n" + PIM_STR "Delete source IP address\n" "source ip address\n") { @@ -8634,8 +8637,6 @@ void pim_cmd_init(void) install_node(&debug_node, pim_debug_config_write); - install_element(CONFIG_NODE, &ip_multicast_routing_cmd); - install_element(CONFIG_NODE, &no_ip_multicast_routing_cmd); install_element(CONFIG_NODE, &ip_pim_rp_cmd); install_element(VRF_NODE, &ip_pim_rp_cmd); install_element(CONFIG_NODE, &no_ip_pim_rp_cmd); @@ -8721,6 +8722,8 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd); + install_element(INTERFACE_NODE, &interface_ip_pim_cmd); + install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd); diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c index 95d0278a3..1fb624a6a 100644 --- a/pimd/pim_igmp_mtrace.c +++ b/pimd/pim_igmp_mtrace.c @@ -615,7 +615,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, static uint32_t qry_id, qry_src; char mtrace_buf[MTRACE_HDR_SIZE + MTRACE_MAX_HOPS * MTRACE_RSP_SIZE]; struct interface *ifp; - struct interface *out_ifp; + struct interface *out_ifp = NULL; struct pim_interface *pim_ifp; struct pim_instance *pim; struct igmp_mtrace *mtracep; diff --git a/pimd/pim_igmp_stats.c b/pimd/pim_igmp_stats.c index 428816e1f..40851a452 100644 --- a/pimd/pim_igmp_stats.c +++ b/pimd/pim_igmp_stats.c @@ -17,6 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "pim_igmp_stats.h" void igmp_stats_init(struct igmp_stats *stats) diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 88be195be..a4aec710e 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -267,7 +267,7 @@ int pim_interface_config_write(struct vty *vty) struct pim_interface *pim_ifp = ifp->info; if (PIM_IF_TEST_PIM(pim_ifp->options)) { - vty_out(vty, " ip pim sm\n"); + vty_out(vty, " ip pim\n"); ++writes; } diff --git a/pimd/subdir.am b/pimd/subdir.am index 55d56ece9..fef8e3657 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -8,6 +8,9 @@ sbin_PROGRAMS += pimd/pimd bin_PROGRAMS += pimd/mtracebis noinst_PROGRAMS += pimd/test_igmpv3_join dist_examples_DATA += pimd/pimd.conf.sample +vtysh_scan += $(top_srcdir)/pimd/pim_cmd.c +man8 += $(MANBUILD)/pimd.8 +man8 += $(MANBUILD)/mtracebis.8 endif pimd_libpim_a_SOURCES = \ diff --git a/pkgsrc/.gitignore b/pkgsrc/.gitignore index 63e9a66d8..c97f963b3 100644 --- a/pkgsrc/.gitignore +++ b/pkgsrc/.gitignore @@ -1,8 +1 @@ -Makefile -Makefile.in *.sh -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/ports/.gitignore b/ports/.gitignore deleted file mode 100644 index dd5bf7c67..000000000 --- a/ports/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.arch-inventory -.arch-ids - -*~ -*.loT - diff --git a/ports/files/.gitignore b/ports/files/.gitignore deleted file mode 100644 index dd5bf7c67..000000000 --- a/ports/files/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.arch-inventory -.arch-ids - -*~ -*.loT - diff --git a/ports/pkg/.gitignore b/ports/pkg/.gitignore deleted file mode 100644 index dd5bf7c67..000000000 --- a/ports/pkg/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.arch-inventory -.arch-ids - -*~ -*.loT - diff --git a/python/clidef.py b/python/clidef.py index 4134f4c94..a140ce3d5 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -96,7 +96,7 @@ class IP4Handler(IPBase): code = Template('_fail = !inet_aton(argv[_i]->arg, &$varname);') class IP6Handler(IPBase): argtype = 'struct in6_addr' - decl = Template('struct in6_addr $varname = IN6ADDR_ANY_INIT;') + decl = Template('struct in6_addr $varname = {};') code = Template('_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);') class IPGenHandler(IPBase): argtype = 'const union sockunion *' diff --git a/qpb/.gitignore b/qpb/.gitignore deleted file mode 100644 index 17e90443e..000000000 --- a/qpb/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -!Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/qpb/qpb_allocator.c b/qpb/qpb_allocator.c index 7e5ba5b0c..aca611ba1 100644 --- a/qpb/qpb_allocator.c +++ b/qpb/qpb_allocator.c @@ -22,6 +22,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "linear_allocator.h" #include "qpb_allocator.h" diff --git a/qpb/subdir.am b/qpb/subdir.am index 3c006fd22..75a733f8f 100644 --- a/qpb/subdir.am +++ b/qpb/subdir.am @@ -2,24 +2,45 @@ if HAVE_PROTOBUF lib_LTLIBRARIES += qpb/libfrr_pb.la endif -qpb_libfrr_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \ - $(Q_PROTOBUF_C_CLIENT_INCLUDES) +qpb_libfrr_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS) +qpb_libfrr_pb_la_LIBADD = $(PROTOBUF_C_LIBS) qpb_libfrr_pb_la_LDFLAGS = -version-info 0:0:0 qpb_libfrr_pb_la_SOURCES = \ + qpb/qpb.c \ + qpb/qpb_allocator.c \ + # end +nodist_qpb_libfrr_pb_la_SOURCES = \ + qpb/qpb.pb-c.c \ + # end + +noinst_HEADERS += \ qpb/linear_allocator.h \ qpb/qpb.h \ - qpb/qpb.c \ qpb/qpb_allocator.h \ # end -if HAVE_PROTOBUF -qpb_libfrr_pb_la_SOURCES += qpb/qpb_allocator.c -nodist_qpb_libfrr_pb_la_SOURCES = qpb/qpb.pb-c.c CLEANFILES += \ qpb/qpb.pb-c.c \ qpb/qpb.pb-c.h \ # end -endif EXTRA_DIST += qpb/qpb.proto + +if HAVE_PROTOBUF + +# Rules +.proto.pb.h: + $(PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^ + +AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V)) +am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY)) +am__v_PROTOC_C_0 = @echo " PROTOC_C" $@; +am__v_PROTOC_C_1 = + +.proto.pb-c.c: + $(AM_V_PROTOC_C)$(PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^ +.pb-c.c.pb-c.h: + @/bin/true + +endif # HAVE_PROTOBUF diff --git a/redhat/.gitignore b/redhat/.gitignore index a38f1c06e..15804cea0 100644 --- a/redhat/.gitignore +++ b/redhat/.gitignore @@ -1,10 +1,2 @@ zebra.spec frr.spec -Makefile -Makefile.in -.nfs* -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/redhat/README.rpm_build.md b/redhat/README.rpm_build.md index c461e543d..a3f095786 100644 --- a/redhat/README.rpm_build.md +++ b/redhat/README.rpm_build.md @@ -3,16 +3,15 @@ Building your own FRRouting RPM (Tested on CentOS 6, CentOS 7 and Fedora 24.) 1. On CentOS 6 (which doesn't provide a bison/automake/autoconf of a recent enough version): - - Check out ../doc/Building_FRR_on_CentOS6.md for details on installing + - Check out ../doc/developer/building-frr-for-centos6.rst for details on installing a bison/automake/autoconf to support frr building. Newer automake/autoconf/bison is only needed to build the rpm and is **not** needed to install the binary rpm package -2. Install the build packages as documented in doc/Building_on_xxxxx.md - and the following additional packages: +2. Install the build packages as documented in doc/developer/building-frr-for-xxxxx.rst and the following additional packages: - yum install rpm-build net-snmp-devel pam-devel + yum install rpm-build net-snmp-devel pam-devel libcap-devel Additionally, on systems with systemd (CentOS 7, Fedora) @@ -28,8 +27,9 @@ Building your own FRRouting RPM cd frr ./bootstrap.sh - ./configure --with-pkg-extra-version=-MyRPMVersion - make SPHINXBUILD=sphinx-build2.7 dist + ./configure --with-pkg-extra-version=-MyRPMVersion \ + SPHINXBUILD=sphinx-build2.7 + make dist Note: configure parameters are not important for the RPM building - except the `with-pkg-extra-version` if you want to give the RPM a specific name to mark your own unoffical build diff --git a/redhat/daemons b/redhat/daemons index de708cf4f..c301a1c23 100644 --- a/redhat/daemons +++ b/redhat/daemons @@ -53,6 +53,7 @@ sharpd=no pbrd=no staticd=no bfdd=no +fabricd=no # # Command line options for the daemons @@ -73,6 +74,7 @@ sharpd_options=("-A 127.0.0.1") pbrd_options=("-A 127.0.0.1") staticd_options=("-A 127.0.0.1") bfdd_options=("-A 127.0.0.1") +fabricd_options=("-A 127.0.0.1") # # If the vtysh_enable is yes, then the unified config is read diff --git a/redhat/frr.init b/redhat/frr.init index 2e33aee17..47a92eed3 100755 --- a/redhat/frr.init +++ b/redhat/frr.init @@ -33,7 +33,7 @@ V_PATH=/var/run/frr # Local Daemon selection may be done by using /etc/frr/daemons. # See /usr/share/doc/frr/README.Debian.gz for further information. # Keep zebra first and do not list watchfrr! -DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd pbrd ldpd nhrpd eigrpd babeld staticd sharpd bfdd" +DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd pbrd ldpd nhrpd eigrpd babeld staticd sharpd bfdd fabricd" MAX_INSTANCES=5 RELOAD_SCRIPT=/usr/lib/frr/frr-reload.py diff --git a/redhat/frr.logrotate b/redhat/frr.logrotate index 654d355fd..df7c5da54 100644 --- a/redhat/frr.logrotate +++ b/redhat/frr.logrotate @@ -93,3 +93,11 @@ /bin/kill -USR1 `cat /var/run/frr/bfdd.pid 2> /dev/null` 2> /dev/null || true endscript } + +/var/log/frr/fabricd.log { + notifempty + missingok + postrotate + /bin/kill -USR1 `cat /var/run/frr/fabricd.pid 2> /dev/null` 2> /dev/null || true + endscript +} diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index 25b48506a..bff0b4051 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -86,7 +86,7 @@ %{!?frr_gid: %global frr_gid 92 } %{!?vty_gid: %global vty_gid 85 } -%define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd staticd bfdd +%define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd staticd bfdd fabricd %if %{with_ldpd} %define daemon_ldpd ldpd @@ -343,22 +343,23 @@ developing OSPF-API and frr applications. --disable-rpki \ %endif %if %{with_bfdd} - --enable-bfdd + --enable-bfdd \ %else - --disable-bfdd + --disable-bfdd \ %endif + SPHINXBUILD=%{sphinx} -make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" SPHINXBUILD=%{sphinx} +make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" pushd doc -make SPHINXBUILD=%{sphinx} info +make info popd %install mkdir -p %{buildroot}%{_sysconfdir}/{frr,sysconfig,logrotate.d,pam.d,default} \ %{buildroot}%{_localstatedir}/log/frr %{buildroot}%{_infodir} -make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" SPHINXBUILD=%{sphinx} install +make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install # Remove this file, as it is uninstalled and causes errors when building on RH9 rm -rf %{buildroot}/usr/share/info/dir @@ -459,6 +460,7 @@ zebra_spec_add_service isisd 2608/tcp "ISISd vty" %if %{with_bfdd} zebra_spec_add_service bfdd 2617/tcp "BFDd vty" %endif +zebra_spec_add_service fabricd 2618/tcp "Fabricd vty" %if "%{initsystem}" == "systemd" for daemon in %all_daemons ; do @@ -559,9 +561,9 @@ fi %files -%doc */*.sample* AUTHORS COPYING +%doc */*.sample* COPYING %doc doc/mpls -%doc ChangeLog NEWS README +%doc README.md %if 0%{?frr_user:1} %dir %attr(751,%{frr_user},%{frr_user}) %{configdir} %dir %attr(750,%{frr_user},%{frr_user}) %{_localstatedir}/log/frr @@ -594,6 +596,7 @@ fi %{_sbindir}/pbrd %endif %{_sbindir}/isisd +%{_sbindir}/fabricd %if %{with_ldpd} %{_sbindir}/ldpd %endif diff --git a/ripd/.gitignore b/ripd/.gitignore index 177250ca6..f149501d6 100644 --- a/ripd/.gitignore +++ b/ripd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ripd ripd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ripd/subdir.am b/ripd/subdir.am index 612db1a7a..0d06e7e65 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -6,9 +6,18 @@ if RIPD noinst_LIBRARIES += ripd/librip.a sbin_PROGRAMS += ripd/ripd dist_examples_DATA += ripd/ripd.conf.sample +vtysh_scan += \ + $(top_srcdir)/ripd/rip_debug.c \ + $(top_srcdir)/ripd/rip_interface.c \ + $(top_srcdir)/ripd/rip_offset.c \ + $(top_srcdir)/ripd/rip_zebra.c \ + $(top_srcdir)/ripd/ripd.c \ + # end + if SNMP module_LTLIBRARIES += ripd/ripd_snmp.la endif +man8 += $(MANBUILD)/ripd.8 endif ripd_librip_a_SOURCES = \ diff --git a/ripngd/.gitignore b/ripngd/.gitignore index 213384d13..e6a8ee6be 100644 --- a/ripngd/.gitignore +++ b/ripngd/.gitignore @@ -1,17 +1,2 @@ -!Makefile -Makefile.in -*.o ripngd ripngd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT -*.a diff --git a/ripngd/subdir.am b/ripngd/subdir.am index 1f7ff09d6..8f834a1d2 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -5,6 +5,14 @@ if RIPNGD noinst_LIBRARIES += ripngd/libripng.a sbin_PROGRAMS += ripngd/ripngd +vtysh_scan += \ + $(top_srcdir)/ripngd/ripng_debug.c \ + $(top_srcdir)/ripngd/ripng_interface.c \ + $(top_srcdir)/ripngd/ripng_offset.c \ + $(top_srcdir)/ripngd/ripng_zebra.c \ + $(top_srcdir)/ripngd/ripngd.c \ + # end +man8 += $(MANBUILD)/ripngd.8 endif ripngd_libripng_a_SOURCES = \ diff --git a/sharpd/.gitignore b/sharpd/.gitignore index cc33cfc18..91b9f2e90 100644 --- a/sharpd/.gitignore +++ b/sharpd/.gitignore @@ -1,17 +1,2 @@ -Makefile -Makefile.in -*.o -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.a -*.libs -.arch-inventory -.arch-ids -*~ -*.loT sharpd sharpd.conf diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 9462eb575..797e336c2 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -191,6 +191,18 @@ DEFPY (remove_routes, return CMD_SUCCESS; } +DEFUN_NOSH (show_debugging_sharpd, + show_debugging_sharpd_cmd, + "show debugging [sharp]", + SHOW_STR + DEBUG_STR + "Sharp Information\n") +{ + vty_out(vty, "Sharp debugging status\n"); + + return CMD_SUCCESS; +} + void sharp_vty_init(void) { install_element(ENABLE_NODE, &install_routes_cmd); @@ -198,5 +210,8 @@ void sharp_vty_init(void) install_element(ENABLE_NODE, &vrf_label_cmd); install_element(ENABLE_NODE, &watch_nexthop_v6_cmd); install_element(ENABLE_NODE, &watch_nexthop_v4_cmd); + + install_element(VIEW_NODE, &show_debugging_sharpd_cmd); + return; } diff --git a/sharpd/subdir.am b/sharpd/subdir.am index 490a2ba78..2a34aecfb 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -6,6 +6,8 @@ if SHARPD noinst_LIBRARIES += sharpd/libsharp.a sbin_PROGRAMS += sharpd/sharpd dist_examples_DATA += sharpd/sharpd.conf.sample +vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c +man8 += $(MANBUILD)/sharpd.8 endif sharpd_libsharp_a_SOURCES = \ diff --git a/snapcraft/.gitignore b/snapcraft/.gitignore index ac7860290..a4796fd73 100644 --- a/snapcraft/.gitignore +++ b/snapcraft/.gitignore @@ -3,4 +3,3 @@ parts prime stage frr*.snap -!*/Makefile diff --git a/solaris/.gitignore b/solaris/.gitignore index a249b6199..3f1a0385a 100644 --- a/solaris/.gitignore +++ b/solaris/.gitignore @@ -17,6 +17,3 @@ depend.smf frr.init *.pkg *.pkg.gz -*~ -*.loT -*.a diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 771d8d1de..f697969a7 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -88,8 +88,8 @@ static struct list *static_list; static int static_list_compare_helper(const char *s1, const char *s2) { - /* Are Both NULL */ - if (s1 == s2) + /* extra (!s1 && !s2) to keep SA happy */ + if (s1 == s2 || (!s1 && !s2)) return 0; if (!s1 && s2) @@ -1390,6 +1390,18 @@ DEFPY(ipv6_route_vrf, table_str); } +DEFUN_NOSH (show_debugging_staticd, + show_debugging_staticd_cmd, + "show debugging [static]", + SHOW_STR + DEBUG_STR + "Static Information\n") +{ + vty_out(vty, "Static debugging status\n"); + + return CMD_SUCCESS; +} + void static_vty_init(void) { install_element(CONFIG_NODE, &ip_mroute_dist_cmd); @@ -1408,6 +1420,8 @@ void static_vty_init(void) install_element(CONFIG_NODE, &ipv6_route_cmd); install_element(VRF_NODE, &ipv6_route_vrf_cmd); + install_element(VIEW_NODE, &show_debugging_staticd_cmd); + static_list = list_new(); static_list->cmp = (int (*)(void *, void *))static_list_compare; static_list->del = (void (*)(void *))static_list_delete; diff --git a/staticd/subdir.am b/staticd/subdir.am index 3b06a92e2..33cc0e205 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -6,6 +6,8 @@ if STATICD noinst_LIBRARIES += staticd/libstatic.a sbin_PROGRAMS += staticd/staticd dist_examples_DATA += staticd/staticd.conf.sample +vtysh_scan += $(top_srcdir)/staticd/static_vty.c +man8 += $(MANBUILD)/staticd.8 endif staticd_libstatic_a_SOURCES = \ diff --git a/tests/.gitignore b/tests/.gitignore index c8368b39b..37cd245de 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,24 +1,6 @@ -Makefile -Makefile.in -*.o -tags -TAGS -.cache -.deps -.nfs* -*~ -*.loT -*.lo -*.la -*.libs -*.bak *.log *.sum *.xml -*.pyc -.arch-inventory -.arch-ids -__pycache__ .pytest_cache /bgpd/test_aspath /bgpd/test_bgp_table diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 000000000..dd4594feb --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C .. check +%: ALWAYS + @$(MAKE) -s -C .. tests/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index a7dec6734..000000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,235 +0,0 @@ -include ../common.am - -PYTHON ?= python - -AUTOMAKE_OPTIONS = subdir-objects -AM_CPPFLAGS += \ - -I.. \ - -I$(top_srcdir) \ - -I$(top_srcdir)/lib \ - -I$(top_builddir)/lib \ - -I$(top_srcdir)/tests/helpers/c \ - -I$(top_builddir)/tests/helpers/c \ - -O -DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" - -if BGPD -TESTS_BGPD = \ - bgpd/test_aspath \ - bgpd/test_capability \ - bgpd/test_packet \ - bgpd/test_peer_attr \ - bgpd/test_ecommunity \ - bgpd/test_mp_attr \ - bgpd/test_mpath \ - bgpd/test_bgp_table -else -TESTS_BGPD = -endif - -if ISISD -if SOLARIS -TESTS_ISISD = -else -TESTS_ISISD = \ - isisd/test_fuzz_isis_tlv \ - isisd/test_isis_vertex_queue \ - # end -endif -else -TESTS_ISISD = -endif - -if OSPF6D -TESTS_OSPF6D = \ - ospf6d/test_lsdb \ - # end -else -TESTS_OSPF6D = -endif - -if ENABLE_BGP_VNC -BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a -else -BGP_VNC_RFP_LIB = -endif - -lib/cli/test_cli.o: lib/cli/test_cli_clippy.c -ospf6d/test_lsdb.o: ospf6d/test_lsdb_clippy.c - -check_PROGRAMS = \ - lib/test_buffer \ - lib/test_checksum \ - lib/test_heavy_thread \ - lib/test_heavy_wq \ - lib/test_heavy \ - lib/test_memory \ - lib/test_nexthop_iter \ - lib/test_privs \ - lib/test_ringbuf \ - lib/test_srcdest_table \ - lib/test_segv \ - lib/test_sig \ - lib/test_stream \ - lib/test_table \ - lib/test_timer_correctness \ - lib/test_timer_performance \ - lib/test_ttable \ - lib/test_zlog \ - lib/test_graph \ - lib/cli/test_cli \ - lib/cli/test_commands \ - $(TESTS_BGPD) \ - $(TESTS_ISISD) \ - $(TESTS_OSPF6D) \ - # end - -if ZEROMQ -check_PROGRAMS += \ - lib/test_zmq \ - # end -endif - -../vtysh/vtysh_cmd.c: - $(MAKE) -C ../vtysh vtysh_cmd.c - -lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c - sed \ - -e 's/"vtysh\.h"/"tests.h"/' \ - -e 's/vtysh_init_cmd/test_init_cmd/' \ - -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \ - < ../vtysh/vtysh_cmd.c \ - > "$@" - -isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz - gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@" - -noinst_HEADERS = \ - ./helpers/c/prng.h \ - ./helpers/c/tests.h \ - ./lib/cli/common_cli.h - -lib_test_buffer_SOURCES = lib/test_buffer.c -lib_test_checksum_SOURCES = lib/test_checksum.c -lib_test_heavy_thread_SOURCES = lib/test_heavy_thread.c helpers/c/main.c -lib_test_heavy_wq_SOURCES = lib/test_heavy_wq.c helpers/c/main.c -lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c -lib_test_memory_SOURCES = lib/test_memory.c -lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c -lib_test_privs_SOURCES = lib/test_privs.c -lib_test_ringbuf_SOURCES = lib/test_ringbuf.c -lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \ - helpers/c/prng.c -lib_test_segv_SOURCES = lib/test_segv.c -lib_test_sig_SOURCES = lib/test_sig.c -lib_test_stream_SOURCES = lib/test_stream.c -lib_test_table_SOURCES = lib/test_table.c -lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \ - helpers/c/prng.c -lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \ - helpers/c/prng.c -lib_test_ttable_SOURCES = lib/test_ttable.c -lib_test_zlog_SOURCES = lib/test_zlog.c -lib_test_graph_SOURCES = lib/test_graph.c -lib_test_zmq_SOURCES = lib/test_zmq.c -lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS) -lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c -lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \ - lib/cli/test_commands.c \ - helpers/c/prng.c -bgpd_test_aspath_SOURCES = bgpd/test_aspath.c -bgpd_test_capability_SOURCES = bgpd/test_capability.c -bgpd_test_packet_SOURCES = bgpd/test_packet.c -bgpd_test_peer_attr_SOURCES = bgpd/test_peer_attr.c -bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c -bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c -bgpd_test_mpath_SOURCES = bgpd/test_mpath.c -bgpd_test_bgp_table_SOURCES = bgpd/test_bgp_table.c -isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c -nodist_isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv_tests.h -BUILT_SOURCES=isisd/test_fuzz_isis_tlv_tests.h -CLEANFILES=isisd/test_fuzz_isis_tlv_tests.h -isisd_test_fuzz_isis_tlv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/tests/isisd -isisd_test_isis_vertex_queue_SOURCES = isisd/test_isis_vertex_queue.c - -ospf6d_test_lsdb_SOURCES = ospf6d/test_lsdb.c lib/cli/common_cli.c - -ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@ -BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm -ISISD_TEST_LDADD = ../isisd/libisis.a $(ALL_TESTS_LDADD) -OSPF6_TEST_LDADD = ../ospf6d/libospf6.a $(ALL_TESTS_LDADD) - -lib_test_buffer_LDADD = $(ALL_TESTS_LDADD) -lib_test_checksum_LDADD = $(ALL_TESTS_LDADD) -lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_memory_LDADD = $(ALL_TESTS_LDADD) -lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD) -lib_test_privs_LDADD = $(ALL_TESTS_LDADD) -lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD) -lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD) -lib_test_segv_LDADD = $(ALL_TESTS_LDADD) -lib_test_sig_LDADD = $(ALL_TESTS_LDADD) -lib_test_stream_LDADD = $(ALL_TESTS_LDADD) -lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm -lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) -lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) -lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) -lib_test_zlog_LDADD = $(ALL_TESTS_LDADD) -lib_test_graph_LDADD = $(ALL_TESTS_LDADD) -lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS) -lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) -lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) -bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD) -bgpd_test_capability_LDADD = $(BGP_TEST_LDADD) -bgpd_test_packet_LDADD = $(BGP_TEST_LDADD) -bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD) -bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD) -bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD) -bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD) -bgpd_test_bgp_table_LDADD = $(BGP_TEST_LDADD) -isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD) -isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD) -ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD) - -EXTRA_DIST = \ - runtests.py \ - bgpd/test_aspath.py \ - bgpd/test_capability.py \ - bgpd/test_ecommunity.py \ - bgpd/test_mp_attr.py \ - bgpd/test_mpath.py \ - bgpd/test_peer_attr.py \ - helpers/python/frrsix.py \ - helpers/python/frrtest.py \ - isisd/test_fuzz_isis_tlv.py \ - isisd/test_fuzz_isis_tlv_tests.h.gz \ - isisd/test_isis_vertex_queue.py \ - lib/cli/test_commands.in \ - lib/cli/test_commands.py \ - lib/cli/test_commands.refout \ - lib/cli/test_cli.in \ - lib/cli/test_cli.py \ - lib/cli/test_cli.refout \ - lib/test_nexthop_iter.py \ - lib/test_ringbuf.py \ - lib/test_srcdest_table.py \ - lib/test_stream.py \ - lib/test_stream.refout \ - lib/test_table.py \ - lib/test_timer_correctness.py \ - lib/test_ttable.py \ - lib/test_ttable.refout \ - lib/test_zlog.py \ - lib/test_graph.py \ - lib/test_graph.refout \ - ospf6d/test_lsdb.py \ - ospf6d/test_lsdb.in \ - ospf6d/test_lsdb.refout \ - # end - -.PHONY: tests.xml -tests.xml: $(check_PROGRAMS) - $(PYTHON) $(srcdir)/runtests.py --junitxml=$@ -v $(srcdir) -check: tests.xml diff --git a/tests/helpers/python/frrtest.py b/tests/helpers/python/frrtest.py index da9e447fc..60bee5c88 100644 --- a/tests/helpers/python/frrtest.py +++ b/tests/helpers/python/frrtest.py @@ -176,8 +176,14 @@ class TestRefOut(object): basedir = os.path.dirname(inspect.getsourcefile(type(self))) program = os.path.join(basedir, self.program) - refin = program + '.in' - refout = program + '.refout' + if getattr(self, 'built_refin', False): + refin = binpath(program) + '.in' + else: + refin = program + '.in' + if getattr(self, 'built_refout', False): + refout = binpath(program) + '.refout' + else: + refout = program + '.refout' intext = '' if os.path.exists(refin): diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index 67a159350..b75c1002d 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "test_fuzz_isis_tlv_tests.h" #include <zebra.h> @@ -114,7 +118,11 @@ static int test(FILE *input, FILE *output) const char *s_tlvs = isis_format_tlvs(tlvs); fprintf(output, "Unpacked TLVs:\n%s", s_tlvs); + struct isis_item *orig_auth = tlvs->isis_auth.head; + tlvs->isis_auth.head = NULL; + s_tlvs = isis_format_tlvs(tlvs); struct isis_tlvs *tlv_copy = isis_copy_tlvs(tlvs); + tlvs->isis_auth.head = orig_auth; isis_free_tlvs(tlvs); struct stream *s2 = stream_new(TEST_STREAM_SIZE); diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz Binary files differindex 4abbe8149..4a89bda84 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 3e31b8335..869dd732e 100644 --- a/tests/isisd/test_isis_vertex_queue.c +++ b/tests/isisd/test_isis_vertex_queue.c @@ -16,42 +16,46 @@ static size_t vertex_count; static void setup_test_vertices(void) { - union isis_N nid, nip = { - .ip.dest.family = AF_UNSPEC + struct isis_spftree t = { }; + struct prefix_pair p = { + }; + uint8_t node_id[7]; vertices = XMALLOC(MTYPE_TMP, sizeof(*vertices) * 16); - nip.ip.dest.family = AF_INET; - nip.ip.dest.prefixlen = 24; - inet_pton(AF_INET, "192.168.1.0", &nip.ip.dest.u.prefix4); - vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE); + p.dest.family = AF_INET; + p.dest.prefixlen = 24; + inet_pton(AF_INET, "192.168.1.0", &p.dest.u.prefix4); + vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE); vertices[vertex_count]->d_N = 20; vertex_count++; - nip.ip.dest.family = AF_INET; - nip.ip.dest.prefixlen = 24; - inet_pton(AF_INET, "192.168.2.0", &nip.ip.dest.u.prefix4); - vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE); + p.dest.family = AF_INET; + p.dest.prefixlen = 24; + inet_pton(AF_INET, "192.168.2.0", &p.dest.u.prefix4); + vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE); vertices[vertex_count]->d_N = 20; vertex_count++; - memset(nid.id, 0, sizeof(nid.id)); - nid.id[6] = 1; - vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_PSEUDO_TE_IS); + memset(node_id, 0, sizeof(node_id)); + node_id[6] = 1; + vertices[vertex_count] = isis_vertex_new(&t, node_id, + VTYPE_PSEUDO_TE_IS); vertices[vertex_count]->d_N = 15; vertex_count++; - memset(nid.id, 0, sizeof(nid.id)); - nid.id[5] = 2; - vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_NONPSEUDO_TE_IS); + memset(node_id, 0, sizeof(node_id)); + node_id[5] = 2; + vertices[vertex_count] = isis_vertex_new(&t, node_id, + VTYPE_NONPSEUDO_TE_IS); vertices[vertex_count]->d_N = 15; vertex_count++; - nip.ip.dest.family = AF_INET; - nip.ip.dest.prefixlen = 24; - inet_pton(AF_INET, "192.168.3.0", &nip.ip.dest.u.prefix4); - vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE); + p.dest.family = AF_INET; + p.dest.prefixlen = 24; + inet_pton(AF_INET, "192.168.3.0", &p.dest.u.prefix4); + vertices[vertex_count] = isis_vertex_new(&t, &p, VTYPE_IPREACH_TE); vertices[vertex_count]->d_N = 20; vertex_count++; }; diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c index 4cc15ba23..8f062d8b5 100644 --- a/tests/lib/cli/test_cli.c +++ b/tests/lib/cli/test_cli.c @@ -41,7 +41,7 @@ DUMMY_DEFUN(cmd13, "alt a X:X::X:X"); DUMMY_DEFUN(cmd14, "pat g { foo A.B.C.D$foo|foo|bar X:X::X:X$bar| baz } [final]"); -#include "lib/cli/test_cli_clippy.c" +#include "tests/lib/cli/test_cli_clippy.c" DEFPY(magic_test, magic_test_cmd, "magic (0-100) {ipv4net A.B.C.D/M|X:X::X:X$ipv6}", diff --git a/tests/lib/cli/test_cli.py b/tests/lib/cli/test_cli.py index e3c31c2d9..7371db283 100644 --- a/tests/lib/cli/test_cli.py +++ b/tests/lib/cli/test_cli.py @@ -2,3 +2,4 @@ import frrtest class TestCli(frrtest.TestRefOut): program = './test_cli' + built_refout = True diff --git a/tests/ospf6d/test_lsdb.c b/tests/ospf6d/test_lsdb.c index ec0835c71..24821febe 100644 --- a/tests/ospf6d/test_lsdb.c +++ b/tests/ospf6d/test_lsdb.c @@ -29,7 +29,7 @@ #include "ospf6d/ospf6_lsdb.h" #include "tests/lib/cli/common_cli.h" -#include "ospf6d/test_lsdb_clippy.c" +#include "tests/ospf6d/test_lsdb_clippy.c" static struct ospf6_lsdb *lsdb; diff --git a/tests/subdir.am b/tests/subdir.am new file mode 100644 index 000000000..739a0e86f --- /dev/null +++ b/tests/subdir.am @@ -0,0 +1,295 @@ +# +# tests +# + +PYTHON ?= python + +if BGPD +TESTS_BGPD = \ + tests/bgpd/test_aspath \ + tests/bgpd/test_capability \ + tests/bgpd/test_packet \ + tests/bgpd/test_peer_attr \ + tests/bgpd/test_ecommunity \ + tests/bgpd/test_mp_attr \ + tests/bgpd/test_mpath \ + tests/bgpd/test_bgp_table +else +TESTS_BGPD = +endif + +if ISISD +if SOLARIS +TESTS_ISISD = +else +TESTS_ISISD = \ + tests/isisd/test_fuzz_isis_tlv \ + tests/isisd/test_isis_vertex_queue \ + # end +endif +else +TESTS_ISISD = +endif + +if OSPF6D +TESTS_OSPF6D = \ + tests/ospf6d/test_lsdb \ + # end +else +TESTS_OSPF6D = +endif + +tests/lib/cli/tests_lib_cli_test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c +tests/lib/cli/test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c +tests/ospf6d/tests_ospf6d_test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c +tests/ospf6d/test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c + +check_PROGRAMS = \ + tests/lib/test_buffer \ + tests/lib/test_checksum \ + tests/lib/test_heavy_thread \ + tests/lib/test_heavy_wq \ + tests/lib/test_heavy \ + tests/lib/test_memory \ + tests/lib/test_nexthop_iter \ + tests/lib/test_privs \ + tests/lib/test_ringbuf \ + tests/lib/test_srcdest_table \ + tests/lib/test_segv \ + tests/lib/test_sig \ + tests/lib/test_stream \ + tests/lib/test_table \ + tests/lib/test_timer_correctness \ + tests/lib/test_timer_performance \ + tests/lib/test_ttable \ + tests/lib/test_zlog \ + tests/lib/test_graph \ + tests/lib/cli/test_cli \ + tests/lib/cli/test_commands \ + $(TESTS_BGPD) \ + $(TESTS_ISISD) \ + $(TESTS_OSPF6D) \ + # end + +if ZEROMQ +check_PROGRAMS += \ + tests/lib/test_zmq \ + # end +endif + +tests/lib/cli/test_commands_defun.c: vtysh/vtysh_cmd.c + sed \ + -e 's%"vtysh/vtysh\.h"%"tests/helpers/c/tests.h"%' \ + -e 's/vtysh_init_cmd/test_init_cmd/' \ + -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \ + < vtysh/vtysh_cmd.c \ + > "$@" + +tests/isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz + gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@" +CLEANFILES += tests/isisd/test_fuzz_isis_tlv_tests.h + +tests/isisd/tests_isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \ + tests/isisd/test_fuzz_isis_tlv_tests.h +tests/isisd/test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \ + tests/isisd/test_fuzz_isis_tlv_tests.h + +noinst_HEADERS += \ + tests/helpers/c/prng.h \ + tests/helpers/c/tests.h \ + tests/lib/cli/common_cli.h \ + # end + +# +# *sigh* - there is no way to get CPPFLAGS or CFLAGS for a group of files :( +# + +TESTS_CPPFLAGS = $(AM_CPPFLAGS) \ + -I$(top_srcdir)/tests/helpers/c \ + -I$(top_builddir)/tests/helpers/c \ + # end +TESTS_CFLAGS = $(SAN_FLAGS) +# note no -Werror + +ALL_TESTS_LDADD = lib/libfrr.la @LIBCAP@ +BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) -lm +ISISD_TEST_LDADD = isisd/libisis.a $(ALL_TESTS_LDADD) +OSPF6_TEST_LDADD = ospf6d/libospf6.a $(ALL_TESTS_LDADD) + +tests_bgpd_test_aspath_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_aspath_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_aspath_SOURCES = tests/bgpd/test_aspath.c +tests_bgpd_test_bgp_table_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_bgp_table_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_bgp_table_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_bgp_table_SOURCES = tests/bgpd/test_bgp_table.c +tests_bgpd_test_capability_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_capability_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_capability_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_capability_SOURCES = tests/bgpd/test_capability.c +tests_bgpd_test_ecommunity_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_ecommunity_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_ecommunity_SOURCES = tests/bgpd/test_ecommunity.c +tests_bgpd_test_mp_attr_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_mp_attr_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_mp_attr_SOURCES = tests/bgpd/test_mp_attr.c +tests_bgpd_test_mpath_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_mpath_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_mpath_SOURCES = tests/bgpd/test_mpath.c +tests_bgpd_test_packet_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_packet_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_packet_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_packet_SOURCES = tests/bgpd/test_packet.c +tests_bgpd_test_peer_attr_CFLAGS = $(TESTS_CFLAGS) +tests_bgpd_test_peer_attr_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD) +tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c + +tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd +tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd +tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD) +tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c +nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h +tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS) +tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD) +tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c + +tests_lib_cli_test_cli_CFLAGS = $(TESTS_CFLAGS) +tests_lib_cli_test_cli_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) +tests_lib_cli_test_cli_SOURCES = tests/lib/cli/test_cli.c tests/lib/cli/common_cli.c +tests_lib_cli_test_commands_CFLAGS = $(TESTS_CFLAGS) +tests_lib_cli_test_commands_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) +tests_lib_cli_test_commands_SOURCES = tests/lib/cli/test_commands_defun.c tests/lib/cli/test_commands.c tests/helpers/c/prng.c +tests_lib_test_buffer_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_buffer_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_buffer_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_buffer_SOURCES = tests/lib/test_buffer.c +tests_lib_test_checksum_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_checksum_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_checksum_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_checksum_SOURCES = tests/lib/test_checksum.c +tests_lib_test_graph_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_graph_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_graph_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_graph_SOURCES = tests/lib/test_graph.c +tests_lib_test_heavy_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_heavy_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_heavy_SOURCES = tests/lib/test_heavy.c tests/helpers/c/main.c +tests_lib_test_heavy_thread_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_heavy_thread_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_heavy_thread_SOURCES = tests/lib/test_heavy_thread.c tests/helpers/c/main.c +tests_lib_test_heavy_wq_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_heavy_wq_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_heavy_wq_SOURCES = tests/lib/test_heavy_wq.c tests/helpers/c/main.c +tests_lib_test_memory_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_memory_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_memory_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_memory_SOURCES = tests/lib/test_memory.c +tests_lib_test_nexthop_iter_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_nexthop_iter_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_nexthop_iter_SOURCES = tests/lib/test_nexthop_iter.c tests/helpers/c/prng.c +tests_lib_test_privs_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_privs_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_privs_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_privs_SOURCES = tests/lib/test_privs.c +tests_lib_test_ringbuf_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_ringbuf_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_ringbuf_SOURCES = tests/lib/test_ringbuf.c +tests_lib_test_segv_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_segv_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_segv_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_segv_SOURCES = tests/lib/test_segv.c +tests_lib_test_sig_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_sig_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_sig_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_sig_SOURCES = tests/lib/test_sig.c +tests_lib_test_srcdest_table_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_srcdest_table_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_srcdest_table_SOURCES = tests/lib/test_srcdest_table.c tests/helpers/c/prng.c +tests_lib_test_stream_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_stream_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_stream_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_stream_SOURCES = tests/lib/test_stream.c +tests_lib_test_table_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_table_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm +tests_lib_test_table_SOURCES = tests/lib/test_table.c +tests_lib_test_timer_correctness_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_timer_correctness_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_timer_correctness_SOURCES = tests/lib/test_timer_correctness.c tests/helpers/c/prng.c +tests_lib_test_timer_performance_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_timer_performance_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_timer_performance_SOURCES = tests/lib/test_timer_performance.c tests/helpers/c/prng.c +tests_lib_test_ttable_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_ttable_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_ttable_SOURCES = tests/lib/test_ttable.c +tests_lib_test_zlog_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_zlog_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_zlog_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_zlog_SOURCES = tests/lib/test_zlog.c +tests_lib_test_zmq_CFLAGS = $(TESTS_CFLAGS) $(ZEROMQ_CFLAGS) +tests_lib_test_zmq_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_zmq_LDADD = lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS) +tests_lib_test_zmq_SOURCES = tests/lib/test_zmq.c + +tests_ospf6d_test_lsdb_CFLAGS = $(TESTS_CFLAGS) +tests_ospf6d_test_lsdb_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD) +tests_ospf6d_test_lsdb_SOURCES = tests/ospf6d/test_lsdb.c tests/lib/cli/common_cli.c + +EXTRA_DIST += \ + tests/runtests.py \ + tests/bgpd/test_aspath.py \ + tests/bgpd/test_capability.py \ + tests/bgpd/test_ecommunity.py \ + tests/bgpd/test_mp_attr.py \ + tests/bgpd/test_mpath.py \ + tests/bgpd/test_peer_attr.py \ + tests/helpers/python/frrsix.py \ + tests/helpers/python/frrtest.py \ + tests/isisd/test_fuzz_isis_tlv.py \ + tests/isisd/test_fuzz_isis_tlv_tests.h.gz \ + tests/isisd/test_isis_vertex_queue.py \ + tests/lib/cli/test_commands.in \ + tests/lib/cli/test_commands.py \ + tests/lib/cli/test_commands.refout \ + tests/lib/cli/test_cli.in \ + tests/lib/cli/test_cli.py \ + tests/lib/cli/test_cli.refout \ + tests/lib/test_nexthop_iter.py \ + tests/lib/test_ringbuf.py \ + tests/lib/test_srcdest_table.py \ + tests/lib/test_stream.py \ + tests/lib/test_stream.refout \ + tests/lib/test_table.py \ + tests/lib/test_timer_correctness.py \ + tests/lib/test_ttable.py \ + tests/lib/test_ttable.refout \ + tests/lib/test_zlog.py \ + tests/lib/test_graph.py \ + tests/lib/test_graph.refout \ + tests/ospf6d/test_lsdb.py \ + tests/ospf6d/test_lsdb.in \ + tests/ospf6d/test_lsdb.refout \ + # end + +.PHONY: tests/tests.xml +tests/tests.xml: $(check_PROGRAMS) + ( cd tests; $(PYTHON) ../$(srcdir)/tests/runtests.py --junitxml=tests.xml -v ../$(srcdir)/tests; ) +check: tests/tests.xml diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c index c751c0b12..652d7618a 100644 --- a/tests/test_lblmgr.c +++ b/tests/test_lblmgr.c @@ -21,6 +21,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "lib/stream.h" #include "lib/zclient.h" diff --git a/tools/.gitignore b/tools/.gitignore index 7bf3be9db..d400dfe8f 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1,10 +1,2 @@ -!Makefile -.arch-inventory -.arch-ids - -*~ -*.loT -.libs -*.o /permutations /ssd diff --git a/tools/etc/iproute2/rt_protos.d/frr.conf b/tools/etc/iproute2/rt_protos.d/frr.conf index 4c6968ac2..bbb358fc6 100644 --- a/tools/etc/iproute2/rt_protos.d/frr.conf +++ b/tools/etc/iproute2/rt_protos.d/frr.conf @@ -11,3 +11,4 @@ 194 sharp 195 pbr 196 static +197 openfabric @@ -587,6 +587,7 @@ case "$1" in ip route flush proto 194 ip route flush proto 195 ip route flush proto 196 + ip route flush proto 197 else [ -n "$dmn" ] && eval "${dmn/-/_}=0" start_watchfrr diff --git a/tools/permutations.c b/tools/permutations.c index 80441753e..c5109dc3e 100644 --- a/tools/permutations.c +++ b/tools/permutations.c @@ -20,6 +20,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "command.h" #include "graph.h" #include "vector.h" diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c index de58e0a20..cc0315c13 100644 --- a/tools/start-stop-daemon.c +++ b/tools/start-stop-daemon.c @@ -25,12 +25,17 @@ * the whole automake/config.h dance. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef HAVE_LXC #define _GNU_SOURCE #include <sched.h> #endif /* HAVE_LXC */ #include <stddef.h> +#undef VERSION #define VERSION "1.9.18" #define MIN_POLL_INTERVAL 20000 /*us*/ @@ -602,7 +607,7 @@ static int pid_is_exec(pid_t pid, const struct stat *esb) struct stat sb; char buf[32]; - sprintf(buf, "/proc/%d/exe", pid); + sprintf(buf, "/proc/%ld/exe", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino); @@ -614,7 +619,7 @@ static int pid_is_user(pid_t pid, uid_t uid) struct stat sb; char buf[32]; - sprintf(buf, "/proc/%d", pid); + sprintf(buf, "/proc/%ld", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_uid == uid); @@ -627,7 +632,7 @@ static int pid_is_cmd(pid_t pid, const char *name) FILE *f; int c; - sprintf(buf, "/proc/%d/stat", pid); + sprintf(buf, "/proc/%ld/stat", (long)pid); f = fopen(buf, "r"); if (!f) return 0; @@ -659,12 +664,12 @@ static void check(pid_t pid) static void do_pidfile(const char *name) { FILE *f; - pid_t pid; + long pid; f = fopen(name, "r"); if (f) { - if (fscanf(f, "%d", &pid) == 1) - check(pid); + if (fscanf(f, "%ld", &pid) == 1) + check((pid_t)pid); fclose(f); } else if (errno != ENOENT) fatal("open pidfile %s: %s", name, strerror(errno)); @@ -677,7 +682,7 @@ static void do_procinit(void) DIR *procdir; struct dirent *entry; int foundany; - pid_t pid; + long pid; procdir = opendir("/proc"); if (!procdir) @@ -685,10 +690,10 @@ static void do_procinit(void) foundany = 0; while ((entry = readdir(procdir)) != NULL) { - if (sscanf(entry->d_name, "%d", &pid) != 1) + if (sscanf(entry->d_name, "%ld", &pid) != 1) continue; foundany++; - check(pid); + check((pid_t)pid); } closedir(procdir); if (!foundany) @@ -723,21 +728,21 @@ static void do_stop(int signal_nr, int quietmode, int *n_killed, for (p = found; p; p = p->next) { if (testmode) - printf("Would send signal %d to %d.\n", signal_nr, - p->pid); + printf("Would send signal %d to %ld.\n", signal_nr, + (long)p->pid); else if (kill(p->pid, signal_nr) == 0) { push(&killed, p->pid); (*n_killed)++; } else { - printf("%s: warning: failed to kill %d: %s\n", progname, - p->pid, strerror(errno)); + printf("%s: warning: failed to kill %ld: %s\n", + progname, (long)p->pid, strerror(errno)); (*n_notkilled)++; } } if (quietmode < 0 && killed) { printf("Stopped %s (pid", what_stop); for (p = killed; p; p = p->next) - printf(" %d", p->pid); + printf(" %ld", (long)p->pid); putchar(')'); if (retry_nr > 0) printf(", retry #%d", retry_nr); @@ -1050,7 +1055,7 @@ int main(int argc, char **argv) if (pidf == NULL) fatal("Unable to open pidfile `%s' for writing: %s", pidfile, strerror(errno)); - fprintf(pidf, "%d\n", pidt); + fprintf(pidf, "%ld\n", (long)pidt); fclose(pidf); } set_namespaces(); diff --git a/vtysh/.gitignore b/vtysh/.gitignore index 5856eac25..c1a39b8a1 100644 --- a/vtysh/.gitignore +++ b/vtysh/.gitignore @@ -1,16 +1,3 @@ -Makefile -Makefile.in -*.o vtysh -tags -TAGS -.deps vtysh_cmd.c -.nfs* extract.pl -.libs -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/vtysh/Makefile b/vtysh/Makefile new file mode 100644 index 000000000..07e093b0f --- /dev/null +++ b/vtysh/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS + @$(MAKE) -s -C .. vtysh/vtysh +%: ALWAYS + @$(MAKE) -s -C .. vtysh/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am deleted file mode 100644 index 936640c83..000000000 --- a/vtysh/Makefile.am +++ /dev/null @@ -1,178 +0,0 @@ -## Process this file with Automake to create Makefile.in - -include ../common.am - -if ENABLE_BGP_VNC -BGP_VNC_RFP_SRCDIR = @top_srcdir@/@LIBRFP@ -BGP_VNC_RFP_INCDIR = -I$(BGP_VNC_RFP_SRCDIR) -BGP_VNC_RFP_SRC = $(BGP_VNC_RFP_SRCDIR)/*.c -BGP_VNC_RFAPI_SRCDIR = @top_srcdir@/bgpd/rfapi -BGP_VNC_RFAPI_INCDIR = -I$(BGP_VNC_RFAPI_SRCDIR) -I$(top_srcdir)/bgpd -BGP_VNC_RFAPI_SRC = $(BGP_VNC_RFAPI_SRCDIR)/*.c -else -BGP_VNC_RFP_INCDIR = -BGP_VNC_RFP_SRCDIR = -BGP_VNC_RFP_SRC = -BGP_VNC_RFAPI_INCDIR = -BGP_VNC_RFAPI_SRCDIR = -BGP_VNC_RFAPI_SRC = -endif -AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \ - $(BGP_VNC_RFAPI_INCDIR) $(BGP_VNC_RFP_INCDIR) -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" - -LIBS = @LIBS@ @CURSES@ @LIBPAM@ - -bin_PROGRAMS = vtysh - -vtysh_SOURCES = vtysh_main.c vtysh.c vtysh_user.c vtysh_config.c -nodist_vtysh_SOURCES = vtysh_cmd.c -CLEANFILES = vtysh_cmd.c -noinst_HEADERS = vtysh.h vtysh_user.h -vtysh_LDADD = ../lib/libfrr.la @LIBCAP@ @LIBREADLINE@ - -examplesdir = $(exampledir) -dist_examples_DATA = vtysh.conf.sample - -EXTRA_DIST = extract.pl - -vtysh_scan = - -if PIMD -vtysh_scan += $(top_srcdir)/pimd/pim_cmd.c -endif - -if BGPD -vtysh_scan += $(top_srcdir)/bgpd/bgp_bfd.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_debug.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_dump.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_evpn_vty.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_filter.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_mplsvpn.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_nexthop.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_route.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_routemap.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_vty.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_flowspec_vty.c -endif - -if RPKI -vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c -endif - -if ISISD -vtysh_scan += $(top_srcdir)/isisd/isis_redist.c -vtysh_scan += $(top_srcdir)/isisd/isis_spf.c -vtysh_scan += $(top_srcdir)/isisd/isis_te.c -vtysh_scan += $(top_srcdir)/isisd/isis_vty.c -vtysh_scan += $(top_srcdir)/isisd/isisd.c -endif - -if OSPFD -vtysh_scan += $(top_srcdir)/ospfd/ospf_bfd.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_dump.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_opaque.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_ri.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_routemap.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_te.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_sr.c -vtysh_scan += $(top_srcdir)/ospfd/ospf_vty.c -endif - -if OSPF6D -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_abr.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_asbr.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_area.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_bfd.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_flood.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_interface.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_intra.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_lsa.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_message.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_neighbor.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_route.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_spf.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_top.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6_zebra.c -vtysh_scan += $(top_srcdir)/ospf6d/ospf6d.c -endif - -if RIPD -vtysh_scan += $(top_srcdir)/ripd/rip_debug.c -vtysh_scan += $(top_srcdir)/ripd/rip_interface.c -vtysh_scan += $(top_srcdir)/ripd/rip_offset.c -vtysh_scan += $(top_srcdir)/ripd/rip_zebra.c -vtysh_scan += $(top_srcdir)/ripd/ripd.c -endif - -if RIPNGD -vtysh_scan += $(top_srcdir)/ripngd/ripng_debug.c -vtysh_scan += $(top_srcdir)/ripngd/ripng_interface.c -vtysh_scan += $(top_srcdir)/ripngd/ripng_offset.c -vtysh_scan += $(top_srcdir)/ripngd/ripng_zebra.c -vtysh_scan += $(top_srcdir)/ripngd/ripngd.c -endif - -if LDPD -vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c -endif - -if NHRPD -vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c -endif - -if EIGRPD -vtysh_scan += $(top_srcdir)/eigrpd/eigrp_dump.c -#vtysh_scan += $(top_srcdir)/eigrpd/eigrp_routemap.c -vtysh_scan += $(top_srcdir)/eigrpd/eigrp_vty.c -endif - -if BABELD -vtysh_scan += $(top_srcdir)/babeld/babel_interface.c -vtysh_scan += $(top_srcdir)/babeld/babel_zebra.c -vtysh_scan += $(top_srcdir)/babeld/babeld.c -endif - -if SHARPD -vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c -endif - -if SNMP -vtysh_scan += $(top_srcdir)/lib/agentx.c -endif - -if PBRD -vtysh_scan += $(top_srcdir)/pbrd/pbr_vty.c -vtysh_scan += $(top_srcdir)/pbrd/pbr_debug.c -endif - -if STATICD -vtysh_scan += $(top_srcdir)/staticd/static_vty.c -endif - -if BFDD -vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c -endif - -vtysh_cmd_FILES = $(vtysh_scan) \ - $(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \ - $(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \ - $(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \ - $(top_srcdir)/lib/vrf.c $(top_srcdir)/lib/if.c \ - $(top_srcdir)/lib/vty.c $(top_srcdir)/zebra/debug.c \ - $(top_srcdir)/lib/logicalrouter.c \ - $(top_srcdir)/lib/nexthop_group.c \ - $(top_srcdir)/zebra/interface.c \ - $(top_srcdir)/zebra/irdp_interface.c \ - $(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \ - $(top_srcdir)/zebra/zserv.c $(top_srcdir)/zebra/router-id.c \ - $(top_srcdir)/zebra/zebra_routemap.c \ - $(top_srcdir)/zebra/zebra_fpm.c \ - $(top_srcdir)/zebra/zebra_ptm.c \ - $(top_srcdir)/zebra/zebra_mpls_vty.c \ - $(top_srcdir)/zebra/zebra_pw.c \ - $(top_srcdir)/watchfrr/watchfrr_vty.c \ - $(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC) - -vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl - ./extract.pl $(vtysh_cmd_FILES) > vtysh_cmd.c diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 92b5686a9..0f68e58d6 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -29,16 +29,18 @@ print <<EOF; #include "command.h" #include "linklist.h" -#include "vtysh.h" +#include "vtysh/vtysh.h" EOF my $cli_stomp = 0; -foreach (@ARGV) { - $file = $_; +sub scan_file { + my ( $file, $fabricd) = @_; + + $cppadd = $fabricd ? "-DFABRICD=1" : ""; - open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -I@top_builddir@ -I@srcdir@/ -I@srcdir@/.. -I@top_srcdir@/lib -I@top_builddir@/lib -I@top_srcdir@/bgpd -I@top_srcdir@/@LIBRFP@ -I@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $file |"); + open (FH, "@CPP@ -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @CPPFLAGS@ $cppadd $file |"); local $/; undef $/; $line = <FH>; close (FH); @@ -77,6 +79,10 @@ foreach (@ARGV) { $cmd =~ s/^\s+//g; $cmd =~ s/\s+$//g; + if ($fabricd) { + $cmd = "fabricd_" . $cmd; + } + # $protocol is VTYSH_PROTO format for redirection of user input if ($file =~ /lib\/keychain\.c$/) { $protocol = "VTYSH_RIPD"; @@ -107,9 +113,9 @@ foreach (@ARGV) { } elsif ($file =~ /lib\/plist\.c$/) { if ($defun_array[1] =~ m/ipv6/) { - $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_BABELD|VTYSH_ISISD"; + $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"; } else { - $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD"; + $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD"; } } elsif ($file =~ /lib\/distribute\.c$/) { @@ -132,6 +138,9 @@ foreach (@ARGV) { elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) { $protocol = "VTYSH_BGPD"; } + elsif ($fabricd) { + $protocol = "VTYSH_FABRICD"; + } else { ($protocol) = ($file =~ /^.*\/([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/); $protocol = "VTYSH_" . uc $protocol; @@ -170,6 +179,10 @@ foreach (@ARGV) { $ecmd =~ s/^\s+//g; $ecmd =~ s/\s+$//g; + if ($fabricd) { + $ecmd = "fabricd_" . $ecmd; + } + # Register $ecmd if (defined ($cmd2str{$ecmd})) { my ($key); @@ -187,6 +200,24 @@ foreach (@ARGV) { } } +foreach (@ARGV) { + if (/\/isisd\//) { + # We scan all the IS-IS files twice, once for isisd, + # once for fabricd. Exceptions are made for the files + # that are not shared between the two. + if (/isis_vty_isisd.c/) { + scan_file($_, 0); + } elsif (/isis_vty_fabricd.c/) { + scan_file($_, 1); + } else { + scan_file($_, 0); + scan_file($_, 1); + } + } else { + scan_file($_, 0); + } +} + # When we have cli commands that map to the same function name, we # can introduce subtle bugs due to code not being called when # we think it is. diff --git a/vtysh/subdir.am b/vtysh/subdir.am new file mode 100644 index 000000000..932429a87 --- /dev/null +++ b/vtysh/subdir.am @@ -0,0 +1,37 @@ +# +# vtysh +# + +if VTYSH +bin_PROGRAMS += vtysh/vtysh +dist_examples_DATA += vtysh/vtysh.conf.sample +man1 += $(MANBUILD)/vtysh.1 +endif + +vtysh_vtysh_SOURCES = \ + vtysh/vtysh_main.c \ + vtysh/vtysh.c \ + vtysh/vtysh_user.c \ + vtysh/vtysh_config.c \ + # end +nodist_vtysh_vtysh_SOURCES = \ + vtysh/vtysh_cmd.c \ + # end +CLEANFILES += vtysh/vtysh_cmd.c + +noinst_HEADERS += \ + vtysh/vtysh.h \ + vtysh/vtysh_user.h \ + # end + +vtysh_vtysh_LDADD = lib/libfrr.la @LIBCAP@ @LIBREADLINE@ @LIBS@ @CURSES@ @LIBPAM@ + +EXTRA_DIST += vtysh/extract.pl + +AM_V_EXTRACT = $(am__v_EXTRACT_$(V)) +am__v_EXTRACT_ = $(am__v_EXTRACT_$(AM_DEFAULT_VERBOSITY)) +am__v_EXTRACT_0 = @echo " EXTRACT " $@; +am__v_EXTRACT_1 = + +vtysh/vtysh_cmd.c: $(vtysh_scan) vtysh/extract.pl + $(AM_V_EXTRACT) vtysh/extract.pl $(vtysh_scan) > vtysh/vtysh_cmd.c diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index c249115fd..6a92b9081 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -132,6 +132,7 @@ struct vtysh_client vtysh_client[] = { {.fd = -1, .name = "eigrpd", .flag = VTYSH_EIGRPD, .next = NULL}, {.fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .next = NULL}, {.fd = -1, .name = "sharpd", .flag = VTYSH_SHARPD, .next = NULL}, + {.fd = -1, .name = "fabricd", .flag = VTYSH_FABRICD, .next = NULL}, {.fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL}, {.fd = -1, .name = "pbrd", .flag = VTYSH_PBRD, .next = NULL}, {.fd = -1, .name = "staticd", .flag = VTYSH_STATICD, .next = NULL}, @@ -1112,7 +1113,7 @@ static char *command_generator(const char *text, int state) return NULL; } -static char **new_completion(char *text, int start, int end) +static char **new_completion(const char *text, int start, int end) { char **matches; @@ -1141,6 +1142,10 @@ static struct cmd_node isis_node = { ISIS_NODE, "%s(config-router)# ", }; +static struct cmd_node openfabric_node = { + OPENFABRIC_NODE, "%s(config-router)# ", +}; + static struct cmd_node interface_node = { INTERFACE_NODE, "%s(config-if)# ", }; @@ -1252,9 +1257,7 @@ struct cmd_node link_params_node = { LINK_PARAMS_NODE, "%s(config-link-params)# ", }; -#if defined(HAVE_RPKI) static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1}; -#endif #if HAVE_BFDD > 0 static struct cmd_node bfd_node = { @@ -1424,7 +1427,6 @@ DEFUNSH(VTYSH_BGPD, address_family_ipv6_labeled_unicast, return CMD_SUCCESS; } -#if defined(HAVE_RPKI) DEFUNSH(VTYSH_BGPD, rpki, rpki_cmd, @@ -1435,8 +1437,6 @@ DEFUNSH(VTYSH_BGPD, return CMD_SUCCESS; } -#endif - DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd, "address-family <l2vpn evpn>", "Enter Address Family command mode\n" @@ -1653,6 +1653,15 @@ DEFUNSH(VTYSH_ISISD, router_isis, router_isis_cmd, "router isis WORD", return CMD_SUCCESS; } +DEFUNSH(VTYSH_FABRICD, router_openfabric, router_openfabric_cmd, "router openfabric WORD", + ROUTER_STR + "OpenFabric routing protocol\n" + "ISO Routing area tag\n") +{ + vty->node = OPENFABRIC_NODE; + return CMD_SUCCESS; +} + DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd, "route-map WORD <deny|permit> (1-65535)", "Create route-map or enter route-map command mode\n" @@ -1767,6 +1776,7 @@ static int vtysh_exit(struct vty *vty) case LDP_NODE: case LDP_L2VPN_NODE: case ISIS_NODE: + case OPENFABRIC_NODE: case RMAP_NODE: case PBRMAP_NODE: case VTY_NODE: @@ -1869,7 +1879,6 @@ DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc", } -#if defined(HAVE_RPKI) DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit", "Exit current mode and down to previous mode\n") { @@ -1882,7 +1891,6 @@ DEFUNSH(VTYSH_BGPD, rpki_quit, rpki_quit_cmd, "quit", { return rpki_exit(self, vty, argc, argv); } -#endif /* HAVE_RPKI */ DEFUNSH(VTYSH_PIMD|VTYSH_ZEBRA, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf", "Exit from VRF configuration mode\n") @@ -2042,6 +2050,18 @@ ALIAS(vtysh_exit_bfdd, vtysh_quit_bfdd_cmd, "quit", "Exit current mode and down to previous mode\n") #endif +DEFUNSH(VTYSH_FABRICD, vtysh_exit_fabricd, vtysh_exit_fabricd_cmd, "exit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit(vty); +} + +DEFUNSH(VTYSH_FABRICD, vtysh_quit_fabricd, vtysh_quit_fabricd_cmd, "quit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit_fabricd(self, vty, argc, argv); +} + DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit", "Exit current mode and down to previous mode\n") { @@ -2245,7 +2265,7 @@ DEFUN (vtysh_show_work_queues, DEFUN (vtysh_show_work_queues_daemon, vtysh_show_work_queues_daemon_cmd, - "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pbrd>", + "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pbrd|fabricd>", SHOW_STR "Work Queue information\n" "For the zebra daemon\n" @@ -2255,7 +2275,8 @@ DEFUN (vtysh_show_work_queues_daemon, "For the ospfv6 daemon\n" "For the bgp daemon\n" "For the isis daemon\n" - "For the pbr daemon\n") + "For the pbr daemon\n" + "For the fabricd daemon\n") { int idx_protocol = 2; unsigned int i; @@ -2593,7 +2614,7 @@ DEFUNSH(VTYSH_ALL, no_vtysh_config_enable_password, DEFUN (vtysh_write_terminal, vtysh_write_terminal_cmd, - "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]", + "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|fabricd|pimd>]", "Write running configuration to memory, network, or terminal\n" "Write to terminal\n" "For the zebra daemon\n" @@ -2604,6 +2625,7 @@ DEFUN (vtysh_write_terminal, "For the ldpd daemon\n" "For the bgp daemon\n" "For the isis daemon\n" + "For the fabricd daemon\n" "For the pim daemon\n") { unsigned int i; @@ -2630,7 +2652,7 @@ DEFUN (vtysh_write_terminal, DEFUN (vtysh_show_running_config, vtysh_show_running_config_cmd, - "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]", + "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|fabricd|pimd>]", SHOW_STR "Current operating configuration\n" "For the zebra daemon\n" @@ -2641,6 +2663,7 @@ DEFUN (vtysh_show_running_config, "For the ldp daemon\n" "For the bgp daemon\n" "For the isis daemon\n" + "For the fabricd daemon\n" "For the pim daemon\n") { return vtysh_write_terminal(self, vty, argc, argv); @@ -3386,8 +3409,7 @@ void vtysh_readline_init(void) rl_initialize(); rl_bind_key('?', (rl_command_func_t *)vtysh_rl_describe); rl_completion_entry_function = vtysh_completion_entry_function; - rl_attempted_completion_function = - (rl_completion_func_t *)new_completion; + rl_attempted_completion_function = new_completion; } char *vtysh_prompt(void) @@ -3494,10 +3516,9 @@ void vtysh_init_vty(void) install_node(&keychain_node, NULL); install_node(&keychain_key_node, NULL); install_node(&isis_node, NULL); + install_node(&openfabric_node, NULL); install_node(&vty_node, NULL); -#if defined(HAVE_RPKI) install_node(&rpki_node, NULL); -#endif #if HAVE_BFDD > 0 install_node(&bfd_node, NULL); install_node(&bfd_peer_node, NULL); @@ -3588,6 +3609,8 @@ void vtysh_init_vty(void) #endif install_element(ISIS_NODE, &vtysh_exit_isisd_cmd); install_element(ISIS_NODE, &vtysh_quit_isisd_cmd); + install_element(OPENFABRIC_NODE, &vtysh_exit_fabricd_cmd); + install_element(OPENFABRIC_NODE, &vtysh_quit_fabricd_cmd); install_element(KEYCHAIN_NODE, &vtysh_exit_ripd_cmd); install_element(KEYCHAIN_NODE, &vtysh_quit_ripd_cmd); install_element(KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd); @@ -3648,6 +3671,7 @@ void vtysh_init_vty(void) install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd); install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd); install_element(ISIS_NODE, &vtysh_end_all_cmd); + install_element(OPENFABRIC_NODE, &vtysh_end_all_cmd); install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd); install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd); install_element(RMAP_NODE, &vtysh_end_all_cmd); @@ -3697,6 +3721,7 @@ void vtysh_init_vty(void) install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd); #endif install_element(CONFIG_NODE, &router_isis_cmd); + install_element(CONFIG_NODE, &router_openfabric_cmd); install_element(CONFIG_NODE, &router_bgp_cmd); install_element(BGP_NODE, &address_family_vpnv4_cmd); install_element(BGP_NODE, &address_family_vpnv6_cmd); @@ -3732,12 +3757,10 @@ void vtysh_init_vty(void) install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd); install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd); -#if defined(HAVE_RPKI) install_element(CONFIG_NODE, &rpki_cmd); install_element(RPKI_NODE, &rpki_exit_cmd); install_element(RPKI_NODE, &rpki_quit_cmd); install_element(RPKI_NODE, &vtysh_end_all_cmd); -#endif /* EVPN commands */ install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd); diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 5bff01a50..ee980d512 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -41,6 +41,7 @@ DECLARE_MGROUP(MVTYSH) #define VTYSH_PBRD 0x04000 #define VTYSH_STATICD 0x08000 #define VTYSH_BFDD 0x10000 +#define VTYSH_FABRICD 0x20000 #define VTYSH_WAS_ACTIVE (-2) @@ -49,9 +50,9 @@ DECLARE_MGROUP(MVTYSH) /* watchfrr is not in ALL since library CLI functions should not be * run on it (logging & co. should stay in a fixed/frozen config, and * things like prefix lists are not even initialised) */ -#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD -#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD -#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD +#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD|VTYSH_FABRICD +#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD|VTYSH_FABRICD +#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD|VTYSH_FABRICD #define VTYSH_NS VTYSH_ZEBRA #define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 42f08342c..9f6e20f2b 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -245,6 +245,9 @@ void vtysh_config_parse_line(void *arg, const char *line) else if (strncmp(line, "router isis", strlen("router isis")) == 0) config = config_get(ISIS_NODE, line); + else if (strncmp(line, "router openfabric", strlen("router openfabric")) + == 0) + config = config_get(OPENFABRIC_NODE, line); else if (strncmp(line, "route-map", strlen("route-map")) == 0) config = config_get(RMAP_NODE, line); else if (strncmp(line, "pbr-map", strlen("pbr-map")) == 0) diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 86fa62f47..7e979f2c8 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -30,6 +30,16 @@ #include <readline/readline.h> #include <readline/history.h> +/* + * The append_history function only appears in newer versions + * of the readline library it appears like. Since we don't + * need this just silently ignore the code on these + * ancient platforms. + */ +#if !defined HAVE_APPEND_HISTORY +#define append_history(A, B) +#endif + #include <lib/version.h> #include "getopt.h" #include "command.h" diff --git a/watchfrr/.gitignore b/watchfrr/.gitignore index b8c020c04..b3f5a6cd9 100644 --- a/watchfrr/.gitignore +++ b/watchfrr/.gitignore @@ -1,16 +1 @@ -!Makefile -Makefile.in -*.o watchfrr -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -*~ -*.loT - diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am index 931f11ef6..f0b49c9a8 100644 --- a/watchfrr/subdir.am +++ b/watchfrr/subdir.am @@ -4,6 +4,8 @@ if WATCHFRR sbin_PROGRAMS += watchfrr/watchfrr +vtysh_scan += $(top_srcdir)/watchfrr/watchfrr_vty.c +man8 += $(MANBUILD)/watchfrr.8 endif noinst_HEADERS += \ diff --git a/zebra/.gitignore b/zebra/.gitignore index 4a06756a2..41a86e7d7 100644 --- a/zebra/.gitignore +++ b/zebra/.gitignore @@ -1,15 +1,3 @@ -!Makefile -Makefile.in -*.o zebra zebra.conf client -tags -TAGS -.deps -.nfs* -.libs -.arch-inventory -.arch-ids -*~ -*.loT diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c index 6ad590973..1f12d4c02 100644 --- a/zebra/if_ioctl_solaris.c +++ b/zebra/if_ioctl_solaris.c @@ -39,6 +39,7 @@ #include "zebra/interface.h" #include "zebra/ioctl_solaris.h" #include "zebra/rib.h" +#include "zebra/rt.h" #include "zebra/zebra_errors.h" static int if_get_addr(struct interface *, struct sockaddr *, const char *); @@ -56,7 +57,6 @@ static int interface_list_ioctl(int af) struct lifconf lifconf; struct interface *ifp; int n; - int save_errno; size_t needed, lastneeded = 0; char *buf = NULL; @@ -77,14 +77,12 @@ calculate_lifc_len: lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */ ret = ioctl(sock, SIOCGLIFNUM, &lifn); - save_errno = errno; - } if (ret < 0) { flog_err_sys(LIB_ERR_SYSTEM_CALL, "interface_list_ioctl: SIOCGLIFNUM failed %s", - safe_strerror(save_errno)); + safe_strerror(errno)); close(sock); return -1; } diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 588f1259c..184c5a4fa 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1048,67 +1048,6 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) return 0; } -/* helper function called by if_netlink_change - * to delete interfaces in case the interface moved - * to an other netns - */ -static void if_netlink_check_ifp_instance_consistency(uint16_t cmd, - struct interface *ifp, - ns_id_t ns_id) -{ - struct interface *other_ifp; - - /* - * look if interface name is also found on other netns - * - only if vrf backend is netns - * - do not concern lo interface - * - then remove previous one - * - for new link case, check found interface is not active - */ - if (!vrf_is_backend_netns() || - !strcmp(ifp->name, "lo")) - return; - other_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name); - if (!other_ifp) - return; - /* because previous interface may be inactive, - * interface is moved back to default vrf - * then one may find the same pointer; ignore - */ - if (other_ifp == ifp) - return; - if ((cmd == RTM_NEWLINK) - && (CHECK_FLAG(other_ifp->status, ZEBRA_INTERFACE_ACTIVE))) - return; - if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_NEWLINK) { - zlog_debug("RTM_NEWLINK %s(%u, VRF %u) replaces %s(%u, VRF %u)\n", - ifp->name, - ifp->ifindex, - ifp->vrf_id, - other_ifp->name, - other_ifp->ifindex, - other_ifp->vrf_id); - } else if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_DELLINK) { - zlog_debug("RTM_DELLINK %s(%u, VRF %u) is replaced by %s(%u, VRF %u)\n", - ifp->name, - ifp->ifindex, - ifp->vrf_id, - other_ifp->name, - other_ifp->ifindex, - other_ifp->vrf_id); - } - /* the found interface replaces the current one - * remove it - */ - if (cmd == RTM_DELLINK) - if_delete(ifp); - else - if_delete(other_ifp); - /* the found interface is replaced by the current one - * suppress it - */ -} - int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) { int len; @@ -1283,8 +1222,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex); - if_netlink_check_ifp_instance_consistency(RTM_NEWLINK, - ifp, ns_id); } else if (ifp->vrf_id != vrf_id) { /* VRF change for an interface. */ if (IS_ZEBRA_DEBUG_KERNEL) @@ -1358,8 +1295,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex); - if_netlink_check_ifp_instance_consistency(RTM_NEWLINK, - ifp, ns_id); } } else { /* Delete interface notification from kernel */ @@ -1385,8 +1320,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (!IS_ZEBRA_IF_VRF(ifp)) if_delete_update(ifp); - if_netlink_check_ifp_instance_consistency(RTM_DELLINK, - ifp, ns_id); } return 0; diff --git a/zebra/interface.c b/zebra/interface.c index eabf0638a..488980c46 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -203,7 +203,6 @@ struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp) if (rn->info) { ifp = (struct interface *)rn->info; route_unlock_node(rn); /* get */ - ifp->node = rn; return ifp; } @@ -254,30 +253,6 @@ struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns, return NULL; } -/* this function must be used only if the vrf backend - * is a netns backend - */ -struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id, - const char *ifname) -{ - struct interface *ifp; - struct ns *ns; - - RB_FOREACH (ns, ns_head, &ns_tree) { - if (ns->ns_id == ns_id) - continue; - /* if_delete_update has removed interface - * from zns->if_table - * so to look for interface, use the vrf list - */ - ifp = if_lookup_by_name(ifname, (vrf_id_t)ns->ns_id); - if (!ifp) - continue; - return ifp; - } - return NULL; -} - const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex) { struct interface *ifp; @@ -757,8 +732,12 @@ void if_delete_update(struct interface *ifp) ifp->node = NULL; /* if the ifp is in a vrf, move it to default so vrf can be deleted if - * desired */ - if (ifp->vrf_id) + * desired. This operation is not done for netns implementation to avoid + * collision with interface with the same name in the default vrf (can + * occur with this implementation whereas it is not possible with + * vrf-lite). + */ + if (ifp->vrf_id && !vrf_is_backend_netns()) if_handle_vrf_change(ifp, VRF_DEFAULT); /* Reset some zebra interface params to default values. */ diff --git a/zebra/interface.h b/zebra/interface.h index 956d430cf..02a05e614 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -328,8 +328,6 @@ extern void zebra_if_init(void); extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t); extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *, const char *); -extern struct interface *if_lookup_by_name_not_ns(ns_id_t ns_id, - const char *ifname); extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *); extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index a6b350de7..63bb2754e 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -100,7 +100,7 @@ static inline int is_selfroute(int proto) || (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP) || (proto == RTPROT_LDP) || (proto == RTPROT_BABEL) || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP) - || (proto == RTPROT_PBR)) { + || (proto == RTPROT_PBR) || (proto == RTPROT_OPENFABRIC)) { return 1; } @@ -147,6 +147,9 @@ static inline int zebra2proto(int proto) case ZEBRA_ROUTE_PBR: proto = RTPROT_PBR; break; + case ZEBRA_ROUTE_OPENFABRIC: + proto = RTPROT_OPENFABRIC; + break; default: /* * When a user adds a new protocol this will show up @@ -205,6 +208,9 @@ static inline int proto2zebra(int proto, int family) case RTPROT_PBR: proto = ZEBRA_ROUTE_PBR; break; + case RTPROT_OPENFABRIC: + proto = ZEBRA_ROUTE_OPENFABRIC; + break; default: /* * When a user adds a new protocol this will show up diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index c4f21d150..cefd1996a 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -54,6 +54,7 @@ #define RTPROT_SHARP 194 #define RTPROT_PBR 195 #define RTPROT_ZSTATIC 196 +#define RTPROT_OPENFABRIC 197 void rt_netlink_init(void); diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index c82f68984..40982639c 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -32,6 +32,7 @@ #include "zebra/rib.h" #include "zebra/rt.h" +#include "zebra/zebra_pbr.h" #include "zebra/zebra_errors.h" /* Thank you, Solaris, for polluting application symbol namespace. */ diff --git a/zebra/subdir.am b/zebra/subdir.am index 5dc375031..a87fcec41 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -5,6 +5,22 @@ if ZEBRA sbin_PROGRAMS += zebra/zebra dist_examples_DATA += zebra/zebra.conf.sample +vtysh_scan += \ + $(top_srcdir)/zebra/debug.c \ + $(top_srcdir)/zebra/interface.c \ + $(top_srcdir)/zebra/router-id.c \ + $(top_srcdir)/zebra/rtadv.c \ + $(top_srcdir)/zebra/zebra_mpls_vty.c \ + $(top_srcdir)/zebra/zebra_ptm.c \ + $(top_srcdir)/zebra/zebra_pw.c \ + $(top_srcdir)/zebra/zebra_routemap.c \ + $(top_srcdir)/zebra/zebra_vty.c \ + $(top_srcdir)/zebra/zserv.c \ + # end + +# can be loaded as DSO - always include for vtysh +vtysh_scan += $(top_srcdir)/zebra/irdp_interface.c +vtysh_scan += $(top_srcdir)/zebra/zebra_fpm.c if IRDP module_LTLIBRARIES += zebra/zebra_irdp.la @@ -16,6 +32,7 @@ if FPM module_LTLIBRARIES += zebra/zebra_fpm.la endif +man8 += $(MANBUILD)/zebra.8 ## endif ZEBRA endif @@ -132,10 +149,11 @@ zebra_zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic zebra_zebra_snmp_la_LIBADD = lib/libfrrsnmp.la zebra_zebra_fpm_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -zebra_zebra_fpm_la_LIBADD = $(Q_FPM_PB_CLIENT_LDOPTS) +zebra_zebra_fpm_la_LIBADD = zebra_zebra_fpm_la_SOURCES = zebra/zebra_fpm.c zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_netlink.c if HAVE_PROTOBUF +zebra_zebra_fpm_la_LIBADD += fpm/libfrrfpm_pb.la qpb/libfrr_pb.la $(PROTOBUF_C_LIBS) zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_protobuf.c if DEV_BUILD zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_dt.c diff --git a/zebra/zebra_fpm_protobuf.c b/zebra/zebra_fpm_protobuf.c index ebd632270..be0f6a23b 100644 --- a/zebra/zebra_fpm_protobuf.c +++ b/zebra/zebra_fpm_protobuf.c @@ -129,6 +129,7 @@ static inline int add_nexthop(qpb_allocator_t *allocator, Fpm__AddRoute *msg, } // TODO: Use src. + (void)src; return 1; } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 5a0c722e3..2eb789d74 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -266,7 +266,8 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, There was a crash because ifp here was coming to be NULL */ if (ifp) if (connected_is_unnumbered(ifp) - || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) { + || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE) + || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); } @@ -303,8 +304,10 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re, nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; nexthop->gate.ipv6 = *ipv6; nexthop->ifindex = ifindex; - if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE) + || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); + } route_entry_nexthop_add(re, nexthop); @@ -428,8 +431,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re, /* Skip nexthops that have been filtered out due to route-map */ /* The nexthops are specific to this route and so the same */ /* nexthop for a different route may not have this flag set */ - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Nexthop Filtered", + __PRETTY_FUNCTION__); return 0; + } /* * Check to see if we should trust the passed in information @@ -438,13 +445,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re, */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); - if (ifp && connected_is_unnumbered(ifp)) { + if ((ifp && connected_is_unnumbered(ifp)) + || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) { if (if_is_operative(ifp)) return 1; - else + else { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Onlink and interface %s is not operative", + __PRETTY_FUNCTION__, ifp->name); return 0; - } else + } + } else { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Interface %s is not unnumbered", + __PRETTY_FUNCTION__, + ifp ? ifp->name : "Unknown"); return 0; + } } /* Make lookup prefix. */ @@ -466,8 +485,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re, } /* Lookup table. */ table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id); - if (!table) + if (!table) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Table not found", + __PRETTY_FUNCTION__); return 0; + } rn = route_node_match(table, (struct prefix *)&p); while (rn) { @@ -480,15 +503,25 @@ static int nexthop_active(afi_t afi, struct route_entry *re, */ if (top && rn == top) if (((afi == AFI_IP) && (rn->p.prefixlen != 32)) - || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) + || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Matched against ourself and prefix length is not max bit length", + __PRETTY_FUNCTION__); return 0; + } /* Pick up selected route. */ /* However, do not resolve over default route unless explicitly * allowed. */ if (is_default_prefix(&rn->p) - && !rnh_resolve_via_default(p.family)) + && !rnh_resolve_via_default(p.family)) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t:%s: Resolved against default route", + __PRETTY_FUNCTION__); return 0; + } dest = rib_dest_from_rnode(rn); if (dest && dest->selected_fib @@ -540,6 +573,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re, } if (resolved && set) re->nexthop_mtu = match->mtu; + if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Recursion failed to find", + __PRETTY_FUNCTION__); return resolved; } else if (re->type == ZEBRA_ROUTE_STATIC) { resolved = 0; @@ -558,6 +594,11 @@ static int nexthop_active(afi_t afi, struct route_entry *re, } if (resolved && set) re->nexthop_mtu = match->mtu; + + if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug( + "\t%s: Static route unable to resolve", + __PRETTY_FUNCTION__); return resolved; } else { return 0; @@ -900,8 +941,12 @@ static unsigned nexthop_active_check(struct route_node *rn, default: break; } - if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: Unable to find a active nexthop", + __PRETTY_FUNCTION__); return 0; + } /* XXX: What exactly do those checks do? Do we support * e.g. IPv4 routes with IPv6 nexthops or vice versa? */ diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 1570edcad..a0a90ac28 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -207,6 +207,9 @@ static int host_rb_entry_compare(const struct host_rb_entry *hle1, return 1; return 0; + } else if (hle1->p.family == AF_INET6) { + return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6, + IPV6_MAX_BYTELEN); } else { zlog_debug("%s: Unexpected family type: %d", __PRETTY_FUNCTION__, hle1->p.family); |