This issue was discovered on a live session with an extremely
old cisco 7206VXR router running 12.2(33)SRE4. The sending router
is sending us an empty NLRI that is MP_REACH. From RFC
exploration(thanks Russ!) it appears that this was
considered a 'valid' way to send EOR.
Following discussion decided that we should treat
this situation as a EOR marker instead of bringing
down the session.
Applying this fix on the FRR router seeing this issue
allows it to continue it's peering relationship with
the ASR. Since this is a point fix I do not see
a high likelihood of further fallout.
Fixes: #1258
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This reverts commit c14777c6bf.
clang 5 is not widely available enough for people to indent with. This
is particularly problematic when rebasing/adjusting branches.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Problem found in testing where ipv6 labeled-unicast prefixes were not received
on the peers if a "service networking restart" was issued. Same problem would
happen with an ifdown/ifup on the link to the peer. Found the problem to be
that peers would establish for labeled-unicast even if a link-local address was
not yet available on the interface toward the peer, causing updates to be sent
without a nexthop value. These were then rejected by the peer. Fix is to delay
peer establishment until after the link-local addresses are available.
Ticket: CM-16779
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed By: Donald Sharp <sharpd@cumulusnetworks.com>
Testing Done: Manual testing successful. Bgp-smoke completed with no new failures
Most of the attributes in 'struct attr_extra' allow for
the more interesting cases of using bgp. The extra
overhead of managing it will induce errors as we add
more attributes and the extra memory overhead is
negligible on anything but full bgp feeds.
Additionally this greatly simplifies the code for
the handling of data.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd: Fix missing label set
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
log.c provides functionality for associating a constant (typically a
protocol constant) with a string and finding the string given the
constant. However this is highly delicate code that is extremely prone
to stack overflows and off-by-one's due to requiring the developer to
always remember to update the array size constant and to do so correctly
which, as shown by example, is never a good idea.b
The original goal of this code was to try to implement lookups in O(1)
time without a linear search through the message array. Since this code
is used 99% of the time for debugs, it's worth the 5-6 additional cmp's
worst case if it means we avoid explitable bugs due to oversights...
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
- All ipv4 labeled-unicast routes are now installed in the ipv4 unicast
table. This allows us to do things like take routes from an ipv4
unicast peer, allocate a label for them and TX them to a ipv4
labeled-unicast peer. We can do the opposite where we take routes from
a labeled-unicast peer, remove the label and advertise them to an ipv4
unicast peer.
- Multipath over a labeled route and non-labeled route is not allowed.
- You cannot activate a peer for both 'ipv4 unicast' and 'ipv4
labeled-unicast'
- The 'tag' variable was overloaded for zebra's route tag feature as
well as the mpls label. I added a 'mpls_label_t mpls' variable to
avoid this. This is much cleaner but resulted in touching a lot of
code.
Add checks related to AFI_L2VPN/SAFI_EVPN that were missing in some parts
of the code. Fix incorrect check skipping EVPN when sending End of RIB.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
The FSF's address changed, and we had a mixture of comment styles for
the GPL file header. (The style with * at the beginning won out with
580 to 141 in existing files.)
Note: I've intentionally left intact other "variations" of the copyright
header, e.g. whether it says "Zebra", "Quagga", "FRR", or nothing.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Originally we used the 'peer' parameter for this:
if (peer_sort (peer) == BGP_PEER_IBGP)
snprintf (buf + strlen (buf), size - strlen (buf), ", localpref %d",
attr->local_pref);
Now we have this:
if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
snprintf (buf + strlen (buf), size - strlen (buf), ", localpref %u",
attr->local_pref);
Remove the now useless 'peer' parameter.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
When we are receiving a route the attr->extra->label_index
is being set to 0. This should be BGP_INVALID_LABEL_INDEX
instead since we cannot rely on 0 to be correct for labels.
I believe that there are probably other spots that need this
type of fix, but I will let testing snuggle-bump them out.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Implement support for negotiating IPv4 or IPv6 labeled-unicast address
family, exchanging prefixes and installing them in the routing table, as
well as interactions with Zebra for FEC registration. This is the
implementation of RFC 3107.
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
This patch introduces the ability to make route type 5 message
when EVPN is enabled. Picked up paramters are collected from the
bgp extra attribute structure and are the ESI, the ethernet tag
information. In addition to this, nexthop attribute is collected too.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This patch introduces code to receive a NLRI message with route type
5, as defined in draft-ietf-bess-evpn-prefix-advertisement-02. It
It increases the number of parameters to extract from the NLRI and
to store into bgp extra information structure. Those parameters are
the ESI (ethernet segment identifier), the gateway IP Address (which
acts like nexthop attribute but is contained inside the NLRI itself)
and the ethernet tag identifier ( that acts for the VXLan Identifier)
This patch updates bgp_update() and bgp_withdraw() api, and then does the
necessary adapations for rfapi.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
To handle BGP NLRI EVPN messages, bgp is modified to handle AFI_L2VPN
and SAFI_EVPN values.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
BGP Large Communities are a novel way to signal information between
networks. An example of a Large Community is: "2914:65400:38016". Large
BGP Communities are composed of three 4-byte integers, separated by a
colon. This is easy to remember and accommodates advanced routing
policies in relation to 4-Byte ASNs.
This feature was developed by:
Keyur Patel <keyur@arrcus.com> (Arrcus, Inc.),
Job Snijders <job@ntt.net> (NTT Communications),
David Lamparter <equinox@opensourcerouting.org>
and Donald Sharp <sharpd@cumulusnetworks.com>
Signed-off-by: Job Snijders <job@ntt.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Introduce internal and IANA defintions for AFI/SAFI and mapping
functions and modify code to use these. This refactoring will
facilitate adding support for other AFI/SAFI whose IANA values
won't be suitable for internal data structure definitions (e.g.,
they are not contiguous).
The commit adds some fixes related to afi/safi testing with 'make check
' command.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Ticket: CM-11416
Reviewed By: CCR-3594 (mpls branch)
Testing Done: Not tested now, tested earlier on mpls branch
After graceful restart procedure, when BGP speaker has finished to send
its VPNv4 routes to the restarting peer, it also sends End-Of-Rib
message for afi=AFI_IPv4 safi=SAFI_MPLS_VPN.
Signed-off-by: Julien Courtat <julien.courtat@6wind.com>
* bgp_packet.c: (bgp_update_receive) doesn't differentiate between NLRIs that
are 0 AFI/SAFI cause they weren't set, and those because a peer sent a
bogus AFI/SAFI, before sending sending what may be a misleading, spurious
log message. Check the .nlri pointer is set and avoid this.
Incorporating a suggestion from: G. Paul Ziemba <unp@ziemba.us>
* bgpd parses NLRIs twice, a first pass "sanity check" and then a second pass
that changes actual state. For most AFI/SAFIs this is done by
bgp_nlri_sanity_check and bgp_nlri_parse, which are almost identical.
As the required action on a syntactic error in an NLRI is to NOTIFY and
shut down the session, it should be acceptable to just do a one pass
parse. There is no need to atomically handle the NLRIs.
* bgp_route.h: (bgp_nlri_sanity_check) Delete
* bgp_route.c: (bgp_nlri_parse) Make the prefixlen size check more general
and don't hard-code AFI/SAFI details, e.g. use prefix_blen library function.
Add error logs consistent with bgp_nlri_sanity_check as much as possible.
Add a "defense in depth" type check of the prefixlen against the sizeof
the (struct prefix) storage - ala bgp_nlri_parse_vpn.
Update standards text from draft RFC4271 to the actual RFC4271 text.
Extend the semantic consistency test of IPv6. E.g. it should skip mcast
NLRIs for unicast safi as v4 does.
* bgp_mplsvpn.{c,h}: Delete bgp_nlri_sanity_check_vpn and make
bgp_nlri_parse_vpn_body the bgp_nlri_parse_vpn function again.
(bgp_nlri_parse_vpn) Remove the notifies. The sanity checks were
responsible for this, but bgp_update_receive handles sending NOTIFY
generically for bgp_nlri_parse.
* bgp_attr.c: (bgp_mp_reach_parse,bgp_mp_unreach_parse) Delete sanity check.
NLRI parsing done after attr parsing by bgp_update_receive.
Arising out of discussions on the need for two-pass NLRI parse with:
Lou Berger <lberger@labn.net>
Donald Sharp <sharpd@cumulusnetworks.com>
When we receive a non v4 EOR, we were parsing it but
incorrectly applying the test for the flag for it.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
* bgp_packet.c: (bgp_update_receive) Lots of repeated code, doing same
thing for each AFI/SAFI. Except when it doesn't, e.g. the IPv4/VPN
case was missing the EoR bgp_clear_stale_route call - the only action
really needed for EoR.
Make this function a lot more regular, using common, AFI/SAFI
independent blocks so far as possible.
Replace the 4 separate bgp_nlris with an array, indexed by an enum.
The distinct blocks that handle calling bgp_nlri_parse for each
different AFI/SAFI can now be replaced with a loop.
Transmogrify the nlri SAFI from the SAFI_MPLS_LABELED_VPN code-point
used on the wire, to the SAFI_MPLS_VPN safi_t enum we use internally
as early as possible.
The existing code was not necessarily sending a NOTIFY for NLRI
parsing errors, if they arose via bgp_nlri_sanity_check. Send the
correct NOTIFY - INVAL_NETWORK for the classic NLRIs and OPT_ATTR_ERR
for the MP ones.
EoR can now be handled in one block. The existing code seemed broken
for EoR recognition in a number of ways:
1. A v4/unicast EoR should be an empty UPDATE. However, it seemed
to be treating an UPDATE with attributes, inc. MP REACH/UNREACH,
but no classic NLRIs, as a v4/uni EoR.
2. For other AFI/SAFIs, it was treating UPDATEs with no classic
withraw and with a zero-length MP withdraw as EoRs. However, that
would mean an UPDATE packet _with_ update NLRIs and a 0-len MP
withdraw could be classed as an EoR.
This seems to be loose coding leading to ambiguous protocol
situations and likely incorrect behaviour, rather than simply being
liberal. Be more strict about checking that an UPDATE really is an
EoR and definitely is not trying to update any NLRIs.
This same loose EoR parsing was noted by Chris Hall previously on
list.
(bgp_nlri_parse) Front end NLRI parse function, to fan-out to the correct
parser for the AFI/SAFI.
* bgp_route.c: (bgp_nlri_sanity_check) We try convert NLRI safi to
internal code-point ASAP, adjust switch for that. Leave the wire
code point in for defensive coding.
(bgp_nlri_parse) rename to bgp_nlri_parse_ip.
* tests/bgp_mp_attr_test.c: Can just use bgp_nlri_parse frontend.
* bgp_route.h: (bgp_nlri_sanity_check) The bulk of the args are equivalent
to a (struct bgp_nlri), consolidate.
* bgp_route.c: (bgp_nlri_sanity_check) Make this a frontend for all afi/safis.
Including SAFI_MPLS_LABELED_VPN.
(bgp_nlri_sanity_check_ip) Regular IP NLRI sanity check based on the
existing code, and adjusted for (struct bgp_nlri *) arg.
* bgp_attr.c: (bgp_mp_reach_parse) Adjust for passing (struct bgp_nlri *)
to bgp_nlri_sanity_check.
Get rid of special-casing to not sanity check VPN.
(bgp_mp_unreach_parse) Ditto.
* bgp_mplsvpn.c: Use the same VPN parsing code for both the sanity
check and the actual parse.
(bgp_nlri_parse_vpn) renamed to bgp_nlri_parse_vpn_body and made
internal.
(bgp_nlri_parse_vpn_body) Added (bool) argument to control whether it
is sanity checking or whether it should update routing state for each
NLRI. Send a NOTIFY and reset the session, if there's a parsing
error, as bgp_nlri_sanity_check_ip does, and as is required by the
RFC.
(bgp_nlri_parse_vpn) now a wrapper to call _body with update.
(bgp_nlri_sanity_check_vpn) wrapper to call parser without
updating.
* bgp_mplsvpn.h: (bgp_nlri_sanity_check_vpn) export for
bgp_nlri_sanity_check.
* bgp_packet.c: (bgp_update_receive) Adjust for bgp_nlri_sanity_check
argument changes.
* test/bgp_mp_attr_test.c: Extend to also test the NLRI parsing functions,
if the initial MP-attr parsing has succeeded. Fix the NLRI in the
VPN cases. Add further VPN tests.
* tests/bgpd.tests/testbgpmpattr.exp: Add the new test cases.
This commit a joint effort of:
Lou Berger <lberger@labn.net>
Donald Sharp <sharpd@cumulusnetworks.com>
Paul Jakma <paul.jakma@hpe.com> / <paul@jakma.org>
* bgp_encap.{c,h} (bgp_nlri_parse_encap) afi is already in the NLRI argument.
update or withdraw is signalled by attr being non-NULL or NULL.
* bgp_packet.c: (update_receive) fixup to match, and also make the attr
argument conform with NLRI_ATTR_ARG for correct error handling on
optional, transitive, partial, attributes.
Reverts the --enable-bgp-standalone and makes it so that you
need to use --enable-cumulus to get the cumulus behavior.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
When compiling/running in with --enable-bgp-standalone=yes allow
v4 sessions to be established with no v4 address configured.
Additionally allow v6 connections with no v6 addresses
configured.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
lib/zebra.h has FILTER_X #define's. These do not belong there.
Put them in lib/filter.h where they belong.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
(cherry picked from commit 0490729cc033a3483fc6b0ed45085ee249cac779)
VPNv6 changes picked from upstream needed fixes and updates due to some
fundamental changes implemented by Cumulus (BGP update-groups, RFC 5549
and nexthop setting etc.) which aren't present upstream.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Updates: 945c8fe, 8ecd326, bb86c60, 93b73df, f4c8985
There wasn't much missing for VPNv6 to begin with; just a few bits of
de- & encoding and a few lists to be updated.
Signed-off-by: Lou Berger <lberger@labn.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
[Editorial note: Signed-off-by may imply an authorship claim, but need not]
Edited-by: Paul Jakma <paul.jakma@hpe.com> / <paul@jakma.org>
(cherry picked from commit 9da04bca0e994ec92b9242159bf27d89c6743354)
Conflicts:
bgpd/bgp_attr.c
bgpd/bgp_mplsvpn.c
bgpd/bgpd.c
OPEN message handler moves the connection from the temporary
"struct peer" (used to accept it) to the real "struct peer" based
on the configuration. RTT needs to be updated only to the real
struct peer, and this patch moves the RTT query to point where
realpeer is known.
Fixes: ef757700d0 "bgpd: allow using rtt in route-map's set metric"
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
(cherry picked from commit 0edba8b6ad9c83fa0a3cc58765fe9f123f4109ac)
Conflicts:
bgpd/bgp_packet.c
Useful when the BGP neighbors are over tunnels that have large
differences in geographic distances and RTTs. Especially useful
for DMVPN setups to allow preferring closes hub.
The parameter is added as new alias command as otherwise it seems
the command parser is not able to match it properly (it seems
merging is done for the various 'set metric' route-map objects in
different routing engines). For same reason also they are listed
as three separate options: optional +/- seems not possibly easily.
Related research papers:
http://www.pps.univ-paris-diderot.fr/~jch/research/delay-based.pdfhttp://arxiv.org/pdf/1309.0632.pdf
Paper on similar extension to Babel:
http://www.pps.univ-paris-diderot.fr/~jch/research/rapport-jonglez-2013.pdf
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit ef757700d0fd51dc0b46df9d3631208919f9b779)
* ANVL testing by Martin Winter threw up a crash in bgpd in aspath_dup
called from bgp_packet_attribute, if attr->aspath was NULL, on an IPv6
UPDATE.
This root cause is that the checks for well-known, mandatory attributes
were being applied only if an UPDATE contained the IPv4 NLRI and the
peer was configured for v4/unicast (i.e. not deconfigured). This is
something inherited from GNU Zebra, and never noticed before.
* bgp_attr.c: (bgp_attr_parse) Move the well-known mandatory attribute
check to here, so that it can be run immediately after all attributes
are parsed, and before any further processing of attributes that might
assume the existence of WK/M attributes (e.g. AS4-Path).
(bgp_attr_munge_as4_attrs) Missing AS_PATH shouldn't happen here anymore,
but retain a check anyway for robustness - it's definitely a hard error
though.
* bgp_attr.h: (bgp_attr_check) No longer needs to be exported, make static.
* bgp_packet.c: (bgp_update_receive) Responsibility for well-known check
now in bgp_attr_parse.
(cherry picked from commit 055086f70febc30fdfd94bb4406e9075d6934cd8)
Conflicts:
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_packet.c
Fix lots of warnings. Some const and type-pun breaks strict-aliasing
warnings left but much reduced.
* bgp_advertise.h: (struct bgp_advertise_fifo) is functionally identical to
(struct fifo), so just use that. Makes it clearer the beginning of
(struct bgp_advertise) is compatible with with (struct fifo), which seems
to be enough for gcc.
Add a BGP_ADV_FIFO_HEAD macro to contain the right cast to try shut up
type-punning breaks strict aliasing warnings.
* bgp_packet.c: Use BGP_ADV_FIFO_HEAD.
(bgp_route_refresh_receive) fix an interesting logic error in
(!ok || (ret != BLAH)) where ret is only well-defined if ok.
* bgp_vty.c: Peer commands should use bgp_vty_return to set their return.
* jhash.{c,h}: Can take const on * args without adding issues & fix warnings.
* libospf.h: LSA sequence numbers use the unsigned range of values, and
constants need to be set to unsigned, or it causes warnings in ospf6d.
* md5.h: signedness of caddr_t is implementation specific, change to an
explicit (uint_8 *), fix sign/unsigned comparison warnings.
* vty.c: (vty_log_fixed) const on level is well-intentioned, but not going
to fly given iov_base.
* workqueue.c: ALL_LIST_ELEMENTS_RO tests for null pointer, which is always
true for address of static variable. Correct but pointless warning in
this case, but use a 2nd pointer to shut it up.
* ospf6_route.h: Add a comment about the use of (struct prefix) to stuff 2
different 32 bit IDs into in (struct ospf6_route), and the resulting
type-pun strict-alias breakage warnings this causes. Need to use 2
different fields to fix that warning?
general:
* remove unused variables, other than a few cases where they serve a
sufficiently useful documentary purpose (e.g. for code that needs
fixing), or they're required dummies. In those cases, try mark them as
unused.
* Remove dead code that can't be reached.
* Quite a few 'no ...' forms of vty commands take arguments, but do not
check the argument matches the command being negated. E.g., should
'distance X <prefix>' succeed if previously 'distance Y <prefix>' was set?
Or should it be required that the distance match the previously configured
distance for the prefix?
Ultimately, probably better to be strict about this. However, changing
from slack to strict might expose problems in command aliases and tools.
* Fix uninitialised use of variables.
* Fix sign/unsigned comparison warnings by making signedness of types consistent.
* Mark functions as static where their use is restricted to the same compilation
unit.
* Add required headers
* Move constants defined in headers into code.
* remove dead, unused functions that have no debug purpose.
(cherry picked from commit 7aa9dcef80b2ce50ecaa77653d87c8b84e009c49)
Conflicts:
bgpd/bgp_advertise.h
bgpd/bgp_mplsvpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_packet.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
lib/command.c
lib/if.c
lib/jhash.c
lib/workqueue.c
ospf6d/ospf6_lsa.c
ospf6d/ospf6_neighbor.h
ospf6d/ospf6_spf.c
ospf6d/ospf6_top.c
ospfd/ospf_api.c
zebra/router-id.c
zebra/rt_netlink.c
zebra/rt_netlink.h
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
When handling a received Update message, only process and store the
prefixes if the corresponding address family has been negotiated with
the peer. Prior to this change, the receive processing only checked
whether the address family was locally configured, trusting to the peer
to not advertise prefixes for an address family that has not been
negotiated. Most implementations conform to this but a misbehavior could
result in processing and memory overhead.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Ticket: CM-5594
Reviewed By: CCR-3946
Testing Done: Sanity test (good case)
Ensure that when the received OPEN message has errors, NOTIFICATION is
generated with the proper error code.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Ticket: CM-5974
Reviewed By: CCR-3945
Testing Done: Manual
Note: This fix should be sent upstream.
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
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
superm-redxp-05#
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>
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-7926
There was a crash from not NULLing out peer->hostname but I cleaned
up a bunch of other suspect ones as well.
Ticket: CM-7439
Reviewed By: Donald Sharp
Testing Done:
If a session was reset due to a NOTIFICATION the "show ip bgp
neighbor" output would not display details on what the
notification actually was. This patch changes that. Example:
superm-redxp-05# show ip bgp neighbors 20.1.2.2
BGP neighbor is 20.1.2.2, remote AS 21, local AS 10, external link
[snip]
Last reset 01:05:07, due to NOTIFICATION sent (OPEN Message Error/Bad Peer AS)
Ticket: CM-7012
Reviwed by: CCR-3451
Testing: See bug
When you specify a neighbor <interface> <something>
and don't specify a remote-as the neighbor relationship
will still come up with ipv6 unnumbered if you have
RA configured on the interface.
Ticket: CM-6883
Reviewed By: CCR-3272
Testing Done: Tested on 2.5.3-SE-1
This commit is a port of the patch bgpd-handle-peer-local-address-failure.patch
from 2.5-br.
When a peering is being established, the IPv4 and IPv6 addresses of the
local end of the connection, as applicable, are obtained and stored in
the peer's 'nexthop' structure to facilitate filling of the NEXT_HOP
field in Update messages among other things. The process of obtaining the
local address involves examination of the list of interfaces to identify
a match corresponding to the socket address of the connection.
There are timing conditions, especially when BGPD starts with a config,
where the interface may not have reached BGP from Zebra at the time a
peering reaches the state to determine the local addresses. The code does
not handle this well and the result could be Updates generated with bad
(Martian) NEXT_HOP values. Resolve the issue by bringing down the connection
in this case as not identifying the local addresses is really an error.
BGP: Make Capability handling a little more robust
This patch does two things:
- Returns the right sub error code when a malformed capability is rcvd
- Verifies that the capability length is a multiple of an individual unit
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com>
group and then replicated and sent for each member peer. The nexthop field
in the update is set only as part of this final step, as it may differ per
member peer. Update logs to display the final nexthop that is sent.
bgp: Fixup of the remote-as command to allow user to not have to enter an actual as number
Signed-off-by: Donald Sharp<sharpd@cumulusnetworks.com>
Reviewed-by:
BGP: Ensure EOR is always sent immediately after all prefixes have been adv.
Its possible that EOR send is delayed until the next KeepAlive timer fires.
This can happen when the send update iteration precisely matches the last
update packet sent. After this since there are no more updates to be sent,
no write thread is setup, but there's still the EOR to be sent. Therefore,
EOR is not sent right away causing some neighbors to not exit RO mode and
delaying convergence overall. This patch ensures that EOR is sent at the end
of all updates on startup.
Signed-off-by: Vivek Venkataraman <vivek@cumulusnetworks.com>
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
This patch implements the 'update-groups' functionality in BGP. This is a
function that can significantly improve BGP performance for Update generation
and resultant network convergence. BGP Updates are formed for "groups" of
peers and then replicated and sent out to each peer rather than being formed
for each peer. Thus major BGP operations related to outbound policy
application, adj-out maintenance and actual Update packet formation
are optimized.
BGP update-groups dynamically groups peers together based on configuration
as well as run-time criteria. Thus, it is more flexible than update-formation
based on peer-groups, which relies on operator configuration.
[Note that peer-group based update formation has been introduced into BGP by
Cumulus but is currently intended only for specific releases.]
From 11098af65b2b8f9535484703e7f40330a71cbae4 Mon Sep 17 00:00:00 2001
Subject: [PATCH] updgrp commits
Summary of changes
- added an option to enable keepalive debugs for a specific peer
- added an option to enable inbound and/or outbound updates debugs for a specific peer
- added an option to enable update debugs for a specific prefix
- added an option to enable zebra debugs for a specific prefix
- combined "deb bgp", "deb bgp events" and "deb bgp fsm" into "deb bgp neighbor-events". "deb bgp neighbor-events" can be enabled for a specific peer.
- merged "deb bgp filters" into "deb bgp update"
- moved the per-peer logging to one central log file. We now have the ability to filter all verbose debugs on a per-peer and per-prefix basis so we no longer need to keep log files per-peer. This simplifies troubleshooting by keeping all BGP logs in one location. The use
r can then grep for the peer IP they are interested in if they wish to see the logs for a specific peer.
- Changed "show debugging" in isis to "show debugging isis" to be consistent with all other protocols. This was very confusing for the user because they would type "show debug" and expect to see a list of debugs enabled across all protocols.
- Removed "undebug" from the parser for BGP. Again this was to be consisten with all other protocols.
- Removed the "all" keyword from the BGP debug parser. The user can now do "no debug bgp" to disable all BGP debugs, before you had to type "no deb all bgp" which was confusing.
The new parse tree for BGP debugging is:
deb bgp as4
deb bgp as4 segment
deb bgp keepalives [A.B.C.D|WORD|X:X::X:X]
deb bgp neighbor-events [A.B.C.D|WORD|X:X::X:X]
deb bgp nht
deb bgp updates [in|out] [A.B.C.D|WORD|X:X::X:X]
deb bgp updates prefix [A.B.C.D/M|X:X::X:X/M]
deb bgp zebra
deb bgp zebra prefix [A.B.C.D/M|X:X::X:X/M]
- Schedule write thread for advertisements and withdraws only if corresponding
FIFOs are growing and/or upon work_queue getting fully processed.
- Set non-default yield time for the main work_queue, as the default value
of 10ms results in yielding after processing very few nodes.
- Remove unnecessary scheduling of write thread when update packet is formed.
- If MRAI is 0, don't start a timer unnecessarily, directly schedule write
thread.
- Some debugs.
ISSUE:
During startup, BGP update prefix packing wasnt optimal and route installation
was found to be spread over.
SOLUTION:
With this patch, update-delay post processing is serialized to achieve:
a. better peer update packing
(which helps in reducing total number of BGP update packets)
b. installation of the resulting routes in zebra as close to each others
as possible.
(which can help zebra batch its processing and updates to Kernel better)
BGP: Fix FSM to handle active/passive connections better
The existing code didn't work well when dual connections resulted between
peers during session bringup. This patch fixes that.
Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
BGP: Event-driven route announcement taking into account min route advertisement interval
ISSUE
BGP starts the routeadv timer (peer->t_routeadv) to expire in 1 sec
when a peer is established. From then on, the timer expires
periodically based on the configured MRAI value (default: 30sec for
EBGP, 5sec for IBGP). At the expiry, the write thread is triggered
that takes the routes from peer's sync FIFO (adj-rib-out) and sends
UPDATEs. This has a few drawbacks:
(1) Delay in new route announcement: Even when the last UPDATE message
was sent a while back, the next route change will necessarily have
to wait for routeadv expiry
(2) CPU usage: The timer is always armed. If the operator chooses to
configure a lower value of MRAI (zero second is a preferred choice
in many deployments) for better convergence, it leads to high CPU
usage for BGP process, even at the times of no network churn.
PATCH
Make the route advertisement event-driven - When routes are added to
peer's sync FIFO, check if the routeadv timer needs to be adjusted (or
started). Conversely, do not arm the routeadv timer unconditionally.
The patch also addresses route announcements during read-only mode
(update-delay). During read-only mode operation, the routeadv timer
is not started. When BGP comes out of read-only mode and all the
routes are processed, the timer is started for all peers with zero
expiry, so that the UPDATEs can be sent all at once. This leads to
(near-)optimal UPDATE packing.
Finally, the patch makes the "max # packets to write to peer socket at
a time" configurable. Currently it is hard-coded to 10. The command is
at the top router-bgp mode and is called "write-quanta <number>". It
is a useful convergence parameter to tweak.
Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
ISSUE:
Quagga BGP doesn't send or use the restart-bit via the Graceful-Restart(GR)
capability. GR capability implementation isn't complete as per the RFC.
PATCH:
Patch uses BGP instance creation as the beginning of the startup period,
and 'restart_time' is taken as the startup period. As a result, BGP will
set the restart bit in the GR capability of the OPEN messages during the
startup period.
As an indication of quagga implementation's capability of sending End-Of-RIB,
helping a restarting neighbor, quagga BGP will now send global GR capability
irrespective of the graceful-restart config in BGP and the address-family
specific GR capability will be sent only if the GR config is present.
Forwarding bit is not set assuming its not preserved.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
When bgp_attr_parse returns BGP_ATTR_PARSE_ERROR, it may already have
parsed and allocated some attributes before hitting that error. Free
the attr's data before returning.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Quagga sources have inherited a slew of Page Feed (^L, \xC) characters
from ancient history. Among other things, these break patchwork's
XML-RPC API because \xC is not a valid character in XML documents.
Nuke them from high orbit.
Patches can be adapted simply by:
sed -e 's%^L%%' -i filename.patch
(you can type page feeds in some environments with Ctrl-V Ctrl-L)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
ISSUE:
Currently, for non-ipv4-unicast address families where prefixes are
encoded in MP_REACH/MP_UNREACH attributes, BGP ends up sending one
prefix per UPDATE message. This is quite inefficient. The patch
addresses the issue.
PATCH:
We introduce a scratch buffer in the peer structure that stores the
MP_REACH/MP_UNREACH attributes for non-ipv4-unicast families. This
enables us to encode multiple prefixes. In the end, the two buffers
are merged to create the UPDATE packet.
Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
[DL: removed no longer existing bgp_packet_withdraw prototype]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
switching the socket to blocking may well block the entire bgpd process
for some time if our peer is overloaded (which may well be the original
reason for the NOTIFY)
The error handling is slightly different from the previous ML discussion
on this; buffer exhaustion isn't technically a fatal TCP error, and we
should probably proceed with FSM actions according to a sent NOTIFY
(adjusting timers) even if we didn't manage to get the NOTIFY onto the
wire.
Acked-by: Leonid Rosenboim <lrosenbo@wrs.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This pushes out the NOTIFY message before closing a connection.
Previously, the TCP_CORK bandwidth optimization code caused NOTIFY
messages to disappear prior to when the connection is closed.
* bgpd/bgp_packet.c: unset CORK, set NODELAY, and replace
writen() by more correct write()
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Keep data flowing, uncork after each BGP_WRITE_PACKET_MAX.
This makes TCP send data sooner, since thread may not be scheduled
again for a a longish time because of new UPDATE's coming in.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.org>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
The readtime value is for diagnostic, and doesn't have to be highly
accurate. This also fixes a problem where the readtime was being measured
with system clock, but the peer_uptime() was comparing with bgp_clock.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
BGP4-ANVL 20.1 ANVL tries to open BGP with version 5 and expects correct
notification in response. Quagga sends notification, but with incorrect
information in it.
The data needs to be a 2-byte value, and for now we respond with 0004 for any
peer version other than 4.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
The timers are rearmed after events processing. After 6a4677b7 we
do not generate events that can rearm the holdtime timer.
Fix it's to call bgp_timer_set() directly as it's done from bgp_event().
Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Tested-by: Martin Winter <mwinter@opensourcerouting.org>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* bgp_packet.c: (bgp_update_receive) for every update received we queue
an event just to cancel the holdtime timer, done in bgp_fsm_update().
Instead cancel the timer directly an avoid a scheduling pass.
This incidently fixes another problem found on a slow box, where thousands
of events threads were queued, and run, but never freed, because they are
moved to the unused list that grows without bounds.
Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Reduce memory heap fragmentation and pressure on the memory allocator.
Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Just the first change pushes bgp_update_receive() from 6th to ~14th on a
full internet table load profiling session.
* bgp_debug.c: (bgp_update_receive) The attrstr initialization is expensive,
moved under the debug conditional where it is used and just initialize the
first char to NULL.
(bgp_update_default_send) Initialize attrstr needed for bgp_dump_attr().
Moved some buffers used for printing IP[4|6] addresses under the debug
conditionals that use them and reduced its size.
Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Address problem where bgpd would reject a session if a peer sent some
capabilities in its Open message, but did not include a Multiprotocol
extensions capability. Note that the session would come up if there
were no capabilities at all in the Open message.
* Add the 'mp_capability' out parameter to
bgp_capability_parse(). Set it to '1' if a Multiprotocol
extensions capability is encountered.
* Switch on 'mp_capability' instead of 'capability' in the calling
functions to determine if the peer indicated the set of AFI/SAFIs
it supports.
The net result is that when a peer does not send an MP capability,
it is assumed to support the AFI/SAFIs configured for it locally.
* bgp_packet.c: (bgp_open_receive) Errors from bgp_open_option_parse are
detected, and the code will stop processing the OPEN and return. However
it does so without calling bgp_notify_send to send a NOTIFY - which means
the peer FSM doesn't get stopped, and bgp_read will be called again later.
Because it returns, it doesn't go through the code near the end of the
function that removes the current message from the peer input streaam.
Thus the next call to bgp_read will try to parse a half-parsed stream as
if it were a new BGP message, leading to an assert later in the code when
it tries to read stuff that isn't there. Add the required call to
bgp_notify_send before returning.
* bgp_open.c: (bgp_capability_as4) Be a bit stricter, check the length field
corresponds to the only value it can be, which is the amount we're going to
read off the stream. And make sure the capability flag gets set, so
callers can know this capability was read, regardless.
(peek_for_as4_capability) Let bgp_capability_as4 do the length check.