vivek [Sun, 15 Nov 2015 18:21:12 +0000 (10:21 -0800)]
BGP: Fix nexthop registration churn
When a BGP nexthop is registered for resolution, if it is learnt from an
EBGP peer and other conditions warrant (non-multihop peer and connected check
is not disabled), the registration includes a flag that indicates that the
nexthop must be resolved only if it is directly connected. In peculiar
situations - e.g., third-party nexthop or policy configuration - the same
nexthop could be learnt from an IBGP peer, and in general, nexthops learnt
from IBGP peers can be resolved over any route. This scenario was causing
a churn in the nexthop registration with the 'must-be-connected' flag being
repeatedly toggled as routes are received from both peers. The registrations
would in turn trigger significant processing.
The fix is to treat 'must-be-connected' as an overriding condition.
The repeated registration and related processing was also causing heavy memory
usage by BGP - for memory buffers used to hold registration information. This
fix will ensure that is no longer the case.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-8005, CM-8013
Reviewed By: CCR-3772
Testing Done: Manual, bgpsmoke (on 2.5-br)
vivek [Sun, 15 Nov 2015 17:57:34 +0000 (09:57 -0800)]
BGP: Handle change to nexthop correctly
When a nexthop change is received and processed, the change flags are not
examined correctly and route change flags not updated correctly. Fix to
ensure correct handling.
vivek [Sun, 15 Nov 2015 15:36:50 +0000 (07:36 -0800)]
Zebra: Ensure correct route is used for redistribute delete.
After the optimization introduced by patch zebra-redist-update-fix.patch
which implements "replace" semantics for redistributed routes instead of
a delete followed by add, the code was passing an incorrect route for
redistribute deletion in one case. This is mainly inconsequential as of
now as the deletion process primarily cares about only the destination, but
the code needs to be corrected and that is done here.
vivek [Sun, 15 Nov 2015 15:17:47 +0000 (07:17 -0800)]
BGP: Fix the setting of link-local nexthops in some situations
This patch addresses three main issues:
a. Passing along the global IPv6 nexthop received from the EBGP peer to
IBGP peers but setting the link-local IPv6 nexthop to ourselves when
advertising EBGP-learnt routes to IBGP peers (in the absence of outbound
route-map or other overrides). The fix is to not send a link-local IPv6
nexthop in this case.
b. Passing along the link-local IPv6 nexthop received from one peer to
another peer which is (or may be) on a different subnet. This violates the
semantics of link-local IPv6 address. The fix is to set the nexthop to
ourselves in the situation where the nexthop normally has to be passed
but is a link-local IPv6 address.
c. Different behavior wrt nexthop advertisement for BGP unnumbered peering
if it is setup using link-local IPv6 address versus IPv4 /30 or /31. The
fix is to make the behavior consistent as long as the interface config is
the same in both cases.
Daniel Walton [Thu, 12 Nov 2015 20:30:22 +0000 (20:30 +0000)]
bgp may add multiple path entries with the same nexthop
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-8129
- We have 14 paths for each prefix, 7 are from ipv4 peers and 7 are from ipv6 peers
- There are 7 unique nexthops
- When comparing the exact same path from an v4 peer vs. a v6 peer the path from
the v4 peer wins. This is due to the "lowest neighbor IP" check in the decision
algorithm. For example below we learn NEXTHOP 210.2.4.2 from 210.2.4.2 and
2001:20:4::2 but only the one from the v4 peer is flagged as multipath.
- The problem is when our bestpath is from a v6 peer, 2001:20:2::2 in this case
(see line 85). 2001:20:2::2 sent us 210.2.2.2 so we will install that nexthop
because it is from our bestpath, the problem is we flag the path from 210.2.2.2
(line 37) as multipath which causes us to install two paths with nexthop 210.2.2.2
Here you can see the two paths with nexthop 210.2.2.2
superm-redxp-05# show ip route 2.23.24.192/28
Routing entry for 2.23.24.192/28
Known via "bgp", distance 20, metric 0, best
Last update 00:32:12 ago
* 210.2.2.2, via swp3
* 210.2.0.2, via swp1
* 210.2.1.2, via swp2
* 210.2.2.2, via swp3
* 210.2.3.2, via swp4
* 210.2.4.2, via swp5
* 210.2.5.2, via swp6
* 210.2.6.2, via swp7
superm-redxp-05#
superm-redxp-05#
The fix is to not flag a path as multipath if it has the same nexthop as the bestpath
Daniel Walton [Tue, 10 Nov 2015 15:29:12 +0000 (15:29 +0000)]
BGP: route-server will now use addpath...chop the _rsclient code
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-8122
per draft-ietf-idr-ix-bgp-route-server-09:
2.3.2.2.2. BGP ADD-PATH Approach
The [I-D.ietf-idr-add-paths] Internet draft proposes a different
approach to multiple path propagation, by allowing a BGP speaker to
forward multiple paths for the same prefix on a single BGP session.
As [RFC4271] specifies that a BGP listener must implement an implicit
withdraw when it receives an UPDATE message for a prefix which
already exists in its Adj-RIB-In, this approach requires explicit
support for the feature both on the route server and on its clients.
If the ADD-PATH capability is negotiated bidirectionally between the
route server and a route server client, and the route server client
propagates multiple paths for the same prefix to the route server,
then this could potentially cause the propagation of inactive,
invalid or suboptimal paths to the route server, thereby causing loss
of reachability to other route server clients. For this reason, ADD-
PATH implementations on a route server should enforce send-only mode
with the route server clients, which would result in negotiating
receive-only mode from the client to the route server.
This allows us to delete all of the following code:
- All XXXX_rsclient() functions
- peer->rib
- BGP_TABLE_MAIN and BGP_TABLE_RSCLIENT
- RMAP_IMPORT and RMAP_EXPORT
Daniel Walton [Thu, 5 Nov 2015 17:29:43 +0000 (17:29 +0000)]
BGP: support for addpath TX
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com
Ticket: CM-8014
This implements addpath TX with the first feature to use it
being "neighbor x.x.x.x addpath-tx-all-paths".
One change to show output is 'show ip bgp x.x.x.x'. If no addpath-tx
features are configured for any peers then everything looks the same
as it is today in that "Advertised to" is at the top and refers to
which peers the bestpath was advertise to.
root@superm-redxp-05[quagga-stash5]# vtysh -c 'show ip bgp 1.1.1.1'
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Advertised to non peer-group peers:
r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Last update: Fri Oct 30 18:26:44 2015
[snip]
but once you enable an addpath feature we must display "Advertised to" on a path-by-path basis:
superm-redxp-05# show ip bgp 1.1.1.1/32
BGP routing table entry for 1.1.1.1/32
Paths: (6 available, best #6, table Default-IP-Routing-Table)
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r2(10.0.0.2) (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 8
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:44 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r3(10.0.0.3) (10.0.0.3)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 7
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r6(10.0.0.6) (10.0.0.6)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 6
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
56.56.56.56 (metric 20) from r5(10.0.0.5) (10.0.0.5)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 5
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
34.34.34.34 (metric 20) from r4(10.0.0.4) (10.0.0.4)
Origin IGP, metric 0, localpref 100, valid, internal
AddPath ID: RX 0, TX 4
Advertised to: r8(10.0.0.8)
Last update: Fri Oct 30 18:26:39 2015
Local, (Received from a RR-client)
12.12.12.12 (metric 20) from r1(10.0.0.1) (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
AddPath ID: RX 0, TX 3
Advertised to: r1(10.0.0.1) r2(10.0.0.2) r3(10.0.0.3) r4(10.0.0.4) r5(10.0.0.5) r6(10.0.0.6) r8(10.0.0.8)
Last update: Fri Oct 30 18:26:34 2015
Feng Lu [Thu, 16 Oct 2014 01:52:36 +0000 (09:52 +0800)]
*: add VRF ID in the API message header
The API messages are used by zebra to exchange the interfaces, addresses,
routes and router-id information with its clients. To distinguish which
VRF the information belongs to, a new field "VRF ID" is added in the
message header. And hence the message version is increased to 3.
* The new field "VRF ID" in the message header:
Length (2 bytes)
Marker (1 byte)
Version (1 byte)
VRF ID (2 bytes, newly added)
Command (2 bytes)
- Client side:
- zclient_create_header() adds the VRF ID in the message header.
- zclient_read() extracts and validates the VRF ID from the header,
and passes the VRF ID to the callback functions registered to
the API messages.
- All relative functions are appended with a new parameter "vrf_id",
including all the callback functions.
- "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6".
Clients need to correctly set the VRF ID when using the API
functions zapi_ipv4_route() and zapi_ipv6_route().
- Till now all messages sent from a client have the default VRF ID
"0" in the header.
- The HELLO message is special, which is used as the heart-beat of
a client, and has no relation with VRF. The VRF ID in the HELLO
message header will always be 0 and ignored by zebra.
- Zebra side:
- zserv_create_header() adds the VRF ID in the message header.
- zebra_client_read() extracts and validates the VRF ID from the
header, and passes the VRF ID to the functions which process
the received messages.
- All relative functions are appended with a new parameter "vrf_id".
* Suppress the messages in a VRF which a client does not care:
Some clients may not care about the information in the VRF X, and
zebra should not send the messages in the VRF X to those clients.
Extra flags are used to indicate which VRF is registered by a client,
and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client
can unregister a VRF when it does not need any information in that
VRF.
A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF
will automatically register to that VRF.
- lib/vrf:
A new utility "VRF bit-map" is provided to manage the flags for
VRFs, one bit per VRF ID.
- Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a
bit-map;
- Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag
in the given bit-map, corresponding to the given VRF ID;
- Use vrf_bitmap_check() to test whether the flag, in the given
bit-map and for the given VRF ID, is set.
- Client side:
- In "struct zclient", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
default_information
These flags are extended for each VRF, and controlled by the
clients themselves (or with the help of zclient_redistribute()
and zclient_redistribute_default()).
- Zebra side:
- In "struct zserv", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
redist_default
ifinfo
ridinfo
These flags are extended for each VRF, as the VRF registration
flags. They are maintained on receiving a ZEBRA_XXX_ADD or
ZEBRA_XXX_DELETE message.
When sending an interface/address/route/router-id message in
a VRF to a client, if the corresponding VRF registration flag
is not set, this message will not be dropped by zebra.
- A new function zread_vrf_unregister() is introduced to process
the new command ZEBRA_VRF_UNREGISTER. All the VRF registration
flags are cleared for the requested VRF.
Those clients, who support only the default VRF, will never receive
a message in a non-default VRF, thanks to the filter in zebra.
* New callback for the event of successful connection to zebra:
- zclient_start() is splitted, keeping only the code of connecting
to zebra.
- Now zclient_init()=>zclient_connect()=>zclient_start() operations
are purely dealing with the connection to zbera.
- Once zebra is successfully connected, at the end of zclient_start(),
a new callback is used to inform the client about connection.
- Till now, in the callback of connect-to-zebra event, all clients
send messages to zebra to request the router-id/interface/routes
information in the default VRF.
Of corse in future the client can do anything it wants in this
callback. For example, it may send requests for both default VRF
and some non-default VRFs.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/zclient.h
lib/zebra.h
zebra/zserv.c
zebra/zserv.h
David Lamparter [Mon, 13 Apr 2015 08:21:37 +0000 (10:21 +0200)]
lib: optimise prefix list setup
- duplicate prefix check can use the trie structure
- appending with a seq# beyond the end of the list can shortcut
Configuration load is now bottlenecked by cmd_element_match() and
strcmp(). For a real-world routeserver prefix list configuration
(38668 lines of config for multiple prefix lists):
before: 4.73s
after: 1.92s x 2.46
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
David Lamparter [Mon, 13 Apr 2015 08:21:36 +0000 (10:21 +0200)]
lib: use trie structure for prefix list matching
Prefix lists were implemented with a simple linear list that is scanned
sequentially. This is, of course, extremely inefficient as it scales by
O(n). This patch adds a trie-ish data structure that allows quickly
descending based on the prefix.
Note that the trie structure used here is designed for real-world use,
hence it uses a relatively crude fixed-size bytewise table instead of
some fancy balancing scheme. It is quite cacheline efficient.
Using real-world routeserver prefix lists, matching against a fulltable
dump:
David Lamparter [Mon, 13 Apr 2015 08:21:35 +0000 (10:21 +0200)]
lib: straighten out ORF prefix list support
BGP ORF prefix lists are in a separate namespace; this was previously
hooked up with a special-purpose AFI value. This is a little kludgy for
extension, hence this splits it off.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Feng Lu [Thu, 3 Jul 2014 10:23:09 +0000 (18:23 +0800)]
zebra, lib/memtypes.c: the netlink sockets work per VRF
This patch lets the netlink sockets work per VRF.
* The definition of "struct nlsock" is moved into zebra/rib.h.
* The previous global variables "netlink" and "netlink_cmd" now
become the members of "struct zebra_vrf", and are initialized
in zebra_vrf_alloc().
* All relative functions now work for a specific VRF, by adding
a new parameter which specifies the working VRF, except those
functions in which the VRF ID can be obtained from the interface.
* kernel_init(), interface_list() and route_read() are now also
working per VRF, and moved from main() to zebra_vrf_enable().
* A new function kernel_terminate() is added to release the
netlink sockets. It is called from zebra_vrf_disable().
* Correct VRF ID, instead of the previous VRF_DEFAULT, are now
passed to the functions of processing interfaces or route
entries.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/memtypes.c
zebra/rib.h
zebra/rt_netlink.c
Feng Lu [Fri, 22 May 2015 09:40:10 +0000 (11:40 +0200)]
zebra: maintain RTADV per VRF
This moves the global variable "rtadv" into the "struct zebra_vrf",
so that RTADV feature can work per VRF.
* rtadv.c/rtadv.h:
Add a proper parameter to the functions so that the entity of the
"struct zebra_vrf" and interfaces can be obtained from the specified
VRF.
The old rtadv_init() is splitted into:
- rtadv_cmd_init(): it installs the RTADV commands; is called from
main();
- new rtadv_init(): it creates the socket; is called from
zebra_vrf_enable().
rtadv_terminate() is added to stop the threads, close the socket and
clear the counters. It is called from zebra_vrf_disable().
rtadv_make_socket() now calls vrf_socket() to create a socket in
the VRF.
* interface.h and rib.h: define the macro RTADV.
* main.c: according changes, refer to rtadv.c.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Conflicts:
zebra/interface.h
zebra/rib.h
zebra/rtadv.c
zebra/rtadv.h
Feng Lu [Fri, 22 May 2015 09:40:09 +0000 (11:40 +0200)]
zebra: add hooks upon enabling / disabling a VRF
zebra_vrf_enable() is the callback for VRF_ENABLE_HOOK.
It presently needs do nothing.
zebra_vrf_disable() is the callback for VRF_DISABLE_HOOK.
It presently withdraws routes, shuts down interfaces, and
clears the router-id candidates in that VRF.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Feng Lu [Fri, 22 May 2015 09:40:08 +0000 (11:40 +0200)]
lib/vrf: enable / disable a VRF
A new API vrf_is_enabled() is defined to check whether a VRF is ready
to use, that is, to allocate resources in that VRF. Currently there's
only one type of resource: socket.
Two new hooks VRF_ENABLE_HOOK/VRF_DISABLE_HOOK are introduced to tell
the user when a VRF gets ready or to be unavailable.
The VRF_ENABLE_HOOK callback is called in the new function vrf_enable(),
which is used to let the VRF be ready to use. Till now, only the default
VRF can be enabled, and we need do nothing to enable the default, except
calling the hook.
The VRF_DISABLE_HOOK callback is called in the new function
vrf_disable(), which is used to let the VRF be unusable. Till now,
it is called only when the VRF is to be deleted.
A new utility vrf_socket() is defined to provide a socket in a given
VRF to the user.
Till now before introducing a way of VRF realization, only the default
VRF is enabled since its birth, and vrf_socket() creates socket for
only the default VRF.
This patch defines the framework of the VRF APIs. The way they serve
the users is:
- vrf_is_enabled() is used to tell the user whether a VRF is usable;
- users are informed by the VRF_ENABLE_HOOK that a VRF gets usable;
they can allocate resources after that;
- users are informed by the VRF_DISABLE_HOOK that a VRF is to be
unavailable, and they must release the resources instantly;
- vrf_socket() is used to provide a socket in a given VRF.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Feng Lu [Fri, 22 May 2015 09:40:07 +0000 (11:40 +0200)]
zebra: maintain the router-id per VRF
A router may need different identifier among the VRFs. So move the
maintenance of router-id per VRF.
* rib.h:
Move the previous global variables in router-id.c into the
"struct zebra_vrf":
- struct list _rid_all_sorted_list/*rid_all_sorted_list
- struct list _rid_lo_sorted_list/*rid_lo_sorted_list
- struct prefix rid_user_assigned
* router-id.c/router-id.h:
A new parameter "vrf_id" is added to all the router-id APIs.
Their operations are done only within the specified VRF.
A new command "router-id A.B.C.D vrf N" is added to allow
manual router-id for any VRF.
The old router_id_init() function is splitted into two:
- router_id_cmd_init(): it only installs the commands
- router_id_init(): this new one initializes the variables for
a specified VRF
* zebra_rib.c: Add new functions zebra_vrf_get/lookup() called
from router-id.c.
* main.c: Replace router_id_init() with router_id_cmd_init() and
call the new router_id_init() in zebra_vrf_new().
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Conflicts:
zebra/rib.h
Feng Lu [Fri, 22 May 2015 09:40:02 +0000 (11:40 +0200)]
zebra: let FIB stand for its respective VRF
A new member "vrf_id" is added to "struct rib", reflecting the VRF
which it belongs to.
A new parameter "vrf_id" is added to the relative functions where
need, except those:
- which already have the parameter "vrf_id"; or
- which have a parameter in type of "struct rib"; or
- which have a parameter in type of "struct interface".
All incoming routes are set to default VRF.
In fact, all routes in FIB are kept in default VRF. And the logic
is not changed.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com>
[DL: conflicts fixed + compile warning fix] Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Conflicts:
zebra/connected.c
zebra/kernel_socket.c
zebra/rib.h
zebra/rt_netlink.c
zebra/zebra_rib.c
zebra/zserv.c
Feng Lu [Fri, 22 May 2015 09:40:01 +0000 (11:40 +0200)]
zebra: show interfaces in a specified VRF or all VRFs
The following commands only show interfaces in the default VRF:
show interface
show interface IFNAME
show interface description
New options are introduced to show interfaces in a specified VRF:
show interface vrf N
show interface IFNAME vrf N
show interface description vrf N
or all VRFs:
show interface vrf all
show interface IFNAME vrf all
show interface description vrf all
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Feng Lu [Fri, 22 May 2015 09:39:59 +0000 (11:39 +0200)]
lib: move the interface list into "struct vrf"
An interface belongs to a specific VRF. So move the interface list
into the "struct vrf".
* vrf.c/vrf.h:
- add a new member "struct list *iflist" to the the "struct vrf";
- call if_init() in vrf_new();
- call if_terminate() in vrf_delete();
- add utilities to access the interface list and VRF ID in the
specified VRF.
* if.c/if.h:
- the global "iflist" now only exists for the default VRF;
- the global "if_master" is initialized on the definition;
- in if_create(), the interface is added into the list in the
specified VRF; if the VRF does not exist, create one;
- add parameters to if_init()/if_terminate() so that the
interface list in the VRF can be initialized/destroyed;
- in if_dump_all() scan the interfaces in all the VRFs;
- add a command "show address vrf N" to show addresses in a
specified VRF;
- add a command "show address vrf all" to show addresses in all
VRFs;
- new APIs ifxxx_vrf() are added to access an interface in a
specified VRF.
The old interface APIs (the global variable "iflist" and the API
functions) are not changed to keep the backward compatibility.
The new APIs are used in the daemons which support multiple VRFs
(till now only zebra).
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Conflicts:
lib/if.c
Feng Lu [Fri, 22 May 2015 09:39:58 +0000 (11:39 +0200)]
*: call if_init()/if_terminate() from vrf_init()/vrf_terminate()
Later, an interface will belong to a specific VRF, and the interface
initialization will be a part of the VRF initialization. So now call
if_init() from vrf_init(), and if_terminate() from vrf_terminate().
Daemons have the according changes:
- if if_init() was called or "iflist" was initialized, now call
vrf_init() instead;
- if if_terminate() was called or "iflist" was destroyed, now call
vrf_terminate() instead.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Conflicts:
bgpd/bgp_main.c
pimd/pim_iface.c
pimd/pim_iface.h
pimd/pim_main.c
pimd/pimd.c
Feng Lu [Fri, 22 May 2015 09:39:56 +0000 (11:39 +0200)]
lib, zebra: move "struct vrf" to be a lib module
Previously "struct vrf" is defined locally in zebra. Now it is moved
to be a lib module.
This is the first step to support multi-VRF in quagga. The
implementation is splitted into small patches for the purpose of
easy review.
* lib:
"struct vrf" with basic members is defined in vrf.c. The member
"void *info" is for user data.
Some basic functions are defined in vrf.c for adding/deleting/
looking up a VRF, scanning the VRF table and initializing the
VRF module.
The type "vrf_id_t" is defined specificly for VRF ID.
* zebra:
The previous "struct vrf" is re-defined as "struct zebra_vrf";
and previous "vrf" variables are renamed to "zvrf".
The previous "struct vrf" related functions are removed from
zbera_rib.c. New functions are defined to maintain the new
"struct zebra_vrf".
The names vrf_xxx are reserved for the functions in VRF module.
So:
- the previous vrf_table() are renamed to zebra_vrf_table();
- the previous vrf_static_table() are renamed to
zebra_vrf_static_table().
The main logic is not changed.
BTW: Add a statement to zebra_snmp.c telling that the SNMP is
running only for the MIBs in the default VRF.
Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Conflicts:
lib/Makefile.am
zebra/zebra_rib.c
zebra/zebra_vty.c
vivek [Thu, 29 Oct 2015 17:30:45 +0000 (10:30 -0700)]
BGP: Do appropriate cleanup on receipt of redistribute update
When there is a change to a redistributed route, either an attribute
such as the metric or the route type itself has changed, protocol clients
receive an update of the route instead of a delete and add as a result
of an earlier optimization. The update needs to be handled as an implicit
delete for any existing redistributed route, especially to handle change
in route type.
vivek [Thu, 29 Oct 2015 16:41:23 +0000 (09:41 -0700)]
BGP: Check for duplicate and overlapping listen ranges
When configuring listen ranges for allowing dynamic BGP neighbors,
ensure that there are no duplicate or overlapping ones. This is
necessary because at the time of handling an incoming connection,
the first range that matches the source of the connection (and hence,
its peer-group parameters) will be used.
Donald Sharp [Wed, 28 Oct 2015 23:59:30 +0000 (19:59 -0400)]
lib: Memory reporting fails over 2GB
Ticket: CM-8015
Reviewed by: CCR-3717
Testing: See bug
The old style mallinfo() function uses an 'int' to
report memory usage data to the program. Unfortunately
modern architectures can chew through 2gb of memory like a
buzz saw hitting some warm butter, especially in the case
of a memory leak or memory fragmentation.
When a daemon uses more than 2gb of memory, just indicate it's
gotten large and we don't know anymore.
Pre-change behavior:
Robot-1# show memory
System allocator statistics:
Total heap allocated: 16777216 TiB
Holding block headers: 1288 KiB
Used small blocks: 0 bytes
Used ordinary blocks: 535 MiB
Free small blocks: 768 bytes
Free ordinary blocks: 16777216 TiB
Ordinary blocks: 266107
Small blocks: 24
Holding blocks: 2
Post-change behavior:
Robot-1# show memory
System allocator statistics:
Total heap allocated: 1572 KiB
Holding block headers: > 2GB
Used small blocks: 0 bytes
Used ordinary blocks: 1443 KiB
Free small blocks: 32 bytes
Free ordinary blocks: 129 KiB
Ordinary blocks: 2
Small blocks: 1
Holding blocks: 2
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
host-111# show ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv6, I - IS-IS, B - BGP, A - Babel, T - Table,
> - selected route, * - FIB route
S 2002:44:44:44::44/128 [99/0] is directly connected, swp1
S>* 2002:44:44:44::44/128 [4/0] is directly connected, swp1
This problem is fixed in the ipv4 code path. Copying the same
code from the ipv4 into the ipv6 code path fixes the issue.
With the fix:
host-111(config)# ipv6 route 2002:44:44:44::44/128 swp1 4
host-111(config)# do show ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv6, I - IS-IS, B - BGP, A - Babel, T - Table,
> - selected route, * - FIB route
S>* 2002:44:44:44::44/128 [4/0] is directly connected, swp1
C * fe80::/64 is directly connected, swp1
C>* fe80::/64 is directly connected, eth0
host-111(config)# ipv6 route 2002:44:44:44::44/128 swp1 99
host-111(config)# do show ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv6, I - IS-IS, B - BGP, A - Babel, T - Table,
> - selected route, * - FIB route
S>* 2002:44:44:44::44/128 [99/0] is directly connected, swp1
C * fe80::/64 is directly connected, swp1
C>* fe80::/64 is directly connected, eth0
host-111(config)#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Daniel Walton [Fri, 23 Oct 2015 17:36:55 +0000 (17:36 +0000)]
Quagga needs better debugs in lib/sockunion.c
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
Ticket: CM-7233
radhika [Thu, 22 Oct 2015 17:14:00 +0000 (10:14 -0700)]
Addition of missing zebra command descriptions
Ticket: CM-7456
Reviewed By: CCR-3528
Testing Done: Unit
Porting of the patch zebra-fix-cmd-type-desc-log.patch from 2.5 branch
Last few Zebra message command types defined were not added to the command type description table used for getting logging strings. This was causing the logs to display "unknown command type" instead of the actual command type. So, added all the missing zebra commands to the command type description table. Also, changed the order of the description table to match with the actual command type definition order.
When saving an integrated config file, certain commands such as
"ipv6 protocol", "ip nht route-map" etc. ended up with a very
different group of commands making it hard to look for them. This
fixes the command grouping so that related commands are located
together.
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Vipin Kumar <vipin@cumulusnetworks.com>
vivek [Wed, 21 Oct 2015 05:09:58 +0000 (22:09 -0700)]
Quagga: Display useful info when doing service quagga status
Ticket: CM-7132
Reviewed By: CCR-3461
Testing Done: the usual
Today, 'service quagga status' merely sets the return code and nothing
more. Like other services, it'd be good to print some useful output as
well.
Example output:
cumulus@top1$ sudo service quagga status ospfd
[ ok ] ospfd-1 is running.
[ ok ] ospfd-2 is running.
cumulus@top1$ sudo service quagga status
[ ok ] zebra is running.
[ ok ] ospfd-1 is running.
[ ok ] ospfd-2 is running.
[ ok ] ospf6d is running.
cumulus@top1$ sudo service quagga status
[ ok ] zebra is running.
[ ok ] ospfd-1 is running.
[FAIL] ospfd-2 is not running ... failed!
[ ok ] ospf6d is running.
cumulus@top1$ echo $?
1
cumulus@top1$
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
BGP Unnumbered and Interface based peering can interact in some strange
ways. One of them is when there's an IPv4 address on a link on which
BGP Unnumbered session is beng attempted, but the IPv4 address is not
a /30 or /31. As per the bug report, we end up attempting to start the
BGP FSM on receiving a notification that an IPv4 address is present on
an interface. To avoid attempting to go past BGP's start state in the
absence of a valid peer address is the right thing to do. And this
simple patch does just that.
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Vipin Kumar <vipin@cumulusnetworks.com>
vivek [Wed, 21 Oct 2015 04:52:52 +0000 (21:52 -0700)]
Zebra: Redistribute replace handling corner cases
Ticket: CM-7309
Reviewed By: CCR-3448
Testing Done: passing route_ospf_route_thrash, the new redist test
When zebra was modified to have redistributed routes follow a replace
logic instead of the del-add, one case was missed. When a route is
replaced with a change only to the source protocol (say from static
to bgp), its possible that the new source protocol is not selected
for redistribution by a client. Since we did not delete the route
initially, if the add is not allowed for the new source protocol
for a client, we need to send a delete of that redistributed route.
This is what the patch fixes.
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Redistributing routes goes through a del/add cycle whenever a redistributed
is updated. This del/add cycle causes disruption by causing traffic loss
for brief/long periods of time(6-8 s in case of OSPF). The modifications in
this patch remove the del/add cycle to ensure that this disruption doesn't
happen.
Also fixed sending no forwarding address when announcing IPv4 routes with IPv6
nexthops, and sending nexthop only when there is a single path.
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Vivek Venkatraman <vivek@cumulusnetworks.com>