diff options
| -rw-r--r-- | bgpd/bgp_packet.c | 9 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 6 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 2 | ||||
| -rw-r--r-- | doc/developer/workflow.rst | 9 | ||||
| -rw-r--r-- | doc/manpages/bgpd.rst | 5 | ||||
| -rw-r--r-- | doc/user/nhrpd.rst | 93 | ||||
| -rw-r--r-- | doc/user/overview.rst | 142 | ||||
| -rw-r--r-- | doc/user/zebra.rst | 19 | ||||
| -rw-r--r-- | ospfd/ospf_interface.c | 4 | ||||
| -rw-r--r-- | tests/lib/test_typelist.h | 9 | ||||
| -rw-r--r-- | tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf | 5 | ||||
| -rw-r--r-- | tests/topotests/bgp_ebgp_requires_policy/r5/zebra.conf | 9 | ||||
| -rw-r--r-- | tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf | 3 | ||||
| -rw-r--r-- | tests/topotests/bgp_ebgp_requires_policy/r6/zebra.conf | 6 | ||||
| -rw-r--r-- | tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py | 74 | ||||
| -rwxr-xr-x | vtysh/extract.pl.in | 2 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 11 | ||||
| -rw-r--r-- | vtysh/vtysh.h | 2 | ||||
| -rw-r--r-- | zebra/router-id.c | 31 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 3 |
20 files changed, 308 insertions, 136 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 5296246b31..b7e9af002b 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1658,10 +1658,11 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) if (peer->nsf[afi][safi]) bgp_clear_stale_route(peer, afi, safi); - zlog_info("%%NOTIFICATION: rcvd End-of-RIB for %s from %s in vrf %s", - get_afi_safi_str(afi, safi, false), peer->host, - vrf ? vrf->name : VRF_DEFAULT_NAME); - } + zlog_info( + "%s: rcvd End-of-RIB for %s from %s in vrf %s", + __func__, get_afi_safi_str(afi, safi, false), + peer->host, vrf ? vrf->name : VRF_DEFAULT_NAME); + } } /* Everything is done. We unintern temporary structures which diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 11118af400..64d7ce9e9f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4357,6 +4357,9 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi) int bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) { + if (peer->sort == BGP_PEER_IBGP) + return 1; + if (peer->sort == BGP_PEER_EBGP && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter) || FILTER_LIST_OUT_NAME(filter) @@ -4367,6 +4370,9 @@ int bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) int bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter) { + if (peer->sort == BGP_PEER_IBGP) + return 1; + if (peer->sort == BGP_PEER_EBGP && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter) || FILTER_LIST_IN_NAME(filter) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0ff64c527b..fd1c1ffd7c 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2843,7 +2843,7 @@ DEFUN (no_bgp_listen_range, argv_find(argv, argc, "A.B.C.D/M", &idx); argv_find(argv, argc, "X:X::X:X/M", &idx); char *prefix = argv[idx]->arg; - argv_find(argv, argc, "WORD", &idx); + argv_find(argv, argc, "PGNAME", &idx); char *peergroup = argv[idx]->arg; /* Convert IP prefix string to struct prefix. */ diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index 40378f0219..8ce3bdeeb2 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -283,7 +283,10 @@ Pre-submission Checklist - ``make test`` - In the case of a major new feature or other significant change, document - plans for continued maintenance of the feature + plans for continued maintenance of the feature. In addition it is a + requirement that automated testing must be written that exercises + the new feature within our existing CI infrastructure. Also the + addition of automated testing to cover any pull request is encouraged. .. _signing-off: @@ -452,6 +455,10 @@ Guidelines for code review may originate with a reviewer or document agreement reached on Slack, the Development mailing list, or the weekly technical meeting. +- Reviewers may ask for new automated testing if they feel that the + code change is large enough/significant enough to warrant such + a requirement. + Coding Practices & Style ======================== diff --git a/doc/manpages/bgpd.rst b/doc/manpages/bgpd.rst index 079aad8c48..f7e20265e5 100644 --- a/doc/manpages/bgpd.rst +++ b/doc/manpages/bgpd.rst @@ -39,11 +39,6 @@ OPTIONS available for the |DAEMON| command: processes in the same namespace. This option is different than the --no_zebra option in that a ZAPI connection is made. -.. option:: -S, --skip_runas - - Skip the normal process of checking capabilities and changing user and group - information. - .. option:: -e, --ecmp Run BGP with a limited ecmp capability, that is different than what BGP diff --git a/doc/user/nhrpd.rst b/doc/user/nhrpd.rst index ec6bc56e76..95ef9cb7ee 100644 --- a/doc/user/nhrpd.rst +++ b/doc/user/nhrpd.rst @@ -4,8 +4,8 @@ NHRP **** -*nhrpd* is an implementation of the :abbr:NHRP `(Next Hop Routing Protocol)`. -NHRP is described in :rfc`2332`. +*nhrpd* is an implementation of the :abbr:`NHRP (Next Hop Routing Protocol)`. +NHRP is described in :rfc:`2332`. NHRP is used to improve the efficiency of routing computer network traffic over :abbr:`NBMA (Non-Broadcast, Multiple Access)` networks. NHRP provides an @@ -13,6 +13,13 @@ ARP-like solution that allows a system to dynamically learn the NBMA address of the other systems that are part of that network, allowing these systems to directly communicate without requiring traffic to use an intermediate hop. +NHRP is a client-server protocol. The server side is called the :abbr:`NHS +(Next Hop Server)` or the hub, while a client is referred to as the :abbr:`NHC +(Next Hop Client)` or the spoke. When a node is configured as an NHC, it +registers its address with the NHS which keeps track of all registered spokes. +An NHC client can then query the addresses of other clients from NHS allowing +all spokes to communicate directly with each other. + Cisco Dynamic Multipoint VPN (DMVPN) is based on NHRP, and |PACKAGE_NAME| nhrpd implements this scenario. @@ -31,7 +38,9 @@ This is similar to Cisco FlexVPN; but in contrast to opennhrp which uses a generic subnet route. To create NBMA GRE tunnel you might use the following (Linux terminal -commands)::: +commands): + +.. code-block:: console ip tunnel add gre1 mode gre key 42 ttl 64 ip addr add 10.255.255.2/32 dev gre1 @@ -68,7 +77,58 @@ command defines the GRE subnet): Configuring NHRP ================ -FIXME +.. index:: ip nhrp holdtime (1-65000) +.. clicmd:: ip nhrp holdtime (1-65000) + + Holdtime is the number of seconds that have to pass before stopping to + advertise an NHRP NBMA address as valid. It also controls how often NHRP + registration requests are sent. By default registrations are sent every one + third of the holdtime. + +.. index:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local +.. clicmd:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local + + Map an IP address of a station to the station's NBMA address. + +.. index:: ip nhrp network-id (1-4294967295) +.. clicmd:: ip nhrp network-id (1-4294967295) + + Enable NHRP on this interface and set the interface's network ID. The + network ID is used to allow creating multiple nhrp domains on a router when + multiple interfaces are configured on the router. Interfaces configured + with the same ID are part of the same logical NBMA network. The ID is a + local only parameter and is not sent to other NHRP nodes and so IDs on + different nodes do not need to match. When NHRP packets are received on an + interface they are assigned to the local NHRP domain for that interface. + +.. index:: ip nhrp nhs A.B.C.D nbma A.B.C.D|FQDN +.. clicmd:: ip nhrp nhs A.B.C.D nbma A.B.C.D|FQDN + + Configure the Next Hop Server address and its NBMA address. + +.. index:: ip nhrp nhs dynamic nbma A.B.C.D +.. clicmd:: ip nhrp nhs dynamic nbma A.B.C.D + + Configure the Next Hop Server to have a dynamic address and set its NBMA + address. + +.. index:: ip nhrp registration no-unique +.. clicmd:: ip nhrp registration no-unique + + Allow the client to not set the unique flag in the NHRP packets. This is + useful when a station has a dynamic IP address that could change over time. + +.. index:: ip nhrp shortcut +.. clicmd:: ip nhrp shortcut + + Enable shortcut (spoke-to-spoke) tunnels to allow NHC to talk to each others + directly after establishing a connection without going through the hub. + +.. index:: ip nhrp mtu +.. clicmd:: ip nhrp mtu + + Configure NHRP advertised MTU. + .. _hub-functionality: @@ -92,25 +152,25 @@ This can be achieved with the following iptables rule. --hashlimit-name loglimit-0 -j NFLOG --nflog-group 1 --nflog-range 128 -You can fine tune the src/dstmask according to the prefix lengths you -announce internal, add additional IP range matches, or rate limitation -if needed. However, the above should be good in most cases. +You can fine tune the src/dstmask according to the prefix lengths you announce +internal, add additional IP range matches, or rate limitation if needed. +However, the above should be good in most cases. This kernel NFLOG target's nflog-group is configured in global nhrp config with: -.. code-block:: frr - - nhrp nflog-group 1 +.. index:: nhrp nflog-group (1-65535) +.. clicmd:: nhrp nflog-group (1-65535) To start sending these traffic notices out from hubs, use the nhrp per-interface directive: -.. code-block:: frr - - interface gre1 - ip nhrp redirect +.. index:: ip nhrp redirect +.. clicmd:: ip nhrp redirect +This enable redirect replies on the NHS similar to ICMP redirects except this +is managed by the nhrp protocol. This setting allows spokes to communicate with +each others directly. .. _integration-with-ike: @@ -134,7 +194,10 @@ git repositories for the patches. NHRP Events =========== -FIXME +.. index:: nhrp event socket SOCKET +.. clicmd:: nhrp event socket SOCKET + + Configure the Unix path for the event socket. Configuration Example ===================== diff --git a/doc/user/overview.rst b/doc/user/overview.rst index 03d7299bf7..db490b518e 100644 --- a/doc/user/overview.rst +++ b/doc/user/overview.rst @@ -4,65 +4,23 @@ Overview ******** -`FRR`_ is a routing software package that provides TCP/IP based routing -services with routing protocols support such as BGP, RIP, OSPF, IS-IS and more -(see :ref:`supported-protocols`). FRR also supports -special BGP Route Reflector and Route Server behavior. In addition to -traditional IPv4 routing protocols, FRR also supports IPv6 routing protocols. -With an SNMP daemon that supports the AgentX protocol, FRR provides routing -protocol MIB read-only access (:ref:`snmp-support`). - -FRR uses an advanced software architecture to provide you with a high quality, -multi server routing engine. FRR has an interactive user interface for each -routing protocol and supports common client commands. Due to this design, you -can add new protocol daemons to FRR easily. You can use FRR library as your -program's client user interface. - -FRR is distributed under the GNU General Public License. +`FRR`_ is a fully featured, high performance, free software IP routing suite. -FRR is a fork of `Quagga <http://www.quagga.net/>`_. +FRR implements all standard routing protocols such as BGP, RIP, OSPF, IS-IS and +more (see :ref:`feature-matrix`), as well as many of their extensions. -.. _about-frr: +FRR is a high performance suite written primarily in C. It can easily handle +full Internet routing tables and is suitable for use on hardware ranging from +cheap SBCs to commercial grade routers. It is actively used in production by +hundreds of companies, universities, research labs and governments. -About FRR -========= +FRR is distributed under GPLv2, with development modeled after the Linux +kernel. Anyone may contribute features, bug fixes, tools, documentation +updates, or anything else. -Today, TCP/IP networks are covering all of the world. The Internet has been -deployed in many countries, companies, and to the home. When you connect to -the Internet your packet will pass many routers which have TCP/IP routing -functionality. - -A system with FRR installed acts as a dedicated router. With FRR, your machine -exchanges routing information with other routers using routing protocols. FRR -uses this information to update the kernel routing table so that the right data -goes to the right place. You can dynamically change the configuration and you -may view routing table information from the FRR terminal interface. - -Adding to routing protocol support, FRR can setup interface's flags, -interface's address, static routes and so on. If you have a small network, or -a stub network, or xDSL connection, configuring the FRR routing software is -very easy. The only thing you have to do is to set up the interfaces and put a -few commands about static routes and/or default routes. If the network is -rather large, or if the network structure changes frequently, you will want to -take advantage of FRR's dynamic routing protocol support for protocols such as -RIP, OSPF, IS-IS or BGP. - -Traditionally, UNIX based router configuration is done by *ifconfig* and -*route* commands. Status of routing table is displayed by *netstat* utility. -Almost of these commands work only if the user has root privileges. FRR has a -different system administration method. There are two user modes in FRR. One -is normal mode, the other is enable mode. Normal mode user can only view -system status, enable mode user can change system configuration. This UNIX -account independent feature will be great help to the router administrator. - -Currently, FRR supports common unicast routing protocols, that is BGP, OSPF, -RIP and IS-IS. Upcoming for MPLS support, an implementation of LDP is -currently being prepared for merging. Implementations of BFD and PIM-SSM -(IPv4) also exist, but are not actively being worked on. - -The ultimate goal of the FRR project is making a production-grade, high -quality, featureful and free IP routing software suite. +FRR is a fork of `Quagga <http://www.quagga.net/>`_. +.. _how-to-get-frr: How to get FRR ============== @@ -79,25 +37,46 @@ For instructions on installing from source, refer to the `developer documentation <http://docs.frrouting.org/projects/dev-guide/en/latest/>`_. +.. _about-frr: + +About FRR +========= + +FRR provides IP routing services. Its role in a networking stack is to exchange +routing information with other routers, make routing and policy decisions, and +inform other layers of these decisions. In the most common scenario, FRR +installs routing decisions into the OS kernel, allowing the kernel networking +stack to make the corresponding forwarding decisions. + +In addition to dynamic routing FRR supports the full range of L3 configuration, +including static routes, addresses, router advertisements etc. It has some +light L2 functionality as well, but this is mostly left to the platform. This +makes it suitable for deployments ranging from small home networks with static +routes to Internet exchanges running full Internet tables. + +FRR runs on all modern \*NIX operating systems, including Linux and the BSDs. +Feature support varies by platform; see the :ref:`feature-matrix`. + + System Architecture -=================== +------------------- .. index:: System architecture - .. index:: Software architecture - .. index:: Software internals Traditional routing software is made as a one process program which provides all of the routing protocol functionalities. FRR takes a different approach. -FRR is a suite of daemons that work together to build the routing table. There -is a daemon for each major supported protocol as well as a middleman daemon -(*Zebra*) which serves as the broker between these daemons and the kernel. +FRR is a suite of daemons that work together to build the routing table. Each +major protocol is implemented in its own daemon, and these daemons talk to a +middleman daemon (*zebra*), which is responsible for coordinating routing +decisions and talking to the dataplane. This architecture allows for high resiliency, since an error, crash or exploit -in one protocol daemon will generally not affect the others. It is also +in one protocol daemon will generally not affect the others. It is also flexible and extensible since the modularity makes it easy to implement new -protocols and tie them into the suite. +protocols and tie them into the suite. Additionally, each daemon implements a +plugin system allowing new functionality to be loaded at runtime. An illustration of the large scale architecture is given below. @@ -121,17 +100,23 @@ An illustration of the large scale architecture is given below. +-------------+ +------------------+ +-------------+ -The multi-process architecture brings extensibility, modularity and -maintainability. All of the FRR daemons can be managed through a single -integrated user interface shell called *vtysh*. *vtysh* connects to each -daemon through a UNIX domain socket and then works as a proxy for user input. -In addition to a unified frontend, *vtysh* also provides the ability to -configure all the daemons using a single configuration file through the -integrated configuration mode avoiding the problem of having to maintain a -separate configuration file for each daemon. +All of the FRR daemons can be managed through a single integrated user +interface shell called *vtysh*. *vtysh* connects to each daemon through a UNIX +domain socket and then works as a proxy for user input. In addition to a +unified frontend, *vtysh* also provides the ability to configure all the +daemons using a single configuration file through the integrated configuration +mode. This avoids the overhead of maintaining a separate configuration file for +each daemon. + +FRR is currently currently implementing a new internal configuration system +based on YANG data models. When this work is completed, FRR will be a fully +programmable routing stack. + + +.. _supported-platforms: Supported Platforms -=================== +------------------- .. index:: Supported platforms .. index:: FRR on other systems @@ -150,7 +135,7 @@ us know if you can get FRR to run on a platform which is not listed below: Versions of these platforms that are older than around 2 years from the point of their original release (in case of GNU/Linux, this is since the kernel's -release on https://kernel.org/) may need some work. Similarly, the following +release on https://kernel.org/) may need some work. Similarly, the following platforms may work with some effort: - Solaris @@ -162,14 +147,15 @@ Recent versions of the following compilers are well tested: - LLVM's Clang - Intel's ICC -.. _supported-protocols: +.. _feature-matrix: -Supported Protocols vs. Platform -================================ +Feature Matrix +^^^^^^^^^^^^^^ -The following table lists all protocols cross-refrenced to all operating -systems that have at least CI build tests. Note that for features, only -features with system dependencies are included here. +The following table lists all protocols cross-referenced to all operating +systems that have at least CI build tests. Note that for features, only +features with system dependencies are included here; if you don't see the +feature you're interested in, it should be supported on your platform. .. role:: mark diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 2099dfdd62..23a062ab02 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -916,3 +916,22 @@ zebra Terminal Mode Commands Display nexthop groups created by zebra. + +Router-id +========= + +Many routing protocols require a router-id to be configured. To have a +consistent router-id across all daemons, the following commands are available +to configure and display the router-id: + +.. index:: [no] router-id A.B.C.D [vrf NAME] +.. clicmd:: [no] router-id A.B.C.D [vrf NAME] + + Configure the router-id of this router. + +.. index:: show router-id [vrf NAME] +.. clicmd:: show router-id [vrf NAME] + + Display the user configured router-id. + + diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index cfcffcdb3d..8efb32af37 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -906,10 +906,12 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf, static void ospf_vl_if_delete(struct ospf_vl_data *vl_data) { + struct interface *ifp = vl_data->vl_oi->ifp; + vl_data->vl_oi->address->u.prefix4.s_addr = 0; vl_data->vl_oi->address->prefixlen = 0; ospf_if_free(vl_data->vl_oi); - if_delete(&vl_data->vl_oi->ifp); + if_delete(&ifp); vlink_count--; } diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h index f20bbc52d9..9039fa8a46 100644 --- a/tests/lib/test_typelist.h +++ b/tests/lib/test_typelist.h @@ -98,12 +98,13 @@ static void ts_hash(const char *text, const char *expect) unsigned i = 0; uint8_t hash[32]; char hashtext[65]; - uint32_t count; + uint32_t swap_count, count; - count = htonl(list_count(&head)); + count = list_count(&head); + swap_count = htonl(count); SHA256_Init(&ctx); - SHA256_Update(&ctx, &count, sizeof(count)); + SHA256_Update(&ctx, &swap_count, sizeof(swap_count)); frr_each (list, &head, item) { struct { @@ -115,7 +116,7 @@ static void ts_hash(const char *text, const char *expect) }; SHA256_Update(&ctx, &hashitem, sizeof(hashitem)); i++; - assert(i < count); + assert(i <= count); } SHA256_Final(hash, &ctx); diff --git a/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf new file mode 100644 index 0000000000..99e6b6818d --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf @@ -0,0 +1,5 @@ +router bgp 65000 + neighbor 192.168.255.2 remote-as 65000 + address-family ipv4 unicast + redistribute connected +! diff --git a/tests/topotests/bgp_ebgp_requires_policy/r5/zebra.conf b/tests/topotests/bgp_ebgp_requires_policy/r5/zebra.conf new file mode 100644 index 0000000000..7ef77a6015 --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r5/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.254/32 +! +interface r5-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf new file mode 100644 index 0000000000..164f975cb7 --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf @@ -0,0 +1,3 @@ +router bgp 65000 + bgp ebgp-requires-policy + neighbor 192.168.255.1 remote-as 65000 diff --git a/tests/topotests/bgp_ebgp_requires_policy/r6/zebra.conf b/tests/topotests/bgp_ebgp_requires_policy/r6/zebra.conf new file mode 100644 index 0000000000..1c617c4272 --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r6/zebra.conf @@ -0,0 +1,6 @@ +! +interface r6-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py index eecacfd00c..6660b4e866 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py +++ b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py @@ -5,7 +5,7 @@ # Part of NetDEF Topology Tests # # Copyright (c) 2019 by -# Network Device Education Foundation, Inc. ("NetDEF") +# Donatas Abraitis <donatas.abraitis@gmail.com> # # Permission to use, copy, modify, and/or distribute this software # for any purpose with or without fee is hereby granted, provided @@ -34,6 +34,7 @@ import sys import json import time import pytest +import functools CWD = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(CWD, '../')) @@ -48,7 +49,7 @@ class TemplateTopo(Topo): def build(self, *_args, **_opts): tgen = get_topogen(self) - for routern in range(1, 5): + for routern in range(1, 7): tgen.add_router('r{}'.format(routern)) switch = tgen.add_switch('s1') @@ -59,6 +60,10 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears['r3']) switch.add_link(tgen.gears['r4']) + switch = tgen.add_switch('s3') + switch.add_link(tgen.gears['r5']) + switch.add_link(tgen.gears['r6']) + def setup_module(mod): tgen = Topogen(TemplateTopo, mod.__name__) tgen.start_topology() @@ -81,32 +86,57 @@ def teardown_module(mod): tgen = get_topogen() tgen.stop_topology() -def test_bgp_remove_private_as(): +def test_ebgp_requires_policy(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) def _bgp_converge(router): - while True: - cmd = "show ip bgp neighbor 192.168.255.1 json" - output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) - if output['192.168.255.1']['bgpState'] == 'Established': - time.sleep(3) - return True - - def _bgp_ebgp_requires_policy(router): - cmd = "show ip bgp 172.16.255.254/32 json" - output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) - if 'prefix' in output: - return True - return False - - if _bgp_converge('r2'): - assert _bgp_ebgp_requires_policy('r2') == True - - if _bgp_converge('r4'): - assert _bgp_ebgp_requires_policy('r4') == False + output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + '192.168.255.1': { + 'bgpState': 'Established' + } + } + return topotest.json_cmp(output, expected) + + def _bgp_has_routes(router): + output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp neighbor 192.168.255.1 routes json")) + expected = { + 'routes': { + '172.16.255.254/32': [ + { + 'valid': True + } + ] + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, 'r2') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(router) + + test_func = functools.partial(_bgp_has_routes, 'r2') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(router) + + test_func = functools.partial(_bgp_converge, 'r4') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(router) + + test_func = functools.partial(_bgp_has_routes, 'r4') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(router) + + test_func = functools.partial(_bgp_converge, 'r6') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(router) + + test_func = functools.partial(_bgp_has_routes, 'r6') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'eBGP policy is not working (r6) in "{}"'.format(router) if __name__ == '__main__': args = ["-s"] + sys.argv[1:] diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index e8df08ef60..13413888bf 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -103,7 +103,7 @@ sub scan_file { $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA"; } elsif ($file =~ /lib\/nexthop_group\.c$/) { - $protocol = "VTYSH_PBRD | VTYSH_SHARPD"; + $protocol = "VTYSH_NH_GROUP"; } elsif ($file =~ /lib\/plist\.c$/) { if ($defun_array[1] =~ m/ipv6/) { diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 5c4e8a313b..b7d35caa39 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2163,7 +2163,8 @@ DEFUNSH(VTYSH_ZEBRA, vtysh_pseudowire, vtysh_pseudowire_cmd, return CMD_SUCCESS; } -DEFUNSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, +DEFUNSH(VTYSH_NH_GROUP, + vtysh_nexthop_group, vtysh_nexthop_group_cmd, "nexthop-group NHGNAME", "Nexthop Group configuration\n" "Name of the Nexthop Group\n") @@ -2172,7 +2173,7 @@ DEFUNSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_nexthop_group, vtysh_nexthop_group_cmd, return CMD_SUCCESS; } -DEFSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_no_nexthop_group_cmd, +DEFSH(VTYSH_NH_GROUP, vtysh_no_nexthop_group_cmd, "no nexthop-group NHGNAME", NO_STR "Nexthop Group Configuration\n" @@ -2209,13 +2210,15 @@ DEFUNSH(VTYSH_VRF, vtysh_quit_vrf, vtysh_quit_vrf_cmd, "quit", return vtysh_exit_vrf(self, vty, argc, argv); } -DEFUNSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_exit_nexthop_group, vtysh_exit_nexthop_group_cmd, +DEFUNSH(VTYSH_NH_GROUP, + vtysh_exit_nexthop_group, vtysh_exit_nexthop_group_cmd, "exit", "Exit current mode and down to previous mode\n") { return vtysh_exit(vty); } -DEFUNSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_quit_nexthop_group, vtysh_quit_nexthop_group_cmd, +DEFUNSH(VTYSH_NH_GROUP, + vtysh_quit_nexthop_group, vtysh_quit_nexthop_group_cmd, "quit", "Exit current mode and down to previous mode\n") { return vtysh_exit_nexthop_group(self, vty, argc, argv); diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index b16761b41a..d0edbb2710 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -56,6 +56,8 @@ DECLARE_MGROUP(MVTYSH) #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|VTYSH_VRRPD #define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD #define VTYSH_KEYS VTYSH_RIPD|VTYSH_EIGRPD +/* Daemons who can process nexthop-group configs */ +#define VTYSH_NH_GROUP VTYSH_PBRD|VTYSH_SHARPD enum vtysh_write_integrated { WRITE_INTEGRATED_UNSPECIFIED, diff --git a/zebra/router-id.c b/zebra/router-id.c index 569ffbab41..b37d4aea70 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -253,6 +253,36 @@ DEFUN (no_router_id, return CMD_SUCCESS; } +DEFUN (show_router_id, + show_router_id_cmd, + "show router-id [vrf NAME]", + SHOW_STR + "Show the configured router-id\n" + VRF_CMD_HELP_STR) +{ + int idx_name = 3; + + vrf_id_t vrf_id = VRF_DEFAULT; + struct zebra_vrf *zvrf; + + if (argc > 2) + VRF_GET_ID(vrf_id, argv[idx_name]->arg, false); + + zvrf = vrf_info_get(vrf_id); + + if ((zvrf != NULL) && (zvrf->rid_user_assigned.u.prefix4.s_addr)) { + vty_out(vty, "zebra:\n"); + if (vrf_id == VRF_DEFAULT) + vty_out(vty, " router-id %s vrf default\n", + inet_ntoa(zvrf->rid_user_assigned.u.prefix4)); + else + vty_out(vty, " router-id %s vrf %s\n", + inet_ntoa(zvrf->rid_user_assigned.u.prefix4), + argv[idx_name]->arg); + } + + return CMD_SUCCESS; +} static int router_id_cmp(void *a, void *b) { @@ -267,6 +297,7 @@ void router_id_cmd_init(void) { install_element(CONFIG_NODE, &router_id_cmd); install_element(CONFIG_NODE, &no_router_id_cmd); + install_element(VIEW_NODE, &show_router_id_cmd); } void router_id_init(struct zebra_vrf *zvrf) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index e77c923230..fff569c092 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2044,6 +2044,9 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx) addattr32(&req.n, req_size, NHA_OIF, nh->ifindex); + if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK)) + req.nhm.nh_flags |= RTNH_F_ONLINK; + num_labels = build_label_stack(nh->nh_label, out_lse, label_buf, sizeof(label_buf)); |
